[
  {
    "path": ".gitattributes",
    "content": "# Ensure all Java files use LF.\n*.java eol=lf\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# This is a comment.\n# Each line is a file pattern followed by one or more owners.\n\n# See: https://help.github.com/articles/about-codeowners/\n\n*       @keizer619\n\n# Components\n/ballerina-test-automation/ @keizer619\n/ballerina-test/ @keizer619\n/build-time-tests/ @azinneera\n/cache-generator/ @warunalakshitha\n/config/ @keizer619\n/devtools-integration-tests/ @azinneera\n/dist-repo-builder/ @keizer619\n/examples/ @MaryamZi @NipunaRanasinghe @gimantha\n/gradle/ @keizer619 \n/installers/ @keizer619\n/language-server-simulator/ @kavinduZoysa\n/project-api-tests/ @azinneera\n/resources/ @keizer619\n/stdlib-integration-tests/ @NipunaRanasinghe\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "content": "name: \"🐞 Report a Bug\"\ndescription: Create an issue if something does not work as expected.\nlabels: [\"Type/Bug\"]\nbody:\n  - type: textarea\n    id: background\n    attributes:\n      label: Description\n      description: Please share a clear and concise description of the problem.\n      placeholder: Description\n  - type: textarea\n    id: steps\n    attributes:\n      label: Steps to Reproduce\n      description: List the steps you followed when you encountered the issue. Provide sample source code to reproduce the issue where applicable.\n    validations:\n      required: true\n  - type: input\n    id: version\n    attributes:\n      label: Version\n      description: Enter product/component version.\n    validations:\n      required: true\n  - type: textarea\n    id: environment\n    attributes:\n      label: Environment Details (with versions)\n      description: Mention the environment details (OS, Client, etc.) that the product is running on.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n- name: '📚 Documentation Issue'\n  about: Request a new article, missing topic, or report an issue if a topic is incorrect in the current documentation.\n  url: https://github.com/ballerina-platform/ballerina-dev-website/issues/new/choose\n- name: General Question\n  url: https://stackoverflow.com/questions/tagged/ballerina\n  about: \"If you have a question then please ask on Stack Overflow using the #ballerina tag.\"\n- name: Chat on Ballerina Discord Channel\n  url: https://discord.gg/ballerinalang\n  about: \"Chat about anything else with the community.\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/improvement.yml",
    "content": "name: \"🚀 Improvement Request\"\ndescription: Suggest an improvement to the product.\nlabels: [\"Type/Improvement\"]\nbody:\n  - type: textarea\n    id: limitation\n    attributes:\n      label: Current Limitation\n      description: Describe the the current limitation.\n    validations:\n      required: true\n  - type: textarea\n    id: suggestion\n    attributes:\n      label: Suggested Improvement\n      description: Describe the the improvement you suggest.\n    validations:\n      required: true\n  - type: input\n    id: version\n    attributes:\n      label: Version\n      description: Enter component version.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/new-feature.yml",
    "content": "name: \"💡 New Feature Request\"\ndescription: Suggest new functionality and features for the product.\nlabels: [\"Type/NewFeature\"]\nbody:\n  - type: textarea\n    id: problem\n    attributes:\n      label: Problem\n      description: What is the problem this feature will solve?\n    validations:\n      required: true\n  - type: textarea\n    id: solution\n    attributes:\n      label: Proposed Solution\n      description: Describe the solution you'd like to have.\n    validations:\n      required: true\n  - type: textarea\n    id: alternatives\n    attributes:\n      label: Alternatives\n      description: Describe any alternatives have you considered\n    validations:\n      required: false\n  - type: input\n    id: version\n    attributes:\n      label: Version\n      description: Enter product/component version.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/task.yml",
    "content": "name: \"✍️ Create a Task\"\ndescription: Create a new task.\nlabels: [\"Type/Task\"]\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Description\n      description: A clear description of what needs to be done.\n    validations:\n      required: true\n  - type: input\n    id: version\n    attributes:\n      label: Version\n      description: Enter product/component version.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/workflows/add_reason_labels.yml",
    "content": "on:\n  issues:\n    types: [closed]\njobs:\n  check-resolution-label:\n    runs-on: ubuntu-latest\n    if:\n      ${{ contains(github.event.issue.labels.*.name, 'Type/Bug') && !(contains(github.event.issue.labels.*.name, 'Reason/EngineeringMistake') ||\n      contains(github.event.issue.labels.*.name, 'Reason/Complex') ||\n      contains(github.event.issue.labels.*.name, 'Reason/Regression') ||\n      contains(github.event.issue.labels.*.name, 'Reason/Other') ||\n      contains(github.event.issue.labels.*.name, 'Reason/Invalid') ||\n      contains(github.event.issue.labels.*.name, 'Reason/MultipleComponentInteraction')) }}\n    steps:\n      - run: echo Resolution label is not set\n      - run: gh issue comment $ISSUE --body \"This issue is **NOT** closed with a proper **Reason/** label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/EngineeringMistake** - The issue occurred due to a mistake made in the past.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/Regression** - The issue has introduced a regression.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/MultipleComponentInteraction** - Issue occured due to interactions in multiple components.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/Complex** - Issue occurred due to complex scenario.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/Invalid** - Issue is invalid.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- **Reason/Other** - None of the above cases.\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          ISSUE: ${{ github.event.issue.html_url }}\n"
  },
  {
    "path": ".github/workflows/bbe-on-demand.yml",
    "content": "name: Run BBE On Demand\n\non:\n  workflow_dispatch:\n    inputs:\n      branch:\n        description: 'Branch to run BBE tests against'\n        required: true\n        default: 'master'\n      javaVersion:\n        description: 'Java version to run BBE tests on'\n        required: true\n        default: '25'\n        type: choice\n        options:\n          - '21'\n          - '25'\n\njobs:\n  bbe-tests:\n    name: Run BBE on Java ${{ github.event.inputs.javaVersion }}\n    if: github.repository_owner == 'ballerina-platform'\n    runs-on: ubuntu-latest\n    concurrency:\n      group: ${{ github.ref }}-manual-bbe-tests\n      cancel-in-progress: true\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.inputs.branch }}\n\n      - name: Set up JDK 21\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'temurin'\n          java-version: '21'\n\n      - name: Build Ballerina pack\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: ${{ secrets.BALLERINA_BOT_WORKFLOW }}\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x :ballerina:testExamples -x :project-api-tests:test\n\n      - name: Set up JDK ${{ github.event.inputs.javaVersion }} for BBE tests\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'temurin'\n          java-version: ${{ github.event.inputs.javaVersion }}\n\n      - name: Run BBE tests\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: ${{ secrets.BALLERINA_BOT_WORKFLOW }}\n        run: |\n          java -version\n          ./gradlew :ballerina:testExamples --stacktrace --scan --console=plain --no-daemon --continue -x :project-api-tests:test\n"
  },
  {
    "path": ".github/workflows/daily-build-2201.12.x.yml",
    "content": "name: Daily build (2201.12.x)\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron:  '0 2 * * *'    # 07:30 in LK time (GMT+5:30)\n\njobs:\n  ubuntu-build:\n\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n        with:\n          ref: 2201.12.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Get daily docker version\n        id: version\n        run: echo \"::set-output name=version::$(date +'%Y-%m-%d')\"\n      - name: Get project version\n        id: project-version\n        run: |\n          SHORT_VERSION=$((grep -w \"version\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          DIST_VERSION=$((grep -w \"version\" | cut -d= -f2 | xargs) < gradle.properties)\n          LANG_VERSION=$((grep -w \"ballerinaLangVersion\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION-$CODE_NAME\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=langversion::$LANG_VERSION\"\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x project-api-tests:test\n      - name: Create linux-deb\n        id: run_installers_deb\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Create linux-rpm\n        id: run_installers_rpm\n        run: |\n          cd installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-x64.deb\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256 installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.version }}.zip\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Ballerina ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina ZIP\n          path: ballerina/build/distributions/ballerina-*-swan-lake.zip\n      - name: Archive Ballerina Short Name ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name ZIP\n          path: ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Linux deb\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer deb\n          path: installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Archive Linux rpm\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer rpm\n          path: installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n      - name: Archive MacOS Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos.zip\n      - name: Archive MacOS-ARM Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos-arm.zip\n      - name: Archive Windows Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-windows.zip\n      - name: Archive Linux deb Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux deb Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256\n      - name: Archive Linux rpm Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux rpm Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256\n      - name: Archive Ballerina Zip Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Zip Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}.zip.sha256\n      - name: Archive Ballerina Short Name Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name Hashes\n          path: ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256\n      - name: Install Ballerina DEB\n        run: sudo dpkg -i installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ steps.project-version.outputs.langversion }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n      - name: Checkout docker repo\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/module-ballerina-docker\n          path: module-ballerina-docker\n      - name: Copy zip artifact\n        run: cp ballerina/build/distributions/ballerina-22*.zip module-ballerina-docker/base/docker/\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v1\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v1\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n      - name: Build the docker image\n        id: docker_build\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          load: true\n          push: false\n          tags: ballerina/ballerina:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          push: true\n          tags: ballerina/ballerina:nightly-2201.12.x\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n      - name: Copy deb artifact\n        run: cp installers/linux-deb/target/ballerina-*-linux-x64.deb module-ballerina-docker/base/devcontainer/\n      - name: Build the dev container docker image\n        id: docker_build_devcontainer\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          load: true\n          push: false\n          tags: ballerina/ballerina-devcontainer:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Run Trivy vulnerability scanner for dev container docker image\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina-devcontainer:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push dev container image\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          push: true\n          tags: ballerina/ballerina-devcontainer:nightly-2201.12.x\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Notify failure\n        if: ${{ failure() }}\n        run: |\n          curl -X POST \\\n          'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"notify-build-failure\\\",\n            \\\"client_payload\\\": {\n              \\\"repoName\\\": \\\"ballerina-distribution\\\",\n              \\\"branch\\\": \\\"2201.12.x\\\"\n            }\n          }\"\n    outputs:\n      project-version: ${{ steps.project-version.outputs.version }}\n      lang-version: ${{ steps.project-version.outputs.langversion }}\n\n  project-api-tests:\n\n    runs-on: ubuntu-latest\n    if: false\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          prodCentralToken: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew :project-api-tests:test --stacktrace --scan --console=plain --no-daemon --continue\n\n  windows-build:\n\n    runs-on: windows-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew.bat clean build --stacktrace --scan --console=plain --no-daemon -x test\n\n  ubuntu-rpm-installer-test:\n    needs: ubuntu-build\n    runs-on: ubuntu-latest\n    container: centos:latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Setup Files\n        run: |\n          cd /etc/yum.repos.d/\n          sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*\n          sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*\n      - name: Download Ballerina rpm Installer\n        uses: actions/download-artifact@v4\n        with:\n          name: Linux Installer rpm\n      - name: Install Ballerina RPM\n        run: |\n          rpm -ivh ballerina-*-linux-x64.rpm\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          sed -i -e \"s/swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          sed -i -e \"s/swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  macos-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Download MacOS Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n      - name: Create macos-pkg\n        id: run_installers_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../\n          echo \"Created macos-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Archive MacOS pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256\n      - name: Archive MacOS pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Install Ballerina PKG\n        run: sudo installer -pkg installers/mac/target/pkg/ballerina-*-macos-x64.pkg -target /\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  macos-arm-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download MacOS-ARM Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n      - name: Create macos-arm-pkg\n        id: run_installers_arm_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created macos-arm-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n      - name: Archive MacOS-ARM pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256\n      - name: Archive MacOS-ARM pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ARM pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n\n  windows-installer-build:\n\n    needs: ubuntu-build\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - uses: actions/setup-dotnet@v1\n        with:\n          dotnet-version: '2.1.x'\n      - name: Install GUID Generator\n        run: dotnet tool install -g dotnet-guid --version 0.5.2\n      - name: Set up Wix toolkit\n        run: echo \"${WIX}bin\" >> $GITHUB_PATH\n        shell: bash\n      - name: Download Windows Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: Windows Installer ZIP\n      - name: Create windows-msi\n        id: run_installers_msi\n        run: |\n          move installers\\windows .\\..\\..\\\n          cd ..\\..\\windows\n          .\\build-ballerina-windows-x64.bat --version ${{ needs.ubuntu-build.outputs.project-version }} --path .\\..\\ballerina-distribution\\ballerina-distribution\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256 D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Archive Windows msi Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows msi Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256\n      - name: Archive Windows msi\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer msi\n          path: D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Install Ballerina msi\n        run: msiexec /i D:\\a\\windows\\target\\msi\\ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi /quiet /qr\n        shell: cmd\n      - name: Update Installer Test Configs\n        run: |\n          set DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          set SWAN_LAKE_LATEST_VERSION=swan-lake-%DISPLAY_TEXT%\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=%DISPLAY_TEXT%/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=%SWAN_LAKE_LATEST_VERSION%/\" ballerina-test-automation/gradle.properties\n        shell: cmd\n      - name: Run Installer Tests\n        working-directory: .\\ballerina-test-automation\\installer-test\n        run: |\n          $env:Path += \";C:\\Program Files\\Ballerina\\bin\"\n          .\\..\\gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  trigger-notifications:\n\n    needs: [ubuntu-build, macos-installer-build, windows-installer-build]\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.12.x\n      - name: Invoke Connector Ballerina Version Bump\n        run: |\n          ballerinaVersion=$((grep -w 'ballerinaLangVersion' | cut -d= -f2) < gradle.properties)\n          echo \"Triggering connectors dependency bumps...\" && \\\n          curl -X POST \\\n          https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: token ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"connector-update\\\",\n            \\\"client_payload\\\": {\n              \\\"ballerinaVersion\\\": \\\"$ballerinaVersion\\\"\n            }\n          }\"\n"
  },
  {
    "path": ".github/workflows/daily-build-2201.13.x.yml",
    "content": "name: Daily build (2201.13.x)\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron:  '0 2 * * *'    # 07:30 in LK time (GMT+5:30)\n\njobs:\n  ubuntu-build:\n\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n        with:\n          ref: 2201.13.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Get daily docker version\n        id: version\n        run: echo \"::set-output name=version::$(date +'%Y-%m-%d')\"\n      - name: Get project version\n        id: project-version\n        run: |\n          SHORT_VERSION=$((grep -w \"version\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          DIST_VERSION=$((grep -w \"version\" | cut -d= -f2 | xargs) < gradle.properties)\n          LANG_VERSION=$((grep -w \"ballerinaLangVersion\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION-$CODE_NAME\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=langversion::$LANG_VERSION\"\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x project-api-tests:test\n      - name: Create linux-deb\n        id: run_installers_deb\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Create linux-rpm\n        id: run_installers_rpm\n        run: |\n          cd installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-x64.deb\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256 installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.version }}.zip\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Ballerina ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina ZIP\n          path: ballerina/build/distributions/ballerina-*-swan-lake.zip\n      - name: Archive Ballerina Short Name ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name ZIP\n          path: ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Linux deb\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer deb\n          path: installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Archive Linux rpm\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer rpm\n          path: installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n      - name: Archive MacOS Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos.zip\n      - name: Archive MacOS-ARM Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos-arm.zip\n      - name: Archive Windows Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-windows.zip\n      - name: Archive Linux deb Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux deb Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256\n      - name: Archive Linux rpm Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux rpm Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256\n      - name: Archive Ballerina Zip Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Zip Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}.zip.sha256\n      - name: Archive Ballerina Short Name Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name Hashes\n          path: ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256\n      - name: Install Ballerina DEB\n        run: sudo dpkg -i installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ steps.project-version.outputs.langversion }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n      - name: Checkout docker repo\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/module-ballerina-docker\n          path: module-ballerina-docker\n      - name: Copy zip artifact\n        run: cp ballerina/build/distributions/ballerina-22*.zip module-ballerina-docker/base/docker/\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v1\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v1\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n      - name: Build the docker image\n        id: docker_build\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          load: true\n          push: false\n          tags: ballerina/ballerina:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          push: true\n          tags: ballerina/ballerina:nightly-2201.13.x\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n      - name: Copy deb artifact\n        run: cp installers/linux-deb/target/ballerina-*-linux-x64.deb module-ballerina-docker/base/devcontainer/\n      - name: Build the dev container docker image\n        id: docker_build_devcontainer\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          load: true\n          push: false\n          tags: ballerina/ballerina-devcontainer:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Run Trivy vulnerability scanner for dev container docker image\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina-devcontainer:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push dev container image\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          push: true\n          tags: ballerina/ballerina-devcontainer:nightly-2201.13.x\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Notify failure\n        if: ${{ failure() }}\n        run: |\n          curl -X POST \\\n          'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"notify-build-failure\\\",\n            \\\"client_payload\\\": {\n              \\\"repoName\\\": \\\"ballerina-distribution\\\",\n              \\\"branch\\\": \\\"2201.13.x\\\"\n            }\n          }\"\n    outputs:\n      project-version: ${{ steps.project-version.outputs.version }}\n      lang-version: ${{ steps.project-version.outputs.langversion }}\n\n  project-api-tests:\n\n    runs-on: ubuntu-latest\n    if: false\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          prodCentralToken: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew :project-api-tests:test --stacktrace --scan --console=plain --no-daemon --continue\n\n  windows-build:\n\n    runs-on: windows-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew.bat clean build --stacktrace --scan --console=plain --no-daemon -x test\n\n  ubuntu-rpm-installer-test:\n    needs: ubuntu-build\n    runs-on: ubuntu-latest\n    container: centos:latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Setup Files\n        run: |\n          cd /etc/yum.repos.d/\n          sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*\n          sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*\n      - name: Download Ballerina rpm Installer\n        uses: actions/download-artifact@v4\n        with:\n          name: Linux Installer rpm\n      - name: Install Ballerina RPM\n        run: |\n          rpm -ivh ballerina-*-linux-x64.rpm\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          sed -i -e \"s/swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          sed -i -e \"s/swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  macos-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Download MacOS Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n      - name: Create macos-pkg\n        id: run_installers_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../\n          echo \"Created macos-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Archive MacOS pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256\n      - name: Archive MacOS pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Install Ballerina PKG\n        run: sudo installer -pkg installers/mac/target/pkg/ballerina-*-macos-x64.pkg -target /\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  macos-arm-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download MacOS-ARM Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n      - name: Create macos-arm-pkg\n        id: run_installers_arm_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created macos-arm-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n      - name: Archive MacOS-ARM pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256\n      - name: Archive MacOS-ARM pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ARM pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n\n  windows-installer-build:\n\n    needs: ubuntu-build\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - uses: actions/setup-dotnet@v1\n        with:\n          dotnet-version: '2.1.x'\n      - name: Install GUID Generator\n        run: dotnet tool install -g dotnet-guid --version 0.5.2\n      - name: Set up Wix toolkit\n        run: echo \"${WIX}bin\" >> $GITHUB_PATH\n        shell: bash\n      - name: Download Windows Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: Windows Installer ZIP\n      - name: Create windows-msi\n        id: run_installers_msi\n        run: |\n          move installers\\windows .\\..\\..\\\n          cd ..\\..\\windows\n          .\\build-ballerina-windows-x64.bat --version ${{ needs.ubuntu-build.outputs.project-version }} --path .\\..\\ballerina-distribution\\ballerina-distribution\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256 D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Archive Windows msi Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows msi Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256\n      - name: Archive Windows msi\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer msi\n          path: D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Install Ballerina msi\n        run: msiexec /i D:\\a\\windows\\target\\msi\\ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi /quiet /qr\n        shell: cmd\n      - name: Update Installer Test Configs\n        run: |\n          set DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          set SWAN_LAKE_LATEST_VERSION=swan-lake-%DISPLAY_TEXT%\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=%DISPLAY_TEXT%/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=%SWAN_LAKE_LATEST_VERSION%/\" ballerina-test-automation/gradle.properties\n        shell: cmd\n      - name: Run Installer Tests\n        working-directory: .\\ballerina-test-automation\\installer-test\n        run: |\n          $env:Path += \";C:\\Program Files\\Ballerina\\bin\"\n          .\\..\\gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  trigger-notifications:\n\n    needs: [ubuntu-build, macos-installer-build, windows-installer-build]\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: 2201.13.x\n      - name: Invoke Connector Ballerina Version Bump\n        run: |\n          ballerinaVersion=$((grep -w 'ballerinaLangVersion' | cut -d= -f2) < gradle.properties)\n          echo \"Triggering connectors dependency bumps...\" && \\\n          curl -X POST \\\n          https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: token ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"connector-update\\\",\n            \\\"client_payload\\\": {\n              \\\"ballerinaVersion\\\": \\\"$ballerinaVersion\\\"\n            }\n          }\"\n"
  },
  {
    "path": ".github/workflows/daily-build-editor.yml",
    "content": "name: Daily build editor\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron:  '0 2 * * *'    # 07:30 in LK time (GMT+5:30)\n\njobs:\n  ubuntu-build:\n\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Use Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: '10.22.1'\n      - name: Checkout Dev Tools Repository\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/ballerina-dev-tools\n          path: ballerina-dev-tools\n      - name: Build with Gradle\n        id: build-dev-tools\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run:  |\n          cd ballerina-dev-tools\n          echo \"::set-output name=version::$(grep \"^version=\" gradle.properties | cut -d'=' -f2)\"\n          echo \"::set-output name=langVersion::$(grep \"^ballerinaLangVersion=\" gradle.properties | cut -d'=' -f2)\"\n          ./gradlew clean build --stacktrace --scan -x test  --console=plain --no-daemon --continue publishToMavenLocal\n          cd ..\n      - name: Checkout Distribution Repository\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/ballerina-distribution\n          path: ballerina-distribution\n      - name: Get daily docker version\n        id: version\n        run: echo \"::set-output name=version::$(date +'%Y-%m-%d')\"\n      - name: Get project version\n        id: project-version\n        run: |\n          cd ballerina-distribution\n          SHORT_VERSION=$((grep -w \"version\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          DIST_VERSION=$((grep -w \"version\" | cut -d= -f2 | xargs) < gradle.properties)\n          LANG_VERSION=$((grep -w \"ballerinaLangVersion\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION-$CODE_NAME\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=langversion::$LANG_VERSION\"\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: |\n          cd ballerina-distribution\n          sed -i \"s/^devToolsVersion=.*/devToolsVersion=${{ steps.build-dev-tools.outputs.version }}/\" gradle.properties\n          sed -i \"s/^ballerinaLangVersion=.*/ballerinaLangVersion=${{ steps.build-dev-tools.outputs.langVersion }}/\" gradle.properties\n          ./gradlew clean build --stacktrace --scan -x test --console=plain --no-daemon --continue -x project-api-tests:test\n      - name: Create linux-deb\n        id: run_installers_deb\n        run: |\n          cd ballerina-distribution/installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Create linux-rpm\n        id: run_installers_rpm\n        run: |\n          cd ballerina-distribution/installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Archive Ballerina ZIP\n        uses: actions/upload-artifact@v4\n        id: artifact-upload\n        with:\n          name: Ballerina ZIP\n          path: ballerina-distribution/ballerina/build/distributions/ballerina-*-swan-lake.zip\n      - name: Archive Ballerina Short Name ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name ZIP\n          path: ballerina-distribution/ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Linux deb\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer deb\n          path: ballerina-distribution/installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Archive Linux rpm\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer rpm\n          path: ballerina-distribution/installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n      - name: Archive MacOS Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n          path: ballerina-distribution/ballerina/build/distributions/ballerina-*-macos.zip\n      - name: Archive MacOS-ARM Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n          path: ballerina-distribution/ballerina/build/distributions/ballerina-*-macos-arm.zip\n      - name: Archive Windows Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer ZIP\n          path: ballerina-distribution/ballerina/build/distributions/ballerina-*-windows.zip\n      - name: Send release notification\n        shell: bash\n        run: |\n          body=$(cat << EOF\n          {\n          \"cards\": [\n              { \n              \"header\": {\n                  \"title\": \"Daily Build\",\n              },\n              \"sections\": [\n                  {\n                  \"widgets\": [\n                      {\n                      \"keyValue\": {\n                          \"topLabel\": \"Ballerina Distribution\",\n                          \"content\": \"v${{ steps.project-version.outputs.langversion }}\",\n                          \"onClick\": {\n                          \"openLink\": {\n                              \"url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"\n                          }\n                          },\n                          \"iconUrl\": \"https://lh6.googleusercontent.com/proxy/R9Rx8vYNd-_HZn58ckf5PNX7RMlC6P-B75fB7UQ_GFH5R0UwtfJ1gVNARBvH1us8LBuK4NVFsvMGnwZkm-H2_9ACwH_j0lQmExR1SRMNGlFcbrm_1O7foFpqqOiVzA\",\n                          \"button\": {\n                          \"textButton\": {\n                              \"text\": \"Download ZIP\",\n                              \"onClick\": {\n                              \"openLink\": {\n                                  \"url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/${{ steps.artifact-upload.outputs.artifact-id }}\"\n                              }\n                              }\n                          }\n                          }\n                      }\n                      }\n                  ]\n                  }\n              ]\n              }\n          ]\n          }\n          EOF\n          )\n          curl \\\n          -X POST \\\n          -H 'Content-Type: application/json' \\\n          \"https://chat.googleapis.com/v1/spaces/AAAApvQDm3o/messages?key=${{ secrets.EDITOR_CHAT_BOT_KEY }}&token=${{ secrets.EDITOR_CHAT_BOT_TOKEN }}\" \\\n          -d \"$body\"\n"
  },
  {
    "path": ".github/workflows/daily-build.yml",
    "content": "name: Daily build\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron:  '0 2 * * *'    # 07:30 in LK time (GMT+5:30)\n\njobs:\n  ubuntu-build:\n\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Get daily docker version\n        id: version\n        run: echo \"::set-output name=version::$(date +'%Y-%m-%d')\"\n      - name: Get project version\n        id: project-version\n        run: |\n          SHORT_VERSION=$((grep -w \"version\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          DIST_VERSION=$((grep -w \"version\" | cut -d= -f2 | xargs) < gradle.properties)\n          LANG_VERSION=$((grep -w \"ballerinaLangVersion\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION-$CODE_NAME\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=langversion::$LANG_VERSION\"\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x project-api-tests:test\n      - name: Create linux-deb\n        id: run_installers_deb\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Create linux-rpm\n        id: run_installers_rpm\n        run: |\n          cd installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.project-version.outputs.version }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-x64.deb\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256 installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.version }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.version }}.zip\n          openssl dgst -sha256 -out ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Ballerina ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina ZIP\n          path: ballerina/build/distributions/ballerina-*-swan-lake.zip\n      - name: Archive Ballerina Short Name ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name ZIP\n          path: ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      \n      # Delete existing nightly release if it exists\n      - name: Delete existing nightly release\n        continue-on-error: true\n        uses: actions/github-script@v7\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          script: |\n            const release = await github.rest.repos.getReleaseByTag({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              tag: 'nightly'\n            });\n            \n            await github.rest.repos.deleteRelease({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              release_id: release.data.id\n            });\n            \n            await github.rest.git.deleteRef({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              ref: 'tags/nightly'\n            });\n      \n      # Create nightly release and upload artifacts\n      - name: Create nightly release\n        uses: softprops/action-gh-release@v1\n        with:\n          tag_name: nightly\n          name: Nightly Build - ${{ steps.version.outputs.version }}\n          body: |\n            Automated nightly build for ${{ steps.version.outputs.version }}\n            Ballerina Version: ${{ steps.project-version.outputs.version }}\n          prerelease: true\n          files: |\n            ballerina/build/distributions/ballerina-*-swan-lake.zip\n            installers/linux-deb/target/ballerina-*-linux-x64.deb\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      \n      - name: Archive Linux deb\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer deb\n          path: installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Archive Linux rpm\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer rpm\n          path: installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n      - name: Archive Linux Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-linux.zip\n      - name: Archive Linux-ARM Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux-ARM Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-linux-arm.zip\n      - name: Archive MacOS Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos.zip\n      - name: Archive MacOS-ARM Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos-arm.zip\n      - name: Archive Windows Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-windows.zip\n      - name: Archive Linux deb Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux deb Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb.sha256\n      - name: Archive Linux rpm Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux rpm Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}-linux-x64.rpm.sha256\n      - name: Archive Ballerina Zip Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Zip Hashes\n          path: ballerina-${{ steps.project-version.outputs.version }}.zip.sha256\n      - name: Archive Ballerina Short Name Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name Hashes\n          path: ballerina-${{ steps.project-version.outputs.sversion }}.zip.sha256\n      - name: Install Ballerina DEB\n        run: sudo dpkg -i installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ steps.project-version.outputs.langversion }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n      - name: Checkout docker repo\n        uses: actions/checkout@v2\n        with:\n          repository: ballerina-platform/module-ballerina-docker\n          path: module-ballerina-docker\n      - name: Copy zip artifact\n        run: cp ballerina/build/distributions/ballerina-22*.zip module-ballerina-docker/base/docker/\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v1\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v1\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n      - name: Build the docker image\n        id: docker_build\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          load: true\n          push: false\n          tags: ballerina/ballerina:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          push: true\n          tags: ballerina/ballerina:nightly\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n      - name: Copy deb artifact\n        run: cp installers/linux-deb/target/ballerina-*-linux-x64.deb module-ballerina-docker/base/devcontainer/\n      - name: Build the dev container docker image\n        id: docker_build_devcontainer\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          load: true\n          push: false\n          tags: ballerina/ballerina-devcontainer:nightly-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Clean up created artifacts\n        run: |\n          rm -rf installers/linux-deb/target/ballerina-*-linux-x64.deb\n          rm -rf installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          rm -rf ballerina/build/distributions/ballerina-*-macos.zip\n          rm -rf ballerina/build/distributions/ballerina-*-macos-arm.zip\n          rm -rf ballerina/build/distributions/ballerina-*-windows.zip\n      - name: Run Trivy vulnerability scanner for dev container docker image\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina-devcontainer:nightly-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n      - name: Build and push dev container image\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/devcontainer/\n          push: true\n          tags: ballerina/ballerina-devcontainer:nightly\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.project-version.outputs.version }}-linux-x64.deb\n      - name: Notify failure\n        if: ${{ failure() }}\n        run: |\n          curl -X POST \\\n          'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"notify-build-failure\\\",\n            \\\"client_payload\\\": {\n              \\\"repoName\\\": \\\"ballerina-distribution\\\",\n              \\\"branch\\\": \\\"master\\\"\n            }\n          }\"\n    outputs:\n      project-version: ${{ steps.project-version.outputs.version }}\n      lang-version: ${{ steps.project-version.outputs.langversion }}\n\n  project-api-tests:\n\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          prodCentralToken: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew :project-api-tests:test --stacktrace --scan --console=plain --no-daemon --continue\n\n  windows-build:\n\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Build with Gradle\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: ./gradlew.bat clean build --stacktrace --scan --console=plain --no-daemon -x test\n\n  ubuntu-rpm-installer-test:\n    needs: ubuntu-build\n    runs-on: ubuntu-latest\n    container: centos:latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Setup Files\n        run: |\n          cd /etc/yum.repos.d/\n          sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*\n          sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*\n      - name: Download Ballerina rpm Installer\n        uses: actions/download-artifact@v4\n        with:\n          name: Linux Installer rpm\n      - name: Install Ballerina RPM\n        run: |\n          rpm -ivh ballerina-*-linux-x64.rpm\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          sed -i -e \"s/swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          sed -i -e \"s/swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  ubuntu-arm-installer-build:\n\n    needs: ubuntu-build\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download Linux-ARM Installer Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: Linux-ARM Installer ZIP\n      - name: Create linux-arm deb\n        working-directory: installers/linux-deb\n        run: |\n          ./build-ballerina-linux-deb-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created linux-arm-deb successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-linux-arm-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-arm-x64.deb\n      - name: Archive Linux deb\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux-ARM Installer deb\n          path: installers/linux-deb/target/ballerina-*-linux-arm-x64.deb\n      - name: Archive Linux deb Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux-ARM deb Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-linux-arm-x64.deb.sha256\n\n  macos-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download MacOS Installer Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS Installer ZIP\n      - name: Create macos-pkg\n        id: run_installers_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../\n          echo \"Created macos-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Archive MacOS pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-x64.pkg.sha256\n      - name: Archive MacOS pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-x64.pkg\n      - name: Install Ballerina PKG\n        run: sudo installer -pkg installers/mac/target/pkg/ballerina-*-macos-x64.pkg -target /\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  macos-arm-installer-build:\n\n    needs: ubuntu-build\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download MacOS-ARM Intaller Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: MacOS-ARM Installer ZIP\n      - name: Create macos-arm-pkg\n        id: run_installers_arm_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.ubuntu-build.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created macos-arm-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256 installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n      - name: Archive MacOS-ARM pkg Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS-ARM pkg Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-macos-arm-x64.pkg.sha256\n      - name: Archive MacOS-ARM pkg\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS Installer ARM pkg\n          path: installers/mac/target/pkg/ballerina-*-macos-arm-x64.pkg\n\n  windows-installer-build:\n\n    needs: ubuntu-build\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - uses: actions/setup-dotnet@v1\n        with:\n          dotnet-version: '2.1.x'\n      - name: Install GUID Generator\n        run: dotnet tool install -g dotnet-guid --version 0.5.2\n      - name: Set up Wix toolkit\n        run: echo \"${WIX}bin\" >> $GITHUB_PATH\n        shell: bash\n      - name: Download Windows Installer Zip\n        uses: actions/download-artifact@v4\n        with:\n          name: Windows Installer ZIP\n      - name: Create windows-msi\n        id: run_installers_msi\n        run: |\n          move installers\\windows .\\..\\..\\\n          cd ..\\..\\windows\n          .\\build-ballerina-windows-x64.bat --version ${{ needs.ubuntu-build.outputs.project-version }} --path .\\..\\ballerina-distribution\\ballerina-distribution\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256 D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Archive Windows msi Hashes\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows msi Hashes\n          path: ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi.sha256\n      - name: Archive Windows msi\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer msi\n          path: D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Install Ballerina msi\n        run: msiexec /i D:\\a\\windows\\target\\msi\\ballerina-${{ needs.ubuntu-build.outputs.project-version }}-windows-x64.msi /quiet /qr\n        shell: cmd\n      - name: Update Installer Test Configs\n        run: |\n          set DISPLAY_TEXT=${{ needs.ubuntu-build.outputs.lang-version }}\n          set SWAN_LAKE_LATEST_VERSION=swan-lake-%DISPLAY_TEXT%\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=%DISPLAY_TEXT%/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=%SWAN_LAKE_LATEST_VERSION%/\" ballerina-test-automation/gradle.properties\n        shell: cmd\n      - name: Run Installer Tests\n        working-directory: .\\ballerina-test-automation\\installer-test\n        run: |\n          $env:Path += \";C:\\Program Files\\Ballerina\\bin\"\n          .\\..\\gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n        env:\n          TEST_MODE_ACTIVE: true\n\n  trigger-notifications:\n\n    needs: [ubuntu-build, macos-installer-build, windows-installer-build]\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Invoke Connector Ballerina Version Bump\n        run: |\n          ballerinaVersion=$((grep -w 'ballerinaLangVersion' | cut -d= -f2) < gradle.properties)\n          echo \"Triggering connectors dependency bumps...\" && \\\n          curl -X POST \\\n          https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: token ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"connector-update\\\",\n            \\\"client_payload\\\": {\n              \\\"ballerinaVersion\\\": \\\"$ballerinaVersion\\\"\n            }\n          }\"\n"
  },
  {
    "path": ".github/workflows/fossa_scan.yml",
    "content": "name: Fossa Scan\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '30 18 * * *'    # 00:00 in LK time (GMT+5:30)\njobs:\n  fossa-scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: fossas/fossa-action@main\n        env:\n          packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }}\n          packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }}       \n        with:\n          api-key: ${{secrets.FOSSA_APIKEY}}\n"
  },
  {
    "path": ".github/workflows/language_server_simulator_fhir.yml",
    "content": "name: Language Server Simulator on FHIR\n\non:\n  schedule:\n    - cron: '0 */12 * * *'\n  workflow_dispatch:\n\njobs:\n  run_simulator:\n    name: Run LS Simulator\n    runs-on: ubuntu-latest\n    timeout-minutes: 240\n    strategy:\n      fail-fast: false\n      matrix:\n        branch: [ \"master\" ]\n        skipGenerators: [ \"\", \"IMPORT_STATEMENT\" ]\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: ${{ matrix.branch }}\n\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n\n      - name: Initialize sub-modules\n        run: git submodule update --init\n\n      - name: Build with Gradle\n        timeout-minutes: 180\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          export DISPLAY=':99.0'\n          /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n          ./gradlew clean :language-server-simulator:runLSSimulatorOnFHIR -Dls.simulation.skipGenerators=${{ matrix.skipGenerators }}\n\n      - name: Check Simulation Failure\n        run: if test -f dump.hprof; then exit 1; else exit 0; fi\n\n      - name: Analyze Heap Dump If Exists\n        if: failure()\n        run: |\n          if test -f dump.hprof; then echo \"Heap sump exists. Analyzing...\"; else exit 0; fi\n          wget https://ftp.jaist.ac.jp/pub/eclipse/mat/1.12.0/rcp/MemoryAnalyzer-1.12.0.20210602-linux.gtk.x86_64.zip\n          unzip MemoryAnalyzer-1.12.0.20210602-linux.gtk.x86_64.zip\n          ./mat/ParseHeapDump.sh ./dump.hprof org.eclipse.mat.api:suspects\n\n      - name: Upload Heap Dumps\n        uses: actions/upload-artifact@v4\n        if: always()\n        with:\n          name: heap_dump-${{ matrix.branch }}.hprof\n          path: '*.hprof'\n\n      - name: Upload Leaks Suspects\n        uses: actions/upload-artifact@v4\n        if: failure()\n        with:\n          name: Leak_Suspects-${{ matrix.branch }}\n          path: 'dump_Leak_Suspects.zip'\n\n      - name: Notify failure\n        if: failure()\n        run: |\n          curl -X POST \\\n          'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"notify-simulator-failure\\\",\n            \\\"client_payload\\\": {\n              \\\"branch\\\": \\\"${{ matrix.branch }}\\\",\n              \\\"runId\\\":\\\"${{ github.run_id }}\\\"\n            }\n          }\"\n"
  },
  {
    "path": ".github/workflows/language_server_simulator_nballerina.yml",
    "content": "name: Language Server Simulator on nBallerina\n\non:\n  schedule:\n    - cron: '0 */12 * * *'\n  workflow_dispatch:\n\njobs:\n  run_simulator:\n    name: Run LS Simulator\n    runs-on: ubuntu-latest\n    timeout-minutes: 240\n    strategy:\n      fail-fast: false\n      matrix:\n        branch: [ \"master\" ]\n        skipGenerators: [ \"\", \"IMPORT_STATEMENT\" ]\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n        with:\n          ref: ${{ matrix.branch }}\n\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n\n      - name: Initialize sub-modules\n        run: git submodule update --init\n\n      - name: Build with Gradle\n        timeout-minutes: 180\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          export DISPLAY=':99.0'\n          /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n          ./gradlew clean :language-server-simulator:runLSSimulatorOnnBallerina -Dls.simulation.skipGenerators=${{ matrix.skipGenerators }}\n\n      - name: Check Simulation Failure\n        run: if test -f dump.hprof; then exit 1; else exit 0; fi\n\n      - name: Analyze Heap Dump If Exists\n        if: failure()\n        run: |\n          if test -f dump.hprof; then echo \"Heap sump exists. Analyzing...\"; else exit 0; fi\n          wget https://ftp.jaist.ac.jp/pub/eclipse/mat/1.12.0/rcp/MemoryAnalyzer-1.12.0.20210602-linux.gtk.x86_64.zip\n          unzip MemoryAnalyzer-1.12.0.20210602-linux.gtk.x86_64.zip\n          ./mat/ParseHeapDump.sh ./dump.hprof org.eclipse.mat.api:suspects\n\n      - name: Upload Heap Dumps\n        uses: actions/upload-artifact@v4\n        if: always()\n        with:\n          name: heap_dump-${{ matrix.branch }}.hprof\n          path: '*.hprof'\n\n      - name: Upload Leaks Suspects\n        uses: actions/upload-artifact@v4\n        if: failure()\n        with:\n          name: Leak_Suspects-${{ matrix.branch }}\n          path: 'dump_Leak_Suspects.zip'\n\n      - name: Notify failure\n        if: failure()\n        run: |\n          curl -X POST \\\n          'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \\\n          -H 'Accept: application/vnd.github.v3+json' \\\n          -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n          --data \"{\n            \\\"event_type\\\": \\\"notify-simulator-failure\\\",\n            \\\"client_payload\\\": {\n              \\\"branch\\\": \\\"${{ matrix.branch }}\\\",\n              \\\"runId\\\":\\\"${{ github.run_id }}\\\"\n            }\n          }\"\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: Build \n\non:\n  push:\n    branches:\n      - master\n      - stage\n      - ballerina-1.1.x\n  workflow_dispatch:\n    inputs:\n      skipTests:\n        description: 'Skip Tests during build'\n        required: false\n        default: 'false'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Get project version\n        id: project-version\n        run: |\n          SHORT_VERSION=$((grep -w \"version\" | cut -d= -f2 | cut -d- -f1) < gradle.properties)\n          DIST_VERSION=$((grep -w \"version\" | cut -d= -f2) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION-$CODE_NAME\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n      - name: Build Ballerina Distribution\n        if: ${{ github.event.inputs.skipTests == '' || github.event.inputs.skipTests == 'false' }}\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x project-api-tests:test\n      - name: Build Ballerina Distribution Skip Tests\n        if: ${{ github.event.inputs.skipTests == 'true' }}\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n        run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x test\n      - name: Archive Ballerina ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina ZIP\n          path: ballerina/build/distributions/ballerina-*-swan-lake.zip\n      - name: Archive Ballerina Short Name ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Ballerina Short Name ZIP\n          path: ballerina/build/distributions/ballerina-${{ steps.project-version.outputs.sversion }}.zip\n      - name: Archive Linux installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Linux installer ZIP\n          path: ballerina/build/distributions/ballerina-*-linux.zip\n      - name: Archive MacOS installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: MacOS installer ZIP\n          path: ballerina/build/distributions/ballerina-*-macos.zip\n      - name: Archive Windows Installer ZIP\n        uses: actions/upload-artifact@v4\n        with:\n          name: Windows Installer ZIP\n          path: ballerina/build/distributions/ballerina-*-windows.zip\n"
  },
  {
    "path": ".github/workflows/publish-release-artifacts-1.2.x.yml",
    "content": "name: Publish Release Artifacts (1.2.x)\n\non:\n  workflow_dispatch:\n    inputs:\n      release_version:\n        description: 'Release Version e.g., 1.2.31, 1.2.31-rc1'\n        default: '1.2.31'\n        required: true\n\njobs:\n  publish-artifacts:\n    name: Publish Release Artifacts\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n\n      - name: Set up JDK 8\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '8'\n\n      - name: Set version env variable\n        id: set-version\n        run: |\n          RELEASE_VERSION=${{ github.event.inputs.release_version }}\n          VERSION=$(cut -d- -f1 <<< $RELEASE_VERSION)\n          TAGGED_VERSION=$RELEASE_VERSION\n          DISPLAY_VERSION=$VERSION\n\n          echo VERSION=$VERSION >> $GITHUB_ENV\n          echo DISPLAY_VERSION=$DISPLAY_VERSION >> $GITHUB_ENV\n          echo GIT_TAG=$TAGGED_VERSION >> $GITHUB_ENV\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=taggedVersion::$TAGGED_VERSION\"\n\n      - name: Download artifacts\n        run: |\n          baseUrl=\"https://github.com/ballerina-platform/ballerina-distribution/releases/download/v$GIT_TAG\"\n          rm -rf $VERSION\n          mkdir $VERSION\n          cd $VERSION\n\n          wget \"$baseUrl/ballerina-$VERSION.zip\"\n          wget \"$baseUrl/jballerina-$VERSION.zip\"\n          wget \"$baseUrl/ballerina-windows-installer-x64-$VERSION.msi\"\n          wget \"$baseUrl/ballerina-linux-installer-x64-$VERSION.deb\"\n          wget \"$baseUrl/ballerina-linux-installer-x64-$VERSION.rpm\"\n          wget \"$baseUrl/ballerina-macos-installer-x64-$VERSION.pkg\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }}\n          packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n\n      - name: Generate metadata json\n        working-directory: ${{ steps.set-version.outputs.version }}\n        run: |\n          date=`date +%Y-%m-%d`\n          winInstSize=`ls -lh ballerina-windows-installer-x64-$VERSION.msi | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          linuxInstSize=`ls -lh ballerina-linux-installer-x64-$VERSION.deb | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          rpmInstSize=`ls -lh ballerina-linux-installer-x64-$VERSION.rpm | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          macInstSize=`ls -lh ballerina-macos-installer-x64-$VERSION.pkg | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          fileName=metadata.json\n          echo { > $fileName\n          echo \"\t\\\"version\\\":\\\"$VERSION\\\",\" >> $fileName\n          echo \"\t\\\"release-date\\\":\\\"$date\\\",\" >> $fileName\n          echo \"\t\\\"windows-installer\\\":\\\"ballerina-windows-installer-x64-$VERSION.msi\\\",\" >> $fileName\n          echo \"\t\\\"windows-installer-size\\\":\\\"$winInstSize\\\",\" >> $fileName\n          echo \"\t\\\"linux-installer\\\":\\\"ballerina-linux-installer-x64-$VERSION.deb\\\",\" >> $fileName\n          echo \"\t\\\"linux-installer-size\\\":\\\"$linuxInstSize\\\",\" >> $fileName\n          echo \"\t\\\"macos-installer\\\":\\\"ballerina-macos-installer-x64-$VERSION.pkg\\\",\" >> $fileName\n          echo \"\t\\\"macos-installer-size\\\":\\\"$macInstSize\\\",\" >> $fileName\n          echo \"\t\\\"rpm-installer\\\":\\\"ballerina-linux-installer-x64-$VERSION.rpm\\\",\" >> $fileName\n          echo \"\t\\\"rpm-installer-size\\\":\\\"$rpmInstSize\\\",\" >> $fileName\n          echo \"\t\\\"other-artefacts\\\":[  \" >> $fileName\n          echo \"\t\t\\\"ballerina-$VERSION.zip\\\",\" >> $fileName\n          echo \"\t\t\\\"ballerina-$VERSION.vsix\\\"\" >> $fileName\n          echo \" \t]\", >> $fileName\n          echo \"\t\\\"api-docs\\\":\\\"ballerina-api-docs-$VERSION.zip\\\",\" >> $fileName\n          echo \"\t\\\"release-notes\\\":\\\"ballerina-release-notes-$VERSION.md\\\"\" >> $fileName\n          echo } >> $fileName\n\n      - name: Archive metadata json\n        uses: actions/upload-artifact@v4\n        with:\n          name: Metadata JSON\n          path: ${{ steps.set-version.outputs.version }}/metadata.json\n\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n\n      - name: Process docker\n        id: process-docker\n        run: |\n          git clone --single-branch --branch ballerina-1.2.x https://github.com/ballerina-platform/module-ballerina-docker\n          DOCKER_REPO='module-ballerina-docker'\n          echo \"::set-output name=dockerRepo::$DOCKER_REPO\"\n\n      - name: Enable experimental functions\n        run: |\n          echo $'{\\n    \"experimental\": true\\n}' | sudo tee /etc/docker/daemon.json\n          sudo service docker restart\n          docker version\n\n      - name: Build and push docker image\n        run: |\n          DOCKER_REPO=${{ steps.process-docker.outputs.dockerRepo }}\n          cp $VERSION/ballerina-$VERSION.zip $DOCKER_REPO/base/docker/\n\n          docker build --no-cache=true --squash --build-arg BALLERINA_DIST=ballerina-$VERSION.zip -t ballerina/ballerina:$VERSION  $DOCKER_REPO/base/docker/\n          rm $DOCKER_REPO/base/docker/ballerina-$VERSION.zip\n          docker push ballerina/ballerina:$VERSION\n          docker rmi ballerina/ballerina:$VERSION\n          docker image prune -f\n\n      - name: Publish Artifacts\n        run: |\n          sudo apt-get install python3-setuptools\n          python3 -m pip install --user awscli\n          aws configure set aws_access_key_id $s3_acc_id\n          aws configure set aws_secret_access_key $s3_acc_key\n          aws s3 cp $VERSION s3://dist-dev.ballerina.io/downloads/$VERSION --recursive\n        env:\n          s3_acc_id: ${{ secrets.S3_ID }}\n          s3_acc_key: ${{ secrets.S3_KEY }}\n"
  },
  {
    "path": ".github/workflows/publish-release-artifacts.yml",
    "content": "name: Publish Release Artifacts\n\non:\n  workflow_dispatch:\n    inputs:\n      release_version:\n        description: 'Release Version e.g., 2201.1.1, 2201.1.1-rc1'\n        default: '2201.1.1'\n        required: true\n\njobs:\n  publish-artifacts:\n    name: Publish Release Artifacts\n    runs-on: ubuntu-latest\n    if: github.repository_owner == 'ballerina-platform'\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n\n      - name: Set version env variable\n        id: set-version\n        env:\n          RELEASE_VERSION: ${{ github.event.inputs.release_version }}\n        run: |\n          if [[ \"$RELEASE_VERSION\" == *-SNAPSHOT ]]; then\n            VERSION=\"${RELEASE_VERSION%-SNAPSHOT}\"\n          else\n            VERSION=\"$RELEASE_VERSION\"\n          fi\n          DIST_VERSION=\"${VERSION%%-*}\"\n          CODE_NAME=\"swan-lake\"\n          TAGGED_VERSION=$RELEASE_VERSION\n          LONG_VERSION=$DIST_VERSION-$CODE_NAME\n\n          UPDATE_NUMBER=$(cut -d'.' -f2 <<< $DIST_VERSION)\n          DISPLAY_VERSION=\"$VERSION (Swan Lake Update $UPDATE_NUMBER)\"\n\n          echo VERSION=$VERSION >> $GITHUB_ENV\n          echo DIST_VERSION=$DIST_VERSION >> $GITHUB_ENV\n          echo LONG_VERSION=$LONG_VERSION >> $GITHUB_ENV\n          echo DISPLAY_VERSION=$DISPLAY_VERSION >> $GITHUB_ENV\n          echo GIT_TAG=$TAGGED_VERSION >> $GITHUB_ENV\n          echo \"version=$VERSION\" >> \"$GITHUB_OUTPUT\"\n          echo \"distVersion=$DIST_VERSION\" >> \"$GITHUB_OUTPUT\"\n          echo \"taggedVersion=$TAGGED_VERSION\" >> \"$GITHUB_OUTPUT\"\n          echo \"::set-output name=updateNumber::$UPDATE_NUMBER\"\n          echo \"::set-output name=longVersion::$LONG_VERSION\"\n\n      - name: Download artifacts\n        run: |\n          baseUrl=\"https://github.com/ballerina-platform/ballerina-distribution/releases/download/v$GIT_TAG\"\n          updateNumber=${{ steps.set-version.outputs.updateNumber }}\n          distVersion=${{ steps.set-version.outputs.distVersion }}\n          rm -rf $VERSION\n          mkdir $VERSION\n          cd $VERSION\n\n          wget \"$baseUrl/ballerina-$LONG_VERSION.zip\"\n          wget \"$baseUrl/ballerina-$distVersion.zip\"\n          wget \"$baseUrl/ballerina-$LONG_VERSION-windows-x64.msi\"\n          wget \"$baseUrl/ballerina-$LONG_VERSION-linux-x64.deb\"\n          wget \"$baseUrl/ballerina-$LONG_VERSION-linux-x64.rpm\"\n          wget \"$baseUrl/ballerina-$LONG_VERSION-macos-x64.pkg\"\n          if [ \"$updateNumber\" -ge 5 ]; then\n            wget \"$baseUrl/ballerina-$LONG_VERSION-macos-arm-x64.pkg\"\n          fi\n          if [ \"$updateNumber\" -ge 11 ]; then\n            wget \"$baseUrl/ballerina-$LONG_VERSION-linux-arm-x64.deb\"\n          fi\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }}\n          packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n\n      - name: Generate metadata json\n        working-directory: ${{ steps.set-version.outputs.version }}\n        run: |\n          updateNumber=${{ steps.set-version.outputs.updateNumber }}\n          date=`date +%Y-%m-%d`\n          winInstSize=`ls -lh ballerina-$LONG_VERSION-windows-x64.msi | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          linuxInstSize=`ls -lh ballerina-$LONG_VERSION-linux-x64.deb | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          rpmInstSize=`ls -lh ballerina-$LONG_VERSION-linux-x64.rpm | cut -d \" \" -f5 | sed 's/M/mb/g'`\n          macInstSize=`ls -lh ballerina-$LONG_VERSION-macos-x64.pkg | cut -d \" \" -f5 | sed 's/M/mb/g'`\n\n          fileName=metadata.json\n          echo \"{\" >> $fileName\n          echo \"\t\\\"version\\\":\\\"$VERSION\\\",\" >> $fileName\n          echo \"\t\\\"short-version\\\":\\\"$VERSION\\\",\" >> $fileName\n          echo \"\t\\\"display-version\\\":\\\"$DISPLAY_VERSION\\\",\" >> $fileName\n          echo \"\t\\\"release-date\\\":\\\"$date\\\",\" >> $fileName\n          echo \"\t\\\"windows-installer\\\":\\\"ballerina-$LONG_VERSION-windows-x64.msi\\\",\" >> $fileName\n          echo \"\t\\\"windows-installer-size\\\":\\\"$winInstSize\\\",\" >> $fileName\n          echo \"\t\\\"linux-installer\\\":\\\"ballerina-$LONG_VERSION-linux-x64.deb\\\",\" >> $fileName\n          echo \"\t\\\"linux-installer-size\\\":\\\"$linuxInstSize\\\",\" >> $fileName\n          if [ \"$updateNumber\" -ge 11 ]; then\n            linuxArmInstSize=`ls -lh ballerina-$LONG_VERSION-linux-arm-x64.deb | cut -d \" \" -f5 | sed 's/M/mb/g'`\n            echo \"\t\\\"linux-arm-installer\\\":\\\"ballerina-$LONG_VERSION-linux-arm-x64.deb\\\",\" >> $fileName\n            echo \"\t\\\"linux-arm-installer-size\\\":\\\"$linuxArmInstSize\\\",\" >> $fileName\n          fi\n          echo \"\t\\\"macos-installer\\\":\\\"ballerina-$LONG_VERSION-macos-x64.pkg\\\",\" >> $fileName\n          echo \"\t\\\"macos-installer-size\\\":\\\"$macInstSize\\\",\" >> $fileName\n          if [ \"$updateNumber\" -ge 5 ]; then\n            macArmInstSize=`ls -lh ballerina-$LONG_VERSION-macos-arm-x64.pkg | cut -d \" \" -f5 | sed 's/M/mb/g'`\n            echo \"\t\\\"macos-arm-installer\\\":\\\"ballerina-$LONG_VERSION-macos-arm-x64.pkg\\\",\" >> $fileName\n            echo \"\t\\\"macos-arm-installer-size\\\":\\\"$macArmInstSize\\\",\" >> $fileName\n          fi\n          echo \"\t\\\"rpm-installer\\\":\\\"ballerina-$LONG_VERSION-linux-x64.rpm\\\",\" >> $fileName\n          echo \"\t\\\"rpm-installer-size\\\":\\\"$rpmInstSize\\\",\" >> $fileName\n          echo \"\t\\\"other-artefacts\\\":[  \" >> $fileName\n          echo \"\t\t\\\"ballerina-$LONG_VERSION.zip\\\"\" >> $fileName\n          echo \" \t]\", >> $fileName\n          echo \"\t\\\"api-docs\\\":\\\"ballerina-api-docs-$VERSION.zip\\\",\" >> $fileName\n          echo \"\t\\\"release-notes\\\":\\\"ballerina-release-notes-$VERSION.md\\\"\" >> $fileName\n          echo \"}\" >> $fileName\n\n      - name: Archive metadata json\n        uses: actions/upload-artifact@v4\n        with:\n          name: Metadata JSON\n          path: ${{ steps.set-version.outputs.version }}/metadata.json\n\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n\n      - name: Clone Docker Repo\n        id: process-docker\n        run: |\n          git clone --single-branch --branch master https://github.com/ballerina-platform/module-ballerina-docker\n          DOCKER_REPO='module-ballerina-docker'\n          echo \"::set-output name=dockerRepo::$DOCKER_REPO\"\n\n      - name: Copy artifacts to Docker repo\n        run: |\n          DOCKER_REPO=${{ steps.process-docker.outputs.dockerRepo }}\n          cp $VERSION/ballerina-${{ steps.set-version.outputs.distVersion }}.zip $DOCKER_REPO/base/docker/\n          cp $VERSION/ballerina-$LONG_VERSION-linux-x64.deb $DOCKER_REPO/base/devcontainer/\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Build and push the Ballerina Docker image\n        id: docker_build\n        uses: docker/build-push-action@v6\n        with:\n          context: ${{ steps.process-docker.outputs.dockerRepo }}/base/docker/\n          push: true\n          tags: ballerina/ballerina:${{ steps.set-version.outputs.taggedVersion }}\n          platforms: linux/amd64,linux/arm64\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.set-version.outputs.distVersion }}.zip\n\n      - name: Build and push dev container image\n        id: docker_build_devcontainer\n        uses: docker/build-push-action@v6\n        with:\n          context: ${{ steps.process-docker.outputs.dockerRepo }}/base/devcontainer/\n          push: true\n          tags: ballerina/ballerina-devcontainer:${{ steps.set-version.outputs.taggedVersion }}\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.set-version.outputs.longVersion }}-linux-x64.deb\n\n      - name: Publish Artifacts\n        run: |\n          sudo apt-get install python3-setuptools\n          python3 -m pip install --user awscli\n          aws configure set aws_access_key_id $s3_acc_id\n          aws configure set aws_secret_access_key $s3_acc_key\n          aws s3 cp $VERSION s3://dist-dev.ballerina.io/downloads/$VERSION --recursive\n        env:\n          s3_acc_id: ${{ secrets.S3_ID }}\n          s3_acc_key: ${{ secrets.S3_KEY }}\n"
  },
  {
    "path": ".github/workflows/publish-release.yml",
    "content": "name: Publish release\n\non:\n  workflow_dispatch:\n    inputs:\n      isPreRelease:\n        description: \"Tag created is a pre-release tag\"\n        required: true\n        default: \"false\"\n      preReleaseSuffix:\n        description: \"The text that will be suffixed to the Git tag. e.g., rc1\"\n        required: false\n        default: \"\"\n\npermissions:\n  id-token: write\n  contents: write\n\njobs:\n  publish-release:\n    name: Publish Release\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: \"temurin\"\n          java-version: \"21.0.3\"\n      - name: Set version env variable\n        id: version-set\n        run: |\n          SHORT_VERSION=$(grep -w \"version\" gradle.properties | cut -d= -f2 | sed 's/-SNAPSHOT//' | xargs)\n          DIST_VERSION=$(grep -w \"version\" gradle.properties | cut -d= -f2 | sed 's/-SNAPSHOT//' | xargs)          \n          LANG_VERSION=$(grep -w \"ballerinaLangVersion\" gradle.properties | cut -d= -f2 | sed 's/-SNAPSHOT//' | xargs)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION\n          TAGGED_VERSION=$RELEASE_VERSION\n          LONG_VERSION=$DIST_VERSION-$CODE_NAME\n          if [ -n \"${{ github.event.inputs.preReleaseSuffix }}\" ]; then\n            TAGGED_VERSION=$RELEASE_VERSION-${{ github.event.inputs.preReleaseSuffix }}\n          fi\n          echo VERSION=$RELEASE_VERSION >> $GITHUB_ENV\n          echo GIT_TAG=$TAGGED_VERSION >> $GITHUB_ENV\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=taggedVersion::$TAGGED_VERSION\"\n          echo \"::set-output name=longVersion::$LONG_VERSION\"\n          echo \"::set-output name=langVersion::$LANG_VERSION\"\n      - name: Pre release depenency version update\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        run: |\n          echo \"Version: ${VERSION}\"\n          echo \"Tagged Version: ${GIT_TAG}\"\n          git config user.name ${{ secrets.BALLERINA_BOT_USERNAME }}\n          git config user.email ${{ secrets.BALLERINA_BOT_EMAIL }}\n          git checkout -b release-${GIT_TAG}\n      - name: Generate UUID\n        run: |\n          UUID=$(uuidgen)\n          perl -pi -e \"s/^\\s*installerVersion=.*/installerVersion=$UUID/\" gradle.properties\n          git config user.name ${{ secrets.BALLERINA_BOT_USERNAME }}\n          git config user.email ${{ secrets.BALLERINA_BOT_EMAIL }}\n          git add gradle.properties\n          git commit -m \"Update UUID for installer\"\n      - name: Grant execute permission for gradlew\n        run: chmod +x gradlew\n      - name: Publish artifact\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }}\n          packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          prodCentralToken: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n        run: |\n          ./gradlew build -x project-api-tests:test -Pversion=${VERSION}\n          ./gradlew release -x project-api-tests:test -Prelease.useAutomaticVersion=true\n      - name: Checkout docker repo\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/module-ballerina-docker\n          path: module-ballerina-docker\n      - name: Copy zip artifact\n        run: cp ballerina/build/distributions/ballerina-22*.zip module-ballerina-docker/base/docker/\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n      - name: Login to DockerHub\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n      - name: Build the docker image\n        id: docker_build\n        uses: docker/build-push-action@v6\n        with:\n          context: module-ballerina-docker/base/docker/\n          load: true\n          push: false\n          tags: ballerina/ballerina:release-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.version-set.outputs.sversion }}.zip\n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: \"ballerina/ballerina:release-test\"\n          skip-dirs: \"ballerina/runtime/examples\"\n          format: \"table\"\n          exit-code: \"1\"\n          timeout: \"10m0s\"\n      - name: cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Set up Node.js\n        uses: actions/setup-node@v2\n        with:\n          node-version: \"14\"\n      - name: Install GitHub CLI\n        run: |\n          npm install -g github-cli\n          gh --version\n      - name: Get Markdown file\n        id: file-url\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          gh repo view ballerina-platform/ballerina-dev-website --json url --jq '.clone_url'\n          gh api repos/ballerina-platform/ballerina-dev-website/contents/downloads/verify-ballerina-artifacts.md -H 'Accept: application/vnd.github.v3.raw' > release_notes.md\n          sed -i '1,10d' release_notes.md\n      - name: Retrieve Branch\n        id: retrieve-branch\n        run: |\n          branchName=$(echo ${{ github.ref }} | cut -d'/' -f3)\n          echo \"::set-output name=branchName::$branchName\"\n      - name: Update Markdown file\n        run: |\n          if ${{ github.event.inputs.isPreRelease }} == 'true'; then \n            echo \"\" > release_notes.md; \n          else sed -i 's/{{ version }}/${{ steps.version-set.outputs.taggedVersion }}/g' release_notes.md; sed -i 's/{{ branch }}/${{ steps.retrieve-branch.outputs.branchName }}/g' release_notes.md; fi\n      - name: Read release notes from file\n        id: release_notes\n        uses: actions/github-script@v4\n        with:\n          github-token: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          script: |\n            const fs = require('fs');\n            const releaseNotes = fs.readFileSync('release_notes.md', 'utf8');\n            core.setOutput('notes', releaseNotes);\n      - name: Create release\n        id: create_release\n        uses: actions/create-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          tag_name: \"v${{ steps.version-set.outputs.taggedVersion }}\"\n          release_name: ${{ steps.version-set.outputs.taggedVersion }}\n          body: ${{ steps.release_notes.outputs.notes }}\n          draft: false\n          prerelease: ${{ github.event.inputs.isPreRelease }}\n      - name: Create linux-deb Installer\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Sign the linux-deb installer\n        run: |\n          cosign sign-blob installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sig --yes\n      - name: Verify the linux-deb installer\n        run: |\n          cosign verify-blob installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Create linux-rpm Installer\n        id: run_installers_rpm\n        run: |\n          cd installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Sign the linux-rpm installer\n        run: |\n          cosign sign-blob installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sig --yes\n      - name: Verify the linux-rpm installer\n        run: |\n          cosign verify-blob installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-x64.deb\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256 installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip\n      - name: Sign the zip artifacts\n        run: |\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip --output-certificate ballerina-${{ steps.version-set.outputs.sversion }}.pem --output-signature ballerina-${{ steps.version-set.outputs.sversion }}.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-macos.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-macos.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.sig --yes\n          cosign sign-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-windows.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-windows.sig --yes\n      - name: Verify the zip artifacts\n        run: |\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip --certificate ballerina-${{ steps.version-set.outputs.sversion }}.pem --signature ballerina-${{ steps.version-set.outputs.sversion }}.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-macos.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-macos.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n          cosign verify-blob ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-windows.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-windows.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Upload zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          asset_content_type: application/octet-stream\n      - name: Upload zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}.pem\n          asset_content_type: application/octet-stream\n      - name: Upload zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}.sig\n          asset_content_type: application/octet-stream\n      - name: Upload zip without tool artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip\n          asset_content_type: application/octet-stream\n      - name: Upload zip without tool artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.sversion }}.pem\n          asset_content_type: application/octet-stream\n      - name: Upload zip without tool artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.sversion }}.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb\n          asset_path: installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm\n          asset_path: installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Linux zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Linux zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Linux zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.sig\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-macos.pem\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-macos.sig\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.pem\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Windows zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Windows zip artifact's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-windows.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-windows.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Windows zip artifact's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-windows.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-windows.sig\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Ballerina zip Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload ballerina Short Name zip Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256\n          asset_content_type: application/octet-stream\n      - name: Install Ballerina DEB\n        run: sudo dpkg -i installers/linux-deb/target/ballerina-*-linux-x64.deb\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ steps.version-set.outputs.langVersion }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      # - name: Run Installer Tests\n      #   working-directory: ./ballerina-test-automation/installer-test\n      #   run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n      #   env:\n      #     TEST_MODE_ACTIVE: true\n      - name: Create linux-arm-deb Installer\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions -a arm\n          echo \"Created linux-arm-deb successfully\"\n      - name: Sign the linux-arm-deb installer\n        run: |\n          cosign sign-blob installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb --output-certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.pem --output-signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.sig --yes\n      - name: Verify the linux-arm-deb installer\n        run: |\n          cosign verify-blob installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb --certificate ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.pem --signature ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Upload Linux-ARM deb Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb\n          asset_path: installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM deb Installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.pem\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM deb Installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.sig\n          asset_path: ./ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb.sig\n          asset_content_type: application/octet-stream\n      - name: Post release PR\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        run: |\n          curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.1\n          bin/hub pull-request -m \"[Automated] Sync master after \"$VERSION\" release\"\n\n    outputs:\n      project-version: ${{ steps.version-set.outputs.longVersion }}\n      upload-asset-url: ${{ steps.create_release.outputs.upload_url }}\n      release-version: ${{ steps.version-set.outputs.taggedVersion }}\n      lang-version: ${{ steps.version-set.outputs.langVersion }}\n\n  macos-installer-build:\n    name: MacOS Installer Build\n    needs: publish-release\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: \"temurin\"\n          java-version: \"21.0.3\"\n      - name: Download MacOS Intaller Zip\n        run: |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-macos.zip\n      - name: cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Create macos-pkg Installer\n        id: run_installers_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.publish-release.outputs.project-version }} -p ./../../\n          echo \"Created macos-pkg successfully\"\n      - name: Sign the MacOS installer\n        run: |\n          cosign sign-blob installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg --output-certificate ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.pem --output-signature ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sig --yes\n      - name: Verify the MacOS installer\n        run: |\n          cosign verify-blob installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg --certificate ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.pem --signature ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256 installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n      - name: Upload MacOS pkg Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS pkg Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n          asset_path: installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.pem\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.pem\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sig\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sig\n          asset_content_type: application/octet-stream\n      - name: Install Ballerina PKG\n        run: sudo installer -pkg installers/mac/target/pkg/ballerina-*-macos-x64.pkg -target /\n      - name: Update Installer Test Configs\n        run: |\n          DISPLAY_TEXT=${{ needs.publish-release.outputs.lang-version }}\n          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n      # - name: Run Installer Tests\n      #   working-directory: ./ballerina-test-automation/installer-test\n      #   run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n      #   env:\n      #     TEST_MODE_ACTIVE: true\n      - name: Download MacOS-ARM Installer Zip\n        run: |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm.zip\n      - name: Create macos-arm-pkg Installer\n        id: run_installers_arm_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.publish-release.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created macos-arm-pkg successfully\"\n      - name: Sign the MacOS-ARM installer\n        run: |\n          cosign sign-blob installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg --output-certificate ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.pem --output-signature ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sig --yes\n      - name: Verify the MacOS-ARM installer\n        run: |\n          cosign verify-blob installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg --certificate ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.pem --signature ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256 installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n      - name: Upload MacOS-ARM pkg Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM pkg Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n          asset_path: installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.pem\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.pem\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sig\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sig\n          asset_content_type: application/octet-stream\n\n  windows-installer-build:\n    name: Windows Installer Build\n    needs: publish-release\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: \"temurin\"\n          java-version: \"21.0.3\"\n      - uses: actions/setup-dotnet@v1\n        with:\n          dotnet-version: \"2.1.x\"\n      - name: Install GUID Generator\n        run: dotnet tool install -g dotnet-guid --version 0.5.2\n      - name: Set up Wix toolkit\n        run: echo \"${WIX}bin\" >> $GITHUB_PATH\n        shell: bash\n      - name: Set cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Download Windows Installer Zip\n        run: |\n          echo default login ${{ secrets.BALLERINA_BOT_USERNAME }} password ${{ secrets.BALLERINA_BOT_TOKEN }} >> _netrc\n          curl --netrc-file _netrc -L -o ballerina-${{ needs.publish-release.outputs.project-version }}-windows.zip https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-windows.zip\n      - name: Create windows-msi Installer\n        id: run_installers_msi\n        run: |\n          move installers\\windows .\\..\\..\\\n          cd ..\\..\\windows\n          .\\build-ballerina-windows-x64.bat --version ${{ needs.publish-release.outputs.project-version }} --path .\\..\\ballerina-distribution\\ballerina-distribution\n      - name: Sign the Windows installer\n        run: |\n          cosign sign-blob D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi --output-certificate ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.pem --output-signature ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sig --yes\n      - name: Verify the Windows installer\n        run: |\n          cosign verify-blob D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi --certificate ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.pem --signature ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/publish-release.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256 D:\\a\\windows\\target\\msi\\ballerina-*-windows-x64.msi\n      - name: Upload Windows msi Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Windows msi Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi\n          asset_path: D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi\n          asset_content_type: application/octet-stream\n      - name: Upload Windows installer's Certificate\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.pem\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.pem\n          asset_content_type: application/octet-stream\n      - name: Upload Windows installer's Signature\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sig\n          asset_path: ./ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sig\n          asset_content_type: application/octet-stream\n      - name: Install Ballerina msi\n        run: msiexec /i D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi /quiet /qr\n        shell: cmd\n      - name: Update Installer Test Configs\n        run: |\n          set DISPLAY_TEXT=${{ needs.publish-release.outputs.lang-version }}\n          set SWAN_LAKE_LATEST_VERSION=swan-lake-%DISPLAY_TEXT%\n          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=%DISPLAY_TEXT%/\" ballerina-test-automation/gradle.properties\n          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=%SWAN_LAKE_LATEST_VERSION%/\" ballerina-test-automation/gradle.properties\n        shell: cmd\n      # - name: Run Installer Tests\n      #   working-directory: .\\ballerina-test-automation\\installer-test\n      #   run: |\n      #     $env:Path += \";C:\\Program Files\\Ballerina\\bin\"\n      #     .\\..\\gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n"
  },
  {
    "path": ".github/workflows/publish_release_bi.yml",
    "content": "name: Publish Release Kola Distribution\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron:  '0 2 * * *'    # 07:30 in LK time (GMT+5:30)\n\npermissions:\n  id-token: write\n  contents: write\n\njobs:\n  publish-release:\n    name: Publish Release\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: Set up JDK 21\n        uses: actions/setup-java@v3\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Use Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: '10.22.1'\n      - name: Clone ballerina-dev-tools\n        run: git clone https://github.com/ballerina-platform/ballerina-dev-tools.git\n      - name: Build ballerina-dev-tools\n        id: build-dev-tools\n        env:\n          packageUser: ${{ github.actor }}\n          packagePAT: ${{ secrets.GITHUB_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n          TEST_MODE_ACTIVE: true\n        run: |\n          cd ballerina-dev-tools\n          VERSION=$((grep -w 'version' | cut -d= -f2 | cut -d- -f1) < gradle.properties)\n          sed -i \"s/^version=.*/version=$VERSION/\" gradle.properties\n          echo \"::set-output name=version::$(grep \"^version=\" gradle.properties | cut -d'=' -f2)\"\n          echo \"::set-output name=langVersion::$(grep \"^ballerinaLangVersion=\" gradle.properties | cut -d'=' -f2)\"\n          ./gradlew clean build --stacktrace --scan -x test  --console=plain --no-daemon --continue publishToMavenLocal\n          cd ..\n          rm -rf ballerina-dev-tools\n      - name: Set version env variable\n        id: version-set\n        run: |\n          sed -i \"s/^devToolsVersion=.*/devToolsVersion=${{ steps.build-dev-tools.outputs.version }}/\" gradle.properties\n          sed -i \"s/^ballerinaLangVersion=.*/ballerinaLangVersion=${{ steps.build-dev-tools.outputs.langVersion }}/\" gradle.properties\n          SHORT_VERSION=$((grep -w 'version' | cut -d= -f2 | cut -d- -f1) < gradle.properties)\n          DIST_VERSION=$((grep -w 'version' | cut -d= -f2) < gradle.properties | rev | cut --complement -d- -f1 | rev)\n          LANG_VERSION=$((grep -w \"ballerinaLangVersion\" | cut -d= -f2 | cut -d- -f1 | xargs) < gradle.properties)\n          CODE_NAME=$((grep -w 'codeName' | cut -d= -f2) < gradle.properties)\n          RELEASE_VERSION=$DIST_VERSION\n          TAGGED_VERSION=$RELEASE_VERSION-bi-pack-$(TZ=\"Asia/Kolkata\" date +'%Y%m%d-%H%M00')\n          LONG_VERSION=$DIST_VERSION-$CODE_NAME\n          echo VERSION=$RELEASE_VERSION >> $GITHUB_ENV\n          echo GIT_TAG=$TAGGED_VERSION >> $GITHUB_ENV\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=sversion::$SHORT_VERSION\"\n          echo \"::set-output name=taggedVersion::$TAGGED_VERSION\"\n          echo \"::set-output name=longVersion::$LONG_VERSION\"\n          echo \"::set-output name=langVersion::$LANG_VERSION\"\n      - name: Pre release dependency version update\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        run: |\n          echo \"Version: ${VERSION}\"\n          echo \"Tagged Version: ${GIT_TAG}\"\n          git config user.name ${{ secrets.BALLERINA_BOT_USERNAME }}\n          git config user.email ${{ secrets.BALLERINA_BOT_EMAIL }}\n          git checkout -b release-${GIT_TAG}\n      - name: Generate UUID\n        run: |\n          UUID=$(uuidgen)\n          perl -pi -e \"s/^\\s*installerVersion=.*/installerVersion=$UUID/\" gradle.properties\n          git config user.name ${{ secrets.BALLERINA_BOT_USERNAME }}\n          git config user.email ${{ secrets.BALLERINA_BOT_EMAIL }}\n          git add gradle.properties\n          git commit -m \"Update UUID for installer\"\n      - name: Grant execute permission for gradlew\n        run: chmod +x gradlew\n      - name: Publish artifact\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }}\n          packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n          prodCentralToken: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }}\n          githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n          ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n        run: |\n          ./gradlew build -x test -x project-api-tests:test -Pversion=${VERSION}\n          ./gradlew release -Prelease.useAutomaticVersion=true -x test\n      - name: Checkout docker repo\n        uses: actions/checkout@v3\n        with:\n          repository: ballerina-platform/module-ballerina-docker\n          path: module-ballerina-docker\n      - name: Copy zip artifact\n        run: cp ballerina/build/distributions/ballerina-22*.zip module-ballerina-docker/base/docker/\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v1\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v1\n      - name: Login to DockerHub\n        uses: docker/login-action@v1\n        with:\n          username: ${{ secrets.DOCKER_HUB_USER }}\n          password: ${{ secrets.DOCKER_HUB_TOKEN }}\n      - name: Build the docker image\n        id: docker_build\n        uses: docker/build-push-action@v2\n        with:\n          context: module-ballerina-docker/base/docker/\n          load: true\n          push: false\n          tags: ballerina/ballerina:release-test\n          build-args: |\n            BALLERINA_DIST=ballerina-${{ steps.version-set.outputs.sversion }}.zip\n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity/trivy-action@master\n        with:\n          image-ref: 'ballerina/ballerina:release-test'\n          skip-dirs: 'ballerina/runtime/examples'\n          format: 'table'\n          exit-code: '1'\n          timeout: \"10m0s\"\n          severity: 'CRITICAL,HIGH'\n      - name: cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Set up Node.js\n        uses: actions/setup-node@v2\n        with:\n          node-version: '14'\n      - name: Install GitHub CLI\n        run: |\n          npm install -g github-cli\n          gh --version\n      - name: Get Markdown file\n        id: file-url\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          gh repo view ballerina-platform/ballerina-dev-website --json url --jq '.clone_url'\n          gh api repos/ballerina-platform/ballerina-dev-website/contents/downloads/verify-ballerina-artifacts.md -H 'Accept: application/vnd.github.v3.raw' > release_notes.md\n          sed -i '1,10d' release_notes.md\n      - name: Retrieve Branch\n        id: retrieve-branch\n        run: |\n          branchName=$(echo ${{ github.ref }} | cut -d'/' -f3)\n          echo \"::set-output name=branchName::$branchName\"\n      - name: Update Markdown file\n        run: echo \"\" > release_notes.md;\n      - name: Read release notes from file\n        id: release_notes\n        uses: actions/github-script@v4\n        with:\n          github-token: ${{ secrets.BALLERINA_BOT_TOKEN }}\n          script: |\n            const fs = require('fs');\n            const releaseNotes = fs.readFileSync('release_notes.md', 'utf8');\n            core.setOutput('notes', releaseNotes);\n      - name: Create release\n        id: create_release\n        uses: actions/create-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          tag_name: \"v${{ steps.version-set.outputs.taggedVersion }}\"\n          release_name: ${{ steps.version-set.outputs.taggedVersion }}\n          body: ${{ steps.release_notes.outputs.notes }}\n          draft: false\n          prerelease: true\n      - name: Create linux-deb Installer\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-deb successfully\"\n      - name: Create linux-rpm Installer\n        id: run_installers_rpm\n        run: |\n          cd installers/linux-rpm\n          ./build-ballerina-linux-rpm-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions\n          echo \"Created linux-rpm successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256 installers/linux-deb/target/ballerina-*-linux-x64.deb\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256 installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-*-linux-x64.rpm\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          openssl dgst -sha256 -out ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256 ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip\n      - name: Upload zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}.zip\n          asset_content_type: application/octet-stream\n      - name: Upload zip without tool artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.sversion }}.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb\n          asset_path: installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm\n          asset_path: installers/linux-rpm/rpmbuild/RPMS/x86_64/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm\n          asset_content_type: application/octet-stream\n      - name: Upload Linux zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Linux-ARM zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm.zip\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos.zip\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-macos-arm.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Windows zip artifacts\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip\n          asset_path: ballerina/build/distributions/ballerina-${{ steps.version-set.outputs.longVersion }}-windows.zip\n          asset_content_type: application/octet-stream\n      - name: Upload Linux deb Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.deb.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Linux rpm Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-x64.rpm.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Ballerina zip Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.longVersion }}.zip.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload ballerina Short Name zip Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256\n          asset_path: ballerina-${{ steps.version-set.outputs.sversion }}.zip.sha256\n          asset_content_type: application/octet-stream\n#      - name: Install Ballerina DEB\n#        run: sudo dpkg -i installers/linux-deb/target/ballerina-*-linux-x64.deb\n#      - name: Update Installer Test Configs\n#        run: |\n#          DISPLAY_TEXT=${{ steps.version-set.outputs.langVersion }}\n#          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n#      - name: Run Installer Tests\n#        working-directory: ./ballerina-test-automation/installer-test\n#        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n#        env:\n#          TEST_MODE_ACTIVE: true\n      - name: Create linux-arm-deb Installer\n        run: |\n          cd installers/linux-deb\n          ./build-ballerina-linux-deb-x64.sh -v ${{ steps.version-set.outputs.longVersion }} -p ./../../ballerina/build/distributions -a arm\n          echo \"Created linux-arm-deb successfully\"\n      - name: Upload Linux-ARM deb Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_name: ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb\n          asset_path: installers/linux-deb/target/ballerina-${{ steps.version-set.outputs.longVersion }}-linux-arm-x64.deb\n          asset_content_type: application/octet-stream\n\n    outputs:\n      project-version: ${{ steps.version-set.outputs.longVersion }}\n      upload-asset-url: ${{ steps.create_release.outputs.upload_url }}\n      release-version: ${{ steps.version-set.outputs.taggedVersion }}\n      lang-version: ${{ steps.version-set.outputs.langVersion }}\n\n  macos-installer-build:\n    name: MacOS Installer Build\n    needs: publish-release\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - name: Download MacOS Intaller Zip\n        run: |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-macos.zip\n      - name: cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Create macos-pkg Installer\n        id: run_installers_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.publish-release.outputs.project-version }} -p ./../../\n          echo \"Created macos-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256 installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n      - name: Upload MacOS pkg Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS pkg Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n          asset_path: installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-x64.pkg\n          asset_content_type: application/octet-stream\n#      - name: Install Ballerina PKG\n#        run: sudo installer -pkg installers/mac/target/pkg/ballerina-*-macos-x64.pkg -target /\n#      - name: Update Installer Test Configs\n#        run: |\n#          DISPLAY_TEXT=${{ needs.publish-release.outputs.lang-version }}\n#          SWAN_LAKE_LATEST_VERSION=\"swan-lake-\"+$DISPLAY_TEXT\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=$DISPLAY_TEXT/\" ballerina-test-automation/gradle.properties\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=$SWAN_LAKE_LATEST_VERSION/\" ballerina-test-automation/gradle.properties\n#      - name: Run Installer Tests\n#        working-directory: ./ballerina-test-automation/installer-test\n#        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n#        env:\n#          TEST_MODE_ACTIVE: true\n      - name: Download MacOS-ARM Installer Zip\n        run: |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm.zip\n      - name: Create macos-arm-pkg Installer\n        id: run_installers_arm_pkg\n        run: |\n          cd installers/mac\n          ./build-ballerina-macos-x64.sh -v ${{ needs.publish-release.outputs.project-version }} -p ./../../ -a arm\n          echo \"Created macos-arm-pkg successfully\"\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256 installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n      - name: Upload MacOS-ARM pkg Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload MacOS-ARM pkg Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n          asset_path: installers/mac/target/pkg/ballerina-${{ needs.publish-release.outputs.project-version }}-macos-arm-x64.pkg\n          asset_content_type: application/octet-stream\n\n  windows-installer-build:\n    name: Windows Installer Build\n    needs: publish-release\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v2\n      - name: Set up JDK 21\n        uses: actions/setup-java@v2\n        with:\n          distribution: 'temurin'\n          java-version: '21.0.3'\n      - uses: actions/setup-dotnet@v1\n        with:\n          dotnet-version: '2.1.x'\n      - name: Install GUID Generator\n        run: dotnet tool install -g dotnet-guid --version 0.5.2\n      - name: Set up Wix toolkit\n        run: echo \"${WIX}bin\" >> $GITHUB_PATH\n        shell: bash\n      - name: Set cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Download Windows Installer Zip\n        run: |\n          echo default login ${{ secrets.BALLERINA_BOT_USERNAME }} password ${{ secrets.BALLERINA_BOT_TOKEN }} >> _netrc\n          curl --netrc-file _netrc -L -o ballerina-${{ needs.publish-release.outputs.project-version }}-windows.zip https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ needs.publish-release.outputs.release-version }}/ballerina-${{ needs.publish-release.outputs.project-version }}-windows.zip\n      - name: Create windows-msi Installer\n        id: run_installers_msi\n        run: |\n          move installers\\windows .\\..\\..\\\n          cd ..\\..\\windows\n          .\\build-ballerina-windows-x64.bat --version ${{ needs.publish-release.outputs.project-version }} --path .\\..\\ballerina-distribution\\ballerina-distribution\n      - name: Generate Hashes\n        run: |\n          openssl dgst -sha256 -out ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256 D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi\n      - name: Upload Windows msi Hashes\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256\n          asset_path: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi.sha256\n          asset_content_type: application/octet-stream\n      - name: Upload Windows msi Installer\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.BALLERINA_BOT_TOKEN }}\n        with:\n          upload_url: ${{ needs.publish-release.outputs.upload-asset-url }}\n          asset_name: ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi\n          asset_path: D:\\a\\windows\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi\n          asset_content_type: application/octet-stream\n#      - name: Install Ballerina msi\n#        run: msiexec /i w\\target\\msi\\ballerina-${{ needs.publish-release.outputs.project-version }}-windows-x64.msi /quiet /qr\n#        shell: cmd\n#      - name: Update Installer Test Configs\n#        run: |\n#          set DISPLAY_TEXT=${{ needs.publish-release.outputs.lang-version }}\n#          set SWAN_LAKE_LATEST_VERSION=swan-lake-%DISPLAY_TEXT%\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version-display-text=.*/swan-lake-latest-version-display-text=%DISPLAY_TEXT%/\" ballerina-test-automation/gradle.properties\n#          perl -pi -e \"s/^\\s*swan-lake-latest-version=.*/swan-lake-latest-version=%SWAN_LAKE_LATEST_VERSION%/\" ballerina-test-automation/gradle.properties\n#        shell: cmd\n#      - name: Run Installer Tests\n#        working-directory: .\\ballerina-test-automation\\installer-test\n#        run: |\n#          $env:Path += \";C:\\Program Files\\Ballerina\\bin\"\n#          .\\..\\gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n\n  send-notification:\n    name: Send Notification\n    runs-on: ubuntu-latest\n    needs: [publish-release, macos-installer-build, windows-installer-build]\n    steps:\n      - name: Send notification to Google Chat\n        run: |\n          body=$(cat << 'EOF'\n          {\n            \"cardsV2\": [\n              {\n                \"cardId\": \"published-ballerina-distribution\",\n                \"card\": {\n                  \"header\": {\n                    \"title\": \"Ballerina Distribution\",\n                    \"subtitle\": \"v${{ needs.publish-release.outputs.release-version }}\",\n                    \"imageUrl\": \"https://lh6.googleusercontent.com/proxy/R9Rx8vYNd-_HZn58ckf5PNX7RMlC6P-B75fB7UQ_GFH5R0UwtfJ1gVNARBvH1us8LBuK4NVFsvMGnwZkm-H2_9ACwH_j0lQmExR1SRMNGlFcbrm_1O7foFpqqOiVzA\",\n                    \"imageType\": \"CIRCLE\"\n                  },\n                  \"sections\": [\n                    {\n                      \"widgets\": [\n                        {\n                          \"textParagraph\": {\n                            \"text\": \"Run \\\"Update Kola\\\" to update the distribution.\"\n                          }\n                        },\n                        {\n                          \"buttonList\": {\n                            \"buttons\": [\n                              {\n                                \"text\": \"Download\",\n                                \"onClick\": {\n                                  \"openLink\": {\n                                    \"url\": \"https://github.com/${{ github.repository }}/releases/tag/v${{ needs.publish-release.outputs.release-version }}\"\n                                  }\n                                }\n                              }\n                            ]\n                          }\n                        }\n                      ]\n                    }\n                  ]\n                }\n              }\n            ]\n          }\n          EOF\n          )\n          curl -X POST -H 'Content-Type: application/json' \"https://chat.googleapis.com/v1/spaces/AAAApvQDm3o/messages?key=${{ secrets.EDITOR_CHAT_BOT_KEY }}&token=${{ secrets.EDITOR_CHAT_BOT_TOKEN }}\" -d \"$body\"\n\n  send-failure-notification:\n    name: Send Failure Notification\n    runs-on: ubuntu-latest\n    if: ${{ failure() }}\n    needs: [publish-release, macos-installer-build, windows-installer-build]\n    steps:\n      - name: Send failure notification to Google Chat\n        run: |\n          body=$(cat << 'EOF'\n          {\n            \"cardsV2\": [\n              {\n                \"cardId\": \"ballerina-dist-build-error\",\n                \"card\": {\n                  \"header\": {\n                    \"title\": \"Ballerina Distribution\",\n                    \"subtitle\": \"Release Failure\",\n                    \"imageUrl\": \"https://lh6.googleusercontent.com/proxy/R9Rx8vYNd-_HZn58ckf5PNX7RMlC6P-B75fB7UQ_GFH5R0UwtfJ1gVNARBvH1us8LBuK4NVFsvMGnwZkm-H2_9ACwH_j0lQmExR1SRMNGlFcbrm_1O7foFpqqOiVzA\",\n                    \"imageType\": \"CIRCLE\"\n                  },\n                  \"sections\": [\n                    {\n                      \"widgets\": [\n                        {\n                          \"decoratedText\": {\n                            \"text\": \"<font color=\\\"#FF0000\\\">Error: The build has failed</font>\",\n                            \"startIcon\": {\n                              \"materialIcon\": {\n                                \"name\": \"error\",\n                                \"fill\": true,\n                                \"weight\": 500,\n                                \"grade\": 100\n                              }\n                            }\n                          }\n                        },\n                        {\n                          \"textParagraph\": {\n                            \"text\": \"Please view the workflow for further details.\"\n                          }\n                        },\n                        {\n                          \"buttonList\": {\n                            \"buttons\": [\n                              {\n                                \"text\": \"View Workflow\",\n                                \"onClick\": {\n                                  \"openLink\": {\n                                    \"url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"\n                                  }\n                                }\n                              }\n                            ]\n                          }\n                        }\n                      ]\n                    }\n                  ]\n                }\n              }\n            ]\n          }\n          EOF\n          )\n          curl -X POST -H 'Content-Type: application/json' \"https://chat.googleapis.com/v1/spaces/AAAApvQDm3o/messages?key=${{ secrets.EDITOR_CHAT_BOT_KEY }}&token=${{ secrets.EDITOR_CHAT_BOT_TOKEN }}\" -d \"$body\"\n"
  },
  {
    "path": ".github/workflows/pull-request.yml",
    "content": "name: Pull Request\n\non:\n    pull_request:\n        branches:\n            - master\n            - ballerina-1.1.x\n            - ballerina-1.2.x\n            - 2201.[0-9]+.x\n\njobs:\n    ubuntu-integration-tests:\n        name: Integration Tests on Ubuntu\n        runs-on: ubuntu-latest\n        concurrency:\n            group: ${{ github.ref }}-integration-tests\n            cancel-in-progress: true\n        steps:\n            -   name: Checkout Repository\n                uses: actions/checkout@v3\n            -   name: Set up JDK 21\n                uses: actions/setup-java@v3\n                with:\n                    distribution: 'temurin'\n                    java-version: '21.0.3'\n            -   name: Build Ballerina Distribution\n                env:\n                    packageUser: ${{ github.actor }}\n                    packagePAT: ${{ secrets.GITHUB_TOKEN }}\n                    devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n                    githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n                    ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n                run: ./gradlew clean build --stacktrace --scan --console=plain --no-daemon --continue -x :ballerina:testExamples -x :project-api-tests:test\n\n    ubuntu-bbe-tests:\n        name: BBE Tests on Ubuntu\n        runs-on: ubuntu-latest\n        concurrency:\n            group: ${{ github.ref }}-bbe-tests\n            cancel-in-progress: true\n        steps:\n            -   name: Checkout Repository\n                uses: actions/checkout@v3\n            -   name: Set up JDK 21\n                uses: actions/setup-java@v3\n                with:\n                    distribution: 'temurin'\n                    java-version: '21.0.3'\n            -   name: Build Ballerina Distribution\n                env:\n                    packageUser: ${{ github.actor }}\n                    packagePAT: ${{ secrets.GITHUB_TOKEN }}\n                    devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n                    githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n                    ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n                run: ./gradlew clean :ballerina:testExamples --stacktrace --scan --console=plain --no-daemon --continue -x :project-api-tests:test\n    windows-build-without-tests:\n        name: Windows Build\n        runs-on: windows-latest\n        concurrency:\n            group: ${{ github.ref }}-windows\n            cancel-in-progress: true\n        steps:\n            -   name: Checkout Repository\n                uses: actions/checkout@v3\n            -   name: Set up JDK 21\n                uses: actions/setup-java@v3\n                with:\n                    distribution: 'temurin'\n                    java-version: '21.0.3'\n            - name: Build Ballerina Distribution\n              env:\n                  packageUser: ${{ github.actor }}\n                  packagePAT: ${{ secrets.GITHUB_TOKEN }}\n                  JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8\n                  devCentralToken: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }}\n                  githubAccessToken: ${{ secrets.GITHUB_TOKEN }}\n                  ballerinaBotWorkflow: $ {{ secrets.BALLERINA_BOT_WORKFLOW }}\n              run: ./gradlew.bat clean build --stacktrace --scan --console=plain --no-daemon --continue -x test\n"
  },
  {
    "path": ".github/workflows/sign-installers.yml",
    "content": "name: Sign release artifacts\n\non:\n  workflow_dispatch:\n    inputs:\n      versionName:\n        description: 'Specify the Version name eg: 2201.6.0'\n        required: true\n        default: ''\n\npermissions:\n  id-token: write \n  contents: write\n\njobs:\n  sign-release:\n    name: Sign release artifacts\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: cosign-installer\n        uses: sigstore/cosign-installer@v3.5.0\n      - name: Install Node\n        uses: actions/setup-node@v2\n        with:\n          node-version: '14'\n      - name: Install GitHub CLI\n        run: |\n          npm install -g github-cli\n      - name: Retrieve MacOS Installer\n        run:\n          |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ github.event.inputs.versionName }}/ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg\n      - name: Sign the MacOS Installer\n        run: |\n          cosign sign-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg --output-certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.pem --output-signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.sig --yes\n      - name: Verify the MacOS Installer\n        run: |\n          cosign verify-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg --certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.pem --signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/sign-installers.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com \n      - name: Retrieve MacOS-ARM Installer\n        run:\n          |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ github.event.inputs.versionName }}/ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg\n      - name: Sign the MacOS-ARM Installer\n        run: |\n          cosign sign-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg --output-certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.pem --output-signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.sig --yes\n      - name: Verify the MacOS-ARM Installer\n        run: |\n          cosign verify-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg --certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.pem --signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/sign-installers.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Retrieve Windows Installer\n        run:\n          |\n          wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ github.event.inputs.versionName }}/ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi\n      - name: Sign the Windows Installer\n        run: |\n          cosign sign-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi --output-certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.pem --output-signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.sig --yes\n      - name: Verify the Windows Installer\n        run: |\n          cosign verify-blob ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi --certificate ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.pem --signature ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.sig --certificate-identity=https://github.com/ballerina-platform/ballerina-distribution/.github/workflows/sign-installers.yml@${{ github.ref }} --certificate-oidc-issuer=https://token.actions.githubusercontent.com\n      - name: Upload Installers' Verification Files\n        env:\n          GH_TOKEN : ${{ secrets.BALLERINA_BOT_TOKEN }}\n        run: |\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.pem --clobber\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-x64.pkg.sig --clobber\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.pem --clobber\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-macos-arm-x64.pkg.sig --clobber\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.pem --clobber\n          gh release upload v${{ github.event.inputs.versionName }} ./ballerina-${{ github.event.inputs.versionName }}-swan-lake-windows-x64.msi.sig --clobber\n          "
  },
  {
    "path": ".github/workflows/test-installers.yml",
    "content": "name: Test Installers\n\non:\n  workflow_dispatch:\n    inputs:\n      releaseVersion:\n        description: 'Version of the release. e.g., swan-lake-beta1'\n        required: true\n      preReleaseSuffix:\n        description: 'The text that will be suffixed to the Git tag. e.g., rc1'\n        required: false\n        default: ''\n\njobs:\n  macos-installer-test:\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v3\n      - name: Set Version\n        id: set-version\n        run: |\n          RELEASE_VERSION=${{ github.event.inputs.releaseVersion }}\n          TAGGED_VERSION=$RELEASE_VERSION\n          if [ -n \"${{ github.event.inputs.preReleaseSuffix }}\" ]; then\n            TAGGED_VERSION=$RELEASE_VERSION-${{ github.event.inputs.preReleaseSuffix }}\n          fi\n          echo VERSION=$RELEASE_VERSION >> $GITHUB_ENV\n          echo GIT_TAG=$TAGGED_VERSION >> $GITHUB_ENV\n          echo \"::set-output name=version::$RELEASE_VERSION\"\n          echo \"::set-output name=taggedVersion::$TAGGED_VERSION\"\n      - name: Download Ballerina pkg Installer\n        run: wget https://github.com/ballerina-platform/ballerina-distribution/releases/download/v${{ steps.set-version.outputs.taggedVersion }}/ballerina-macos-x64-${{ steps.set-version.outputs.version }}.pkg\n      - name: Install Ballerina pkg\n        run: sudo installer -pkg ballerina-macos-x64-${{ steps.set-version.outputs.version }}.pkg -target /\n      - name: Run Installer Tests\n        working-directory: ./ballerina-test-automation/installer-test\n        run: ./../gradlew build --stacktrace -scan --console=plain --no-daemon -DballerinaInstalled=true\n"
  },
  {
    "path": ".github/workflows/trigger-bbe-generation.yml",
    "content": "name: Generate Ballerina By Examples\non:\n    push:\n        branches:\n            - '2201.0.x'\n        paths:\n            - 'examples/**'\njobs:\n    trigger-bbe-gen:\n        name: Trigger Ballerina By Examples genration\n        if: github.repository_owner == 'ballerina-platform'\n        runs-on: ubuntu-latest\n        steps:\n            -   run: |\n                    curl --request \\\n                    POST 'https://api.github.com/repos/ballerina-platform/ballerina-dev-website/dispatches' \\\n                    --header 'Accept: application/vnd.github.v3+json' \\\n                    --header 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \\\n                    --header 'Content-Type: application/json' \\\n                    --data-raw '{\n                        \"event_type\": \"distribution-update\"\n                    }'\n"
  },
  {
    "path": ".gitignore",
    "content": "*.class\n*.log\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n.idea\n*.iml\n*.ipr\n*.iws\n\n# generated files\ntarget\n/gen\n/compiler/ballerina-lang/src/main/resources/grammar/BallerinaLexer.tokens\n/tool-plugins/intellij/src/main/antlr/org/ballerinalang/plugins/idea/grammar/BallerinaLexer.tokens\nvelocity.log\n\n# direct downloads\nballerina/downloads/ballerina-jre-artifacts-zip/\n\n# gradle\n.gradle\nbuild/\ngradle-app.setting\n!gradle-wrapper.jar\n.gradletasknamecache\n\n# mac\n.DS_Store\n\n.classpath\n.project\n.settings\n.vscode\n\n# Temporarily ignore\nCVE-2025-27553\nCVE-2025-30474\n\n# Config.toml files that may be used with examples\nexamples/**/Config.toml\n"
  },
  {
    "path": ".trivyignore",
    "content": "# False positive\nCVE-2020-7768\n\n# Need to be fixed\nCVE-2025-48924\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Ballerina Distribution\n\n[![Ballerina Distribution Build](https://github.com/ballerina-platform/ballerina-distribution/workflows/Build/badge.svg)](https://github.com/ballerina-platform/ballerina-distribution/actions?query=workflow%3A%22Build%22)\n[![Daily build](https://github.com/ballerina-platform/ballerina-distribution/workflows/Daily%20build/badge.svg)](https://github.com/ballerina-platform/ballerina-distribution/actions?query=workflow%3A%22Daily+build%22)\n\nThe Ballerina distribution repository builds the final Ballerina distributions. It combines the Ballerina runtime with standard libraries and language extensions.\n\n## Table of contents\n\n- [Getting started](#getting-started)\n- [Download and install](#download-and-install)\n- [Contributing to Ballerina](#contributing-to-ballerina)\n- [License](#license)\n- [Useful links](#useful-links)\n\n## Getting started\n\nYou can use one of the following options to try out Ballerina.\n\n* [Getting Started](https://ballerina.io/learn/getting-started/)\n* [Quick Tour](https://ballerina.io/learn/quick-tour/)\n* [Ballerina by Example](https://ballerina.io/learn/by-example/)\n\n## Download and install\n\n### Download the binary\n\nYou can download the Ballerina distribution at http://ballerina.io/downloads.\n\n### Install from source\n\nAlternatively, you can install Ballerina from the source using the following instructions.\n\n#### Prerequisites\n\n* JDK21 ([Adopt OpenJDK21](https://adoptopenjdk.net/) or any other OpenJDK distribution)\n\n#### Building the source\n\n1. Clone this repository using the following command.\n\n    ```bash\n    git clone https://github.com/ballerina-platform/ballerina-distribution\n    ```\n2. This repository is depending on Github packages. You need to have a personal access token with read package permissions. Then you need to set following environment variables.\n    \n    Linux/Unix\n    ```bash\n    export packageUser=<Your github username>\n    export packagePAT=<Your personal access token>\n    ```\n    \n    Windows\n    ```batch\n    set packageUser=<Your github username>\n    set packagePAT=<Your personal access token>\n    ```\n3. This repository contains central integration tests. You need to have dev access token of the bctestorg organization to run these tests. Then you need to set following environment variables. \n\n   Linux/Unix\n    ```bash\n    export BALLERINA_DEV_CENTRAL=true\n    export BALLERINA_CENTRAL_ACCESS_TOKEN=<Dev access token>\n    ```\n\n   Windows\n    ```batch\n    set BALLERINA_DEV_CENTRAL=true\n    set BALLERINA_CENTRAL_ACCESS_TOKEN=<Dev access token>\n    ```\n   Else you can disable central integration tests and build the repository.\n   \n4. Run the Gradle build command ``./gradlew build`` from the repository root directory.\n5. Out of the ZIP distributions in the `ballerina/build/distributions/` directory, extract the `ballerina-<version>-SNAPSHOT.zip` file (e.g., `ballerina-swan-lake-beta3-SNAPSHOT.zip`). The other distributions are used for installer generation.\n\n## Contributing to Ballerina\n\nAs an open source project, Ballerina welcomes contributions from the community. To start contributing, read these [contribution guidelines](https://github.com/ballerina-platform/ballerina-lang/blob/master/CONTRIBUTING.md) for information on how you should go about contributing to our project.\n\nCheck the issue tracker for open issues that interest you. We look forward to receiving your contributions.\n\n## License\n\nBallerina code is distributed under [Apache license 2.0](https://github.com/ballerina-platform/ballerina-lang/blob/master/LICENSE).\n\n## Useful links\n\n* The ballerina-dev@googlegroups.com mailing list is for discussing code changes to the Ballerina project.\n* Chat live with us via our [Discord server](https://discord.gg/ballerinalang).\n* Technical questions should be posted on Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag.\n"
  },
  {
    "path": "ballerina/COPYRIGHT",
    "content": "\nCopyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n\nThis product includes software developed at WSO2 (http://wso2.com/).\n\n=========================================================================\n==  ANTLR Notice                                                    ==\n=========================================================================\n\n[The BSD License]\nCopyright (c) 2012 Terence Parr and Sam Harwell\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted\nprovided that the following conditions are met:\n\n\t- Redistributions of source code must retain the above copyright notice, this list of\n\t  conditions and the following disclaimer.\n\t- Redistributions in binary form must reproduce the above copyright notice, this list of\n\t  conditions and the following disclaimer in the documentation and/or other materials\n\t  provided with the distribution.\n\t- Neither the name of the author nor the names of its contributors may be used to endorse\n\t  or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\nTHE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\nSTRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\nTHE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=========================================================================\n==  Saxon-HE Notice                                                    ==\n=========================================================================\n\nMost of the open source code in the Saxon product is governed by the Mozilla Public\nLicense version 2.0, which is reproduced below.\n\nhttps://www.mozilla.org/en-US/MPL/2.0/\n\n=========================================================================\n(This notice is included in the Saxon distribution because Saxon includes a QuickSort\nmodule that was originally developed by Wolfgang Hoschek at CERN, and which was licensed\nfor use under the conditions specified here.)\n\n\nCopyright © 1999 CERN - European Organization for Nuclear Research.\n\nPermission to use, copy, modify, distribute and sell this software and its documentation for any purpose\nis hereby granted without fee, provided that the above copyright notice appear in all copies and\nthat both that copyright notice and this permission notice appear in supporting documentation.\nCERN makes no representations about the suitability of this software for any purpose.\nIt is provided \"as is\" without expressed or implied warranty.\n\n=========================================================================\n\n\n(This notice is included in the Saxon distribution because Saxon's XPath parser\nwas originally derived from an XPath parser written by James Clark and made available\nunder this license. The Saxon XPath parser has since diverged very substantially, but\nthere are traces of the original code still present.)\n\nCopyright (c) 1998, 1999 James Clark\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL JAMES CLARK BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\nExcept as contained in this notice, the name of James Clark shall\nnot be used in advertising or otherwise to promote the sale, use or\nother dealings in this Software without prior written authorization\nfrom James Clark.\n=========================================================================\n\n\n(This notice is included in the Saxon distribution because Saxon\nuses code for conversion of XML Schema Regular expressions to\nJava/.NET regular expressions that was originally written by James\nClark and made available under this license. The Saxon version of\nthe code has been enhanced in various ways but is still recognizably\nbased on the original.)\n\nCopyright (c) 2001-2003 Thai Open Source Software Center Ltd\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Thai Open Source Software Center Ltd nor\n    the names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=========================================================================\n\n\n(This notice is included in the Saxon distribution because Saxon\nuses code performing Unicode Normalization that was originally written by Mark\nDavis and made available under this license. The Saxon version of the\ncode has been enhanced in various minor ways but is still recognizably\nbased on the original. For details of modifications, see the comments in\nthe source code.)\n\n\nCOPYRIGHT AND PERMISSION NOTICE\nCopyright © 1991-2007 Unicode, Inc. All rights reserved. Distributed under the Terms of Use\nin http://www.unicode.org/copyright.html.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of the Unicode\ndata files and any associated documentation (the \"Data Files\") or Unicode software and any\nassociated documentation (the \"Software\") to deal in the Data Files or Software without\nrestriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,\nand/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or\nSoftware are furnished to do so, provided that (a) the above copyright notice(s) and this\npermission notice appear with all copies of the Data Files or Software, (b) both the above\ncopyright notice(s) and this permission notice appear in associated documentation, and\n(c) there is clear notice in each modified Data File or in the Software as well as in the\ndocumentation associated with the Data File(s) or Software that the data or software has\nbeen modified.\n\nTHE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.\nIN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE\nBE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,\nOR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\nWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\nARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA\nFILES OR SOFTWARE.\n\nExcept as contained in this notice, the name of a copyright holder shall not be used\nin advertising or otherwise to promote the sale, use or other dealings in these\nData Files or Software without prior written authorization of the copyright holder.\n\n=========================================================================\n==  SLF4J Notice                                                       ==\n=========================================================================\n\n Copyright (c) 2004-2017 QOS.ch\n All rights reserved.\n\n Permission is hereby granted, free  of charge, to any person obtaining\n a  copy  of this  software  and  associated  documentation files  (the\n \"Software\"), to  deal in  the Software without  restriction, including\n without limitation  the rights to  use, copy, modify,  merge, publish,\n distribute,  sublicense, and/or sell  copies of  the Software,  and to\n permit persons to whom the Software  is furnished to do so, subject to\n the following conditions:\n\n The  above  copyright  notice  and  this permission  notice  shall  be\n included in all copies or substantial portions of the Software.\n\n THE  SOFTWARE IS  PROVIDED  \"AS  IS\", WITHOUT  WARRANTY  OF ANY  KIND,\n EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF\n MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION\n WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "ballerina/LICENSE",
    "content": "\nThis product is licensed by WSO2 LLC. under Apache License 2.0. The license\ncan be downloaded from the following locations:\n\thttp://www.apache.org/licenses/LICENSE-2.0.html\n\thttp://www.apache.org/licenses/LICENSE-2.0.txt\n\nThis product also contains software under different licenses. This table below\nall the contained libraries (jar files) and the license under which they are \nprovided to you.\n\nAt the bottom of this file is a table that shows what each license indicated\nbelow is and where the actual text of the license can be found.\n\n\nName                                                                                                Type           License             \n_________________________________________________________________________________________________________________________________________________\nballerina-command-1.5.0.jar                                                                         jar            apache2             \nsequence-model-generator-ls-extension-2.0.0.jar                                                     jar            apache2             \norg.eclipse.lsp4j.jsonrpc-0.15.0.jar                                                                bundle         apache2             \njson-to-record-converter-2201.12.0.jar                                                              jar            apache2             \nballerinalang-data-mapper-2201.12.0.jar                                                             jar            apache2             \nopenapi-ls-extension-2.3.0.jar                                                                      jar            apache2             \ngraphql-model-generator-ls-extension-2.0.0.jar                                                      jar            apache2             \nlanguage-server-core-2201.12.0.jar                                                                  jar            apache2             \nperformance-analyzer-services-2201.12.0.jar                                                         jar            apache2             \nflow-model-generator-ls-extension-2.0.0.jar                                                         jar            apache2             \nxml-to-record-converter-2201.12.0.jar                                                               jar            apache2             \nlanguage-server-cli-2201.12.0.jar                                                                   jar            apache2             \nservice-model-generator-ls-extension-2.0.0.jar                                                      jar            apache2             \ntrigger-service-2201.12.0.jar                                                                       jar            apache2             \nlanguage-server-stdio-launcher-2201.12.0.jar                                                        jar            apache2             \ntest-manager-service-ls-extension-2.0.0.jar                                                         jar            apache2             \ncommons-io-2.15.1.jar                                                                               bundle         apache2             \narchitecture-model-generator-ls-extension-2.0.0.jar                                                 jar            apache2             \norg.eclipse.lsp4j-0.15.0.jar                                                                        bundle         apache2             \npartial-parser-2201.12.0.jar                                                                        jar            apache2             \nguava-32.0.1-jre.jar                                                                                bundle         apache2             \ncloud-tooling-3.3.0.jar                                                                             jar            apache2             \nbal-shell-service-2201.12.0.jar                                                                     jar            apache2             \ndebug-adapter-core-2201.12.0.jar                                                                    jar            apache2             \njava-semver-0.9.0.jar                                                                               jar            mit                 \norg.eclipse.lsp4j.jsonrpc.debug-0.15.0.jar                                                          bundle         epl2                \ndebug-adapter-cli-2201.12.0.jar                                                                     jar            apache2             \norg.eclipse.lsp4j.debug-0.12.0.jar                                                                  bundle         epl2                \ncentral-client-2201.12.0.jar                                                                        jar            apache2             \nokhttp-3.14.0.jar                                                                                   jar            apache2             \nobject-2201.12.0.jar                                                                                jar            apache2             \ngraphql-model-generator-core-2.0.0.jar                                                              jar            apache2             \nsyntax-api-calls-gen-2201.12.0.jar                                                                  jar            apache2             \njackson-dataformat-yaml-2.15.3.jar                                                                  bundle         apache2             \nasm-analysis-9.7.jar                                                                                bundle         bsd3                \ntable-2201.12.0.jar                                                                                 jar            apache2             \nballerina-to-openapi-2.3.0.jar                                                                      jar            apache2             \njaeger-core-0.31.0.jar                                                                              jar            apache2             \ntransactions-jta-5.0.8.jar                                                                          jar            apache2             \nvalue-2201.12.0.jar                                                                                 jar            apache2             \ncommons-beanutils-1.9.4.jar                                                                         bundle         apache2             \nballerina-tools-api-2201.12.0.jar                                                                   jar            apache2             \njballerina.java-2201.12.0.jar                                                                       jar            apache2             \ncommons-codec-1.14.jar                                                                              bundle         apache2             \naxiom-impl-1.4.0.jar                                                                                bundle         apache2             \nformatter-cli-2201.12.0.jar                                                                         jar            apache2             \nballerina-linter-2201.12.0.jar                                                                      jar            apache2             \nasm-commons-9.7.jar                                                                                 bundle         bsd3                \nshell-core-2201.12.0.jar                                                                            jar            apache2             \nstring-2201.12.0.jar                                                                                jar            apache2             \ntransaction-2201.12.0.jar                                                                           jar            apache2             \nballerina-bindgen-2201.12.0.jar                                                                     jar            apache2             \njackson-core-2.15.3.jar                                                                             bundle         apache2             \nasm-9.7.jar                                                                                         bundle         bsd3                \njackson-annotations-2.15.3.jar                                                                      bundle         apache2             \ngraphql-code-generator-0.13.0.jar                                                                   jar            mit                 \nformatter-core-2201.12.0.jar                                                                        jar            apache2             \nballerina-metrics-extension-2201.12.0.jar                                                           jar            apache2             \nballerina-parser-2201.12.0.jar                                                                      jar            apache2             \nstream-2201.12.0.jar                                                                                jar            apache2             \nnetty-resolver-4.1.118.Final.jar                                                                    bundle         apache2             \nkotlin-stdlib-common-1.6.0.jar                                                                      jar            apache2             \nfunction-2201.12.0.jar                                                                              jar            apache2             \nmaven-resolver-2201.12.0.jar                                                                        jar            apache2             \njava-diff-utils-4.5.jar                                                                             bundle         apache2             \ntoml-parser-2201.12.0.jar                                                                           jar            mit                 \narchitecture-model-generator-plugin-2.0.0.jar                                                       jar            apache2             \nannotations-2201.12.0.jar                                                                           jar            apache2             \nasyncapi-cli-0.11.0.jar                                                                             jar            apache2             \ntesterina-runtime-2201.12.0.jar                                                                     jar            apache2             \njavax.mail-1.6.2.jar                                                                                bundle         cddl1               \nfuture-2201.12.0.jar                                                                                jar            apache2             \norg.wso2.carbon.metrics.core-2.3.7.jar                                                              bundle         apache2             \nasm-tree-9.7.jar                                                                                    bundle         bsd3                \norg.jacoco.report-0.8.12.jar                                                                        bundle         epl2                \ngraphql-cli-0.13.0                 \ncommons-compress-1.26.2.jar                                                                         bundle         apache2             \nbool-2201.12.0             \njline-3.25.0.jar                                                                                    bundle         upl1.0              \nmodel-generator-commons-2.0.0             \nnetty-transport-4.1.118.Final.jar                                                                   bundle         apache2             \norg.jacoco.core-0.8.12.jar                                                                          bundle         epl2                \norg.wso2.transport.local-file-system-6.0.55.jar                                                     bundle         apache2             \nshell-cli-2201.12.0             \njackson-databind-2.15.3.jar                                                                         bundle         apache2             \ninteger-2201.12.0             \njavax.transaction-api-1.3.jar                                                                       bundle         cddl1               \nopenapi-cli-2.3.0             \nsnakeyaml-2.0.jar                                                                                   bundle         apache2             \nstax2-api-4.2.1.jar                                                                                 bundle         bsd                 \npackage-semantic-analyzer-1.0.0.jar                                                                 jar            apache2             \nballerina-io-internal-2201.12.0             \nasm-util-9.7.jar                                                                                    bundle         bsd3                \nopenapi-build-extension-2.3.0             \nsemver-checker-cli-2201.12.0             \ncommons-text-1.10.0.jar                                                                             bundle         apache2             \ngson-2.10.1.jar                                                                                     bundle         apache2             \njaeger-thrift-0.31.0.jar                                                                            jar            apache2             \nopenapi-bal-task-plugin-2.3.0             \nnetty-common-4.1.118.Final.jar                                                                      bundle         apache2             \nregexp-2201.12.0             \nballerina-cli-2201.12.0             \ntesterina-core-2201.12.0             \ntypedesc-2201.12.0             \ntransactions-api-5.0.8.jar                                                                          jar            apache2             \ndiagram-util-2201.12.0             \npersist-cli-1.6.0             \nquery-2201.12.0             \nnetty-buffer-4.1.118.Final.jar                                                                      bundle         apache2             \nsqlite-jdbc-3.47.0.0.jar                                                                            bundle         apache2             \nkotlin-stdlib-1.6.0.jar                                                                             jar            apache2             \nfloatingpoint-2201.12.0             \narchitecture-model-generator-core-2.0.0             \norg.wso2.securevault-1.0.0-wso2v2.jar                                                               bundle         apache2             \nnetty-transport-native-kqueue-4.1.118.Final.jar                                                     bundle         apache2             \ngraphql-schema-file-generator-0.13.0             \nokio-jvm-3.4.0.jar                                                                                  bundle         apache2             \ngeronimo-stax-api_1.0_spec-1.0.1.jar                                                                bundle         apache2             \nlanguage-server-commons-2201.12.0             \nwoodstox-core-6.5.0.jar                                                                             bundle         apache2             \norg.wso2.carbon.core-5.1.0.jar                                                                      bundle         apache2             \nsequence-model-generator-core-2.0.0             \ntransactions-5.0.8.jar                                                                              jar            apache2             \njackson-datatype-jsr310-2.15.3.jar                                                                  bundle         apache2             \nerror-2201.12.0             \natomikos-util-5.0.8.jar                                                                             jar            apache2             \nconfigurable-schema-generator-2201.12.0             \njacocoagent.jar                                                                                     jar            apache2             \ndecimal-2201.12.0             \narray-2201.12.0             \nnetty-transport-native-epoll-4.1.118.Final.jar                                                      bundle         apache2             \ncompiler-0.8.9.jar                                                                                  jar            apache2             \norg.wso2.carbon.messaging-2.3.7.jar                                                                 bundle         apache2             \nstaxon-core-1.2.0.wso2v2.jar                                                                        bundle         apache2             \ndocerina-2201.12.0             \nidentifier-util-2201.12.0             \nopenapi-validator-2.3.0             \nopenapi-core-2.3.0             \nmap-2201.12.0             \naxiom-api-1.4.0.jar                                                                                 bundle         apache2             \nballerina-profiler-1.0.jar                                                                          jar            apache2             \nxml-2201.12.0             \npicocli-4.0.1.jar                                                                                   bundle         apache2             \nballerina-rt-2201.12.0             \nprogressbar-0.7.4.jar                                                                               jar            mit                 \nballerina-lang-2201.12.0             \nflow-model-generator-core-2.0.0             \ncommons-collections-3.2.2.jar                                                                       bundle         apache2             \nprotoc-cli-0.5.0             \norg.wso2.transport.http.netty-6.3.11.jar                                                            bundle         apache2             \nsemver-checker-core-2201.12.0             \nballerinai-observe-0.0.0.jar                                                                        jar            apache2             \nballerinai-transaction-0.0.0.jar                                                                    jar            apache2             \nballerina-openapi-2.3.0.jar                                                                         jar            apache2             \nballerina-toml-0.8.0.jar                                                                            jar            apache2             \nballerina-toml.parser-0.8.0.jar                                                                     jar            apache2             \nballerina-toml.lexer-0.8.0.jar                                                                      jar            apache2             \nballerina-toml.writer-0.8.0.jar                                                                     jar            apache2             \nballerina-data.yaml-0.8.0.jar                                                                       jar            apache2             \nballerina-lang.__internal-0.0.0.jar                                                                 jar            apache2             \nballerina-time-2.7.0.jar                                                                            jar            apache2             \nballerina-ftp-2.13.0.jar                                                                            jar            apache2             \nballerina-lang.future-0.0.0.jar                                                                     jar            apache2             \nballerina-io-1.8.0.jar                                                                              jar            apache2             \nballerina-lang.boolean-0.0.0.jar                                                                    jar            apache2             \nballerina-lang.decimal-0.0.0.jar                                                                    jar            apache2             \nballerina-avro-1.2.0.jar                                                                            jar            apache2             \nballerina-lang.function-0.0.0.jar                                                                   jar            apache2             \nballerina-auth-2.14.0.jar                                                                           jar            apache2             \nballerina-tcp-1.13.0.jar                                                                            jar            apache2             \nballerina-lang.array-0.0.0.jar                                                                      jar            apache2             \nballerina-lang.string-0.0.0.jar                                                                     jar            apache2             \nballerina-data.jsondata-1.1.0.jar                                                                   jar            apache2             \nballerina-lang.object-0.0.0.jar                                                                     jar            apache2             \nballerina-lang.transaction-0.0.0.jar                                                                jar            apache2             \nballerina-random-1.7.0.jar                                                                          jar            apache2             \nballerina-lang.typedesc-0.0.0.jar                                                                   jar            apache2             \nballerina-websocket-2.14.0.jar                                                                      jar            apache2             \nballerina-jballerina.java-0.0.0.jar                                                                 jar            apache2             \nballerina-observe-1.5.0.jar                                                                         jar            apache2             \nballerina-observe.mockextension-1.5.0.jar                                                           jar            apache2             \nballerina-uuid-1.10.0.jar                                                                           jar            apache2             \nballerina-email-2.12.0.jar                                                                          jar            apache2             \nballerina-task-2.7.0.jar                                                                            jar            apache2             \nballerina-edi-1.5.0.jar                                                                             jar            apache2             \nballerina-lang.query-0.0.0.jar                                                                      jar            apache2             \nballerina-cloud-3.3.0.jar                                                                           jar            apache2             \nballerina-url-2.6.0.jar                                                                             jar            apache2             \nballerina-lang.stream-0.0.0.jar                                                                     jar            apache2             \nballerina-cache-3.10.0.jar                                                                          jar            apache2             \nballerina-sql-1.16.0.jar                                                                            jar            apache2             \nballerina-lang.int-0.0.0.jar                                                                        jar            apache2             \nballerina-xslt-2.9.0.jar                                                                            jar            apache2             \nballerina-lang.error-0.0.0.jar                                                                      jar            apache2             \nballerina-lang.float-0.0.0.jar                                                                      jar            apache2             \nballerina-lang.value-0.0.0.jar                                                                      jar            apache2             \nballerina-data.csv-0.8.0.jar                                                                        jar            apache2             \nballerina-persist-1.6.0.jar                                                                         jar            apache2             \nballerina-math.vector-1.2.0.jar                                                                     jar            apache2             \nballerina-lang.runtime-0.0.0.jar                                                                    jar            apache2             \nballerina-websubhub-1.15.0.jar                                                                      jar            apache2             \nballerina-data.xmldata-1.3.0.jar                                                                    jar            apache2             \nballerina-protobuf.types.any-1.8.0.jar                                                              jar            apache2             \nballerina-protobuf-1.8.0.jar                                                                        jar            apache2             \nballerina-protobuf.types.duration-1.8.0.jar                                                         jar            apache2             \nballerina-protobuf.types.timestamp-1.8.0.jar                                                        jar            apache2             \nballerina-protobuf.types.wrappers-1.8.0.jar                                                         jar            apache2             \nballerina-protobuf.types.empty-1.8.0.jar                                                            jar            apache2             \nballerina-protobuf.types.struct-1.8.0.jar                                                           jar            apache2             \nballerina-log-2.12.0.jar                                                                            jar            apache2             \nballerina-jwt-2.15.0.jar                                                                            jar            apache2             \nballerina-oauth2-2.14.0.jar                                                                         jar            apache2             \nballerina-mime-2.12.0.jar                                                                           jar            apache2             \nballerina-crypto-2.9.0.jar                                                                          jar            apache2             \nballerina-test-0.0.0.jar                                                                            jar            apache2             \nballerina-lang.table-0.0.0.jar                                                                      jar            apache2             \nballerina-grpc-1.14.0.jar                                                                           jar            apache2             \nballerina-grpc.types.wrappers-1.14.0.jar                                                            jar            apache2             \nballerina-grpc.types.any-1.14.0.jar                                                                 jar            apache2             \nballerina-grpc.types.struct-1.14.0.jar                                                              jar            apache2             \nballerina-grpc.types.timestamp-1.14.0.jar                                                           jar            apache2             \nresources.jar                                                                                       jar            apache2             \nballerina-grpc.types.duration-1.14.0.jar                                                            jar            apache2             \nballerina-mqtt-1.4.0.jar                                                                            jar            apache2             \nballerina-websub-2.14.0.jar                                                                         jar            apache2             \nballerina-constraint-1.7.0.jar                                                                      jar            apache2             \nballerina-jballerina.java.arrays-1.6.0.jar                                                          jar            apache2             \nballerina-xmldata-2.9.0.jar                                                                         jar            apache2             \nballerina-os-1.10.0.jar                                                                             jar            apache2             \nballerina-ldap-1.3.0.jar                                                                            jar            apache2             \nballerina-udp-1.13.0.jar                                                                            jar            apache2             \nballerina-graphql.dataloader-1.16.0.jar                                                             jar            apache2             \nballerina-graphql.parser-1.16.0.jar                                                                 jar            apache2             \nballerina-graphql.subgraph-1.16.0.jar                                                               jar            apache2             \nballerina-graphql-1.16.0.jar                                                                        jar            apache2             \nballerina-lang.xml-0.0.0.jar                                                                        jar            apache2             \nballerina-lang.map-0.0.0.jar                                                                        jar            apache2             \nballerina-soap.wssec-2.3.0.jar                                                                      jar            apache2             \nballerina-soap-2.3.0.jar                                                                            jar            apache2             \nballerina-soap.soap11-2.3.0.jar                                                                     jar            apache2             \nballerina-soap.soap12-2.3.0.jar                                                                     jar            apache2             \nballerina-http.httpscerr-2.14.0.jar                                                                 jar            apache2             \nballerina-http-2.14.0.jar                                                                           jar            apache2             \nballerina-lang.annotations-0.0.0.jar                                                                jar            apache2             \nballerina-lang.regexp-0.0.0.jar                                                                     jar            apache2             \nballerina-file-1.12.0.jar                                                                           jar            apache2             \nballerina-yaml.lexer-0.8.0.jar                                                                      jar            apache2             \nballerina-yaml.composer-0.8.0.jar                                                                   jar            apache2             \nballerina-yaml.common-0.8.0.jar                                                                     jar            apache2             \nballerina-yaml.serializer-0.8.0.jar                                                                 jar            apache2             \nballerina-yaml.emitter-0.8.0.jar                                                                    jar            apache2             \nballerina-yaml.schema-0.8.0.jar                                                                     jar            apache2             \nballerina-yaml-0.8.0.jar                                                                            jar            apache2             \nballerina-yaml.parser-0.8.0.jar                                                                     jar            apache2             \nobserve-internal-native-1.5.0.jar                                                                   jar            apache2             \ntransaction-native-1.12.0.jar                                                                       jar            apache2             \ndata.yaml-compiler-plugin-0.8.0.jar                                                                 jar            apache2             \ndata.yaml-native-0.8.0.jar                                                                          jar            apache2             \nconstraint-native-1.7.0.jar                                                                         jar            apache2             \ntime-native-2.7.0.jar                                                                               jar            apache2             \nftp-compiler-plugin-2.13.0.jar                                                                      jar            apache2             \ncommons-vfs2-2.8.0.jar                                                                              bundle         apache2             \njsch-0.1.55.jar                                                                                     jar            bsd3                \nftp-native-2.13.0.jar                                                                               jar            apache2             \ncommons-net-3.9.0.jar                                                                               bundle         apache2             \nio-compiler-plugin-1.8.0.jar                                                                        jar            apache2             \nio-native-1.8.0.jar                                                                                 jar            apache2             \njackson-core-2.18.0.jar                                                                             bundle         apache2             \njackson-databind-2.18.0.jar                                                                         bundle         apache2             \njackson-annotations-2.18.0.jar                                                                      bundle         apache2             \navro-1.11.4.jar                                                                                     bundle         apache2             \navro-native-1.2.0.jar                                                                               jar            apache2             \nauth-native-2.14.0.jar                                                                              jar            apache2             \ntcp-compiler-plugin-1.13.0.jar                                                                      jar            apache2             \ntcp-native-1.13.0.jar                                                                               jar            apache2             \nnetty-transport-native-unix-common-4.1.118.Final.jar                                                bundle         apache2             \nlz4-1.3.0.jar                                                                                       bundle         apache2             \njboss-marshalling-2.0.5.Final.jar                                                                   jar            apache2             \nnetty-codec-4.1.118.Final.jar                                                                       bundle         apache2             \nprotobuf-java-3.25.5.jar                                                                            bundle         upl1.0              \nnetty-handler-4.1.118.Final.jar                                                                     bundle         apache2             \nnetty-codec-socks-4.1.118.Final.jar                                                                 bundle         apache2             \ndata.jsondata-compiler-plugin-1.1.0.jar                                                             jar            apache2             \njson-path-2.9.0.jar                                                                                 bundle         apache2             \ndata.jsondata-native-1.1.0.jar                                                                      jar            apache2             \njson-smart-2.4.11.jar                                                                               bundle         apache2             \naccessors-smart-2.4.7.jar                                                                           bundle         apache2             \nwebsocket-compiler-plugin-2.14.0.jar                                                                jar            apache2             \nhttp-native-2.14.0.jar                                                                              jar            apache2             \nnetty-codec-http-4.1.118.Final.jar                                                                  bundle         apache2             \nmime-native-2.12.0.jar                                                                              jar            apache2             \nnetty-handler-proxy-4.1.118.Final.jar                                                               bundle         apache2             \nwebsocket-native-2.14.0.jar                                                                         jar            apache2             \nopentelemetry-sdk-trace-1.0.0.jar                                                                   jar            apache2             \nobserve-native-1.5.0.jar                                                                            jar            apache2             \nopentelemetry-semconv-1.0.0-alpha.jar                                                               jar            apache2             \nopentelemetry-sdk-testing-1.0.0.jar                                                                 jar            apache2             \nopentelemetry-sdk-common-1.0.0.jar                                                                  jar            apache2             \nemail-compiler-plugin-2.12.0.jar                                                                    jar            apache2             \nmimepull-1.9.11.jar                                                                                 bundle         edl1                \nactivation-1.1.1.jar                                                                                jar            cddl1               \ngreenmail-1.5.11.jar                                                                                bundle         apache2             \nemail-native-2.12.0.jar                                                                             jar            apache2             \nquartz-2.3.2.jar                                                                                    bundle         apache2             \ntask-native-2.7.0.jar                                                                               jar            apache2             \ncloud-compiler-plugin-3.3.0.jar                                                                     jar            apache2             \nurl-native-2.6.0.jar                                                                                jar            apache2             \ncache-compiler-plugin-3.10.0.jar                                                                    jar            apache2             \ncache-native-3.10.0.jar                                                                             jar            apache2             \nsql-compiler-plugin-1.16.0.jar                                                                      jar            apache2             \nsql-native-1.16.0.jar                                                                               jar            apache2             \nHikariCP-3.3.1.jar                                                                                  bundle         apache2             \njakarta.activation-1.2.2.jar                                                                        bundle         edl1                \nSaxon-HE-11.4.jar                                                                                   jar            mpl10               \nxmlresolver-4.5.2.jar                                                                               jar            apache2             \nxslt-native-2.9.0.jar                                                                               jar            apache2             \ndata.csv-compiler-plugin-0.8.0.jar                                                                  jar            apache2             \ndata.csv-native-0.8.0.jar                                                                           jar            apache2             \npersist-compiler-plugin-1.6.0.jar                                                                   jar            apache2             \npersist-native-1.6.0.jar                                                                            jar            apache2             \nwebsubhub-compiler-plugin-1.15.0.jar                                                                jar            apache2             \nwebsubhub-native-1.15.0.jar                                                                         jar            apache2             \ndata.xmldata-compiler-plugin-1.3.0.jar                                                              jar            apache2             \ndata.xmldata-native-1.3.0.jar                                                                       jar            apache2             \nprotobuf-native-1.8.0.jar                                                                           jar            apache2             \nlog-compiler-plugin-2.12.0.jar                                                                      jar            apache2             \nlog-native-2.12.0.jar                                                                               jar            apache2             \njwt-native-2.15.0.jar                                                                               jar            apache2             \noauth2-native-2.14.0.jar                                                                            jar            apache2             \njakarta.activation-api-2.0.1.jar                                                                    bundle         edl1                \nbcpg-jdk18on-1.78.jar                                                                               bundle         apache2 + bouncy    \nbcutil-jdk18on-1.78.jar                                                                             bundle         bouncy              \nbcpkix-jdk18on-1.78.jar                                                                             bundle         bouncy              \nbcprov-jdk18on-1.78.jar                                                                             bundle         bouncy              \ncrypto-native-2.9.0.jar                                                                             jar            apache2             \ntesterina-compiler-plugin-0.1.0.jar                                                                 jar            apache2             \ngrpc-compiler-plugin-1.14.0.jar                                                                     jar            apache2             \nnetty-codec-http2-4.1.118.Final.jar                                                                 bundle         apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final-osx-aarch_64.jar                                       bundle         apache2             \nnetty-tcnative-classes-2.0.70.Final.jar                                                             bundle         apache2             \ngrpc-native-1.14.0.jar                                                                              jar            apache2             \ncommons-pool-1.5.6.wso2v1.jar                                                                       bundle         apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final-linux-aarch_64.jar                                     bundle         apache2             \nballerina-parser-2201.12.0.jar                                                                      jar            apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final-osx-x86_64.jar                                         bundle         apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final-linux-x86_64.jar                                       bundle         apache2             \nproto-google-common-protos-1.17.0.jar                                                               jar            apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final.jar                                                    bundle         apache2             \nformatter-core-2201.12.0.jar                                                                        jar            apache2             \nnetty-tcnative-boringssl-static-2.0.70.Final-windows-x86_64.jar                                     bundle         apache2             \nmqtt-compiler-plugin-1.4.0.jar                                                                      jar            epl2                \norg.eclipse.paho.mqttv5.client-1.2.5.jar                                                            bundle         epl2                \nmqtt-native-1.4.0.jar                                                                               jar            apache2             \nwebsub-compiler-plugin-2.14.0.jar                                                                   jar            apache2             \nwebsub-native-2.14.0.jar                                                                            jar            apache2             \nconstraint-compiler-plugin-1.7.0.jar                                                                jar            apache2             \nxmldata-compiler-plugin-2.9.0.jar                                                                   jar            apache2             \nxmldata-native-2.9.0.jar                                                                            jar            apache2             \nos-compiler-plugin-1.10.0.jar                                                                       jar            apache2             \nos-test-utils-1.10.0.jar                                                                            jar            apache2             \nos-native-1.10.0.jar                                                                                jar            apache2             \nldap-native-1.3.0.jar                                                                               jar            mit                 \nunboundid-ldapsdk-7.0.0.jar                                                                         bundle         apache2 + gpl2 + lgpl2\nudp-compiler-plugin-1.13.0.jar                                                                      jar            apache2             \nudp-native-1.13.0.jar                                                                               jar            apache2             \ngraphql-commons-1.16.0.jar                                                                          jar            apache2             \ngraphql-compiler-plugin-1.16.0.jar                                                                  jar            apache2             \ngraphql-native-1.16.0.jar                                                                           jar            apache2             \nwss4j-ws-security-dom-3.0.1.jar                                                                     bundle         apache2             \nwss4j-ws-security-common-3.0.1.jar                                                                  bundle         apache2             \nxmlsec-3.0.3.jar                                                                                    bundle         apache2             \nsoap-native-2.3.0.jar                                                                               jar            mit                 \nballerina-to-openapi-2.3.0.jar                                                                      jar            apache2             \nhttp-compiler-plugin-2.14.0.jar                                                                     jar            apache2             \nfile-compiler-plugin-1.12.0.jar                                                                     jar            apache2             \nfile-native-1.12.0.jar                                                                              jar            apache2             \n\n\nThe license types used by the above libraries and their information is given below:\n\napache2        Apache License Version 2.0\n               http://www.apache.org/licenses/LICENSE-2.0.html\nmit            MIT License\n               http://www.opensource.org/licenses/mit-license.php\nepl2           Eclipse Public License Version 2.0\n               https://www.eclipse.org/legal/epl-2.0/\nbsd3           Berkeley License - 3\n               http://opensource.org/licenses/BSD-3-Clause\ncddl1          Common Development and Distribution License\n               http://www.opensource.org/licenses/cddl1.php\nupl1.0         Universal Permissive License, Version 1.0\n               http://opensource.org/licenses/UPL\nbsd            Berkeley License\n               http://www.opensource.org/licenses/bsd-license.php\nedl1           Eclipse Distribution License Version 1.0\n               http://www.eclipse.org/org/documents/edl-v10.php\nmpl10          Mozilla Public License Version 1.0\n               http://www.mozilla.org/MPL/\nbouncy         Bouncy Castle License\n               http://www.bouncycastle.org/licence.html\nlgpl2          Lesser General Public License Version 2.1\n               http://www.gnu.org/licenses/lgpl-2.1.php\ngpl2           General Public License Version 2.0\n               https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"
  },
  {
    "path": "ballerina/README",
    "content": "Hello, I'm Ballerina.\n=====================\nBallerina is a general purpose, concurrent, and strongly typed programming language with both textual\nand graphical syntaxes. It is designed to make it easier to write programs that integrate with data sources,\nservices, and network-connected APIs of all kinds. It is optimized primarily for such programs - while it can\nbe use to program anything, it is not recommended to use Ballerina if a significant portion of the program is\nnot related to integrating with data sources, services, or network-connected APIs.\n\nBallerina has been inspired by Java, Go, and other languages, but it has a concurrency model built around a \nsequence diagram metaphor.\n\nGetting started\n==================\nYou can download the Ballerina distribution, try samples, and read the documentation at http://ballerinalang.org.\n\nBuilding from the source\n==================================\nIf you want to build Ballerina from the source code:\n\n1. Get a clone or download the source from this repository:\n    https://github.com/ballerina-lang/ballerina\n2. Run the following Maven command from the root directory:\n    mvn clean install\n3. Extract the Ballerina distribution created at `ballerina/distribution/zip/ballerina/target/ballerina-<version>-SNAPSHOT.zip`\nto your local directory."
  },
  {
    "path": "ballerina/build.gradle",
    "content": "/*\n ~ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~ *\n ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ * you may not use this file except in compliance with the License.\n ~ * You may obtain a copy of the License at\n ~ *\n ~ * http://www.apache.org/licenses/LICENSE-2.0\n ~ *\n ~ * Unless required by applicable law or agreed to in writing, software\n ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ * See the License for the specific language governing permissions and\n ~ * limitations under the License.\n ~ */\n\n\nimport groovy.json.JsonSlurper\nimport org.apache.tools.ant.filters.ReplaceTokens\nimport org.apache.tools.ant.taskdefs.condition.Os\n\nimport static groovy.io.FileType.FILES\n\ndescription = 'Ballerina - Tools'\n\next {\n    jreLocation = \"downloads/ballerina-jre-artifacts-zip/\"\n    distributionName = \"ballerina\"\n    shortVersion = \"${version}\".replaceAll(\"-SNAPSHOT\", \"\")\n}\n\nconfigurations {\n    jBallerinaDistribution\n    ballerinaDistribution\n    ballerinaLinuxDistribution\n    ballerinaLinuxArmDistribution\n    ballerinaMacDistribution\n    ballerinaMacArmDistribution\n    ballerinaWindowsDistribution\n    repoBuilder\n}\n\ndependencies {\n    repoBuilder project(':dist-repo-builder')\n    implementation project(':cache-generator')\n}\n\ndef jBallerinaDistributionZip = file(\"$project.buildDir/distributions/ballerina-${shortVersion}.zip\")\ndef ballerinaDistributionZip = file(\"$project.buildDir/distributions/ballerina-${ballerinaLangVersion}.zip\")\ndef ballerinaLinuxDistributionZip = file(\"$project.buildDir/distributions/ballerina-linux-${ballerinaLangVersion}.zip\")\ndef ballerinaLinuxArmDistributionZip = file(\"$project.buildDir/distributions/ballerina-linux-arm-${ballerinaLangVersion}.zip\")\ndef ballerinaMacDistributionZip = file(\"$project.buildDir/distributions/ballerina-macos-${ballerinaLangVersion}.zip\")\ndef ballerinaMacArmDistributionZip = file(\"$project.buildDir/distributions/ballerina-macos-arm-${ballerinaLangVersion}.zip\")\ndef ballerinaWindowsDistributionZip = file(\"$project.buildDir/distributions/ballerina-windows-${ballerinaLangVersion}.zip\")\n\ntask unpackBallerinaJre(type: Download) {\n    group = \"unpack_dependencies\"\n    def jreBaseURL = \"https://github.com/ballerina-platform/ballerina-custom-jre/releases/download/${ballerinaJreVersion}\"\n    src([\n            \"${jreBaseURL}/ballerina-jre-linux-64-${ballerinaJreVersion}.zip\",\n            \"${jreBaseURL}/ballerina-jre-linux-arm-64-${ballerinaJreVersion}.zip\",\n            \"${jreBaseURL}/ballerina-jre-macos-64-${ballerinaJreVersion}.zip\",\n            \"${jreBaseURL}/ballerina-jre-macos-arm-64-${ballerinaJreVersion}.zip\",\n            \"${jreBaseURL}/ballerina-jre-win-64-${ballerinaJreVersion}.zip\"\n    ])\n    onlyIfModified true\n    dest \"${jreLocation}\"\n}\n\ntask unpackJballerinaTools(type: Copy) {\n    group = \"unpack_dependencies\"\n    configurations.jbalTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        from zipTree(artifact.getFile())\n        into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n    }\n}\n\ntask unpackDevTools(type: Copy) {\n    group = \"unpack_dependencies\"\n    configurations.devTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        from zipTree(artifact.getFile())\n        into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n    }\n}\n\ntask downloadDocUi {\n    def response = new JsonSlurper().parseText(new URL(docUiApi).text)\n    def zipFileUrl = response.fileURL\n    def zipInputStream = new URL(zipFileUrl).openStream()\n    def outputFile = new File(\"${buildDir}/target/extracted-distributions/doc-ui-zip/ballerina-doc-ui.zip\")\n    doLast {\n        outputFile.parentFile.mkdirs()\n        outputFile.withOutputStream { outputStream ->\n            outputStream << zipInputStream\n        }\n    }\n}\n\ntask unpackAwsLambdaBala(type: Copy) {\n    group = \"unpack_dependencies\"\n    configurations.awsLambdaBala.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        from zipTree(artifact.getFile())\n        into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n    }\n}\n\ntask unpackStdLibs() {\n    doLast {\n        configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            copy {\n                from project.zipTree(artifact.getFile())\n                into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n            }\n        }\n    }\n}\n\ntask unpackBalTools() {\n    doLast {\n        configurations.ballerinaTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            copy {\n                from project.zipTree(artifact.getFile())\n                into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n            }\n        }\n    }\n}\n\ntask unpackC2cLibs() {\n    doLast {\n        configurations.ballerinaC2cLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            copy {\n                from project.zipTree(artifact.getFile())\n                into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n            }\n        }\n    }\n}\n\ntask unpackC2cTooling() {\n    doLast {\n        configurations.ballerinaC2cTooling.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            copy {\n                from project.zipTree(artifact.getFile())\n                into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n            }\n        }\n    }\n}\n\ntask unpackOpenapiModule() {\n    doLast {\n        configurations.openapiModule.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            copy {\n                from project.zipTree(artifact.getFile())\n                into new File(\"${buildDir}/target/extracted-distributions\", artifact.name + \"-zip\")\n            }\n        }\n    }\n}\n\ntask downloadBalCommand(type: Download) {\n    group = \"unpack_dependencies\"\n    def commandBaseURL = \"https://github.com/ballerina-platform/ballerina-update-tool/releases/download/v${ballerinaCommandVersion}\"\n    src([\n            \"${commandBaseURL}/ballerina-command-${ballerinaCommandVersion}.zip\"\n    ])\n    onlyIfModified true\n    dest \"${buildDir}/target/\"\n}\n\ntask unpackBalCommand(type: Copy) {\n    group = \"unpack_dependencies\"\n    from zipTree { \"${buildDir}/target/ballerina-command-${ballerinaCommandVersion}.zip\" }\n    into new File(\"${buildDir}/target/\")\n}\n\ntask extractJreForLinux(type: Copy) {\n    group = \"extract_jre\"\n    from zipTree { \"${jreLocation}/ballerina-jre-linux-64-${ballerinaJreVersion}.zip\" }\n    into(\"${buildDir}/target/extracted-jre-linux\")\n}\n\ntask extractJreForLinuxArm(type: Copy) {\n    group = \"extract_jre\"\n    from zipTree { \"${jreLocation}/ballerina-jre-linux-arm-64-${ballerinaJreVersion}.zip\" }\n    into(\"${buildDir}/target/extracted-jre-linux-arm\")\n}\n\ntask extractJreForMac(type: Copy) {\n    group = \"extract_jre\"\n    from zipTree { \"${jreLocation}/ballerina-jre-macos-64-${ballerinaJreVersion}.zip\" }\n    into(\"${buildDir}/target/extracted-jre-macos\")\n}\n\ntask extractJreForMacArm(type: Copy) {\n    group = \"extract_jre\"\n    from zipTree { \"${jreLocation}/ballerina-jre-macos-arm-64-${ballerinaJreVersion}.zip\" }\n    into(\"${buildDir}/target/extracted-jre-macos-arm\")\n}\n\ntask extractJreForWindows(type: Copy) {\n    group = \"extract_jre\"\n    from zipTree { \"${jreLocation}/ballerina-jre-win-64-${ballerinaJreVersion}.zip\" }\n    into(\"${buildDir}/target/extracted-jre-windows\")\n}\n\ntask deleteTemporaryFiles(type: Delete) {\n    delete 'build/target'\n}\n\ntask copyOtherRepos(type: Copy) {\n    duplicatesStrategy = DuplicatesStrategy.INCLUDE\n\n    def ballerinaDist = \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n    into ballerinaDist\n\n    /* Standard Libraries */\n    configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n        from(\"${artifactExtractedPath}/libs\") {\n            into \"bre/lib/\"\n        }\n        from(\"${artifactExtractedPath}/bala\") {\n            into \"repo/bala\"\n        }\n    }\n\n    /* Bal tools (e.g. openapi, graphql etc.) */\n    configurations.ballerinaTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n        from(\"${artifactExtractedPath}/bala\") {\n            into \"repo/bala\"\n        }\n    }\n\n    /* C2C Libraries */\n    configurations.ballerinaC2cLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n        from(\"${artifactExtractedPath}/libs\") {\n            into \"bre/lib/\"\n        }\n        from(\"${artifactExtractedPath}/bala\") {\n            into \"repo/bala\"\n        }\n    }\n\n    /* C2C Tooling */\n    configurations.ballerinaC2cTooling.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n        from(\"${artifactExtractedPath}\") {\n            into \"lib/tools/lang-server/lib/\"\n        }\n    }\n\n    /* OpenAPI Module */\n    configurations.openapiModule.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n        from(\"${artifactExtractedPath}/bala\") {\n            into \"repo/bala\"\n        }\n        from(\"${artifactExtractedPath}/cache\") {\n            into \"repo/cache\"\n        }\n    }\n\n    /* Language Server Extension Artifacts */\n    configurations.devTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n        def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/${artifact.name}-zip\"\n        from(\"${artifactExtractedPath}/ls-extensions/bre-libs\") {\n            into \"bre/lib/\"\n        }\n        from(\"${artifactExtractedPath}/ls-extensions/ls-libs\") {\n            into \"lib/tools/lang-server/lib/\"\n        }\n    }\n}\n\ntask buildDistRepo(type: JavaExec) {\n    classpath = project.configurations.repoBuilder\n    main = 'io.ballerina.dist.DistRepoBuilder'\n    args \"$buildDir/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n}\n\ntask copyDevToolsCoverageReport(type: Copy) {\n    from \"$project.buildDir/target/extracted-distributions/ballerina-dev-tools-zip/tests/testerina-report-tools-${devToolsVersion}.zip\"\n    into \"$project.buildDir/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/lib/tools/coverage\"\n    rename(\"testerina-report-tools-${devToolsVersion}.zip\", \"report.zip\")\n}\n\ntask copyDevToolsDocUi(type: Copy) {\n    from zipTree(\"$project.buildDir/target/extracted-distributions/doc-ui-zip/ballerina-doc-ui.zip\")\n    into \"$project.buildDir/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/lib/tools/doc-ui\"\n}\n\ntask filterApiDocs(type: Delete) {\n    delete \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/docs/ballerina/lang.__internal\"\n    delete \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/docs/ballerina/lang.annotations\"\n}\n\ntask combineDocs(type: Exec) {\n    workingDir \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/docs\"\n    if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n        commandLine 'cmd', '/c', \"$project.buildDir/target/extracted-distributions/jballerina-tools-zip/\" +\n                \"jballerina-tools-${ballerinaLangVersion}/bin/bal.bat\", \"doc\", \"--combine\"\n    } else {\n        commandLine \"$project.buildDir/target/extracted-distributions/jballerina-tools-zip/\" +\n                \"jballerina-tools-${ballerinaLangVersion}/bin/bal\", \"doc\", \"--combine\"\n    }\n}\n\ntask packageDist(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina Tools Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}\"\n        parentDir = \"${baseName}-${shortVersion}\"\n    }\n    archiveFileName = \"${baseName}-${shortVersion}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"/LICENSE\"\n    }\n    into(\"${parentDir}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/examples\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/lib/\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    /* Dependencies */\n    into(\"${parentDir}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina Tools Distribution Packaged'\n    }\n\n    outputs.file jBallerinaDistributionZip\n}\n\ntask packageDistZip(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}\"\n    }\n    archiveFileName = \"${distributionName}-${version}-${codeName}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}\") {\n        from({ new File(temporaryDir, 'dependencies').mkdirs(); temporaryDir })\n    }\n\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n\n    }\n    into(\"${parentDir}\") {\n        from \"../resources/tools\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal\"\n        fileMode = 0775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal.bat\"\n        fileMode = 0775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina Distribution Packaged'\n    }\n\n    outputs.file ballerinaDistributionZip\n}\n\ntask packageDistLinux(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina Linux Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}-linux\"\n    }\n    archiveFileName = \"${parentDir}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}/dependencies\") {\n        from \"build/target/extracted-jre-linux\"\n        fileMode = 0755\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/bal.bat\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n    }\n    into(\"${parentDir}\") {\n        from \"../resources/tools\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"**/scripts/**\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal\"\n        fileMode = 775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/bal_completion.bash\"\n        fileMode = 775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/_bal\"\n        fileMode = 775\n    }\n\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina Linux Distribution Packaged'\n    }\n\n    outputs.file ballerinaLinuxDistributionZip\n}\n\ntask packageDistLinuxArm(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina Linux-ARM Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}-linux-arm\"\n    }\n    archiveFileName = \"${parentDir}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}/dependencies\") {\n        from \"build/target/extracted-jre-linux-arm\"\n        fileMode = 0755\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/bal.bat\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n    }\n    into(\"${parentDir}\") {\n        from \"../resources/tools\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"**/scripts/**\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal\"\n        fileMode = 775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/bal_completion.bash\"\n        fileMode = 775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/_bal\"\n        fileMode = 775\n    }\n\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina Linux-ARM Distribution Packaged'\n    }\n\n    outputs.file ballerinaLinuxArmDistributionZip\n}\n\ntask packageDistMac(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina MacOS Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}-macos\"\n    }\n    archiveFileName = \"${parentDir}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}/dependencies\") {\n        from \"build/target/extracted-jre-macos\"\n        fileMode = 0755\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/bal.bat\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal\"\n        fileMode = 775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}\" +\n                \"/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/bal_completion.bash\"\n        fileMode = 775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/_bal\"\n        fileMode = 775\n    }\n\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina MacOS Distribution Packaged'\n    }\n\n    outputs.file ballerinaMacDistributionZip\n}\n\ntask packageDistMacArm(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina MacOS-ARM Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}-macos-arm\"\n    }\n    archiveFileName = \"${parentDir}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}/dependencies\") {\n        from \"build/target/extracted-jre-macos-arm\"\n        fileMode = 0755\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/bal.bat\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal\"\n        fileMode = 775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}\" +\n                \"/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/bal_completion.bash\"\n        fileMode = 775\n    }\n    into(\"${parentDir}/scripts\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/scripts/_bal\"\n        fileMode = 775\n    }\n\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina MacOS-ARM Distribution Packaged'\n    }\n\n    outputs.file ballerinaMacArmDistributionZip\n}\n\ntask packageDistWindows(type: Zip) {\n    group = \"package_distribution\"\n    description = 'Ballerina Windows Distribution Assembly'\n    ext {\n        baseName = \"${distributionName}-${version}\"\n        parentDir = \"${baseName}-${codeName}-windows\"\n    }\n    archiveFileName = \"${parentDir}.zip\"\n    entryCompression = ZipEntryCompression.DEFLATED\n\n    into(\"${parentDir}/dependencies\") {\n        from \"build/target/extracted-jre-windows\"\n        fileMode = 0755\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples/\") {\n        from \"${project.rootDir}/examples/\"\n        fileMode = 0755\n    }\n\n    // Code2Cloud Extension Examples\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/examples\") {\n        from \"build/target/extracted-distributions/c2c-examples-zip\"\n        exclude \"index.js\"\n    }\n\n    /* Tools artifacts */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n        exclude \"distributions/ballerina-version\"\n        exclude \"distributions/installer-version\"\n        exclude \"/bin/bal\"\n        exclude \"/bin/version.txt\"\n        exclude \"/LICENSE\"\n    }\n\n    /* Files */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}\") {\n        from \"LICENSE\"\n    }\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bin\") {\n        from \"lib/version.txt\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: version])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/ballerina-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [version: shortVersion])\n    }\n    into(\"${parentDir}/distributions\") {\n        from \"../resources/tools/distributions/installer-version\"\n        fileMode = 0644\n        filter(ReplaceTokens, tokens: [uuid: installerVersion])\n    }\n    into(\"${parentDir}/bin\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/bin/bal.bat\"\n        fileMode = 775\n        filter(ReplaceTokens, tokens: [ballerinaCommandVersion: ballerinaCommandVersion])\n    }\n    into(\"${parentDir}/lib\") {\n        from \"build/target/ballerina-command-${ballerinaCommandVersion}/lib/ballerina-command-${ballerinaCommandVersion}.jar\"\n        fileMode = 0775\n    }\n\n    /* Dependencies */\n    into(\"${parentDir}/distributions/ballerina-${shortVersion}/bre/lib\") {\n        from configurations.exten\n    }\n\n    doLast {\n        println 'Ballerina Windows Distribution Packaged'\n    }\n\n    outputs.file ballerinaWindowsDistributionZip\n}\n\ntask unzipDistForTests(type: Copy) {\n    from zipTree(\"${project.rootDir}/ballerina/build/distributions/ballerina-${version}-${codeName}.zip\")\n    into file(\"${project.rootDir}/ballerina/build/target/extracted-distributions/\")\n}\n\nartifacts {\n    jBallerinaDistribution file: jBallerinaDistributionZip, builtBy: packageDist\n    ballerinaDistribution file: ballerinaDistributionZip, builtBy: packageDistZip\n    ballerinaLinuxDistribution file: ballerinaLinuxDistributionZip, builtBy: packageDistLinux\n    ballerinaLinuxArmDistribution file: ballerinaLinuxArmDistributionZip, builtBy: packageDistLinuxArm\n    ballerinaMacDistribution file: ballerinaMacDistributionZip, builtBy: packageDistMac\n    ballerinaMacArmDistribution file: ballerinaMacArmDistributionZip, builtBy: packageDistMacArm\n    ballerinaWindowsDistribution file: ballerinaWindowsDistributionZip, builtBy: packageDistWindows\n}\n\ntask testExamples() {\n    def distPath = \"${project.rootDir}/ballerina/build/target/extracted-distributions/ballerina-${version}-${codeName}\"\n    def bbeList = []\n\n    PatternSet patternSet = new PatternSet()\n    patternSet.exclude(\"**/.ballerina/**\")\n    patternSet.exclude(\"**/Ballerina.toml\")\n    patternSet.exclude(\"**/Ballerina.lock\")\n    patternSet.exclude(\"**/ballerina-internal.log\")\n    inputs.files(files(\"${distPath}/examples\").asFileTree.matching(patternSet))\n\n    doFirst {\n        copy {\n            into \"$distPath/lib\"\n            from configurations.externalTestJars\n        }\n\n        def src = \"${project.rootDir}/examples/\"\n        def dis = \"${distPath}\"\n        copy {\n            from(src)\n            into dis\n        }\n        def inputFile = new File(\"${distPath}/index.json\")\n        def categories = new JsonSlurper().parseText(inputFile.text)\n        categories.each { category ->\n            def examples = category.samples\n            examples.each { example ->\n                def folder = new File(\"${distPath}/${example.url}\")\n                if (folder.exists()) {\n                    bbeList.push(example)\n                }\n            }\n        }\n    }\n\n    ext.prepareProject = { bbe ->\n        if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n            //TODO: Need to verify with windows\n            exec {\n                workingDir \"${distPath}/${bbe}\"\n                commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat init test\"\n            }\n\n        } else {\n            exec {\n                workingDir \"${distPath}/${bbe}\"\n                commandLine 'sh', '-c', \"${distPath}/bin/bal init test\"\n            }\n        }\n\n        if (bbe.startsWith('mysql')) {\n            def tomlFile = new File(\"${distPath}/${bbe}/Ballerina.toml\")\n            tomlFile.append(\"\\n\\n[[platform.java11.dependency]]\")\n            tomlFile.append(\"\\npath = \\\"$distPath/lib/mysql-connector-java-8.0.21.jar\\\"\\n\")\n        }\n\n        if (bbe.startsWith('grpc')) {\n            new File(\"${distPath}/${bbe}\").eachFileRecurse(FILES) {\n                if(it.name.endsWith('.proto')) {\n                    def grpcCommand =  \"grpc --input ${it.name} --output .\"\n                    if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                        //TODO: Need to verify with windows\n                        exec {\n                            workingDir \"${distPath}/${bbe}\"\n                            commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat ${grpcCommand}\"\n                        }\n\n                    } else {\n                        exec {\n                            workingDir \"${distPath}/${bbe}\"\n                            commandLine 'sh', '-c', \"${distPath}/bin/bal ${grpcCommand}\"\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    ext.buildBBE = { bbe ->\n\n        def exitVal\n        def additionalParams = bbe.url == \"natural-expressions\" ? \"--experimental\" : \"\"\n        println \"Building example '${bbe.url}'\"\n        if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n            //TODO: Need to verify with windows\n            exitVal = exec {\n                ignoreExitValue true\n                workingDir \"${distPath}/${bbe.url}\"\n                commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat\", 'build', \"${additionalParams}\"\n                commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat\", 'test', \"${additionalParams}\"\n            }\n        } else {\n            exitVal = exec {\n                ignoreExitValue true\n                workingDir \"${distPath}/${bbe.url}\"\n                commandLine 'sh', '-c', \"${distPath}/bin/bal build ${additionalParams}\"\n                commandLine 'sh', '-c', \"${distPath}/bin/bal test ${additionalParams}\"\n            }\n        }\n        if (exitVal.getExitValue() == 1) {\n            return true\n        }\n        return false\n    }\n\n    ext.outputVerification = { bbe ->\n\n        def directoryPath = \"${distPath}/${bbe.url}\"\n        File fileReference\n        def curlCommands = []\n        def ports = []\n        def fileOut = []\n        def balName = bbe.url.replace('-', '_') + \".bal\"\n        FileTree tree = fileTree(directoryPath)\n        def curlCommandsFilePath = \"${directoryPath}/curlcommandout.txt\"\n        def portFilePath = \"${directoryPath}/ports.txt\"\n        def outputFilePath = \"${directoryPath}/output.txt\"\n        def additionalBuildParams = \"\"\n        tree.each { content ->\n            if (content.name.contains(\"client.out\")) {\n                fileReference = file(content)\n                fileReference.readLines().each { lines ->\n                    fileOut.add(lines.trim())\n                    if (lines.startsWith(\"curl\")) {\n                        lines = lines.trim() + \" >> output.txt\"\n                        curlCommands.add(lines)\n                        if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                            curlCommands.add(\"echo. >> output.txt\")\n                        } else {\n                            curlCommands.add(\"echo >> output.txt\")\n                        }\n                    }\n                }\n            } else if (content.name.contains(\"server.out\") || content.name.contains(\"service.out\")) {\n                fileReference = file(content)\n                String portPrefixHttp = \"[ballerina/http] started HTTP/WS listener 0.0.0.0:\"\n                String portPrefixHttps = \"[ballerina/http] started HTTPS/WSS listener 0.0.0.0:\"\n                String portPrefixWs = \"[ballerina/websocket] started WS listener 0.0.0.0:\"\n                String portPrefixWss = \"[ballerina/websocket] started WSS listener 0.0.0.0:\"\n                fileReference.readLines().each { lines ->\n                    if (lines.contains(portPrefixHttp)) {\n                        lines = (lines - portPrefixHttp).trim()\n                        ports.add(lines)\n                    } else if (lines.contains(portPrefixHttps)) {\n                        lines = (lines - portPrefixHttps).trim()\n                        ports.add(lines)\n                    } else if (lines.contains(portPrefixWs)) {\n                        lines = (lines - portPrefixWs).trim()\n                        ports.add(lines)\n                    } else if (lines.contains(portPrefixWss)) {\n                        lines = (lines - portPrefixWss).trim()\n                        ports.add(lines)\n                    }\n                }\n            }\n        }\n        def failFlag = false\n        if (!ports.isEmpty() && !curlCommands.isEmpty()) {\n            fileReference = new File(portFilePath)\n            ports.each {\n                fileReference << \"${it}\\n\"\n            }\n            fileReference = new File(curlCommandsFilePath)\n            curlCommands.each {\n                fileReference << \"${it}\\n\"\n            }\n            println \"Verify output '${bbe.url}'\"\n            def scriptPath = \"${project.rootDir}/ballerina/lib\"\n            def exitVal\n            if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                exitVal = exec {\n                    def windowsPath = scriptPath.replace('/', '\\\\')\n                    workingDir \"$windowsPath\"\n                    commandLine \"$windowsPath\\\\run.bat\", \"${directoryPath}\", \"${distPath}/bin/bal.bat\", \"${balName}\", \"${curlCommandsFilePath}\", \"${portFilePath}\", \"${additionalBuildParams}\"\n                    ignoreExitValue true\n                }\n            } else {\n                exitVal = exec {\n                    workingDir \"$scriptPath\"\n                    commandLine \"bash\", \"run.sh\", \"${directoryPath}\", \"${distPath}/bin/./bal\", \"${balName}\", \"${curlCommandsFilePath}\", \"${portFilePath}\", \"${additionalBuildParams}\"\n                    ignoreExitValue true\n                }\n            }\n            // Return immediately if command failed\n            if (exitVal.getExitValue() == 1) {\n                println \"Failed due to build failure.\"\n                return true\n            }\n            File bbeOutput = new File(outputFilePath)\n            if (bbeOutput.exists()) {\n                bbeOutput.readLines().each {\n                    if (!fileOut.contains(it.trim()) && it) {\n                        println \"Failed due to output did not match. Line ${it}\"\n                        failFlag = true\n                    }\n                }\n            }\n            delete portFilePath\n            delete curlCommandsFilePath\n            delete outputFilePath\n        } else if (ports.isEmpty() && curlCommands.isEmpty()) {\n            balName = bbe.url.replace('-', '_')\n            def str = \"\"\n            fileOut = []\n            def bbeOutput = []\n            def cmdOutAry = []\n            def errOut = new ByteArrayOutputStream()\n            new ByteArrayOutputStream().withStream { os ->\n                println \"Output Verification '${bbe.url}'\"\n                if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                    exec {\n                        workingDir \"${directoryPath}\"\n                        commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat\", 'run', \"${balName}.bal \", ${additionalBuildParams}\n                        ignoreExitValue true\n                        standardOutput = os\n                        errorOutput = errOut\n                    }\n                } else {\n                    exec {\n                        workingDir \"${directoryPath}\"\n                        commandLine 'sh', '-c', \"${distPath}/bin/bal run ${balName}.bal ${additionalBuildParams}\"\n                        ignoreExitValue true\n                        standardOutput = os\n                        errorOutput = errOut\n                    }\n                }\n                cmdOutAry.add(os.toString())\n                cmdOutAry.add(errOut.toString())\n            }\n\n            File file = file(\"${directoryPath}/${balName}.out\")\n            file.readLines().each {\n                str = it.trim()\n                if (str?.trim()) {\n                    if (str[0] != '#') {\n                        fileOut.add(str)\n                    }\n                }\n            }\n\n            def lines = \"${cmdOutAry[0]}\".split('\\n')\n            lines = lines + \"${cmdOutAry[1]}\".split('\\n')\n            lines.each {\n                str = it.trim()\n                if (str != \"Compiling source\" && str != \"${balName}.bal\" && str != \"Running executable\" && str != \"\"\n                        && str != \"Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8\" && !str.startsWith('HINT')) {\n                    bbeOutput.add(str)\n                }\n            }\n\n            for (int i = 0; i < bbeOutput.size(); i++) {\n                def index = fileOut.findIndexOf { it == bbeOutput[i] }\n                if (index == -1) {\n                    println \"Failed due to output did not match. Line ${i}: ${bbeOutput[i]}\"\n                    failFlag = true\n                }\n            }\n        }\n        return failFlag\n    }\n\n    doLast {\n        def failedBuildExamples = []\n        def failOutputVerificationExamples = []\n        bbeList.each { bbe ->\n            if (bbe.verifyOutput) {\n                boolean outputVerificationFailFlag = outputVerification(bbe)\n                if (outputVerificationFailFlag) {\n                    failOutputVerificationExamples.add(bbe.url)\n                }\n            }\n\n            if (bbe.verifyBuild) {\n                File tomlFile = new File(\"${distPath}/${bbe.url}/Ballerina.toml\")\n                if (!tomlFile.exists()) {\n                    prepareProject(bbe.url)\n                }\n                boolean buildFailFlag = buildBBE(bbe)\n                if (buildFailFlag) {\n                    failedBuildExamples.add(bbe.url)\n                }\n                delete tomlFile\n            }\n        }\n\n        boolean buildFailure = false\n        if (!failedBuildExamples.isEmpty()) {\n            println \"\\n\\tThe following BBEs failed while building:\\n\"\n            failedBuildExamples.each {\n                println \"\\t ${it}\"\n            }\n            sleep(10 * 1000)\n            buildFailure = true\n        }\n\n        if (!failOutputVerificationExamples.isEmpty()) {\n            println \"\\n\\tThe following BBEs failed while verifying the output:\\n\"\n            failOutputVerificationExamples.each {\n                println \"\\t ${it}\"\n            }\n            sleep(10 * 1000)\n            buildFailure = true\n        }\n        if (buildFailure) {\n            sleep(10 * 1000)\n            throw new GradleException('There are test failures')\n        }\n    }\n}\n\ndef addH2Dependency = { filePath ->\n    // Add the H2 database dependency to Ballerina.toml file\n    def tomlFile = new File(filePath)\n    tomlFile.append(\"\\n\\n[[platform.java21.dependency]]\")\n    tomlFile.append(\"\\nartifactId = \\\"h2\\\"\")\n    tomlFile.append(\"\\nversion = \\\"2.2.224\\\"\")\n    tomlFile.append(\"\\ngroupId = \\\"com.h2database\\\"\")\n}\n\ndef buildAndTestStandardLibs = { distPath, stdlibTest, isStageTest, testMinorVersionDifference ->\n    def exitVal\n    def additionalBuildParams = \"\"\n\n    if (stdlibTest == \"config\") {\n        additionalBuildParams = \"--user.name=ballerina-user\"\n    }\n\n    if (stdlibTest == \"websub-generic\" || stdlibTest == \"websub-advance\") {\n        additionalBuildParams = \"--test.hub.url=https://localhost:23191/websub/hub\"\n    }\n\n    println \"Testing standard library ${stdlibTest}\"\n    if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n        if (!isStageTest) {\n            def tomlFile = new File(\"${distPath}/${stdlibTest}/Ballerina.toml\")\n            if (!tomlFile.exists()) {\n                exec {\n                    workingDir \"${distPath}/${stdlibTest}\"\n                    commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat init test\"\n                }\n            }\n            if (stdlibTest == 'transaction') {\n                addH2Dependency(\"${distPath}/${stdlibTest}/Ballerina.toml\")\n            }\n        } else {\n            exec {\n                workingDir \"${distPath}/${stdlibTest}\"\n                commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat clean\"\n            }\n        }\n        if (testMinorVersionDifference) {\n            exec {\n                workingDir \"${distPath}/${stdlibTest}\"\n                commandLine 'cmd', '/c', \"rm Dependencies.toml\"\n            }\n        }\n        exitVal = exec {\n            ignoreExitValue true\n            workingDir \"${distPath}/${stdlibTest}\"\n            commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat test ${additionalBuildParams}\"\n        }\n    } else {\n        if (!isStageTest) {\n            def tomlFile = new File(\"${distPath}/${stdlibTest}/Ballerina.toml\")\n            if (!tomlFile.exists()) {\n                exec {\n                    workingDir \"${distPath}/${stdlibTest}\"\n                    commandLine 'sh', '-c', \"${distPath}/bin/bal init test\"\n                }\n            }\n            if (stdlibTest == 'transaction') {\n                addH2Dependency(\"${distPath}/${stdlibTest}/Ballerina.toml\")\n            }\n        } else {\n            exec {\n                workingDir \"${distPath}/${stdlibTest}\"\n                commandLine 'sh', '-c', \"${distPath}/bin/bal clean\"\n            }\n        }\n        if (testMinorVersionDifference) {\n            exec {\n                workingDir \"${distPath}/${stdlibTest}\"\n                commandLine 'sh', '-c', \"rm Dependencies.toml\"\n            }\n        }\n        exitVal = exec {\n            environment \"BALLERINA_STAGE_CENTRAL\", \"$isStageTest\"\n            ignoreExitValue true\n            workingDir \"${distPath}/${stdlibTest}\"\n            commandLine 'sh', '-c', \"${distPath}/bin/bal test ${additionalBuildParams}\"\n        }\n    }\n    if (exitVal.getExitValue() == 1) {\n        return true\n    }\n    return false\n}\n\ntask testStdlibs() {\n    def distPath = \"${project.rootDir}/ballerina/build/target/extracted-distributions/ballerina-${version}-${codeName}\"\n    def stdlibTestsList = []\n\n    PatternSet patternSet = new PatternSet()\n    patternSet.exclude(\"**/.ballerina/**\")\n    patternSet.exclude(\"**/Ballerina.toml\")\n    patternSet.exclude(\"**/Ballerina.lock\")\n    patternSet.exclude(\"**/ballerina-internal.log\")\n    inputs.files(files(\"${distPath}/stdlib-integration-tests\").asFileTree.matching(patternSet))\n\n    doFirst {\n        def src = \"${project.rootDir}/stdlib-integration-tests/\"\n        def dis = \"${distPath}\"\n        copy {\n            from(src)\n            into dis\n        }\n        def inputFile = new File(\"${distPath}/index.json\")\n        def stdlibTests = new JsonSlurper().parseText(inputFile.text)\n        stdlibTests.each { stdlibTest ->\n            def folder = new File(\"${distPath}/${stdlibTest.path}\")\n            if (folder.exists()) {\n                stdlibTestsList.push(stdlibTest)\n            }\n        }\n    }\n\n    doLast {\n        def failedStdLibs = []\n        stdlibTestsList.each { stdlibTest ->\n            if (stdlibTest.enableTest) {\n                boolean stdLibTestFailFlag = buildAndTestStandardLibs(distPath, stdlibTest.path, false, false)\n                if (stdLibTestFailFlag) {\n                    failedStdLibs.add(stdlibTest.path);\n                }\n            }\n        }\n\n        if (!failedStdLibs.isEmpty()) {\n            sleep(10 * 1000)\n            println \"\\n\\tThe following Standard Library Tests Failed:\\n\"\n            failedStdLibs.each {\n                println \"\\t ${it}\"\n            }\n            throw new GradleException('There are test failures')\n        }\n\n    }\n}\n\n// Task used to run automated testing before stdlib release. Not executed during normal build\ntask testStdlibsWithStaging() {\n\n    def distPath = \"${project.rootDir}/ballerina/build/target/extracted-distributions/ballerina-${version}-${codeName}\"\n    def stdlibTestsList = []\n    def testMinorVersionDifference = project.hasProperty('testMinorVersionDifference') ? true : false\n\n    doFirst {\n        def indexJsonFile = new File(\"${distPath}/index.json\")\n        def stdlibTests = new JsonSlurper().parseText(indexJsonFile.text)\n        stdlibTests.each { stdlibTest ->\n            def folder = new File(\"${distPath}/${stdlibTest.path}\")\n            if (folder.exists()) {\n                stdlibTestsList.push(stdlibTest)\n            }\n        }\n    }\n\n    doLast {\n        def failedStdLibs = []\n        stdlibTestsList.each { stdlibTest ->\n            if (stdlibTest.enableTest) {\n                boolean stdLibTestFailFlag = buildAndTestStandardLibs(distPath, stdlibTest.path, true, testMinorVersionDifference)\n                if (stdLibTestFailFlag) {\n                    failedStdLibs.add(stdlibTest.path);\n                }\n            }\n        }\n\n        if (!failedStdLibs.isEmpty()) {\n            sleep(10 * 1000)\n            println \"\\n\\tThe following Standard Library Tests Failed with Staging Central:\\n\"\n            failedStdLibs.each {\n                println \"\\t ${it}\"\n            }\n            throw new GradleException('There are test failures')\n        }\n    }\n}\n\ntask testDevToolsIntegration() {\n    def distPath = \"${project.rootDir}/ballerina/build/target/extracted-distributions/ballerina-${version}-${codeName}\"\n    def devtoolsProjectList = []\n\n    PatternSet patternSet = new PatternSet()\n    patternSet.exclude(\"**/.ballerina/**\")\n    patternSet.exclude(\"**/Ballerina.toml\")\n    patternSet.exclude(\"**/Ballerina.lock\")\n    patternSet.exclude(\"**/ballerina-internal.log\")\n\n    inputs.files(files(\"${distPath}/devtools-integration-tests\").asFileTree.matching(patternSet))\n\n    doFirst {\n        // Copy projects to distPath\n        def devToolsProjectSrc = \"${project.rootDir}/devtools-integration-tests/\"\n        copy {\n            from(devToolsProjectSrc)\n            into distPath\n        }\n\n        // Read the projects from the index.json\n        def inputFile = new File(\"${distPath}/index.json\")\n        def devtoolsProjects = new JsonSlurper().parseText(inputFile.text)\n\n        // For each project in the devtools integration tests folder, we add it to the project list\n        devtoolsProjects.each { devtoolsProject ->\n            def folder = new File(\"${distPath}/${devtoolsProject.path}\")\n            if (folder.exists()) {\n                devtoolsProjectList.push(\"$devtoolsProject.path\")\n            }\n        }\n    }\n\n    doLast {\n        // For each devtools project in the list\n        devtoolsProjectList.each { String devtoolsProject ->\n            // Read the modules from the index.json\n            def inputFile = new File(\"${distPath}/index.json\")\n            def projectModules = new JsonSlurper().parseText(inputFile.text)\n\n            // For each module we execute the `test -c ${projectModule} command\n            projectModules.each { projectModuleVal ->\n                def projectModule = projectModuleVal.path\n                def additionalBuildParams = \"\"\n\n                if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                    exec {\n                        workingDir \"${buildDir}/${devtoolsProject}\"\n                        commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat init test\"\n                    }\n                    exec {\n                        workingDir \"${buildDir}/${devtoolsProject}\"\n                        commandLine 'cmd', '/c',\n                                \"${distPath}/bin/bal.bat test ${additionalBuildParams}\"\n                    }\n                } else {\n                    exec {\n                        workingDir \"${distPath}/${devtoolsProject}\"\n                        commandLine 'sh', '-c',\n                                \"${distPath}/bin/bal init test\"\n                    }\n                    exec {\n                        workingDir \"${distPath}/${devtoolsProject}\"\n                        commandLine 'sh', '-c',\n                                \"${distPath}/bin/bal test ${additionalBuildParams}\"\n                    }\n                }\n            }\n\n        }\n    }\n}\n\ntask generateCache(dependsOn: ':cache-generator:build') {\n    doFirst {\n        copy {\n            from \"${project.rootDir}/cache-generator/build/libs/cache-generator-${project.version}.jar\"\n            into \"$buildDir/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/bre/lib\"\n        }\n    }\n\n    doLast {\n        def distPath = \"${project.rootDir}/ballerina/build/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n\n        /* Standard Libraries */\n        def stdlibJson = file(\"${project.rootDir}/ballerina/build/target/extensions.json\")\n        def parsedJson = new JsonSlurper().parseText(stdlibJson.text)\n        def maxLevel = 0\n        parsedJson.standard_library.each { module ->\n            def moduleLevel = module.level\n            if (moduleLevel > maxLevel) {\n                maxLevel = moduleLevel\n            }\n        }\n        def sortedLibs = []\n        def dependencyMap = [:]\n        for (currentLevel in 1..maxLevel) {\n            parsedJson.standard_library.each { module ->\n                if (module.level == currentLevel) {\n                    def libName = module.name.toString().split(\"-\")[-1] + \"-ballerina-zip\"\n                    sortedLibs.add(libName)\n                }\n            }\n        }\n\n        def configStdlibs = []\n        configurations.ballerinaStdLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            configStdlibs.add(artifact.name + \"-zip\")\n        }\n\n        sortedLibs.each { lib ->\n            if (configStdlibs.contains(lib)) {\n                def versionList = [file(file(\"${buildDir}/target/extracted-distributions/\" + lib +\n                        \"/bala\").listFiles()[0].toString() + \"/\" + lib.split(\"-\")[0]).listFiles()[0].name]\n                dependencyMap[\"${lib}\"] = versionList\n            }\n        }\n\n        sortedLibs.each { lib ->\n            if (configStdlibs.contains(lib)) {\n                def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + lib\n                String balaDir = artifactExtractedPath + \"/bala\"\n\n                new File(\"${balaDir}\").listFiles().each { orgDirFile ->\n                    String orgDir = orgDirFile.toString()\n                    String moduleDir = new File(\"${orgDir}\").listFiles()[0].toString()\n                    String versionDir = new File(\"${moduleDir}\").listFiles()[0].toString()\n                    String balaPath = new File(\"${versionDir}\").listFiles()[0].toString()\n                    String jbalPath = \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n\n                    if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                        exec {\n                            workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                            commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat gencache ${balaPath} ${jbalPath}\"\n                            ignoreExitValue true\n                        }\n                    } else {\n                        exec {\n                            workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                            commandLine 'sh', '-c', \"${distPath}/bin/bal gencache ${balaPath} ${jbalPath}\"\n                            ignoreExitValue true\n                        }\n                    }\n                    def dependencyGraphJson = file(\"${balaPath}/dependency-graph.json\")\n                    def parsedDependencyJson = new JsonSlurper().parseText(dependencyGraphJson.text)\n                    parsedDependencyJson.modules.dependencies.each { dependency ->\n                        if ( dependency.module_name.size() > 0 ) {\n                            for ( i in 0..dependency.module_name.size()) {\n                                def moduleName = dependency.module_name[i].toString() + \"-ballerina-zip\"\n                                if ( sortedLibs.contains(moduleName) ) {\n                                    if ( !dependencyMap[\"${moduleName}\"].contains(dependency.version[i].toString()))\n                                        dependencyMap[\"${moduleName}\"].add(dependency.version[i].toString())\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /* C2C Libraries */\n        configurations.ballerinaC2cLibs.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n            String balaDir = artifactExtractedPath + \"/bala\"\n\n            String orgDir = new File(\"${balaDir}\").listFiles()[0].toString()\n            String moduleDir = new File(\"${orgDir}\").listFiles()[0].toString()\n            String versionDir = new File(\"${moduleDir}\").listFiles()[0].toString()\n            String balaPath = new File(\"${versionDir}\").listFiles()[0].toString()\n            String jbalPath = \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n\n            if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                exec {\n                    workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                    commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat gencache ${balaPath} ${jbalPath}\"\n                    ignoreExitValue true\n                }\n            }\n            else {\n                exec {\n                    workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                    commandLine 'sh', '-c', \"${distPath}/bin/bal gencache ${balaPath} ${jbalPath}\"\n                    ignoreExitValue true\n                }\n            }\n        }\n\n        /* OpenAPI Module */\n        configurations.openapiModule.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + artifact.name + \"-zip\"\n            String balaDir = artifactExtractedPath + \"/bala\"\n\n            String orgDir = new File(\"${balaDir}\").listFiles()[0].toString()\n            String moduleDir = new File(\"${orgDir}\").listFiles()[0].toString()\n            String versionDir = new File(\"${moduleDir}\").listFiles()[0].toString()\n            String balaPath = new File(\"${versionDir}\").listFiles()[0].toString()\n            String jbalPath = \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n\n            if (Os.isFamily(Os.FAMILY_WINDOWS)) {\n                exec {\n                    workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                    commandLine 'cmd', '/c', \"${distPath}/bin/bal.bat gencache ${balaPath} ${jbalPath}\"\n                    ignoreExitValue true\n                }\n            }\n            else {\n                exec {\n                    workingDir \"${buildDir}/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}\"\n                    commandLine 'sh', '-c', \"${distPath}/bin/bal gencache ${balaPath} ${jbalPath}\"\n                    ignoreExitValue true\n                }\n            }\n        }\n        delete \"$buildDir/target/extracted-distributions/jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/bre/lib/cache-generator-${project.version}.jar\"\n        delete \"${project.rootDir}/cache-generator/build/libs/cache-generator-${project.version}.jar\"\n        delete \"${project.rootDir}/module_list.json\"\n    }\n}\n\ntask generateBalToolsToml () {\n    doFirst {\n        download.run {\n            src \"https://raw.githubusercontent.com/ballerina-platform/ballerina-release/${balstdlibBranch}/dependabot/resources/extensions.json\"\n            dest \"${project.rootDir}/ballerina/build/target/\"\n        }\n    }\n    doLast {\n        def configBalTools = []\n        configurations.ballerinaTools.resolvedConfiguration.resolvedArtifacts.each { artifact ->\n            configBalTools.add(artifact.name + \"-zip\")\n        }\n\n        def stdlibJson = file(\"${project.rootDir}/ballerina/build/target/extensions.json\")\n        def parsedJson = new JsonSlurper().parseText(stdlibJson.text)\n        def maxLevel = 0\n        parsedJson.standard_library.each { module ->\n            def moduleLevel = module.level\n            if (moduleLevel > maxLevel) {\n                maxLevel = moduleLevel\n            }\n        }\n        def sortedLibs = []\n        for (currentLevel in 1..maxLevel) {\n            parsedJson.standard_library.each { module ->\n                if (module.level == currentLevel) {\n                    def libName = module.name.toString() + \"-zip\"\n                    sortedLibs.add(libName)\n                }\n            }\n        }\n\n        def balToolsTomlString = \"\"\n        String balToolsTomlPath = \"${buildDir}/target/extracted-distributions/\" +\n                \"jballerina-tools-zip/jballerina-tools-${ballerinaLangVersion}/resources/bal-tools.toml\"\n        def file = new File(balToolsTomlPath)\n\n        configBalTools.each { lib ->\n            if (sortedLibs.contains(lib)) {\n                def artifactExtractedPath = \"${buildDir}/target/extracted-distributions/\" + lib\n                String balaDir = artifactExtractedPath + \"/bala\"\n\n                new File(\"${balaDir}\").listFiles().each { orgDirFile ->\n                    String orgDir = orgDirFile.toString()\n                    String moduleDir = new File(\"${orgDir}\").listFiles()[0].toString()\n                    String versionDir = new File(\"${moduleDir}\").listFiles()[0].toString()\n                    String balaPath = new File(\"${versionDir}\").listFiles()[0].toString()\n\n                    def toolJson = new File(\"${balaPath}/tool/bal-tool.json\")\n                    def parsedToolJson = new JsonSlurper().parseText(toolJson.text)\n\n                    def packageJson = new File(\"${balaPath}/package.json\")\n                    def parsedPackageJson = new JsonSlurper().parseText(packageJson.text)\n\n                    balToolsTomlString += \"[[tool]]\\n\" +\n                            \"id = \\\"\" + parsedToolJson.tool_id.toString() + \"\\\"\\n\" +\n                            \"org = \\\"\" + parsedPackageJson.organization.toString() + \"\\\"\\n\" +\n                            \"name = \\\"\" + parsedPackageJson.name.toString() + \"\\\"\\n\" +\n                            \"version = \\\"\" + parsedPackageJson.version.toString() + \"\\\"\\n\" +\n                            \"active = true\\n\\n\"\n                }\n            }\n        }\n        file.write(balToolsTomlString)\n    }\n}\n\n/* Unpack Dependencies */\nunpackJballerinaTools.dependsOn unpackBallerinaJre\nunpackDevTools.dependsOn unpackJballerinaTools\nunpackStdLibs.dependsOn unpackDevTools\nunpackBalTools.dependsOn unpackStdLibs\ngenerateBalToolsToml.dependsOn unpackBalTools // Generate bal-tools.toml\nunpackC2cLibs.dependsOn generateBalToolsToml\nunpackC2cTooling.dependsOn unpackC2cLibs\nunpackOpenapiModule.dependsOn unpackC2cTooling\ndownloadBalCommand.dependsOn unpackOpenapiModule\n\n\n/* Cache Generation */\ngenerateCache.dependsOn unpackStdLibs\ngenerateCache.dependsOn unpackC2cTooling\ngenerateCache.dependsOn unpackOpenapiModule\ngenerateCache.dependsOn copyDevToolsDocUi\ngenerateCache.dependsOn generateBalToolsToml\n\n/* Extract JRE */\nextractJreForLinux.dependsOn unpackBalCommand\nextractJreForMac.dependsOn extractJreForLinux\nextractJreForLinuxArm.dependsOn extractJreForMac\nextractJreForMacArm.dependsOn extractJreForLinuxArm\nextractJreForWindows.dependsOn extractJreForMacArm\n\ncopyOtherRepos.dependsOn extractJreForWindows\ncopyDevToolsCoverageReport.dependsOn copyOtherRepos\ncopyDevToolsDocUi.dependsOn copyDevToolsCoverageReport\ncopyDevToolsDocUi.dependsOn downloadDocUi\nbuildDistRepo.dependsOn copyDevToolsDocUi\nbuildDistRepo.dependsOn generateCache\nfilterApiDocs.dependsOn buildDistRepo\ncombineDocs.dependsOn filterApiDocs\n\n/* Package Distributions */\npackageDist.dependsOn buildDistRepo\npackageDist.dependsOn combineDocs\npackageDist.dependsOn generateCache\npackageDistZip.dependsOn packageDist\npackageDistLinux.dependsOn packageDistZip\npackageDistLinux.dependsOn unzipDistForTests\npackageDistLinuxArm.dependsOn packageDistLinux\npackageDistMac.dependsOn packageDistLinuxArm\npackageDistMacArm.dependsOn packageDistMac\npackageDistWindows.dependsOn packageDistMacArm\nunzipDistForTests.dependsOn packageDistZip\nunpackStdLibs.dependsOn unpackBallerinaJre\nunpackStdLibs.dependsOn unpackJballerinaTools\nunpackBalCommand.dependsOn downloadBalCommand\n\ntestExamples.dependsOn unzipDistForTests\ntestStdlibs.dependsOn unzipDistForTests\ntestDevToolsIntegration.dependsOn unzipDistForTests\n\n/* Delete Temporary Files */\ndeleteTemporaryFiles.dependsOn packageDistWindows\ndeleteTemporaryFiles.dependsOn testExamples\ndeleteTemporaryFiles.dependsOn testStdlibs\ndeleteTemporaryFiles.dependsOn testDevToolsIntegration\ntest.dependsOn deleteTemporaryFiles\ntest.dependsOn testExamples\ntest.dependsOn testStdlibs\n"
  },
  {
    "path": "ballerina/lib/run.bat",
    "content": "@echo off\r\n\r\nREM Change directory to provided path\r\ncd %1\r\n\r\nREM  run ballerina file as background process\r\nSTART \"\" /b %2 run %3\r\n\r\nREM wait till server starts\r\nping -n 10 127.0.0.0 > nul\r\n\r\nREM invoke curl commnads\r\ncmd<%4\r\n\r\nREM kill the process which is using the server ports\r\nfor /f \"tokens=*\" %%b in (%5) do (\r\nIF \"%%b.\"==\".\" (echo \"empty\") ELSE (\r\n\r\nnetstat /o /a | find /i \"listening\" | find \":%%b\" > nul 2>nul && (\r\nfor /f \"tokens=5\" %%a in ('netstat -aon ^| find \":%%b\" ^| find \"LISTENING\"') do taskkill /f /pid %%a\r\n) || (\r\n echo %%b is not open\r\n)\r\n)\r\n)\r\n"
  },
  {
    "path": "ballerina/lib/run.sh",
    "content": "#!/bin/bash\n\nkill_service() {\n  case \"$(uname -s)\" in\n  Darwin)\n    kill $(lsof -ti:$1)\n    ;;\n\n  Linux)\n    fuser -k $1/tcp\n    ;;\n  *) ;;\n  esac\n}\n\n# Change directory to provided path\ncd ${1}\n\n# run ballerina file as background process\nmy_array=($(${2} run ${3} ${6})) &\n\nsleep 10\n\n# invoke curl commnads\n. ${4}\n\n# kill the process which is using the server ports\nwhile read -r line; do\n  if lsof -Pi :$line -sTCP:LISTEN -t >/dev/null; then\n    kill_service $line\n  else\n    echo \"Service is not running\"\n  fi\ndone <${5}\n"
  },
  {
    "path": "ballerina/lib/version.txt",
    "content": "Ballerina Platform version: @version@\n"
  },
  {
    "path": "ballerina-test/build.gradle",
    "content": "/*\n  ~ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~ *\n  ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ * you may not use this file except in compliance with the License.\n  ~ * You may obtain a copy of the License at\n  ~ *\n  ~ * http://www.apache.org/licenses/LICENSE-2.0\n  ~ *\n  ~ * Unless required by applicable law or agreed to in writing, software\n  ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ * See the License for the specific language governing permissions and\n  ~ * limitations under the License.\n  ~ */\n  \ndescription = 'Ballerina - Tools Test'\n\nconfigurations {\n    jBallerinaDistribution\n    ballerinaDistribution\n    ballerinaLinuxDistribution\n    ballerinaMacDistribution\n    ballerinaWindowsDistribution\n}\n\ndependencies {\n    testImplementation \"org.testng:testng:${testngVersion}\"\n    testImplementation \"net.lingala.zip4j:zip4j:${netLingalaZip4jVersion}\"\n    testImplementation \"commons-io:commons-io:${commonsIoVersion}\"\n    testImplementation \"org.apache.commons:commons-lang3:${commonsLang3Version}\"\n\n    jBallerinaDistribution project(path: \":ballerina\", configuration: \"jBallerinaDistribution\")\n    ballerinaDistribution project(path: \":ballerina\", configuration: \"ballerinaDistribution\")\n    ballerinaLinuxDistribution project(path: \":ballerina\", configuration: \"ballerinaLinuxDistribution\")\n    ballerinaMacDistribution project(path: \":ballerina\", configuration: \"ballerinaMacDistribution\")\n    ballerinaWindowsDistribution project(path: \":ballerina\", configuration: \"ballerinaWindowsDistribution\")\n}\n\ntask distributionTest {\n    dependsOn configurations.jBallerinaDistribution\n    dependsOn configurations.ballerinaDistribution\n    dependsOn configurations.ballerinaLinuxDistribution\n    dependsOn configurations.ballerinaLinuxDistribution\n    dependsOn configurations.ballerinaWindowsDistribution\n    test {\n        systemProperty \"distributions.dir\", \"$buildDir/../../ballerina/build/distributions\"\n        systemProperty \"target.dir\", \"$buildDir\"\n        systemProperty \"maven.version\", \"$version\"\n        systemProperty \"examples.dir\", \"$buildDir/../../examples\"\n        systemProperty \"line.check.extensions\", \".java, .bal\"\n        systemProperty \"short.version\", \"$version\".split(\"-\")[0]\n        systemProperty \"version.display.text\", \"$version\".split(\"-\")[0]\n        systemProperty \"spec.version\", \"$specVersion\"\n        systemProperty \"tool.version\", \"$ballerinaCommandVersion\"\n        systemProperty \"code.name\", \"$project.codeName\"\n        systemProperty \"openapi.version\", \"$openapiModuleVersion\"\n\n        useTestNG() {\n            suites 'src/test/resources/testng.xml'\n            suites 'src/test/resources/testing-line-length.xml'\n        }\n        testLogging {\n            showStandardStreams = true\n        }\n    }\n}\n\ntest.dependsOn distributionTest\n"
  },
  {
    "path": "ballerina-test/gradle.properties",
    "content": "filePath=/../examples\ndebug=true\nfileExtensions=.java, .bal\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/lengthValidation/LengthValidator.java",
    "content": "/*\n  ~ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~ *\n  ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ * you may not use this file except in compliance with the License.\n  ~ * You may obtain a copy of the License at\n  ~ *\n  ~ * http://www.apache.org/licenses/LICENSE-2.0\n  ~ *\n  ~ * Unless required by applicable law or agreed to in writing, software\n  ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ * See the License for the specific language governing permissions and\n  ~ * limitations under the License.\n  ~ */\n\npackage org.ballerinalang.distribution.lengthValidation;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.NoSuchElementException;\nimport org.testng.annotations.Test;\nimport org.testng.Assert;\n\nimport java.nio.file.Paths;\nimport java.util.regex.Pattern;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.EXAMPLES_DIR;\nimport static org.ballerinalang.distribution.utils.TestUtils.EXTENSTIONS_TO_BE_FILTERED_FOR_LINE_CHECKS;\nimport static org.ballerinalang.distribution.utils.TestUtils.OUT;\n\n/**\n  Used to validate the filtered \n  file inside a example directory\n*/\npublic class LengthValidator {\n\n    private static int LINE_MAX_LIMIT = 120;\n    private static String[] fileFilterExtensions;\n    private static String defaultFilerExtension = \".bal\";\n    private static boolean isValidationFailure = false;\n    private static Pattern descriptionLine = Pattern.compile(\"^\\\\s*//\");\n\n    public static void logger(String message) {\n        OUT.println(message);\n    }\n    \n    /**\n      Check the length count of each lines in a file\n    */\n    public static void validateLineLength(String path, String fileName) throws LineLengthExceededException, NoSuchElementException {\n        BufferedReader reader;\n        String relativePath = String.format(\"/examples/%s\", EXAMPLES_DIR.relativize(Paths.get(path)).toString());\n        try {\n            reader = new BufferedReader(new FileReader(path));\n            String line;\n\n            int lineCount = 1;\n            do {\n                line = reader.readLine();\n                // Ignore comments line length\n                if (line != null && !descriptionLine.matcher(line).find()) {\n                    int count = line.length();\n                    if(count > LINE_MAX_LIMIT){\n                        logger(String.format(\"[%s] Line number %d.\", relativePath, lineCount));\n                        isValidationFailure = true;\n                    }\n                }\n                lineCount += 1;\n            } while (line != null);\n\n            reader.close();\n\n        } catch (IOException e) {\n            logger(String.format(\"[%s] An IOException occurred for file name : %s\", fileName, path));\n            throw new NoSuchElementException(\"An error occurred during IO operation\");\n        } catch(NoSuchElementException e) {\n            logger(String.format(\"Invalid file name given : %s\",  relativePath));\n            throw new NoSuchElementException(\"Invalid file name\");\n        }\n\n    }\n    \n    /**\n      Check the extension of the files\n    */\n    public static void validateFileExtension(File fileEntry, String[] extensions) throws LineLengthExceededException {\n        for(String extension: extensions) {\n            if(fileEntry.getName().endsWith(extension)) {\n                LengthValidator.validateLineLength(fileEntry.getPath(), fileEntry.getName());\n            }\n        }\n    }\n\n    /**\n      Check the files in folder\n    */\n    public static  void listFilesForFolder(final File folder) throws LineLengthExceededException {\n        for (final File fileEntry : folder.listFiles()) {\n            if (fileEntry.isDirectory() && !fileEntry.getName().endsWith(\"tests\")) {\n                listFilesForFolder(fileEntry);\n            } else {\n                validateFileExtension(fileEntry, fileFilterExtensions);\n            }\n        }\n    }\n\n    @Test\n    public void validateLength() throws LineLengthExceededException, IOException, InterruptedException {\n        String filePath = EXAMPLES_DIR.toString();\n        if (!EXTENSTIONS_TO_BE_FILTERED_FOR_LINE_CHECKS.isEmpty()) {\n            String[] splittedArg = EXTENSTIONS_TO_BE_FILTERED_FOR_LINE_CHECKS.split(\",\");\n            fileFilterExtensions = new String[splittedArg.length];\n            int counter = 0;\n            for (String extension : splittedArg) {\n                fileFilterExtensions[counter] = extension.trim();\n                counter += 1;\n            }\n        } else {\n            fileFilterExtensions = new String[] { defaultFilerExtension };\n        }\n\n        LengthValidator.listFilesForFolder(new File(filePath));\n\n        Assert.assertFalse(isValidationFailure, \"bal files should only contain lines of 120 character length\");\n    }\n}\n\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/lengthValidation/LineLengthExceededException.java",
    "content": "/*\n  ~ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~ *\n  ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ * you may not use this file except in compliance with the License.\n  ~ * You may obtain a copy of the License at\n  ~ *\n  ~ * http://www.apache.org/licenses/LICENSE-2.0\n  ~ *\n  ~ * Unless required by applicable law or agreed to in writing, software\n  ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ * See the License for the specific language governing permissions and\n  ~ * limitations under the License.\n  ~ */\n\npackage org.ballerinalang.distribution.lengthValidation;\n\npublic class LineLengthExceededException extends Exception{\n\n    LineLengthExceededException(String message) {\n        super(message);\n    }\n}\n\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/ArtifactBuildTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.DataProvider;\n\nimport java.io.IOException;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.DISTRIBUTIONS_DIR;\nimport static org.ballerinalang.distribution.utils.TestUtils.MAVEN_VERSION;\n\n/**\n * Tests related to artifact generation.\n */\npublic class ArtifactBuildTest {\n\n    @DataProvider(name = \"distribution-provider\")\n    public Object[][] distributionNameProvider() {\n        return new Object[][]{\n                {\"ballerina-\" + MAVEN_VERSION},\n                {\"ballerina-linux-\" + MAVEN_VERSION},\n                {\"ballerina-macos-\" + MAVEN_VERSION}\n        };\n    }\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        for (Object[] dist : distributionNameProvider()) {\n            String distName = (String) dist[0];\n            TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(distName + \".zip\"));\n        }\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/BallerinaCommandTest.java",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\n\n/**\n * Test ballerina commands.\n */\npublic class BallerinaCommandTest {\n    private static final String DIST_NAME = \"ballerina-\" + TestUtils.MAVEN_VERSION;\n    public static final String VERSION = System.getProperty(\"maven.version\");\n    public static final String SHORT_VERSION = System.getProperty(\"short.version\");\n    private static final String SPEC_VERSION = System.getProperty(\"spec.version\");\n    public static final String VERSION_DISPLAY_TEXT = System.getProperty(\"version.display.text\");\n    private static final String TOOL_VERSION = System.getProperty(\"tool.version\");\n    private static final String path = TestUtils.TEST_DISTRIBUTION_PATH.resolve(DIST_NAME).resolve(\"bin\").resolve(\"bal\").toString();\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(TestUtils.DISTRIBUTIONS_DIR.resolve(DIST_NAME + \".zip\"));\n    }\n\n    @Test(description = \"Execute smoke testing to verify installation.\")\n    public void testVersionCommand() throws IOException {\n        TestUtils.testInstallation(path, VERSION, SPEC_VERSION, TOOL_VERSION, VERSION_DISPLAY_TEXT);\n    }\n\n    @Test(description = \"Execute smoke testing to verify build command.\", dependsOnMethods = {\"testVersionCommand\"})\n    public void testBuildCommand() throws IOException {\n        String projectName = \"project1\";\n        String moduleName = \"module1\";\n\n        TestUtils.executeCommand(path + \" new \" + projectName);\n        TestUtils.executeCommand(\"cd \" + projectName + \" && \" + path + \" add \" + moduleName);\n        String actualOutput = TestUtils.executeCommand(\"cd \" + projectName + \" && \" + path + \" build\");\n\n        Assert.assertTrue(actualOutput.contains(\"Compiling source\"));\n        Assert.assertTrue(actualOutput.contains(\"Generating executable\"));\n    }\n\n    @Test(description = \"Execute smoke testing to verify dist commands.\", dependsOnMethods = {\"testVersionCommand\"})\n    public void testDistCommands() throws IOException {\n        Path ballerinaHome = Paths.get(TestUtils.getUserHome()).resolve(\".ballerina\").resolve(\"ballerina-version\");\n        // test bal dist list\n        String actualOutput = TestUtils.executeCommand(path + \" dist list\");\n        Assert.assertTrue(actualOutput.contains(\"Distributions available locally:\"));\n        Assert.assertTrue(actualOutput.contains(\"Distributions available remotely:\"));\n        Assert.assertTrue(actualOutput.contains(\"1.* channel\"));\n        Assert.assertTrue(actualOutput.contains(\"1.0.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.1.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.2.0\"));\n        Assert.assertTrue(actualOutput.contains(\"Swan Lake channel\"));\n        Assert.assertTrue(actualOutput.contains(\"slp1\"));\n        Assert.assertTrue(actualOutput.contains(\"slp8\"));\n\n        // test bal dist pull and fetching dependencies\n        actualOutput = TestUtils.executeCommand(path + \" dist pull 1.2.3\");\n        Assert.assertTrue(actualOutput.contains(\"Fetching the '1.2.3' distribution from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Fetching the dependencies for '1.2.3' from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Downloading jdk8u202-b08-jre\"));\n        Assert.assertTrue(actualOutput.contains(\"'1.2.3' successfully set as the active distribution\"));\n        TestUtils.testInstallation(path, \"1.2.3\", \"2020R1\", TOOL_VERSION, \"1.2.3\");\n\n        // test bal dist update\n        actualOutput = TestUtils.executeCommand(path + \" dist update\");\n        Assert.assertTrue(actualOutput.contains(\"Fetching the latest patch distribution for 'jballerina-1.2.3' from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Successfully set the latest patch distribution\"));\n        Assert.assertEquals(TestUtils.getContent(ballerinaHome).split(\"-\")[1].trim(),\n                actualOutput.split(\"Downloading \")[1].split(\" \")[0]);\n        actualOutput = TestUtils.executeCommand(path + \" dist update\");\n        Assert.assertTrue(actualOutput.contains(\"is already the active distribution\"));\n\n        // test bal dist use\n        actualOutput = TestUtils.executeCommand(path + \" dist use 1.2.3\");\n        Assert.assertTrue(actualOutput.contains(\"'1.2.3' successfully set as the active distribution\"));\n        TestUtils.testInstallation(path, \"1.2.3\", \"2020R1\", TOOL_VERSION, \"1.2.3\");\n        actualOutput = TestUtils.executeCommand(path + \" dist pull slp7\");\n        Assert.assertTrue(actualOutput.contains(\"Fetching the 'slp7' distribution from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Fetching the dependencies for 'slp7' from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Downloading jdk-21.0.5+11-jre\"));\n        Assert.assertTrue(actualOutput.contains(\"'slp7' successfully set as the active distribution\"));\n        TestUtils.testInstallation(path, \"swan-lake-preview7\", \"v2020-09-22\", TOOL_VERSION, \"Preview 7\");\n\n        // test bal dist remove <version>\n        actualOutput = TestUtils.executeCommand(path + \" dist remove slp7\");\n        Assert.assertTrue(actualOutput.contains(\"The active Ballerina distribution cannot be removed\"));\n        actualOutput = TestUtils.executeCommand(path + \" dist remove \" + SHORT_VERSION);\n        Assert.assertTrue(actualOutput.contains(\"Distribution '\" + SHORT_VERSION + \"' successfully removed\"));\n        actualOutput = TestUtils.executeCommand(path + \" dist use \" + SHORT_VERSION);\n        Assert.assertTrue(actualOutput.contains(\"Distribution '\" + SHORT_VERSION + \"' not found\"));\n\n        actualOutput = TestUtils.executeCommand(path + \" dist update\");\n        Assert.assertTrue(actualOutput.contains(\"Fetching the latest patch distribution for 'ballerina-slp7' from the remote server...\"));\n        Assert.assertTrue(actualOutput.contains(\"Successfully set the latest patch distribution\"));\n        Assert.assertEquals(actualOutput.split(\"Downloading \")[1].split(\" \")[0],\n                actualOutput.split(\"Downloading \")[1].split(\" \")[0]);\n\n        // test bal dist remove -a\n        actualOutput = TestUtils.executeCommand(path + \" dist remove -a\");\n        Assert.assertTrue(actualOutput.contains(\"All non-active distributions are successfully removed\"));\n        actualOutput = TestUtils.executeCommand(path + \" dist use 1.2.3\");\n        Assert.assertTrue(actualOutput.contains(\"Distribution '1.2.3' not found\"));\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/DistributionArtifactCheckTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.DISTRIBUTIONS_DIR;\nimport static org.ballerinalang.distribution.utils.TestUtils.SHORT_VERSION;\nimport static org.ballerinalang.distribution.utils.TestUtils.TEST_DISTRIBUTION_PATH;\n\n/**\n * Check if necessary files exists to build in the distribution.\n */\npublic class DistributionArtifactCheckTest {\n    private static final String DIST_NAME = \"ballerina-\" + SHORT_VERSION;\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DIST_NAME + \".zip\"));\n    }\n\n    @Test()\n    public void c2cExistsTest() {\n        Path cachePath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"repo\")\n                .resolve(\"cache\")\n                .resolve(\"ballerina\")\n                .resolve(\"cloud\");\n\n        Path dockerBbePath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"examples\")\n                .resolve(\"c2c-docker-deployment\");\n\n        Path k8sBbePath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"examples\")\n                .resolve(\"c2c-k8s-deployment\");\n\n        Path docsPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"docs\")\n                .resolve(\"ballerina\")\n                .resolve(\"cloud\");\n\n        Assert.assertTrue(Files.exists(cachePath));\n        Assert.assertTrue(Files.exists(dockerBbePath));\n        Assert.assertTrue(Files.exists(k8sBbePath));\n        Assert.assertTrue(Files.exists(docsPath));\n    }\n\n    @Test()\n    public void c2cToolingExistsTest() {\n        Path c2cToolingLibPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"lib\")\n                .resolve(\"tools\")\n                .resolve(\"lang-server\")\n                .resolve(\"lib\");\n\n        Assert.assertNotNull(TestUtils.findFileOrDirectory(c2cToolingLibPath, \"cloud-tooling-\"));\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/GraphqlToolTest.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.*;\n\npublic class GraphqlToolTest {\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + \".zip\"));\n    }\n\n    @Test(description = \"Check GraphQL client generation\")\n    public void testGraphqlClientGenerationUsingEndpoint() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/client-gen/project_1\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"graphql_endpoint.config.yaml\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"client.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"types.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"config_types.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"utils.bal\")));\n        TestUtils.deleteGeneratedFiles(\"client.bal\", GRAPHQL_CMD);\n    }\n\n    @Test(description = \"Check GraphQL client generation\")\n    public void testGraphqlClientGenerationUsingSchemaFile() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/client-gen/project_2\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"graphql_schema.config.yaml\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"client.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"types.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"config_types.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"utils.bal\")));\n        TestUtils.deleteGeneratedFiles(\"client.bal\", GRAPHQL_CMD);\n    }\n\n    @Test(description = \"Check GraphQL schema generation\")\n    public void testGraphqlSchemaGeneration() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/schema-gen\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"service.bal\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"schema_graphql.graphql\")));\n        TestUtils.deleteGeneratedFiles(\"schema_graphql.graphql\", GRAPHQL_CMD);\n    }\n\n    @Test(description = \"Check GraphQL schema generation\")\n    public void testGraphqlSchemaGenerationWithServicePathFlag() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/schema-gen/project_1\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"main.bal\");\n        buildArgs.add(\"-s\");\n        buildArgs.add(\"/gql\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"schema_gql.graphql\")));\n        TestUtils.deleteGeneratedFiles(\"schema_gql.graphql\", GRAPHQL_CMD);\n    }\n\n    @Test(description = \"Check GraphQL service generation\")\n    public void testGraphqlServiceGeneration() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/service-gen\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"schema_starwars.graphql\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"service.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"types.bal\")));\n        TestUtils.deleteGeneratedFiles(\"service.bal\", GRAPHQL_CMD);\n    }\n\n    @Test(description = \"Check GraphQL service generation\")\n    public void testGraphqlServiceGenerationWithRecordFlag() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/graphql/service-gen\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"schema_book.graphql\");\n        buildArgs.add(\"-r\");\n        boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"service.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"types.bal\")));\n        TestUtils.deleteGeneratedFiles(\"service.bal\", GRAPHQL_CMD);\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/GrpcToolingTest.java",
    "content": "/*\n * Copyright (c) 2022, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.DISTRIBUTIONS_DIR;\nimport static org.ballerinalang.distribution.utils.TestUtils.RESOURCES_PATH;\nimport static org.ballerinalang.distribution.utils.TestUtils.WHITESPACE_PATTERN;\nimport static org.ballerinalang.distribution.utils.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerinalang.distribution.utils.TestUtils.getStringFromGivenBalFile;\n\npublic class GrpcToolingTest {\n\n    private String helpCommandOutput = \"NAMEballerina-grpc-GenerateBallerinasourcesforthegivenProtocolBufferdefinitionSYNOPSISbalgrpc--input<proto-file-path>[--output<path>][--modemode][--proto-path<path>]DESCRIPTIONGeneratetheBallerinagRPCclient/servicesourcesforagivengRPCprotocolbuffer(Protobuf)definition.OPTIONS--input<path>Pathtoa'.proto'fileoradirectorycontainingmultiple'.proto'files.--output<path>LocationofthegeneratedBallerinasourcefiles.Iftheoutputpathisnotspecified,theoutputwillbewrittentoadirectorycorrespondingtothepackageintheprotocolbufferdefinition.Ifapackageisnotspecified,theoutputwillbewrittentoa'temp'directoryinthecurrentlocation.--modemodeSetthe'client'or'service'modetogeneratesamplecode.Ifnotspecified,onlythestubfileisgenerated.--proto-path<path>Pathtoadirectoryinwhichtolookfor'.proto'fileswhenresolvingimportdirectives.EXAMPLESGeneratetheBallerinagRPCstubfile(forthegiven'.proto'file)ina'stub'directory.$balgrpc--inputchat.proto--outputstubGeneratetheBallerinagRPCstubfileandclientsamplecode(forthegiven'.proto'file)ina'client'directory.$balgrpc--inputchat.proto--outputclient--modeclientGeneratetheBallerinagRPCstubfileandservicesamplecode(forthegiven'.proto'file)ina'service'directory.$balgrpc--inputchat.proto--outputservice--modeservice\";\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + \".zip\"));\n    }\n\n    @Test\n    public void grpcCommandWithoutInputOptionTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/grpc\");\n        List<String> buildArgs = new LinkedList<>();\n        InputStream result = TestUtils.executeGrpcCommand(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs, true);\n        String expectedMsg = \"ballerina:missingrequiredoption'--input=<protoPath>'Run'balhelp'forusage.\";\n        Assert.assertEquals(readOutputFromStreamAsString(result), expectedMsg);\n    }\n\n    @Test\n    public void grpcCommandWithoutInputValueTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/grpc\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"--input\");\n        InputStream result = TestUtils.executeGrpcCommand(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs, true);\n        String expectedMsg = \"ballerina:flag'--input'(<protoPath>)needsanargumentRun'balhelp'forusage.\";\n        Assert.assertEquals(readOutputFromStreamAsString(result), expectedMsg);\n    }\n\n    @Test\n    public void grpcCommandWithValidInputTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/grpc\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"--input\");\n        buildArgs.add(\"proto-files/route_guide.proto\");\n        buildArgs.add(\"--output\");\n        buildArgs.add(TestUtils.getResource(testResource).toString());\n        InputStream result = TestUtils.executeGrpcCommand(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs, true);\n        Assert.assertEquals(readOutputFromStreamAsString(result), \"\");\n        String generatedTypes = getStringFromGivenBalFile(TestUtils.getResource(testResource)\n                .resolve(\"route_guide_pb.bal\"));\n        String expectedTypes = getStringFromGivenBalFile(RESOURCES_PATH\n                .resolve(\"grpc/expected-files/route_guide_pb.bal\"));\n        Assert.assertEquals(generatedTypes, expectedTypes);\n    }\n\n    @Test\n    public void grpcHelpCommandTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/grpc\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"--help\");\n        InputStream result = TestUtils.executeGrpcCommand(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs, false);\n        Assert.assertEquals(readOutputFromStreamAsString(result), helpCommandOutput);\n    }\n\n    @Test\n    public void grpcHCommandTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/grpc\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-h\");\n        InputStream result = TestUtils.executeGrpcCommand(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs, false);\n        Assert.assertEquals(readOutputFromStreamAsString(result), helpCommandOutput);\n    }\n\n    private String readOutputFromStreamAsString(InputStream result) throws IOException {\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(result))) {\n            Stream<String> logLines = br.lines();\n            String generatedLog = logLines.collect(Collectors.joining(\"\\n\"));\n            logLines.close();\n            generatedLog = (generatedLog.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            return generatedLog;\n        }\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/OpenAPIArtifactBuildTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.*;\n\n/**\n * OpenAPI Tests related to artifact generation.\n */\npublic class OpenAPIArtifactBuildTest {\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + \".zip\"));\n    }\n\n    @Test(description = \"Check openapi to ballerina generator command\")\n    public void buildOpenAPIToBallerinaTest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/openapi\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"petstore.yaml\");\n        boolean successful = TestUtils.executeOpenAPI(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"petstore_service.bal\")));\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"client.bal\")));\n        TestUtils.deleteGeneratedFiles(\"petstore\", OPENAPI_CMD);\n    }\n\n    @Test(description = \"Check openapi to ballerina generator command with service file only.\")\n    public void buildOpenAPIToBallerinaServiceFileGenerationTest() throws IOException,\n            InterruptedException {\n        Path testResource = Paths.get(\"/openapi\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"petstore.yaml\");\n        buildArgs.add(\"--mode\");\n        buildArgs.add(\"service\");\n        boolean successful = TestUtils.executeOpenAPI(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"petstore_service.bal\")));\n        TestUtils.deleteGeneratedFiles(\"petstore\", OPENAPI_CMD);\n    }\n\n    @Test(description = \"Check openapi to ballerina generator command for given tags\")\n    public void buildOpenAPIToBallerinaWithFilterTagsTest() throws IOException,\n            InterruptedException {\n        Path testResource = Paths.get(\"/openapi\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"petstoreTags.yaml\");\n        buildArgs.add(\"--tags\");\n        buildArgs.add(\"list\");\n        boolean successful = TestUtils.executeOpenAPI(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n\n        Path expectedServiceFile = RESOURCES_PATH.resolve(\"openapi/expected/filtered_tags.bal\");\n        Stream<String> expectedServiceLines = Files.lines(expectedServiceFile);\n        String expectedService = expectedServiceLines.collect(Collectors.joining(\"\\n\"));\n\n        if (Files.exists(RESOURCES_PATH.resolve(\"openapi/petstoretags_service.bal\"))) {\n            Path generatedServiceFile = TestUtils.getResource(testResource).resolve(\"petstoretags_service.bal\");\n            Stream<String> serviceLines = Files.lines(generatedServiceFile);\n            String generatedService = serviceLines.collect(Collectors.joining(\"\\n\"));\n            serviceLines.close();\n//            expectedService = replaceContractPath(expectedServiceLines, expectedService, generatedService);\n\n            expectedService = (expectedService.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            generatedService = (generatedService.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n\n            if (expectedService.equals(generatedService)) {\n                Assert.assertTrue(true);\n            } else {\n                Assert.fail(\"Expected content and actual generated content is mismatched for: petstoreTags.yaml\");\n            }\n            //Clean the generated files\n            TestUtils.deleteGeneratedFiles(\"petstoretags\", OPENAPI_CMD);\n        }\n    }\n\n    @Test(description = \"Check openapi to ballerina client generator command\")\n    public void buildOpenAPIToBallerinaClientGenerationTests() throws IOException,\n            InterruptedException {\n        Path testResource = Paths.get(\"/openapi\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"openapi_client.yaml\");\n        buildArgs.add(\"--mode\");\n        buildArgs.add(\"client\");\n        buildArgs.add(\"--client-methods\");\n        buildArgs.add(\"remote\");\n        boolean successful = TestUtils.executeOpenAPI(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n\n        if (Files.exists(RESOURCES_PATH.resolve(\"openapi/client.bal\")) &&\n                Files.exists(RESOURCES_PATH.resolve(\"openapi/types.bal\")) &&\n                Files.exists(RESOURCES_PATH.resolve(\"openapi/utils.bal\"))) {\n            String generatedClient = getStringFromGivenBalFile(TestUtils.getResource(testResource).resolve(\"client.bal\"));\n            String expectedClient = getStringFromGivenBalFile(RESOURCES_PATH.resolve(\"openapi/expected/client.bal\"));\n\n            String generatedTypes = getStringFromGivenBalFile(TestUtils.getResource(testResource).resolve(\"types.bal\"));\n            String expectedTypes = getStringFromGivenBalFile(RESOURCES_PATH.resolve(\"openapi/expected/types.bal\"));\n\n            String generatedUtils = getStringFromGivenBalFile(TestUtils.getResource(testResource).resolve(\"utils.bal\"));\n            String expectedUtils = getStringFromGivenBalFile(RESOURCES_PATH.resolve(\"openapi/expected/utils.bal\"));\n\n            Assert.assertEquals(expectedClient, generatedClient);\n            Assert.assertEquals(expectedTypes, generatedTypes);\n            Assert.assertEquals(expectedUtils, generatedUtils);\n\n            TestUtils.deleteGeneratedFiles(\"client.bal\", OPENAPI_CMD);\n        } else {\n            Assert.fail(\"Client generation failed\");\n        }\n    }\n\n    @Test(description = \"Check ballerina to openapi generator command\")\n    public void buildBallerinaToOpenAPITest() throws IOException, InterruptedException {\n        Path testResource = Paths.get(\"/openapi\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"-i\");\n        buildArgs.add(\"petstore.bal\");\n        boolean successful = TestUtils.executeOpenAPI(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        Assert.assertTrue(successful);\n        Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve(\"hello_openapi.yaml\")));\n        TestUtils.deleteGeneratedFiles(\"hello_openapi.yaml\", OPENAPI_CMD);\n    }\n\n    //OpenAPI integration tests\n    @Test(description = \"Test for openapi validator off\")\n    public void buildOpenAPIValidatorOffTest() throws IOException, InterruptedException {\n\n        Path testResource = Paths.get(\"/openapi/integration-tests/testFiles\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"openapi-validator-off.bal\");\n        InputStream outputs = TestUtils.executeOpenapiBuild(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        String msg = \"WARNING [openapi-validator-off.bal\";\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(outputs))) {\n\n            Stream<String> logLines = br.lines();\n            String generatedLog = logLines.collect(Collectors.joining(\"\\n\"));\n            logLines.close();\n\n            generatedLog = (generatedLog.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            msg = (msg.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            if (generatedLog.contains(msg)) {\n                Assert.assertTrue(true);\n            } else {\n                Assert.fail(\"OpenAPIValidator Off execution fail.\");\n            }\n        }\n    }\n\n    @Test(description = \"Tests for openapi validator on\")\n    public void buildOpenAPIValidatorONTest() throws IOException, InterruptedException {\n\n        Path testResource = Paths.get(\"/openapi/integration-tests/testFiles\");\n        List<String> buildArgs = new LinkedList<>();\n        buildArgs.add(\"openapi-validator-on.bal\");\n        InputStream outputs = TestUtils.executeOpenapiBuild(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),\n                buildArgs);\n        String msg = \"ERROR [openapi-validator-on.bal:\";\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(outputs))) {\n\n            Stream<String> logLines = br.lines();\n            String generatedLog = logLines.collect(Collectors.joining(\"\\n\"));\n            logLines.close();\n\n            generatedLog = (generatedLog.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            msg = (msg.trim()).replaceAll(WHITESPACE_PATTERN, \"\");\n            if (generatedLog.contains(msg)) {\n                Assert.assertTrue(true);\n            } else {\n                Assert.fail(\"OpenAPIValidator On execution fail.\");\n            }\n        }\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n\n    //Replace contract file path in generated service file with common URL.\n    public String replaceContractPath(Stream<String> expectedServiceLines, String expectedService,\n                                      String generatedService) {\n        Pattern pattern = Pattern.compile(\"\\\\bcontract\\\\b: \\\"(.*?)\\\"\");\n        Matcher matcher = pattern.matcher(generatedService);\n        matcher.find();\n        String contractPath = \"contract: \" + \"\\\"\" + matcher.group(1) + \"\\\"\";\n        expectedService = expectedService.replaceAll(\"\\\\bcontract\\\\b: \\\"(.*?)\\\"\",\n                Matcher.quoteReplacement(contractPath));\n        expectedServiceLines.close();\n        return expectedService;\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/OpenAPIDistributionArtifactCheck.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.DISTRIBUTIONS_DIR;\nimport static org.ballerinalang.distribution.utils.TestUtils.OPENAPI_VERSION;\nimport static org.ballerinalang.distribution.utils.TestUtils.SHORT_VERSION;\nimport static org.ballerinalang.distribution.utils.TestUtils.TEST_DISTRIBUTION_PATH;\n\n/**\n * Check if necessary openAPI files exists to build in the distribution.\n */\npublic class OpenAPIDistributionArtifactCheck {\n    private static final String DIST_NAME = \"ballerina-\" + SHORT_VERSION;\n    private static final String OPENAPI_VERSION_DIR = OPENAPI_VERSION.contains(\"-\") ? \n            OPENAPI_VERSION.substring(0, OPENAPI_VERSION.indexOf(\"-\")) : OPENAPI_VERSION;\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DIST_NAME + \".zip\"));\n    }\n\n    @Test\n    public void openapiAnnotationExistsTest() {\n        Path birPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"repo\")\n                .resolve(\"bala\")\n                .resolve(\"ballerina\")\n                .resolve(\"openapi\")\n                .resolve(OPENAPI_VERSION_DIR)\n                .resolve(\"bir\");\n\n        Path jarPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"repo\")\n                .resolve(\"bala\")\n                .resolve(\"ballerina\")\n                .resolve(\"openapi\")\n                .resolve(OPENAPI_VERSION_DIR)\n                .resolve(\"java21\")\n                .resolve(\"compiler-plugin\")\n                .resolve(\"libs\");\n\n        Path toolOpenApiLibsPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"repo\")\n                .resolve(\"bala\")\n                .resolve(\"ballerina\")\n                .resolve(\"tool.openapi\")\n                .resolve(OPENAPI_VERSION_DIR)\n                .resolve(\"java21\")\n                .resolve(\"tool\")\n                .resolve(\"libs\");\n\n        Path breLibPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"bre\")\n                .resolve(\"lib\");\n\n        Path docsPath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"docs\")\n                .resolve(\"ballerina\")\n                .resolve(\"openapi\");\n\n        Assert.assertTrue(Files.exists(birPath));\n        Assert.assertTrue(Files.exists(jarPath.resolve(\"openapi-validator-\" + OPENAPI_VERSION + \".jar\")));\n        Assert.assertTrue(Files.exists(toolOpenApiLibsPath.resolve(\"ballerina-to-openapi-\" + OPENAPI_VERSION +\".jar\")));\n        Assert.assertTrue(Files.exists(toolOpenApiLibsPath.resolve(\"openapi-bal-task-plugin-\" + OPENAPI_VERSION +\".jar\")));\n        Assert.assertTrue(Files.exists(toolOpenApiLibsPath.resolve(\"openapi-cli-\" + OPENAPI_VERSION +\".jar\")));\n        Assert.assertTrue(Files.exists(toolOpenApiLibsPath.resolve(\"openapi-core-\" + OPENAPI_VERSION +\".jar\")));\n        Assert.assertTrue(Files.exists(docsPath));\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n//        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/test/PlatformDistributionArtifactCheckTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.test;\n\nimport org.ballerinalang.distribution.utils.TestUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.util.Objects;\n\nimport static org.ballerinalang.distribution.utils.TestUtils.*;\n\n/**\n * Check if necessary files exists to build in the platform specific distributions.\n */\npublic class PlatformDistributionArtifactCheckTest {\n\n    private static final String DIST_NAME = \"ballerina-\" + SHORT_VERSION;\n\n    @DataProvider(name = \"distribution-provider\")\n    public Object[][] distributionNameProvider() {\n        return new Object[][]{\n                {\"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME},\n                {\"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME + \"-linux\"},\n                {\"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME + \"-macos\"},\n                {\"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME + \"-windows\"}\n        };\n    }\n\n    @BeforeClass\n    public void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        for (Object[] dist : distributionNameProvider()) {\n            String distName = (String) dist[0];\n            TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(distName + \".zip\"));\n        }\n    }\n\n    @Test(dataProvider = \"distribution-provider\", enabled = false)\n    public void c2cExistsTest(String distributionFileName) {\n        Path distributionsPath = TEST_DISTRIBUTION_PATH.resolve(distributionFileName).resolve(\"distributions\");\n        String jballerinaFileName = TestUtils.findFileOrDirectory(distributionsPath, DIST_NAME);\n        Objects.requireNonNull(jballerinaFileName);\n\n        Path cachePath = TEST_DISTRIBUTION_PATH\n                .resolve(DIST_NAME)\n                .resolve(\"repo\")\n                .resolve(\"cache\")\n                .resolve(\"ballerina\")\n                .resolve(\"cloud\")\n                .resolve(\"1.0.0\");\n\n        Path breLibPath = distributionsPath\n                .resolve(jballerinaFileName)\n                .resolve(\"bre\")\n                .resolve(\"lib\");\n\n        Path bbePath = distributionsPath\n                .resolve(jballerinaFileName)\n                .resolve(\"examples\")\n                .resolve(\"c2c-deployment\");\n\n        Path docsPath = distributionsPath\n                .resolve(jballerinaFileName)\n                .resolve(\"docs\")\n                .resolve(\"ballerina\")\n                .resolve(\"cloud\");\n\n        Assert.assertTrue(Files.exists(cachePath));\n        Assert.assertNotNull(TestUtils.findFileOrDirectory(breLibPath, \"c2c-extension-\"));\n        Assert.assertTrue(Files.exists(bbePath));\n        Assert.assertTrue(Files.exists(docsPath));\n    }\n\n    @Test(dataProvider = \"distribution-provider\")\n    public void c2cToolingExistsTest(String distributionFileName) {\n        Path distributionsPath = TEST_DISTRIBUTION_PATH.resolve(distributionFileName).resolve(\"distributions\");\n        String jballerinaFileName = TestUtils.findFileOrDirectory(distributionsPath, DIST_NAME);\n        Objects.requireNonNull(jballerinaFileName);\n\n        Path c2cToolingLibPath = distributionsPath\n                .resolve(jballerinaFileName)\n                .resolve(\"lib\")\n                .resolve(\"tools\")\n                .resolve(\"lang-server\")\n                .resolve(\"lib\");\n\n        Assert.assertNotNull(TestUtils.findFileOrDirectory(c2cToolingLibPath, \"cloud-tooling-\"));\n    }\n\n    @AfterClass\n    public void cleanUp() throws IOException {\n        TestUtils.cleanDistribution();\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/java/org/ballerinalang/distribution/utils/TestUtils.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerinalang.distribution.utils;\n\nimport net.lingala.zip4j.ZipFile;\nimport net.lingala.zip4j.exception.ZipException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.testng.Assert;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FilenameFilter;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Objects;\nimport java.sql.Timestamp;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n/**\n * Utility class for tests\n */\npublic class TestUtils {\n    public static final PrintStream OUT = System.out;\n    public static final Path TARGET_DIR = Paths.get(System.getProperty(\"target.dir\"));\n    public static final Path MAVEN_VERSION = Paths.get(System.getProperty(\"maven.version\"));\n    public static final Path SHORT_VERSION = Paths.get(System.getProperty(\"short.version\"));\n    public static final Path CODE_NAME = Paths.get(System.getProperty(\"code.name\"));\n    public static final String OPENAPI_VERSION = System.getProperty(\"openapi.version\");\n    public static final Path DISTRIBUTIONS_DIR = Paths.get(System.getProperty(\"distributions.dir\"));\n    public static final Path TEST_DISTRIBUTION_PATH = TARGET_DIR.resolve(\"test-distribution\");\n    public static final Path EXAMPLES_DIR = Paths.get(System.getProperty(\"examples.dir\"));\n    public static final String EXTENSTIONS_TO_BE_FILTERED_FOR_LINE_CHECKS = System.getProperty(\"line.check.extensions\");\n    public static final Path RESOURCES_PATH = TARGET_DIR.resolve(\"resources/test\");\n    private static final String SWAN_LAKE_KEYWORD = \"swan-lake\";\n    public static final String WHITESPACE_PATTERN = \"\\\\s+\";\n    private static String balFile = \"bal\";\n    public static final String DISTRIBUTION_FILE_NAME = \"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME;\n    public static final String OPENAPI_CMD = \"openapi\";\n    public static final String GRAPHQL_CMD = \"graphql\";\n\n    /**\n     * Log the output of an input stream.\n     *\n     * @param inputStream The stream.\n     * @throws IOException Error reading the stream.\n     */\n    private static void logOutput(InputStream inputStream) throws IOException {\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {\n            br.lines().forEach(OUT::println);\n        }\n    }\n    \n    /**\n     * Execute ballerina build command.\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return True if build is successful, else false.\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static boolean executeBuild(String distributionName, Path sourceDirectory, List<String> args) throws\n            IOException, InterruptedException {\n        if (System.getProperty(\"os.name\").startsWith(\"Windows\")) {\n            balFile = \"bal.bat\";\n        }\n        args.add(0, \"build\");\n        args.add(0, TEST_DISTRIBUTION_PATH.resolve(distributionName).resolve(\"bin\").resolve(balFile).toString());\n        OUT.println(\"Executing: \" + StringUtils.join(args, ' '));\n        ProcessBuilder pb = new ProcessBuilder(args);\n        pb.directory(sourceDirectory.toFile());\n        Process process = pb.start();\n        int exitCode = process.waitFor();\n        logOutput(process.getInputStream());\n        logOutput(process.getErrorStream());\n        return exitCode == 0;\n    }\n\n    /**\n     * Execute ballerina build command with openAPI annotation.\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return inputream with log outputs\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static InputStream executeOpenapiBuild(String distributionName, Path sourceDirectory, List<String> args) throws\n            IOException, InterruptedException {\n        args.add(0, \"build\");\n        Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);\n        return process.getErrorStream();\n    }\n\n    /**\n     * Execute bal grpc command with provided input\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are located.\n     * @param args             The arguments to be passed to the build command.\n     * @return error stream from the `grpc` command as an `InputStream`\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static InputStream executeGrpcCommand(String distributionName, Path sourceDirectory, List<String> args,\n                                                 boolean getError) throws\n            IOException, InterruptedException {\n        args.add(0, \"grpc\");\n        Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);\n        process.waitFor();\n        return getError ? process.getErrorStream() : process.getInputStream();\n    }\n\n    /**\n     * Execute ballerina openapi command.\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return True if build is successful, else false.\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static boolean executeOpenAPI(String distributionName, Path sourceDirectory, List<String> args) throws\n            IOException, InterruptedException {\n        args.add(0, OPENAPI_CMD);\n        Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);\n        int exitCode = process.waitFor();\n        logOutput(process.getInputStream());\n        logOutput(process.getErrorStream());\n        return exitCode == 0;\n    }\n\n    /**\n     * Execute ballerina graphql command.\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return True if build is successful, else false.\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static boolean executeGraphql(String distributionName, Path sourceDirectory, List<String> args) throws\n            IOException, InterruptedException {\n        args.add(0, GRAPHQL_CMD);\n        Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);\n        int exitCode = process.waitFor();\n        logOutput(process.getInputStream());\n        logOutput(process.getErrorStream());\n        return exitCode == 0;\n    }\n\n    /**\n     *  Get Process from given arguments.\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return process\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static Process getProcessBuilderResults(String distributionName, Path sourceDirectory, List<String> args)\n            throws IOException, InterruptedException {\n        \n        if (System.getProperty(\"os.name\").startsWith(\"Windows\")) {\n            balFile = \"bal.bat\";\n        }\n        args.add(0, TEST_DISTRIBUTION_PATH.resolve(distributionName).resolve(\"bin\").resolve(balFile).toString());\n        OUT.println(\"Executing: \" + StringUtils.join(args, ' '));\n        ProcessBuilder pb = new ProcessBuilder(args);\n        pb.directory(sourceDirectory.toFile());\n        Process process = pb.start();\n        int exitCode = process.waitFor();\n        return process;\n    }\n    \n    /**\n     * Extracts a distribution to a temporary directory.\n     *\n     * @param distributionZipPath Path to the distribution.\n     * @throws ZipException Error occurred when extracting.\n     */\n    public static void prepareDistribution(Path distributionZipPath) throws ZipException {\n        OUT.println(\"Extracting: \" + distributionZipPath.normalize());\n        ZipFile zipFile = new ZipFile(distributionZipPath.toFile());\n        zipFile.extractAll(TEST_DISTRIBUTION_PATH.toAbsolutePath().toString());\n    }\n    \n    /**\n     * Delete the temporary directory used to extract distributions.\n     *\n     * @throws IOException If temporary directory does not exists.\n     */\n    public static void cleanDistribution() throws IOException {\n        FileUtils.deleteDirectory(TEST_DISTRIBUTION_PATH.toFile());\n    }\n    \n    /**\n     * Get the exact path to a test resource.\n     *\n     * @param resource Path of the file or directory.\n     * @return The exact path of the file or directory.\n     */\n    public static Path getResource(Path resource) {\n        File file = new File(TestUtils.class.getResource(resource.toString()).getFile());\n        return file.toPath();\n    }\n    \n    /**\n     * Find the name of a file or directory that starts with a given name.\n     *\n     * @param dir     Directory to find in.\n     * @param dirName The name of the file or directory to find.\n     * @return Name of the file or directory if found. Else null.\n     */\n    public static String findFileOrDirectory(Path dir, String dirName) {\n        FilenameFilter fileNameFilter = (dir1, name) -> name.startsWith(dirName);\n        String[] fileNames = Objects.requireNonNull(dir.toFile().list(fileNameFilter));\n        return fileNames.length > 0 ? fileNames[0] : null;\n    }\n\n    /**\n     * Delete openapi and graphql generated files.\n     *\n     * @param generatedFileName file name that need to delete.\n     */\n    public static void deleteGeneratedFiles(String generatedFileName, String command) throws IOException {\n        Path resourcesPath = RESOURCES_PATH.resolve(command);\n        if (Files.exists(resourcesPath)) {\n            List<File> listFiles = Arrays.asList(\n                    Objects.requireNonNull(new File(String.valueOf(resourcesPath)).listFiles()));\n            for (File existsFile: listFiles) {\n                String fileName = existsFile.getName();\n                if (fileName.equals(generatedFileName) || fileName.equals(generatedFileName + \"_service.bal\") ||\n                        fileName.equals(\"client.bal\") || fileName.equals(\"types.bal\") || fileName.equals(\"utils.bal\") ||\n                        fileName.equals(\"config_types.bal\")) {\n                    existsFile.delete();\n                }\n            }\n            Path directoryPath = resourcesPath.resolve(\"tests\");\n            if (Files.isDirectory(directoryPath)) {\n                File file = new File(directoryPath.toString());\n                FileUtils.deleteDirectory(file);\n            }\n        }\n    }\n\n    /**\n     * Execute the given command.\n     *\n     * @param command command needs to be execute\n     * @return output of the executed command\n     */\n    public static String executeCommand(String command) throws IOException {\n        String output = \"\";\n        File file = new File(getUserHome() + File.separator\n                + \"temp-\" + new Timestamp(System.currentTimeMillis()).getTime() + \".sh\");\n        file.createNewFile();\n        file.setExecutable(true);\n        PrintWriter writer = new PrintWriter(file.getPath(), StandardCharsets.UTF_8);\n        writer.println(command);\n        writer.close();\n\n        ProcessBuilder pb = new ProcessBuilder(file.getPath());\n        Process process = pb.start();\n        InputStream inputStream = process.getInputStream();\n        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));\n        String line;\n        while ((line = reader.readLine()) != null) {\n            output += line + \"\\n\";\n        }\n        if (output.isEmpty()) {\n            inputStream =  process.getErrorStream();\n            reader = new BufferedReader(new InputStreamReader(inputStream));\n            while ((line = reader.readLine()) != null) {\n                output += line + \"\\n\";\n            }\n        }\n        file.delete();\n        return output;\n    }\n\n    /**\n     * Provide user home directory based on command.\n     *\n     * @return user home directory\n     */\n    public static String getUserHome() {\n        String userHome = System.getenv(\"HOME\");\n        if (userHome == null) {\n            userHome = System.getProperty(\"user.home\");\n        }\n        return userHome;\n    }\n\n    /**\n     * Execute smoke testing to verify installation.\n     *\n     * @param path Path to the bal file\n     * @param jBallerinaVersion Installed jBallerina version\n     * @param specVersion Installed language specification\n     * @param toolVersion Installed tool version\n     * @param versionDisplayText Installed version display text\n     */\n    public static void testInstallation(String path, String jBallerinaVersion, String specVersion, String toolVersion,\n                                        String versionDisplayText) throws IOException {\n        Assert.assertEquals(TestUtils.executeCommand(path + \" -v\"),\n                TestUtils.getVersionOutput(jBallerinaVersion, specVersion, toolVersion, versionDisplayText));\n    }\n\n    /**\n     * Get version output for version command.\n     *  @param jBallerinaVersion Installed jBallerina version\n     *  @param specVersion Installed language specification\n     *  @param toolVersion Installed tool version\n     *  @param versionDisplayText display text for installed jBallerina version\n     *\n     * @return version output\n     */\n    public static String getVersionOutput(String jBallerinaVersion, String specVersion, String toolVersion,\n                                          String versionDisplayText) {\n        String toolText = TestUtils.isOldToolVersion(toolVersion) ? \"Ballerina tool\" : \"Update Tool\";\n        if (jBallerinaVersion.contains(TestUtils.SWAN_LAKE_KEYWORD)) {\n            return \"Ballerina \" + versionDisplayText + \" (Swan Lake)\\n\" + \"Language specification \" + specVersion +\n                    \"\\n\" + toolText + \" \" + toolVersion + \"\\n\";\n        }\n\n        String ballerinaReference = isSupportedRelease(jBallerinaVersion) ? \"jBallerina\" : \"Ballerina\";\n        return ballerinaReference + \" \" + jBallerinaVersion + \"\\n\" + \"Language specification \" + specVersion + \"\\n\" +\n                toolText + \" \" + toolVersion + \"\\n\";\n    }\n\n    /**\n     * To check whether older tool version before swan lake support\n     *\n     * @param toolVersion\n     * @return returns is a older version\n     */\n    public static boolean isOldToolVersion(String toolVersion) {\n        return toolVersion.equals(\"0.8.5\") || toolVersion.equals(\"0.8.0\");\n    }\n\n    /**\n     * To check whether installation is a 1.0.x release.\n     *\n     * @return returns is a 1.0.x release\n     */\n    public static boolean isSupportedRelease(String version) {\n        if (version.contains(SWAN_LAKE_KEYWORD)) {\n            return true;\n        }\n\n        String[] versions = version.split(\"\\\\.\");\n        return !(versions[0].equals(\"1\") && versions[1].equals(\"0\"));\n    }\n\n    /**\n     * Get the content of the file.\n     * @param filePath Path to the file\n     * @return content of the file\n     * @throws IOException\n     */\n    public static String getContent(Path filePath) throws IOException {\n        return Files.readString(filePath);\n    }\n\n    public static String getStringFromGivenBalFile(Path expectedServiceFile) throws IOException {\n        Stream<String> expectedServiceLines = Files.lines(expectedServiceFile);\n        String expectedServiceContent = expectedServiceLines.collect(Collectors.joining(System.lineSeparator()));\n        expectedServiceLines.close();\n        return expectedServiceContent.trim().replaceAll(\n                WHITESPACE_PATTERN, \"\").replaceAll(System.lineSeparator(), \"\");\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/client-gen/project_1/graphql_endpoint.config.yaml",
    "content": "## The GraphQL schema. E.g., https://countries.trevorblades.com or ./schemas/country.graphql\nschema: https://countries.trevorblades.com\n## The GraphQL documents that have queries/mutations\ndocuments:\n  - ./query_country.graphql\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/client-gen/project_1/query_country.graphql",
    "content": "query countryByCode($code: ID!) {\n    country(code: $code) {\n        name\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/client-gen/project_2/graphql_schema.config.yaml",
    "content": "## The GraphQL schema. E.g., https://countries.trevorblades.com or ./schemas/country.graphql\nschema: ./schema_country.graphql\n## The GraphQL documents that have queries/mutations\ndocuments:\n  - ./queries/query_country.graphql\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/client-gen/project_2/queries/query_country.graphql",
    "content": "query countryByCode($code: ID!) {\n    country(code: $code) {\n        name\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/client-gen/project_2/schema_country.graphql",
    "content": "schema {\n    query: Query\n}\n\n\"Directs the executor to include this field or fragment only when the `if` argument is true\"\ndirective @include(\n    \"Included when true.\"\n    if: Boolean!\n) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\n\"Directs the executor to skip this field or fragment when the `if`'argument is true.\"\ndirective @skip(\n    \"Skipped when true.\"\n    if: Boolean!\n) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\ndirective @cacheControl(maxAge: Int, scope: CacheControlScope) on OBJECT | FIELD_DEFINITION | INTERFACE\n\n\"Marks the field, argument, input field or enum value as deprecated\"\ndirective @deprecated(\n    \"The reason for the deprecation\"\n    reason: String = \"No longer supported\"\n) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION\n\n\"Exposes a URL that specifies the behaviour of this scalar.\"\ndirective @specifiedBy(\n    \"The URL that specifies the behaviour of this scalar.\"\n    url: String!\n) on SCALAR\n\ntype Continent {\n    code: ID!\n    countries: [Country!]!\n    name: String!\n}\n\ntype Country {\n    capital: String\n    code: ID!\n    continent: Continent!\n    currency: String\n    emoji: String!\n    emojiU: String!\n    languages: [Language!]!\n    name: String!\n    native: String!\n    phone: String!\n    states: [State!]!\n}\n\ntype Language {\n    code: ID!\n    name: String\n    native: String\n    rtl: Boolean!\n}\n\ntype Query {\n    continent(code: ID!): Continent\n    continents(filter: ContinentFilterInput): [Continent!]!\n    countries(filter: CountryFilterInput): [Country!]!\n    country(code: ID!): Country\n    language(code: ID!): Language\n    languages(filter: LanguageFilterInput): [Language!]!\n}\n\ntype State {\n    code: String\n    country: Country!\n    name: String!\n}\n\nenum CacheControlScope {\n    PRIVATE\n    PUBLIC\n}\n\n\"The `Upload` scalar type represents a file upload.\"\nscalar Upload\n\ninput ContinentFilterInput {\n    code: StringQueryOperatorInput\n}\n\ninput CountryFilterInput {\n    code: StringQueryOperatorInput\n    continent: StringQueryOperatorInput\n    currency: StringQueryOperatorInput\n}\n\ninput LanguageFilterInput {\n    code: StringQueryOperatorInput\n}\n\ninput StringQueryOperatorInput {\n    eq: String\n    in: [String!]\n    ne: String\n    nin: [String!]\n    regex: String\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/schema-gen/project_1/Ballerina.toml",
    "content": "[package]\norg = \"ballerina_sdl_file_generator_test\"\nname = \"project_1\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/schema-gen/project_1/main.bal",
    "content": "// Copyright (c) 2023 WSO2 LLC. (http://www.wso2.org). All Rights Reserved.\n//\n// WSO2 LLC. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/graphql;\n\npublic type Person record {|\n    string name;\n    int age;\n|};\n\nservice /'service/gql on new graphql:Listener(4000) {\n    resource function get profile() returns Person {\n        return {\n            name: \"Walter White\",\n            age: 52\n        };\n    }\n}\n\nservice /gql on new graphql:Listener(4001) {\n    resource function get school() returns School {\n        return new;\n    }\n}\n\nservice /'service/gql/'new on new graphql:Listener(4002) {\n    resource function get name() returns string {\n        return \"Ballerina\";\n    }\n\n    resource function get age() returns int {\n       return 27;\n    }\n}\n\nservice class School {\n    resource function get name(string name) returns string {\n        return name;\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/schema-gen/service.bal",
    "content": "// Copyright (c) 2023 WSO2 LLC. (http://www.wso2.org). All Rights Reserved.\n//\n// WSO2 LLC. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/graphql;\n\n# Episodes of Starwars Series\npublic enum Episode {\n    # The episode new hope.\n    #       `Luke Skywalker` joins forces with a Jedi Knight.\n    #\n    # Check new lines in the documentation\n    #\n    NEWHOPE,\n    #\n    EMPIRE,\n    # The episode jedi\n    JEDI\n}\n\n#\n# + stars - Number of stars\n# + episode - The episode\npublic type Review record {\n    int stars;\n    Episode episode?;\n    string commentary?;\n};\n\n# The review input type\npublic type ReviewInput record {\n    # Number of stars\n    int stars;\n    string commentary;\n};\n\npublic type Profile distinct service object {\n    # The name of the human\n    # + id -\n    # + age -\n    # This should be an integer\n    #\n    # This is a Non-Null type argument\n    # + return - The name\n    resource function get name(string id, int age, boolean isAdult) returns string;\n};\n\n# Planet of the Human\npublic type Planet distinct service object {\n    # The home planet of the human, or null if unknown\n    # + return - The homePlanet\n    resource function get homePlanet() returns string?;\n};\n\n# A mechanical character from the Star Wars universe.\n# It can be a **Human** or a ~Droid~\npublic type Character distinct service object {\n    *Profile;\n\n    # The unique identifier of the character\n    # + return - The id\n    resource function get id() returns string;\n\n    # The episodes this character appears in\n    # + return - The episodes\n    # # Deprecated\n    # This field is deprecated.\n    # Use `appears` field instead of this.\n    @deprecated\n    resource function get appearsIn() returns Episode[];\n};\n\n# A humanoid creature from the Star Wars universe\ndistinct service class Human {\n    *Character;\n    *Planet;\n    # The unique identifier of the human\n    #   The type of the id is String\n    #\n    # The \"id\" returns a string\n    # + return - The id\n    resource function get id() returns string {\n        return \"\";\n    }\n\n    # The name of the human\n    # + return - The name\n    resource function get name(string id, int age, boolean isAdult) returns string {\n        return \"\";\n    }\n\n    # The home planet of the human, or null if unknown\n    # + return - The homePlanet\n    resource function get homePlanet() returns string? {\n        return;\n    }\n\n    # Height in meters, or null if unknown\n    # + return - The height\n    resource function get height() returns float? {\n        return ;\n    }\n\n    # Mass in kilograms, or null if unknown\n    # + return - The mass\n    resource function get mass() returns int? {\n        return ;\n    }\n\n    # The episodes this human appears in\n    # + return - The episodes\n    resource function get appearsIn() returns Episode[] {\n        return [JEDI];\n    }\n}\n\nservice /graphql on new graphql:Listener(9000) {\n\n    # Fetch the hero of the Star Wars\n    # + episode - The episode which hero appears\n    # This is a Nullable input\n    #\n    # + return - The hero\n    resource function get hero(Episode? episode) returns Profile {\n        return new Human();\n    }\n\n    # Returns reviews of the Star Wars\n    # + episode - The episode\n    # Default value of the `episode` is \"\"JEDI\"\"\n    # + return - The reviews\n    resource function get reviews(Episode episode = JEDI, string name = \"Luke\") returns Review?[] {\n        return [];\n    }\n\n    # Returns characters by id, or null if character is not found\n    # + name - Name of the character\n    #\n    # + return - The characters\n    resource function get characters(string[] idList, string name) returns Character?[] {\n        Character[] characters = [new Human()];\n        return characters;\n    }\n\n    # Returns a human by id,\n    # or null if human is not found\n    # + id - **id** of the human\n    # + return - The Human\n    resource function get human(string id) returns Human? {\n        if id.includes(\"human\") {\n            return new Human();\n        }\n        return;\n    }\n\n    # The home planet of the human, or null if unknown\n    # + return - The homePlanet\n    resource function get planet() returns Planet? {\n        return;\n    }\n\n    # Add new reviews.\n    # Return the updated review values\n    # + episode - Episode name\n    # + reviewInput - Review of the episode.\n    #\n    # This should be an `input object` type value\n    # + return - The reviews\n    remote function createReview(Episode episode, ReviewInput reviewInput) returns Review {\n        Review review = {\n            stars: reviewInput.stars\n        };\n        return review;\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/service-gen/schema_book.graphql",
    "content": "type Query {\n    \"Fetch all the books from database\"\n    books: [Book]\n    \"Fetch a book by its id\"\n    book(\n        id: Int!\n    ): Book\n}\n\ntype Book {\n    id: Int!\n    title: String!\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/graphql/service-gen/schema_starwars.graphql",
    "content": "type Query {\n    \"Fetch the hero of the Star Wars\"\n    hero(episode: Episode): Character!\n    \"Returns reviews of the Star Wars\"\n    reviews(episode: Episode!): [Review]!\n    \"Returns characters by id, or null if character is not found\"\n    characters(idList: [String!]!): [Character]!\n    \"Returns a droid by id, or null if droid is not found\"\n    droid(id: String! = \"\"): Droid\n    \"Returns a human by id, or null if human is not found\"\n    human(id: String!): Human\n    \"Returns a starship by id, or null if starship is not found\"\n    starship(id: String!): Starship\n    \"Returns search results by text, or null if search item is not found\"\n    search(text: String!): [SearchResult!]\n}\n\n\"A mechanical character from the Star Wars universe\"\ninterface Character {\n    \"The unique identifier of the character\"\n    id: String!\n    \"The name of the character\"\n    name: String!\n    \"This character's friends, or an empty list if they have none\"\n    friends: [Character!]!\n    \"The episodes this character appears in\"\n    appearsIn: [Episode!]!\n}\n\n\"A humanoid creature from the Star Wars universe\"\ntype Human implements Character {\n    \"The unique identifier of the human\"\n    id: String!\n    \"The name of the human\"\n    name: String!\n    \"The home planet of the human, or null if unknown\"\n    homePlanet: String\n    \"Height in meters, or null if unknown\"\n    height: Float\n    \"Mass in kilograms, or null if unknown\"\n    mass: Int\n    \"This human's friends, or an empty list if they have none\"\n    friends: [Character!]!\n    \"The episodes this human appears in\"\n    appearsIn: [Episode!]!\n    \"A list of starships this person has piloted, or an empty list if none\"\n    starships: [Starship!]!\n}\n\nenum Episode {\n    JEDI\n    EMPIRE\n    NEWHOPE\n}\n\n\"A ship from the Star Wars universe\"\ntype Starship {\n    \"The unique identifier of the starship\"\n    id: String!\n    \"The name of the starship\"\n    name: String!\n    \"The length of the starship, or null if unknown\"\n    length: Float\n    \"Cordinates of the starship, or null if unknown\"\n    cordinates: [[Float!]!]\n}\n\n\"An autonomous mechanical character in the Star Wars universe\"\ntype Droid implements Character {\n    \"The unique identifier of the droid\"\n    id: String!\n    \"The name of the droid\"\n    name: String!\n    \"This droid's friends, or an empty list if they have none\"\n    friends: [Character!]!\n    \"The episodes this droid appears in\"\n    appearsIn: [Episode!]!\n    \"This droid's primary function\"\n    primaryFunction: String\n}\n\ntype Review {\n    episode: Episode!\n    stars: Int!\n    commentary: String\n}\n\n\"auto-generated union type from Ballerina\"\nunion SearchResult = Human|Droid|Starship\n\ntype Mutation {\n    \"Add new reviews and return the review values\"\n    createReview(\n        \"Episode name\"\n        episode: Episode!\n        \"Review of the episode\"\n        reviewInput: ReviewInput!\n    ): Review!\n}\n\ninput ReviewInput {\n    stars: Int!\n    commentary: String\n}\n\ntype Subscription {\n    \"Subscribe to review updates\"\n    reviewAdded(\n        \"Episode name\"\n        episode: Episode!\n    ): Review!\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/grpc/expected-files/route_guide_pb.bal",
    "content": "import ballerina/grpc;\nimport ballerina/protobuf;\n\npublic const string ROUTE_GUIDE_DESC = \"0A11726F7574655F67756964652E70726F746F120A726F757465677569646522410A05506F696E74121A0A086C6174697475646518012001280552086C61746974756465121C0A096C6F6E67697475646518022001280552096C6F6E67697475646522510A0952656374616E676C6512210A026C6F18012001280B32112E726F75746567756964652E506F696E7452026C6F12210A02686918022001280B32112E726F75746567756964652E506F696E7452026869224C0A074665617475726512120A046E616D6518012001280952046E616D65122D0A086C6F636174696F6E18022001280B32112E726F75746567756964652E506F696E7452086C6F636174696F6E22540A09526F7574654E6F7465122D0A086C6F636174696F6E18012001280B32112E726F75746567756964652E506F696E7452086C6F636174696F6E12180A076D65737361676518022001280952076D6573736167652293010A0C526F75746553756D6D617279121F0A0B706F696E745F636F756E74180120012805520A706F696E74436F756E7412230A0D666561747572655F636F756E74180220012805520C66656174757265436F756E74121A0A0864697374616E6365180320012805520864697374616E636512210A0C656C61707365645F74696D65180420012805520B656C617073656454696D653285020A0A526F757465477569646512360A0A4765744665617475726512112E726F75746567756964652E506F696E741A132E726F75746567756964652E466561747572652200123E0A0C4C697374466561747572657312152E726F75746567756964652E52656374616E676C651A132E726F75746567756964652E4665617475726522003001123E0A0B5265636F7264526F75746512112E726F75746567756964652E506F696E741A182E726F75746567756964652E526F75746553756D6D61727922002801123F0A09526F7574654368617412152E726F75746567756964652E526F7574654E6F74651A152E726F75746567756964652E526F7574654E6F746522002801300142680A1B696F2E677270632E6578616D706C65732E726F7574656775696465420F526F757465477569646550726F746F50015A36676F6F676C652E676F6C616E672E6F72672F677270632F6578616D706C65732F726F7574655F67756964652F726F7574656775696465620670726F746F33\";\n\npublic isolated client class RouteGuideClient {\n    *grpc:AbstractClientEndpoint;\n\n    private final grpc:Client grpcClient;\n\n    public isolated function init(string url, *grpc:ClientConfiguration config) returns grpc:Error? {\n        self.grpcClient = check new (url, config);\n        check self.grpcClient.initStub(self, ROUTE_GUIDE_DESC);\n    }\n\n    isolated remote function GetFeature(Point|ContextPoint req) returns Feature|grpc:Error {\n        map<string|string[]> headers = {};\n        Point message;\n        if req is ContextPoint {\n            message = req.content;\n            headers = req.headers;\n        } else {\n            message = req;\n        }\n        var payload = check self.grpcClient->executeSimpleRPC(\"routeguide.RouteGuide/GetFeature\", message, headers);\n        [anydata, map<string|string[]>] [result, _] = payload;\n        return <Feature>result;\n    }\n\n    isolated remote function GetFeatureContext(Point|ContextPoint req) returns ContextFeature|grpc:Error {\n        map<string|string[]> headers = {};\n        Point message;\n        if req is ContextPoint {\n            message = req.content;\n            headers = req.headers;\n        } else {\n            message = req;\n        }\n        var payload = check self.grpcClient->executeSimpleRPC(\"routeguide.RouteGuide/GetFeature\", message, headers);\n        [anydata, map<string|string[]>] [result, respHeaders] = payload;\n        return {content: <Feature>result, headers: respHeaders};\n    }\n\n    isolated remote function RecordRoute() returns RecordRouteStreamingClient|grpc:Error {\n        grpc:StreamingClient sClient = check self.grpcClient->executeClientStreaming(\"routeguide.RouteGuide/RecordRoute\");\n        return new RecordRouteStreamingClient(sClient);\n    }\n\n    isolated remote function ListFeatures(Rectangle|ContextRectangle req) returns stream<Feature, grpc:Error?>|grpc:Error {\n        map<string|string[]> headers = {};\n        Rectangle message;\n        if req is ContextRectangle {\n            message = req.content;\n            headers = req.headers;\n        } else {\n            message = req;\n        }\n        var payload = check self.grpcClient->executeServerStreaming(\"routeguide.RouteGuide/ListFeatures\", message, headers);\n        [stream<anydata, grpc:Error?>, map<string|string[]>] [result, _] = payload;\n        FeatureStream outputStream = new FeatureStream(result);\n        return new stream<Feature, grpc:Error?>(outputStream);\n    }\n\n    isolated remote function ListFeaturesContext(Rectangle|ContextRectangle req) returns ContextFeatureStream|grpc:Error {\n        map<string|string[]> headers = {};\n        Rectangle message;\n        if req is ContextRectangle {\n            message = req.content;\n            headers = req.headers;\n        } else {\n            message = req;\n        }\n        var payload = check self.grpcClient->executeServerStreaming(\"routeguide.RouteGuide/ListFeatures\", message, headers);\n        [stream<anydata, grpc:Error?>, map<string|string[]>] [result, respHeaders] = payload;\n        FeatureStream outputStream = new FeatureStream(result);\n        return {content: new stream<Feature, grpc:Error?>(outputStream), headers: respHeaders};\n    }\n\n    isolated remote function RouteChat() returns RouteChatStreamingClient|grpc:Error {\n        grpc:StreamingClient sClient = check self.grpcClient->executeBidirectionalStreaming(\"routeguide.RouteGuide/RouteChat\");\n        return new RouteChatStreamingClient(sClient);\n    }\n}\n\npublic isolated client class RecordRouteStreamingClient {\n    private final grpc:StreamingClient sClient;\n\n    isolated function init(grpc:StreamingClient sClient) {\n        self.sClient = sClient;\n    }\n\n    isolated remote function sendPoint(Point message) returns grpc:Error? {\n        return self.sClient->send(message);\n    }\n\n    isolated remote function sendContextPoint(ContextPoint message) returns grpc:Error? {\n        return self.sClient->send(message);\n    }\n\n    isolated remote function receiveRouteSummary() returns RouteSummary|grpc:Error? {\n        var response = check self.sClient->receive();\n        if response is () {\n            return response;\n        } else {\n            [anydata, map<string|string[]>] [payload, _] = response;\n            return <RouteSummary>payload;\n        }\n    }\n\n    isolated remote function receiveContextRouteSummary() returns ContextRouteSummary|grpc:Error? {\n        var response = check self.sClient->receive();\n        if response is () {\n            return response;\n        } else {\n            [anydata, map<string|string[]>] [payload, headers] = response;\n            return {content: <RouteSummary>payload, headers: headers};\n        }\n    }\n\n    isolated remote function sendError(grpc:Error response) returns grpc:Error? {\n        return self.sClient->sendError(response);\n    }\n\n    isolated remote function complete() returns grpc:Error? {\n        return self.sClient->complete();\n    }\n}\n\npublic class FeatureStream {\n    private stream<anydata, grpc:Error?> anydataStream;\n\n    public isolated function init(stream<anydata, grpc:Error?> anydataStream) {\n        self.anydataStream = anydataStream;\n    }\n\n    public isolated function next() returns record {|Feature value;|}|grpc:Error? {\n        var streamValue = self.anydataStream.next();\n        if streamValue is () {\n            return streamValue;\n        } else if streamValue is grpc:Error {\n            return streamValue;\n        } else {\n            record {|Feature value;|} nextRecord = {value: <Feature>streamValue.value};\n            return nextRecord;\n        }\n    }\n\n    public isolated function close() returns grpc:Error? {\n        return self.anydataStream.close();\n    }\n}\n\npublic isolated client class RouteChatStreamingClient {\n    private final grpc:StreamingClient sClient;\n\n    isolated function init(grpc:StreamingClient sClient) {\n        self.sClient = sClient;\n    }\n\n    isolated remote function sendRouteNote(RouteNote message) returns grpc:Error? {\n        return self.sClient->send(message);\n    }\n\n    isolated remote function sendContextRouteNote(ContextRouteNote message) returns grpc:Error? {\n        return self.sClient->send(message);\n    }\n\n    isolated remote function receiveRouteNote() returns RouteNote|grpc:Error? {\n        var response = check self.sClient->receive();\n        if response is () {\n            return response;\n        } else {\n            [anydata, map<string|string[]>] [payload, _] = response;\n            return <RouteNote>payload;\n        }\n    }\n\n    isolated remote function receiveContextRouteNote() returns ContextRouteNote|grpc:Error? {\n        var response = check self.sClient->receive();\n        if response is () {\n            return response;\n        } else {\n            [anydata, map<string|string[]>] [payload, headers] = response;\n            return {content: <RouteNote>payload, headers: headers};\n        }\n    }\n\n    isolated remote function sendError(grpc:Error response) returns grpc:Error? {\n        return self.sClient->sendError(response);\n    }\n\n    isolated remote function complete() returns grpc:Error? {\n        return self.sClient->complete();\n    }\n}\n\npublic isolated client class RouteGuideRouteSummaryCaller {\n    private final grpc:Caller caller;\n\n    public isolated function init(grpc:Caller caller) {\n        self.caller = caller;\n    }\n\n    public isolated function getId() returns int {\n        return self.caller.getId();\n    }\n\n    isolated remote function sendRouteSummary(RouteSummary response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendContextRouteSummary(ContextRouteSummary response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendError(grpc:Error response) returns grpc:Error? {\n        return self.caller->sendError(response);\n    }\n\n    isolated remote function complete() returns grpc:Error? {\n        return self.caller->complete();\n    }\n\n    public isolated function isCancelled() returns boolean {\n        return self.caller.isCancelled();\n    }\n}\n\npublic isolated client class RouteGuideRouteNoteCaller {\n    private final grpc:Caller caller;\n\n    public isolated function init(grpc:Caller caller) {\n        self.caller = caller;\n    }\n\n    public isolated function getId() returns int {\n        return self.caller.getId();\n    }\n\n    isolated remote function sendRouteNote(RouteNote response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendContextRouteNote(ContextRouteNote response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendError(grpc:Error response) returns grpc:Error? {\n        return self.caller->sendError(response);\n    }\n\n    isolated remote function complete() returns grpc:Error? {\n        return self.caller->complete();\n    }\n\n    public isolated function isCancelled() returns boolean {\n        return self.caller.isCancelled();\n    }\n}\n\npublic isolated client class RouteGuideFeatureCaller {\n    private final grpc:Caller caller;\n\n    public isolated function init(grpc:Caller caller) {\n        self.caller = caller;\n    }\n\n    public isolated function getId() returns int {\n        return self.caller.getId();\n    }\n\n    isolated remote function sendFeature(Feature response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendContextFeature(ContextFeature response) returns grpc:Error? {\n        return self.caller->send(response);\n    }\n\n    isolated remote function sendError(grpc:Error response) returns grpc:Error? {\n        return self.caller->sendError(response);\n    }\n\n    isolated remote function complete() returns grpc:Error? {\n        return self.caller->complete();\n    }\n\n    public isolated function isCancelled() returns boolean {\n        return self.caller.isCancelled();\n    }\n}\n\npublic type ContextRouteNoteStream record {|\n    stream<RouteNote, error?> content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextPointStream record {|\n    stream<Point, error?> content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextFeatureStream record {|\n    stream<Feature, error?> content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextRouteSummary record {|\n    RouteSummary content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextRouteNote record {|\n    RouteNote content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextRectangle record {|\n    Rectangle content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextPoint record {|\n    Point content;\n    map<string|string[]> headers;\n|};\n\npublic type ContextFeature record {|\n    Feature content;\n    map<string|string[]> headers;\n|};\n\n@protobuf:Descriptor {value: ROUTE_GUIDE_DESC}\npublic type RouteSummary record {|\n    int point_count = 0;\n    int feature_count = 0;\n    int distance = 0;\n    int elapsed_time = 0;\n|};\n\n@protobuf:Descriptor {value: ROUTE_GUIDE_DESC}\npublic type RouteNote record {|\n    Point location = {};\n    string message = \"\";\n|};\n\n@protobuf:Descriptor {value: ROUTE_GUIDE_DESC}\npublic type Rectangle record {|\n    Point lo = {};\n    Point hi = {};\n|};\n\n@protobuf:Descriptor {value: ROUTE_GUIDE_DESC}\npublic type Point record {|\n    int latitude = 0;\n    int longitude = 0;\n|};\n\n@protobuf:Descriptor {value: ROUTE_GUIDE_DESC}\npublic type Feature record {|\n    string name = \"\";\n    Point location = {};\n|};\n\n"
  },
  {
    "path": "ballerina-test/src/test/resources/grpc/proto-files/route_guide.proto",
    "content": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Taken from: https://github.com/grpc/grpc-go/blob/v1.38.0/examples/route_guide/routeguide/route_guide.proto\n\nsyntax = \"proto3\";\n\noption go_package = \"google.golang.org/grpc/examples/route_guide/routeguide\";\noption java_multiple_files = true;\noption java_package = \"io.grpc.examples.routeguide\";\noption java_outer_classname = \"RouteGuideProto\";\n\npackage routeguide;\n\n// Interface exported by the server.\nservice RouteGuide {\n  // A simple RPC.\n  //\n  // Obtains the feature at a given position.\n  //\n  // A feature with an empty name is returned if there's no feature at the given\n  // position.\n  rpc GetFeature(Point) returns (Feature) {}\n\n  // A server-to-client streaming RPC.\n  //\n  // Obtains the Features available within the given Rectangle.  Results are\n  // streamed rather than returned at once (e.g. in a response message with a\n  // repeated field), as the rectangle may cover a large area and contain a\n  // huge number of features.\n  rpc ListFeatures(Rectangle) returns (stream Feature) {}\n\n  // A client-to-server streaming RPC.\n  //\n  // Accepts a stream of Points on a route being traversed, returning a\n  // RouteSummary when traversal is completed.\n  rpc RecordRoute(stream Point) returns (RouteSummary) {}\n\n  // A Bidirectional streaming RPC.\n  //\n  // Accepts a stream of RouteNotes sent while a route is being traversed,\n  // while receiving other RouteNotes (e.g. from other users).\n  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}\n}\n\n// Points are represented as latitude-longitude pairs in the E7 representation\n// (degrees multiplied by 10**7 and rounded to the nearest integer).\n// Latitudes should be in the range +/- 90 degrees and longitude should be in\n// the range +/- 180 degrees (inclusive).\nmessage Point {\n  int32 latitude = 1;\n  int32 longitude = 2;\n}\n\n// A latitude-longitude rectangle, represented as two diagonally opposite\n// points \"lo\" and \"hi\".\nmessage Rectangle {\n  // One corner of the rectangle.\n  Point lo = 1;\n\n  // The other corner of the rectangle.\n  Point hi = 2;\n}\n\n// A feature names something at a given point.\n//\n// If a feature could not be named, the name is empty.\nmessage Feature {\n  // The name of the feature.\n  string name = 1;\n\n  // The point where the feature is detected.\n  Point location = 2;\n}\n\n// A RouteNote is a message sent while at a given point.\nmessage RouteNote {\n  // The location from which the message is sent.\n  Point location = 1;\n\n  // The message to be sent.\n  string message = 2;\n}\n\n// A RouteSummary is received in response to a RecordRoute rpc.\n//\n// It contains the number of individual points received, the number of\n// detected features, and the total distance covered as the cumulative sum of\n// the distance between each point.\nmessage RouteSummary {\n  // The number of points received.\n  int32 point_count = 1;\n\n  // The number of known features passed while traversing the route.\n  int32 feature_count = 2;\n\n  // The distance covered in metres.\n  int32 distance = 3;\n\n  // The duration of the traversal in seconds.\n  int32 elapsed_time = 4;\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/expected/client.bal",
    "content": "// AUTO-GENERATED FILE. DO NOT MODIFY.\n// This file is auto-generated by the Ballerina OpenAPI tool.\nimport ballerina/http;\n\n# The Stripe REST API. Please see https://stripe.com/docs/api for more details.\npublic isolated client class Client {\n    final http:Client clientEp;\n    # Gets invoked to initialize the `connector`.\n    #\n    # + config - The configurations to be used when initializing the `connector`\n    # + serviceUrl - URL of the target service\n    # + return - An error if connector initialization failed\n    public isolated function init(ConnectionConfig config, string serviceUrl) returns error? {\n        http:ClientConfiguration httpClientConfig = {auth: config.auth, httpVersion: config.httpVersion, timeout: config.timeout, forwarded: config.forwarded, poolConfig: config.poolConfig, compression: config.compression, circuitBreaker: config.circuitBreaker, retryConfig: config.retryConfig, validation: config.validation};\n        do {\n            if config.http1Settings is ClientHttp1Settings {\n                ClientHttp1Settings settings = check config.http1Settings.ensureType(ClientHttp1Settings);\n                httpClientConfig.http1Settings = {...settings};\n            }\n            if config.http2Settings is http:ClientHttp2Settings {\n                httpClientConfig.http2Settings = check config.http2Settings.ensureType(http:ClientHttp2Settings);\n            }\n            if config.cache is http:CacheConfig {\n                httpClientConfig.cache = check config.cache.ensureType(http:CacheConfig);\n            }\n            if config.responseLimits is http:ResponseLimitConfigs {\n                httpClientConfig.responseLimits = check config.responseLimits.ensureType(http:ResponseLimitConfigs);\n            }\n            if config.secureSocket is http:ClientSecureSocket {\n                httpClientConfig.secureSocket = check config.secureSocket.ensureType(http:ClientSecureSocket);\n            }\n            if config.proxy is http:ProxyConfig {\n                httpClientConfig.proxy = check config.proxy.ensureType(http:ProxyConfig);\n            }\n        }\n        http:Client httpEp = check new (serviceUrl, httpClientConfig);\n        self.clientEp = httpEp;\n        return;\n    }\n\n    # Retrieves a PaymentMethod object.\n    #\n    # + payment_method - Payment Method\n    # + headers - Headers to be sent with the request\n    # + queries - Queries to be sent with the request\n    # + return - Successful response.\n    remote isolated function getPaymentMethodsPaymentMethod(string payment_method, GetPaymentMethodsPaymentMethodHeaders headers, *GetPaymentMethodsPaymentMethodQueries queries) returns json|error {\n        string resourcePath = string `/v1/payment_methods/${getEncodedUri(payment_method)}`;\n        resourcePath = resourcePath + check getPathForQueryParam(queries);\n        map<string|string[]> httpHeaders = http:getHeaderMap(headers);\n        return self.clientEp->get(resourcePath, httpHeaders);\n    }\n\n    # Creates a new customer object.\n    #\n    # + customer - Customer ID\n    # + headers - Headers to be sent with the request\n    # + payload - Customer Details\n    # + return - Successful response.\n    remote isolated function postCustomers(string customer, customer_customer_body payload, map<string|string[]> headers = {}) returns customer|error {\n        string resourcePath = string `/v1/customer/${getEncodedUri(customer)}`;\n        http:Request request = new;\n        map<Encoding> requestBodyEncoding = {\"address\": {style: DEEPOBJECT, explode: true}};\n        string encodedRequestBody = createFormURLEncodedRequestBody(payload, requestBodyEncoding);\n        request.setPayload(encodedRequestBody, \"application/x-www-form-urlencoded\");\n        return self.clientEp->post(resourcePath, request, headers);\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/expected/filtered_tags.bal",
    "content": "// AUTO-GENERATED FILE.\n// This file is auto-generated by the Ballerina OpenAPI tool.\n\nimport ballerina/http;\n\nlistener http:Listener ep0 = new (80, config = {host: \"petstore.openapi.io\"});\n\nservice /v1 on ep0 {\n    # List all pets\n    #\n    # + 'limit - How many items to return at one time (max 100)\n    # + return - returns can be any of following types\n    # http:Ok (An paged array of pets)\n    # http:DefaultStatusCodeResponse (unexpected error)\n    resource function get pets(int:Signed32? 'limit) returns Pets|ErrorDefault {\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/expected/types.bal",
    "content": "// AUTO-GENERATED FILE. DO NOT MODIFY.\n// This file is auto-generated by the Ballerina OpenAPI tool.\nimport ballerina/constraint;\nimport ballerina/http;\n\npublic type customer_address record {\n    @constraint:String {maxLength: 5000}\n    string city?;\n    @constraint:String {maxLength: 5000}\n    string country?;\n    @constraint:String {maxLength: 5000}\n    string line1?;\n    @constraint:String {maxLength: 5000}\n    string line2?;\n    @constraint:String {maxLength: 5000}\n    string postal_code?;\n    @constraint:String {maxLength: 5000}\n    string state?;\n};\n\n# Represents the Headers record for the operation: getPaymentMethodsPaymentMethod\npublic type GetPaymentMethodsPaymentMethodHeaders record {\n    # limit of the payment\n    string X\\-LIMIT;\n};\n\n# Provides settings related to HTTP/1.x protocol.\npublic type ClientHttp1Settings record {|\n    # Specifies whether to reuse a connection for multiple requests\n    http:KeepAlive keepAlive = http:KEEPALIVE_AUTO;\n    # The chunking behaviour of the request\n    http:Chunking chunking = http:CHUNKING_AUTO;\n    # Proxy server related options\n    ProxyConfig proxy?;\n|};\n\n# Represents the Queries record for the operation: getPaymentMethodsPaymentMethod\npublic type GetPaymentMethodsPaymentMethodQueries record {\n    # Payment Method\n    string payment\\ method\\ name;\n};\n\n# Proxy server configurations to be used with the HTTP client endpoint.\npublic type ProxyConfig record {|\n    # Host name of the proxy server\n    string host = \"\";\n    # Proxy server port\n    int port = 0;\n    # Proxy server username\n    string userName = \"\";\n    # Proxy server password\n    @display {label: \"\", kind: \"password\"}\n    string password = \"\";\n|};\n\n# Provides a set of configurations for controlling the behaviours when communicating with a remote HTTP endpoint.\n@display {label: \"Connection Config\"}\npublic type ConnectionConfig record {|\n    # Configurations related to client authentication\n    http:CredentialsConfig auth;\n    # The HTTP version understood by the client\n    http:HttpVersion httpVersion = http:HTTP_2_0;\n    # Configurations related to HTTP/1.x protocol\n    ClientHttp1Settings http1Settings?;\n    # Configurations related to HTTP/2 protocol\n    http:ClientHttp2Settings http2Settings?;\n    # The maximum time to wait (in seconds) for a response before closing the connection\n    decimal timeout = 60;\n    # The choice of setting `forwarded`/`x-forwarded` header\n    string forwarded = \"disable\";\n    # Configurations associated with request pooling\n    http:PoolConfiguration poolConfig?;\n    # HTTP caching related configurations\n    http:CacheConfig cache?;\n    # Specifies the way of handling compression (`accept-encoding`) header\n    http:Compression compression = http:COMPRESSION_AUTO;\n    # Configurations associated with the behaviour of the Circuit Breaker\n    http:CircuitBreakerConfig circuitBreaker?;\n    # Configurations associated with retrying\n    http:RetryConfig retryConfig?;\n    # Configurations associated with inbound response size limits\n    http:ResponseLimitConfigs responseLimits?;\n    # SSL/TLS-related options\n    http:ClientSecureSocket secureSocket?;\n    # Proxy server related options\n    http:ProxyConfig proxy?;\n    # Enables the inbound payload validation functionality which provided by the constraint package. Enabled by default\n    boolean validation = true;\n    # Enables relaxed data binding on the client side. When enabled, `nil` values are treated as optional,\n    # and absent fields are handled as `nilable` types. Enabled by default.\n    boolean laxDataBinding = true;\n|};\n\npublic type customer_customer_body record {\n    customer_address address?;\n    # An integer amount in %s that represents the customer's current balance, which affect the customer's future invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice.\n    int balance?;\n};\n\npublic type customer record {\n    # The customer's address.\n    customer_address? address?;\n    string name?;\n};\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/expected/utils.bal",
    "content": "// AUTO-GENERATED FILE. DO NOT MODIFY.\n// This file is auto-generated by the Ballerina OpenAPI tool.\n\nimport ballerina/http;\nimport ballerina/url;\n\ntype SimpleBasicType string|boolean|int|float|decimal;\n\n# Represents encoding mechanism details.\ntype Encoding record {\n    # Defines how multiple values are delimited\n    string style = FORM;\n    # Specifies whether arrays and objects should generate as separate fields\n    boolean explode = true;\n    # Specifies the custom content type\n    string contentType?;\n    # Specifies the custom headers\n    map<any> headers?;\n};\n\nenum EncodingStyle {\n    DEEPOBJECT, FORM, SPACEDELIMITED, PIPEDELIMITED\n}\n\nfinal Encoding & readonly defaultEncoding = {};\n\n# Generate client request when the media type is given as application/x-www-form-urlencoded.\n#\n# + encodingMap - Includes the information about the encoding mechanism\n# + anyRecord - Record to be serialized\n# + return - Serialized request body or query parameter as a string\nisolated function createFormURLEncodedRequestBody(record {|anydata...;|} anyRecord, map<Encoding> encodingMap = {}) returns string {\n    string[] payload = [];\n    foreach [string, anydata] [key, value] in anyRecord.entries() {\n        Encoding encodingData = encodingMap.hasKey(key) ? encodingMap.get(key) : defaultEncoding;\n        if value is SimpleBasicType {\n            payload.push(key, \"=\", getEncodedUri(value.toString()));\n        } else if value is SimpleBasicType[] {\n            payload.push(getSerializedArray(key, value, encodingData.style, encodingData.explode));\n        } else if (value is record {}) {\n            if encodingData.style == DEEPOBJECT {\n                payload.push(getDeepObjectStyleRequest(key, value));\n            } else {\n                payload.push(getFormStyleRequest(key, value));\n            }\n        } else if (value is record {}[]) {\n            payload.push(getSerializedRecordArray(key, value, encodingData.style, encodingData.explode));\n        }\n        payload.push(\"&\");\n    }\n    _ = payload.pop();\n    return string:'join(\"\", ...payload);\n}\n\n# Serialize the record according to the deepObject style.\n#\n# + parent - Parent record name\n# + anyRecord - Record to be serialized\n# + return - Serialized record as a string\nisolated function getDeepObjectStyleRequest(string parent, record {} anyRecord) returns string {\n    string[] recordArray = [];\n    foreach [string, anydata] [key, value] in anyRecord.entries() {\n        if value is SimpleBasicType {\n            recordArray.push(parent + \"[\" + key + \"]\" + \"=\" + getEncodedUri(value.toString()));\n        } else if value is SimpleBasicType[] {\n            recordArray.push(getSerializedArray(parent + \"[\" + key + \"]\" + \"[]\", value, DEEPOBJECT, true));\n        } else if value is record {} {\n            string nextParent = parent + \"[\" + key + \"]\";\n            recordArray.push(getDeepObjectStyleRequest(nextParent, value));\n        } else if value is record {}[] {\n            string nextParent = parent + \"[\" + key + \"]\";\n            recordArray.push(getSerializedRecordArray(nextParent, value, DEEPOBJECT));\n        }\n        recordArray.push(\"&\");\n    }\n    _ = recordArray.pop();\n    return string:'join(\"\", ...recordArray);\n}\n\n# Serialize the record according to the form style.\n#\n# + parent - Parent record name\n# + anyRecord - Record to be serialized\n# + explode - Specifies whether arrays and objects should generate separate parameters\n# + return - Serialized record as a string\nisolated function getFormStyleRequest(string parent, record {} anyRecord, boolean explode = true) returns string {\n    string[] recordArray = [];\n    if explode {\n        foreach [string, anydata] [key, value] in anyRecord.entries() {\n            if value is SimpleBasicType {\n                recordArray.push(key, \"=\", getEncodedUri(value.toString()));\n            } else if value is SimpleBasicType[] {\n                recordArray.push(getSerializedArray(key, value, explode = explode));\n            } else if value is record {} {\n                recordArray.push(getFormStyleRequest(parent, value, explode));\n            }\n            recordArray.push(\"&\");\n        }\n        _ = recordArray.pop();\n    } else {\n        foreach [string, anydata] [key, value] in anyRecord.entries() {\n            if value is SimpleBasicType {\n                recordArray.push(key, \",\", getEncodedUri(value.toString()));\n            } else if value is SimpleBasicType[] {\n                recordArray.push(getSerializedArray(key, value, explode = false));\n            } else if value is record {} {\n                recordArray.push(getFormStyleRequest(parent, value, explode));\n            }\n            recordArray.push(\",\");\n        }\n        _ = recordArray.pop();\n    }\n    return string:'join(\"\", ...recordArray);\n}\n\n# Serialize arrays.\n#\n# + arrayName - Name of the field with arrays\n# + anyArray - Array to be serialized\n# + style - Defines how multiple values are delimited\n# + explode - Specifies whether arrays and objects should generate separate parameters\n# + return - Serialized array as a string\nisolated function getSerializedArray(string arrayName, anydata[] anyArray, string style = \"form\", boolean explode = true) returns string {\n    string key = arrayName;\n    string[] arrayValues = [];\n    if anyArray.length() > 0 {\n        if style == FORM && !explode {\n            arrayValues.push(key, \"=\");\n            foreach anydata i in anyArray {\n                arrayValues.push(getEncodedUri(i.toString()), \",\");\n            }\n        } else if style == SPACEDELIMITED && !explode {\n            arrayValues.push(key, \"=\");\n            foreach anydata i in anyArray {\n                arrayValues.push(getEncodedUri(i.toString()), \"%20\");\n            }\n        } else if style == PIPEDELIMITED && !explode {\n            arrayValues.push(key, \"=\");\n            foreach anydata i in anyArray {\n                arrayValues.push(getEncodedUri(i.toString()), \"|\");\n            }\n        } else if style == DEEPOBJECT {\n            foreach anydata i in anyArray {\n                arrayValues.push(key, \"[]\", \"=\", getEncodedUri(i.toString()), \"&\");\n            }\n        } else {\n            foreach anydata i in anyArray {\n                arrayValues.push(key, \"=\", getEncodedUri(i.toString()), \"&\");\n            }\n        }\n        _ = arrayValues.pop();\n    }\n    return string:'join(\"\", ...arrayValues);\n}\n\n# Serialize the array of records according to the form style.\n#\n# + parent - Parent record name\n# + value - Array of records to be serialized\n# + style - Defines how multiple values are delimited\n# + explode - Specifies whether arrays and objects should generate separate parameters\n# + return - Serialized record as a string\nisolated function getSerializedRecordArray(string parent, record {}[] value, string style = FORM, boolean explode = true) returns string {\n    string[] serializedArray = [];\n    if style == DEEPOBJECT {\n        int arayIndex = 0;\n        foreach var recordItem in value {\n            serializedArray.push(getDeepObjectStyleRequest(parent + \"[\" + arayIndex.toString() + \"]\", recordItem), \"&\");\n            arayIndex = arayIndex + 1;\n        }\n    } else {\n        if !explode {\n            serializedArray.push(parent, \"=\");\n        }\n        foreach var recordItem in value {\n            serializedArray.push(getFormStyleRequest(parent, recordItem, explode), \",\");\n        }\n    }\n    _ = serializedArray.pop();\n    return string:'join(\"\", ...serializedArray);\n}\n\n# Get Encoded URI for a given value.\n#\n# + value - Value to be encoded\n# + return - Encoded string\nisolated function getEncodedUri(anydata value) returns string {\n    string|error encoded = url:encode(value.toString(), \"UTF8\");\n    if encoded is string {\n        return encoded;\n    } else {\n        return value.toString();\n    }\n}\n\n# Generate query path with query parameter.\n#\n# + queryParam - Query parameter map\n# + encodingMap - Details on serialization mechanism\n# + return - Returns generated Path or error at failure of client initialization\nisolated function getPathForQueryParam(map<anydata> queryParam, map<Encoding> encodingMap = {}) returns string|error {\n    map<anydata> queriesMap = http:getQueryMap(queryParam);\n    string[] param = [];\n    if queriesMap.length() > 0 {\n        param.push(\"?\");\n        foreach var [key, value] in queriesMap.entries() {\n            if value is () {\n                _ = queriesMap.remove(key);\n                continue;\n            }\n            Encoding encodingData = encodingMap.hasKey(key) ? encodingMap.get(key) : defaultEncoding;\n            if value is SimpleBasicType {\n                param.push(key, \"=\", getEncodedUri(value.toString()));\n            } else if value is SimpleBasicType[] {\n                param.push(getSerializedArray(key, value, encodingData.style, encodingData.explode));\n            } else if value is record {} {\n                if encodingData.style == DEEPOBJECT {\n                    param.push(getDeepObjectStyleRequest(key, value));\n                } else {\n                    param.push(getFormStyleRequest(key, value, encodingData.explode));\n                }\n            } else {\n                param.push(key, \"=\", value.toString());\n            }\n            param.push(\"&\");\n        }\n        _ = param.pop();\n    }\n    string restOfPath = string:'join(\"\", ...param);\n    return restOfPath;\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/Ballerina.toml",
    "content": "[package]\norg= \"ballerina\"\nname= \"openAPI\"\nversion= \"0.1.0\""
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/Package.md",
    "content": ""
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/testFiles/openapi-validator-off.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\nimport ballerina/openapi;\n\nlistener http:Listener ep0 = new (9090, config = {host: \"localhost\"});\n\n@openapi:ServiceInfo {\n    contract: \"openapi_validator_off.yaml\",\n    failOnErrors: false\n}\nservice /api/v1 on ep0 {\n    resource function get [string param1]/[string param3](http:Caller caller) returns error? {\n        string msg = \"Hello, \" + param1 + \" \" + param3;\n        var result = caller->respond(<@untainted>msg);\n        if (result is error) {\n            log:printError(\"Error sending response\");\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/testFiles/openapi-validator-on.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\nimport ballerina/openapi;\n\nlistener http:Listener ep0 = new(9090, config = {host: \"localhost\"});\n\n@openapi:ServiceInfo {\n        contract: \"openapi_validator_on.yaml\",\n        failOnErrors: true\n}\nservice /api/v1 on ep0{\n    resource function get [string param1]/[string param3](http:Caller caller) returns error? {\n        string msg = \"Hello, \" + param1 + \" \" + param3 ;\n        var result = caller->respond(<@untainted> msg);\n        if (result is error) {\n            log:printError(\"Error sending response\", result);\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/testFiles/openapi_validator_off.yaml",
    "content": "openapi: 3.0.1\ninfo:\n  title: Openapi validator off\n  description: test 2 or more uri parameters\n  version: 1.0.0\nservers:\n  - url: http://localhost/api/v1\npaths:\n  /{param1}/{param2}:\n    get:\n      operationId: test2Params\n      parameters:\n        - name: param1\n          in: path\n          required: true\n          schema:\n            type: string\n            description: param1\n        - name: param2\n          in: path\n          required: true\n          schema:\n            type: string\n            description: param2\n      responses:\n        '200':\n          description: test\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/integration-tests/testFiles/openapi_validator_on.yaml",
    "content": "openapi: 3.0.1\ninfo:\n  title: Openapi validator off\n  description: test 2 or more uri parameters\n  version: 1.0.0\nservers:\n  - url: http://localhost/api/v1\npaths:\n  /{param1}/{param2}:\n    get:\n      operationId: test2Params\n      parameters:\n        - name: param1\n          in: path\n          required: true\n          schema:\n            type: string\n            description: param1\n        - name: param2\n          in: path\n          required: true\n          schema:\n            type: string\n            description: param2\n      responses:\n        '200':\n          description: test\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/openapi_client.yaml",
    "content": "openapi: 3.0.0\ninfo:\n  contact:\n    email: dev-platform@stripe.com\n    name: Stripe Dev Platform Team\n    url: https://stripe.com\n  description: The Stripe REST API. Please see https://stripe.com/docs/api for more\n    details.\n  termsOfService: https://stripe.com/us/terms/\n  title: Stripe API\n  version: '2020-08-27'\n  x-stripeSpecFilename: spec3\n\npaths:\n  \"/v1/payment_methods/{payment_method}\":\n    get:\n      description: \"Retrieves a PaymentMethod object.\"\n      operationId: GetPaymentMethodsPaymentMethod\n      tags:\n        - \"Payment_Methods\"\n      security:\n        - basicAuth: []\n      parameters:\n        - in: path\n          name: payment_method\n          description: Payment Method\n          required: true\n          schema:\n            maxLength: 5000\n            type: string\n          style: simple\n        - in: query\n          name: payment method name\n          description: Payment Method\n          required: true\n          schema:\n            maxLength: 5000\n            type: string\n          style: deepObject\n        - in: header\n          name: X-LIMIT\n          description: limit of the payment\n          required: true\n          schema:\n            maxLength: 5000\n            type: string\n          style: simple\n      responses:\n        '200':\n          content:\n            application/json:\n              schema: {}\n          description: Successful response.\n  \"/v1/customer/{customer}\":\n    post:\n      description: \"Creates a new customer object.\"\n      operationId: PostCustomers\n      tags:\n        - \"Customers\"\n      parameters:\n        - in: path\n          name: customer\n          description: Customer ID\n          schema:\n            type: string\n          required: true\n      security:\n        - basicAuth: []\n      requestBody:\n        content:\n          application/x-www-form-urlencoded:\n            encoding:\n              address:\n                style: deepObject\n                explode: true\n            schema:\n              properties:\n                address:\n                  $ref: \"#/components/schemas/customer_address\"\n                balance:\n                  description: An integer amount in %s that represents the customer's\n                    current balance, which affect the customer's future invoices.\n                    A negative amount represents a credit that decreases the amount\n                    due on an invoice; a positive amount increases the amount due\n                    on an invoice.\n                  type: integer\n        description: Customer Details\n      responses:\n        '200':\n          content:\n            application/json:\n              schema:\n                \"$ref\": \"#/components/schemas/customer\"\n          description: Successful response.\ncomponents:\n  schemas:\n    customer_address:\n      properties:\n        city:\n          maxLength: 5000\n          type: string\n        country:\n          maxLength: 5000\n          type: string\n        line1:\n          maxLength: 5000\n          type: string\n        line2:\n          maxLength: 5000\n          type: string\n        postal_code:\n          maxLength: 5000\n          type: string\n        state:\n          maxLength: 5000\n          type: string\n      title: optional_fields_address\n      type: object\n    customer:\n      properties:\n        address:\n          anyOf:\n            - \"$ref\": \"#/components/schemas/customer_address\"\n          description: The customer's address.\n          nullable: true\n        name:\n          type: string\n      type: object\n  securitySchemes:\n    basicAuth:\n      description: 'Basic HTTP authentication. Allowed headers-- Authorization: Basic\n        <api_key> | Authorization: Basic <base64 hash of `api_key:`>'\n      scheme: basic\n      type: http\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/petstore.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\n\nlistener http:Listener helloEp = new (9090);\n\nservice /hello on helloEp {\n    resource function get hi(http:Caller caller) {\n        http:Response res = new;\n        res.setPayload(\"Hello World!\");\n\n        var result = caller->respond(res);\n        if (result is error) {\n           log:printError(\"Error when responding\", err = result.toString());\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/petstore.yaml",
    "content": "openapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: OpenApi Petstore\n  license:\n    name: MIT\nservers:\n  - url: http://petstore.{host}.io/v1\n    description: The production API server\n    variables:\n      host:\n        default: openapi\n        description: this value is assigned by the service provider\n  - url: https://{subdomain}.swagger.io:{port}/{basePath}\n    description: The production API server\n    variables:\n      subdomain:\n        default: petstore\n        description: this value is assigned by the service provider\n      port:\n        enum:\n          - '8443'\n          - '443'\n        default: '443'\n      basePath:\n        default: v2\ntags:\n  - name: pets\n    description: Pets Tag\n  - name: list\n    description: List Tag\nsecurity:\n  - petstore_auth:\n      - write:pets\n      - read:pets\n  - user_auth:\n      - read:user\n\npaths:\n  /pets:\n    get:\n      summary: List all pets\n      description: Show a list of pets in the system\n      operationId: listPets\n      tags:\n        - pets\n        - list\n      parameters:\n        - name: limit\n          in: query\n          description: How many items to return at one time (max 100)\n          required: false\n          schema:\n            type: integer\n            format: int32\n      responses:\n        '200':\n          description: An paged array of pets\n          headers:\n            x-next:\n              description: A link to the next page of responses\n              schema:\n                type: string\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Pets\"\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Error\"\n    post:\n      summary: Create pet\n      operationId: createPets\n      tags:\n        - pets\n      requestBody:\n        content:\n          application/json:\n            schema: {}\n      responses:\n        '202':\n          description: Accepted\n  /pets/{petId}:\n    get:\n      summary: Info for a specific pet\n      operationId: showPetById\n      tags:\n        - pets\n      parameters:\n        - name: petId\n          in: path\n          required: true\n          description: The id of the pet to retrieve\n          schema:\n            type: string\n      responses:\n        '200':\n          description: Expected response to a valid request\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Pets\"\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Error\"\ncomponents:\n  schemas:\n    Pet:\n      required:\n        - id\n        - name\n      properties:\n        id:\n          type: integer\n          format: int64\n        name:\n          type: string\n        tag:\n          type: string\n        type:\n          type: string\n    Dog:\n      allOf:\n        - $ref: \"#/components/schemas/Pet\"\n        - type: object\n          properties:\n            bark:\n              type: boolean\n    Pets:\n      type: array\n      items:\n        $ref: \"#/components/schemas/Pet\"\n    Error:\n      required:\n        - code\n        - message\n      properties:\n        code:\n          type: integer\n          format: int32\n        message:\n          type: string\n"
  },
  {
    "path": "ballerina-test/src/test/resources/openapi/petstoreTags.yaml",
    "content": "openapi: \"3.0.0\"\ninfo:\n  version: 1.0.0\n  title: OpenApi Petstore\n  license:\n    name: MIT\nservers:\n  - url: http://petstore.{host}.io/v1\n    description: The production API server\n    variables:\n      host:\n        default: openapi\n        description: this value is assigned by the service provider\n  - url: https://{subdomain}.swagger.io:{port}/{basePath}\n    description: The production API server\n    variables:\n      subdomain:\n        default: petstore\n        description: this value is assigned by the service provider\n      port:\n        enum:\n          - '8443'\n          - '443'\n        default: '443'\n      basePath:\n        default: v2\ntags:\n  - name: pets\n    description: Pets Tag\n  - name: list\n    description: List Tag\nsecurity:\n  - petstore_auth:\n      - write:pets\n      - read:pets\n  - user_auth:\n      - read:user\n\npaths:\n  /pets:\n    get:\n      summary: List all pets\n      description: Show a list of pets in the system\n      operationId: listPets\n      tags:\n        - list\n      parameters:\n        - name: limit\n          in: query\n          description: How many items to return at one time (max 100)\n          required: false\n          schema:\n            type: integer\n            format: int32\n      responses:\n        '200':\n          description: An paged array of pets\n          headers:\n            x-next:\n              description: A link to the next page of responses\n              schema:\n                type: string\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Pets\"\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Error\"\n    post:\n      summary: Create a pet\n      operationId: createPets\n      tags:\n        - pets\n      requestBody:\n        content:\n          application/json:\n            schema: {}\n      responses:\n        '202':\n          description: Accepted\n  /pets/{petId}:\n    get:\n      summary: Info for a specific pet\n      operationId: showPetById\n      tags:\n        - pets\n      parameters:\n        - name: petId\n          in: path\n          required: true\n          description: The id of the pet to retrieve\n          schema:\n            type: string\n      responses:\n        '200':\n          description: Expected response to a valid request\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Pets\"\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/Error\"\ncomponents:\n  schemas:\n    Pet:\n      required:\n        - id\n        - name\n      properties:\n        id:\n          type: integer\n          format: int64\n        name:\n          type: string\n        tag:\n          type: string\n        type:\n          type: string\n    Dog:\n      allOf:\n        - $ref: \"#/components/schemas/Pet\"\n        - type: object\n          properties:\n            bark:\n              type: boolean\n    Pets:\n      type: array\n      items:\n        $ref: \"#/components/schemas/Pet\"\n    Error:\n      required:\n        - code\n        - message\n      properties:\n        code:\n          type: integer\n          format: int32\n        message:\n          type: string\n"
  },
  {
    "path": "ballerina-test/src/test/resources/testing-line-length.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n ~ Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~      http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Ballerina-External-Line-Length-Test-Suite\">\n    <test name=\"ballerina-external-length-validation-tests\" parallel=\"false\">\n        <classes>\n            <class name=\"org.ballerinalang.distribution.lengthValidation.LengthValidator\"/>\n        </classes>\n    </test>\n</suite>\n\n"
  },
  {
    "path": "ballerina-test/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n ~ Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~      http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Ballerina-External-Annotation-Test-Suite\">\n    <test name=\"ballerina-external-annotations-tests\" parallel=\"false\">\n        <classes>\n            <class name=\"org.ballerinalang.distribution.test.DistributionArtifactCheckTest\"/>\n            <class name=\"org.ballerinalang.distribution.test.PlatformDistributionArtifactCheckTest\"/>\n            <!-- <class name=\"org.ballerinalang.distribution.test.OpenAPIDistributionArtifactCheck\"/> -->\n            <!-- <class name=\"org.ballerinalang.distribution.test.OpenAPIArtifactBuildTest\"/> -->\n            <!-- <class name=\"org.ballerinalang.distribution.test.GrpcToolingTest\"/> -->\n            <!-- <class name=\"org.ballerinalang.distribution.test.BallerinaCommandTest\"/> -->\n            <!-- <class name=\"org.ballerinalang.distribution.test.GraphqlToolTest\"/> -->\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "ballerina-test-automation/build.gradle",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\napply plugin: 'java'\n\njar {\n    from {\n        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }\n    }\n}\n\ngroup 'io.ballerina'\nversion '1.0-SNAPSHOT'\n\nsourceCompatibility = 1.8\n\ntasks.withType(JavaCompile) {\n    options.encoding = 'UTF-8'\n}\n\nrepositories {\n    mavenLocal()\n    maven {\n        url = 'http://maven.wso2.org/nexus/content/repositories/releases/'\n    }\n\n    maven {\n        url = 'http://maven.wso2.org/nexus/content/repositories/snapshots/'\n    }\n\n    maven {\n        url = 'http://maven.wso2.org/nexus/content/groups/wso2-public/'\n    }\n\n    maven {\n        url = 'http://repo.maven.apache.org/maven2'\n    }\n}\n\nbuildScan {\n    termsOfServiceUrl = 'https://gradle.com/terms-of-service'\n    termsOfServiceAgree = 'yes'\n}\n"
  },
  {
    "path": "ballerina-test-automation/gradle.properties",
    "content": "swan-lake-latest-version=swan-lake-2201.13.0\nswan-lake-latest-spec-version=2024R1\nswan-lake-latest-version-display-text=2201.13.0\nswan-lake-latest-tool-version=1.5.1\nlatest-tool-version=1.5.1\n1-x-channel-latest-version=1.2.13\n1-x-channel-latest-spec-version=2020R1\n"
  },
  {
    "path": "ballerina-test-automation/gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/../gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "ballerina-test-automation/gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      http://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\..\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/build.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id 'java'\n}\n\ngroup 'io.ballerina'\nversion '1.0-SNAPSHOT'\n\nsourceCompatibility = 1.8\n\ndependencies {\n    implementation project(':test-automation')\n    implementation 'org.testng:testng:6.14.3'\n    testImplementation 'org.testng:testng'\n    implementation 'com.googlecode.json-simple:json-simple:1.1.1'\n}\n\nrepositories {\n    mavenCentral()\n}\n\nconfigurations {\n    testClasses {\n        extendsFrom(testRuntimeOnly)\n    }\n}\n\ntask testJar(type: Jar) {\n    from sourceSets.test.output\n}\n\n// add the jar generated by the testJar task to the testClasses dependency\nartifacts {\n    testClasses testJar\n}\n\ntest {\n    useTestNG()\n    options.suites('src/test/resources/testng.xml')\n    systemProperty 'BALLERINA_VERSION', project.properties['swan-lake-latest-version']\n    systemProperty 'SPEC_VERSION', project.properties['swan-lake-latest-spec-version']\n    systemProperty 'VERSION_DISPLAY_TEXT', project.properties['swan-lake-latest-version-display-text']\n    systemProperty 'TOOL_VERSION', project.properties['swan-lake-latest-tool-version']\n    systemProperty 'LATEST_TOOL_VERSION', project.properties['latest-tool-version']\n    systemProperty 'LATEST_PATCH_VERSION', project.properties['1-x-channel-latest-version']\n    systemProperty 'LATEST_PATCH_SPEC_VERSION', project.properties['1-x-channel-latest-spec-version']\n    if (System.getProperty('ballerinaInstalled')) {\n        systemProperty 'BALLERINA_INSTALLED', System.getProperty('ballerinaInstalled')\n    } else {\n        systemProperty 'BALLERINA_INSTALLED', \"false\"\n    }\n    testLogging {\n        showStandardStreams = true\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/src/test/java/io/ballerina/installer/test/CentralTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.installer.test;\n\nimport io.ballerina.test.Executor;\nimport org.testng.Assert;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class CentralTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testPull(Executor executor) {\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.transferArtifacts();\n            executor.install();\n        }\n        //Checks part as output varies depending on the network speed\n        Assert.assertTrue(executor.executeCommand(\"pull ballerinax/googleapis_sheets\", false, toolVersion)\n                .contains(\"pulled from central successfully\"));\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.uninstall();\n            executor.cleanArtifacts();\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/src/test/java/io/ballerina/installer/test/InstallerTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.installer.test;\n\nimport io.ballerina.test.Executor;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class InstallerTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String specVersion = System.getProperty(\"SPEC_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testSmoke(Executor executor) {\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.transferArtifacts();\n            executor.install();\n        }\n\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion, System.getProperty(\"VERSION_DISPLAY_TEXT\"));\n\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.uninstall();\n            executor.cleanArtifacts();\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/src/test/java/io/ballerina/installer/test/ProjectTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.installer.test;\n\nimport io.ballerina.test.Executor;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class ProjectTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String specVersion = System.getProperty(\"SPEC_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testProject(Executor executor) throws InterruptedException {\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.transferArtifacts();\n            executor.install();\n        }\n\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion,\n                System.getProperty(\"VERSION_DISPLAY_TEXT\"));\n        TestUtils.testProject(executor, version, specVersion, toolVersion);\n\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.uninstall();\n            executor.cleanArtifacts();\n        }\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testBBEs(Executor executor) throws InterruptedException {\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.transferArtifacts();\n            executor.install();\n        }\n\n        TestUtils.testBBEs(executor, version, specVersion, toolVersion);\n\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.uninstall();\n            executor.cleanArtifacts();\n        }\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testDirectoryPath(Executor executor) throws InterruptedException {\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.transferArtifacts();\n            executor.install();\n        }\n\n        TestUtils.testDirectoryPath(executor, toolVersion);\n\n        if (!System.getProperty(\"BALLERINA_INSTALLED\").equals(\"true\")) {\n            executor.uninstall();\n            executor.cleanArtifacts();\n        }\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/src/test/java/io/ballerina/installer/test/TestUtils.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.ballerina.installer.test;\n\nimport io.ballerina.test.CentOS;\nimport io.ballerina.test.Executor;\nimport io.ballerina.test.MacOS;\nimport io.ballerina.test.Ubuntu;\nimport io.ballerina.test.Utils;\nimport io.ballerina.test.Windows;\nimport org.json.simple.JSONArray;\nimport org.json.simple.JSONObject;\nimport org.json.simple.parser.JSONParser;\nimport org.json.simple.parser.ParseException;\nimport org.testng.Assert;\n\nimport java.io.FileNotFoundException;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Locale;\n\npublic class TestUtils {\n    private static final String OS = System.getProperty(\"os.name\").toLowerCase(Locale.getDefault());\n    private static final String SWAN_LAKE_KEYWORD = \"swan-lake\";\n    private static final String VERSION_DISPLAY_TEXT = System.getProperty(\"VERSION_DISPLAY_TEXT\");\n\n    /**\n     * Get version output for version command.\n     *\n     * @param jBallerinaVersion  Installed jBallerina version\n     * @param specVersion        Installed language specification\n     * @param toolVersion        Installed tool version\n     * @param versionDisplayText display text for installed jBallerina version\n     * @return version output\n     */\n    public static String getVersionOutput(String jBallerinaVersion, String specVersion, String toolVersion,\n                                          String versionDisplayText) {\n        String toolText = TestUtils.isOldToolVersion(toolVersion) ? \"Ballerina tool\" : \"Update Tool\";\n        if (jBallerinaVersion.contains(TestUtils.SWAN_LAKE_KEYWORD)) {\n            String shortVersion = jBallerinaVersion.split(\"-\")[jBallerinaVersion.split(\"-\").length - 1];\n            int minorVersion = Integer.parseInt(shortVersion.split(\"\\\\.\")[1]);\n            String updateVersionText = minorVersion > 0 ? \" Update \" + minorVersion : \"\";\n\n            return \"Ballerina \" + versionDisplayText + \" (Swan Lake\" + updateVersionText + \")\\nLanguage specification \"\n                    + specVersion + \"\\n\" + toolText + \" \" + toolVersion + \"\\n\";\n        }\n\n        String ballerinaReference = isSupportedRelease(jBallerinaVersion) ? \"jBallerina\" : \"Ballerina\";\n        return ballerinaReference + \" \" + versionDisplayText + System.lineSeparator() + \"Language specification \"\n                + specVersion + System.lineSeparator() + toolText + \" \" + toolVersion + System.lineSeparator();\n    }\n\n    public static Executor getExecutor(String version) {\n        Executor executor;\n        if (OS.contains(\"win\")) {\n            executor = new Windows(version);\n        } else if (OS.contains(\"mac\")) {\n            executor = new MacOS(version);\n        } else {\n            String provider = System.getenv(\"OS_TYPE\");\n            if (provider != null && provider.equalsIgnoreCase(\"centos\")) {\n                executor = new CentOS(version);\n            } else {\n                executor = new Ubuntu(version);\n            }\n        }\n        return executor;\n    }\n\n    public static void testDistCommands(Executor executor, String version, String specVersion, String toolVersion,\n                                        String previousVersion, String previousSpecVersion,\n                                        String previousVersionsLatestPatch, String latestToolVersion)\n            throws InterruptedException {\n        //Test installation\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion, VERSION_DISPLAY_TEXT);\n\n        //Test `ballerina dist list`\n        String actualOutput = executor.executeCommand(\"dist list\", false, toolVersion);\n        Assert.assertTrue(actualOutput.contains(\"1.0.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.1.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.2.0\"));\n        Assert.assertTrue(actualOutput.contains(\"slp1\"));\n\n        //Test `ballerina dist pull`\n        executor.executeCommand(\"dist pull \"\n                + TestUtils.getSupportedVersion(toolVersion, previousVersion), true, toolVersion);\n        Thread.sleep(10000);\n        TestUtils.testInstallation(executor, previousVersion, previousSpecVersion, toolVersion, previousVersion);\n\n        //Test Update notification message\n        if (isSupportedRelease(previousVersion)) {\n            //TODO : This is a bug and have fixed in the update tool. Need to update here once new version is released.\n            String expectedOutput = \"A new version of Ballerina is available: jballerina-\" + previousVersionsLatestPatch\n                    + \"\\nUse 'ballerina dist pull jballerina-\" + previousVersionsLatestPatch\n                    + \"' to download and use the distribution\\n\\n\";\n            //  Assert.assertEquals(executor.executeCommand(\"ballerina build help\", false), expectedOutput);\n        }\n\n        //Test `ballerina dist use`\n        executor.executeCommand(\"dist use \" + TestUtils.getSupportedVersion(toolVersion, version), true,\n                toolVersion);\n\n        //Verify the the installation\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion, VERSION_DISPLAY_TEXT);\n\n        //Test `ballerina dist update`\n        executor.executeCommand(\"dist use \" + TestUtils.getSupportedVersion(toolVersion, previousVersion),\n                true, toolVersion);\n        executor.executeCommand(\"dist remove \" + TestUtils.getSupportedVersion(toolVersion, version), true,\n                toolVersion);\n\n\n        //TODO: Temporary attempt\n        executor.executeCommand(\"update\", true, toolVersion);\n\n        executor.executeCommand(\"dist update\", true, latestToolVersion);\n        Thread.sleep(10000);\n        TestUtils.testInstallation(executor, previousVersionsLatestPatch, previousSpecVersion, latestToolVersion,\n                previousVersionsLatestPatch);\n\n        //Try `ballerina dist remove`\n        executor.executeCommand(\"dist remove \" + TestUtils.getSupportedVersion(toolVersion, previousVersion),\n                true, latestToolVersion);\n    }\n\n    /**\n     * Execute smoke testing to verify installation.\n     *\n     * @param executor    Executor for relevant operating system\n     * @param version     Installed jBallerina version\n     * @param specVersion Installed language specification\n     * @param toolVersion Installed tool version\n     */\n    public static void testInstallation(Executor executor, String version, String specVersion, String toolVersion,\n                                        String versionDisplayText) {\n        String versionOutput = executor.executeCommand(\"-v\", false, toolVersion);\n        String cleanedVersionOutput = versionOutput.replaceAll(\"(\\\\d+\\\\.\\\\d+\\\\.\\\\d+)-\\\\d{8}-\\\\d{6}-[a-fA-F0-9]+\", \"$1\");\n        Assert.assertEquals(cleanedVersionOutput,\n                TestUtils.getVersionOutput(version, specVersion, toolVersion, versionDisplayText));\n    }\n\n    /**\n     * Execute smoke testing to verify fetching dependencies.\n     *\n     * @param executor    Executor for relevant operating system\n     * @param toolVersion Installed tool version\n     */\n    public static void testDependencyFetch(Executor executor, String toolVersion) throws InterruptedException {\n        String cmdName = Utils.getCommandName(toolVersion);\n        Path userDir = Paths.get(System.getProperty(\"user.dir\"));\n        executor.executeCommand(\"dist list\", false, toolVersion);\n        executor.executeCommand(\"new project1 && cd project1 &&\" + cmdName + \"add module1 && \" +\n                cmdName + \"build\", false, toolVersion);\n        Path projectPath = userDir.resolve(\"project1\");\n        Assert.assertTrue(Files.isDirectory(projectPath));\n        Assert.assertTrue(Files.isDirectory(projectPath.resolve(\"modules\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath.resolve(\"target/bin/project1.jar\")));\n        //Test `Fetching compatible JRE dependency`\n        String output = executor.executeCommand(\"dist pull slp1\", true, toolVersion);\n        Thread.sleep(10000);\n        Assert.assertTrue(output.contains(\"Downloading slp1\"));\n        Assert.assertTrue(output.contains(\"Fetching the dependencies for 'slp1' from the remote server...\"));\n        Assert.assertTrue(output.contains(\"jdk8u202-b08-jre\"));\n        Assert.assertTrue(output.contains(\"'slp1' successfully set as the active distribution\"));\n        TestUtils.testInstallation(executor, \"swan-lake-preview1\", \"v2020-06-18\", toolVersion, \"Preview 1\");\n        executor.executeCommand(\"new project2 && cd project2 && \" + cmdName + \"add module1 && \" +\n                cmdName + \"build module1\", false, toolVersion);\n        projectPath = userDir.resolve(\"project2\");\n        Assert.assertTrue(Files.isDirectory(projectPath));\n        Assert.assertTrue(Files.isDirectory(projectPath.resolve(\"src\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath.resolve(\"target/bin/module1.jar\")));\n\n        output = executor.executeCommand(\"dist pull 1.2.10\", true, toolVersion);\n        Thread.sleep(10000);\n        Assert.assertTrue(output.contains(\"Downloading 1.2.10\"));\n        Assert.assertTrue(output.contains(\"Fetching the dependencies for '1.2.10' from the remote server...\"));\n        Assert.assertTrue(output.contains(\"jdk8u265-b01-jre\"));\n        Assert.assertTrue(output.contains(\"'1.2.10' successfully set as the active distribution\"));\n        TestUtils.testInstallation(executor, \"1.2.10\", \"2020R1\", toolVersion, \"1.2.10\");\n\n        executor.executeCommand(\"new project3 && cd project3 &&\" + cmdName + \"add module1 && \" +\n                cmdName + \"build module1\", false, toolVersion);\n        projectPath = userDir.resolve(\"project3\");\n        Assert.assertTrue(Files.isDirectory(projectPath));\n        Assert.assertTrue(Files.isDirectory(projectPath.resolve(\"src\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath.resolve(\"target/bin/module1.jar\")));\n    }\n\n    /**\n     * Execute smoke testing to verify dist list.\n     *\n     * @param executor Executor for relevant operating system\n     */\n    public static void verifyDistList(Executor executor, String toolVersion) {\n        String actualOutput = executor.executeCommand(\"dist list\", false, toolVersion);\n        Assert.assertTrue(actualOutput.contains(\"1.0.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.1.0\"));\n        Assert.assertTrue(actualOutput.contains(\"1.2.0\"));\n        Assert.assertTrue(actualOutput.contains(\"slp1\"));\n    }\n\n    /**\n     * To check whether installation is a 1.0.x release.\n     *\n     * @return returns is a 1.0.x release\n     */\n    public static boolean isSupportedRelease(String version) {\n        if (version.contains(TestUtils.SWAN_LAKE_KEYWORD)) {\n            return true;\n        }\n\n        String[] versions = version.split(\"\\\\.\");\n        return !(versions[0].equals(\"1\") && versions[1].equals(\"0\"));\n    }\n\n    /**\n     * To check whether older tool version before swan lake support\n     *\n     * @param toolVersion\n     * @return returns is a older version\n     */\n    public static boolean isOldToolVersion(String toolVersion) {\n        return toolVersion.equals(\"0.8.5\") || toolVersion.equals(\"0.8.0\");\n    }\n\n    /**\n     * Test project and module creation.\n     *\n     * @param executor            Executor for relevant operating system\n     * @param previousVersion     Ballerina version to be installed\n     * @param previousSpecVersion Installed language specification\n     * @param toolVersion         Installed tool version\n     */\n    public static void testProject(Executor executor, String previousVersion, String previousSpecVersion,\n                                   String toolVersion) throws InterruptedException {\n        String cmdName = Utils.getCommandName(toolVersion);\n        executor.executeCommand(\"new sampleProject1 && cd sampleProject1 && \" + cmdName + \"add module1 && \" +\n                cmdName + \"build\", false, toolVersion);\n        Path userDir = Paths.get(System.getProperty(\"user.dir\"));\n        Path projectPath = userDir.resolve(\"sampleProject1\");\n        Assert.assertTrue(Files.exists(projectPath));\n        Assert.assertTrue(Files.isDirectory(projectPath.resolve(\"modules\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath.resolve(\"target/bin/sampleProject1.jar\")));\n\n        /*\n        executor.executeCommand(\"dist pull \" + previousVersion, true, toolVersion);\n        Thread.sleep(10000);\n        testInstallation(executor, previousVersion, previousSpecVersion, toolVersion, previousVersion);\n        executor.executeCommand(\"new sampleProject2 && cd sampleProject2 && \" + cmdName + \"add module1 && \" +\n                cmdName + \"build module1\", false, toolVersion);\n        projectPath = userDir.resolve(\"sampleProject2\");\n        Assert.assertTrue(Files.exists(projectPath));\n        Assert.assertTrue(Files.isDirectory(projectPath.resolve(\"src\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath.resolve(\"target/bin/module1.jar\")));\n         */\n    }\n\n    public static void testBBEs(Executor executor, String previousVersion, String previousSpecVersion,\n                                String toolVersion) throws InterruptedException {\n        Path userDir = Paths.get(System.getProperty(\"user.dir\"));\n        Path bbeExamplesPath = userDir.resolve(\"../../examples\");\n        Path bbeJsonFilePath = bbeExamplesPath.resolve(\"index.json\");\n        String cmdName = Utils.getCommandName(toolVersion);\n\n        List<String> bbeTests = new ArrayList<>();\n\n        JSONParser jsonParser = new JSONParser();\n\n        try (FileReader reader = new FileReader(bbeJsonFilePath.toString())) {\n            JSONArray bbeTestData = (JSONArray) jsonParser.parse(reader);\n\n            bbeTestData.forEach(testGroup -> {\n                JSONObject testGroupJsonObject = (JSONObject) testGroup;\n                JSONArray tests = (JSONArray) testGroupJsonObject.get(\"samples\");\n\n                tests.forEach(test -> {\n                    JSONObject testJsonObject = (JSONObject) test;\n                    if (testJsonObject.get(\"verifyBuild\").equals(true) &&\n                            testJsonObject.get(\"verifyOutput\").equals(true)) {\n                        bbeTests.add((String) testJsonObject.get(\"url\"));\n                    }\n                });\n            });\n        } catch (FileNotFoundException e) {\n            e.printStackTrace();\n        } catch (IOException e) {\n            e.printStackTrace();\n        } catch (ParseException e) {\n            e.printStackTrace();\n        }\n\n        bbeTests.forEach(testName -> {\n            Path balFilePath = bbeExamplesPath.resolve(testName);\n\n            executor.executeCommand(\"version && cd \" + balFilePath.toString() + \" && \" + cmdName + \"init && \" +\n                    cmdName + \"build\", false, toolVersion);\n\n            Assert.assertTrue(Files.exists(balFilePath));\n            Assert.assertTrue(Files.exists(balFilePath.resolve(\"target\").resolve(\"bin\").\n                    resolve(testName.replaceAll(\"-\", \"_\") + \".jar\")));\n        });\n    }\n\n    private static String getSupportedVersion(String toolVersion, String version) {\n        if (TestUtils.isOldToolVersion(toolVersion)) {\n            return \"jballerina-\" + version;\n        }\n        if (version.contains(TestUtils.SWAN_LAKE_KEYWORD)) {\n            if (version.contains(\"alpha\") || version.contains(\"beta\")) {\n                return \"sl\" + version.split(\"-\")[0];\n            } else if (version.contains(\"preview\")) {\n                return \"slp\" + version.replace(\"swan-lake-preview\", \"\");\n            }\n            return version.split(\"-\")[0];\n        }\n        return version;\n    }\n\n    public static void testDirectoryPath(Executor executor, String toolVersion) throws InterruptedException {\n        String cmdName = Utils.getCommandName(toolVersion);\n\n        executor.executeCommand(\"version && mkdir \\\"test space1\\\" && cd \\\"test space1\\\" && \" + cmdName +\n                \"new sampleProject1 && cd sampleProject1 && \" + cmdName + \"add module1 && \" +\n                cmdName + \"build\", false, toolVersion);\n\n        Path userDir = Paths.get(System.getProperty(\"user.dir\"));\n        Path projectPath1 = userDir.resolve(\"test space1\").resolve(\"sampleProject1\");\n        Assert.assertTrue(Files.exists(projectPath1));\n        Assert.assertTrue(Files.isDirectory(projectPath1.resolve(\"modules\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath1.resolve(\"target/bin/sampleProject1.jar\")));\n\n        executor.executeCommand(\"version && mkdir \\\"test space2\\\" && cd \\\"test space2\\\" && \" + cmdName +\n                \"new sampleProject2 && cd sampleProject2 && \" + cmdName + \"add module1\", false, toolVersion);\n        executor.executeCommand(\"version && \" + cmdName + \"build \\\"test space2/sampleProject2\\\"\", false, toolVersion);\n\n        Path projectPath2 = userDir.resolve(\"test space2\").resolve(\"sampleProject2\");\n        Assert.assertTrue(Files.exists(projectPath2));\n        Assert.assertTrue(Files.isDirectory(projectPath2.resolve(\"modules\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath2.resolve(\"target/bin/sampleProject2.jar\")));\n\n        executor.executeCommand(\"version && mkdir \\\"test space3\\\" && cd \\\"test space3\\\" && \" + cmdName +\n                \"new \\\"sample project3\\\" && cd \\\"sample project3\\\" && \" + cmdName + \"add module1\", false, toolVersion);\n        executor.executeCommand(\"version && cd \\\"test space3\\\" && \" + cmdName + \"build \\\"sample project3\\\"\",\n                false, toolVersion);\n\n        Path projectPath3 = userDir.resolve(\"test space3\").resolve(\"sample project3\");\n        Assert.assertTrue(Files.exists(projectPath3));\n        Assert.assertTrue(Files.isDirectory(projectPath3.resolve(\"modules\").resolve(\"module1\")));\n        Assert.assertTrue(Files.exists(projectPath3.resolve(\"target/bin/sample_project3.jar\")));\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/installer-test/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~ WSO2 Inc. licenses this file to you under the Apache License,\n  ~ Version 2.0 (the \"License\"); you may not use this file except\n  ~ in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing,\n  ~ software distributed under the License is distributed on an\n  ~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~ KIND, either express or implied. See the License for the\n  ~ specific language governing permissions and limitations\n  ~ under the License.\n  ~\n  -->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Suite1\" verbose=\"1\">\n    <test name=\"io.ballerina.test\">\n        <classes>\n            <!-- <class name=\"io.ballerina.installer.test.InstallerTest\"/> -->\n            <class name=\"io.ballerina.installer.test.ProjectTest\"/>\n<!--            <class name=\"io.ballerina.installer.test.CentralTest\"/>-->\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "ballerina-test-automation/settings.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nrootProject.name = 'ballerina-test-automation'\ninclude 'test-automation'\ninclude 'installer-test'\ninclude 'update-tool-test'\n\nproject(':test-automation').projectDir = \"$rootDir/test-automation\" as File\nproject(':installer-test').projectDir = \"$rootDir/installer-test\" as File\nproject(':update-tool-test').projectDir = \"$rootDir/update-tool-test\" as File\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/build.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id 'java'\n}\n\ngroup 'io.ballerina'\nversion '1.0-SNAPSHOT'\n\nsourceCompatibility = 1.8\n\ndependencies {\n    implementation 'org.testng:testng:6.14.3'\n    testImplementation 'org.testng:testng'\n}\n\nrepositories {\n    mavenCentral()\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/CentOS.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\npublic class CentOS implements Executor {\n    private String packageName;\n    private String installerName;\n    private String version;\n\n    public CentOS(String version) {\n        this.version = version;\n        installerName = \"ballerina-linux-x64-\" + version + \".rpm\";\n        packageName = \"ballerina-\" + version;\n    }\n\n    @Override\n    public String transferArtifacts() {\n        Utils.downloadFile(version, installerName);\n        return Utils.executeCommand(\"cp \" + installerName + \" ~\");\n    }\n\n    @Override\n    public String install() {\n        return Utils.executeCommand(\"sudo rpm -i ~/\" + installerName);\n    }\n\n    @Override\n    public String executeCommand(String command, boolean isAdminMode, String toolVersion) {\n        String sudoCommand = isAdminMode ? \"sudo \" : \"\";\n        String ballerinaStagingUpdate = Utils.BALLERINA_STAGING_UPDATE ? \"BALLERINA_STAGING_UPDATE=true \" : \"\";\n        return Utils.executeCommand(sudoCommand + ballerinaStagingUpdate + Utils.getCommandName(toolVersion) + command);\n    }\n\n    @Override\n    public String uninstall() {\n        return Utils.executeCommand(\"sudo rpm -e \" + packageName);\n    }\n\n    @Override\n    public String cleanArtifacts() {\n        return Utils.executeCommand(\"rm ~/\" + installerName + \" && rm -rf ~/.ballerina\");\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/Executor.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\npublic interface Executor {\n    String transferArtifacts();\n\n    String install();\n\n    String executeCommand(String command, boolean isAdminMode, String toolVersion);\n\n    String uninstall();\n\n    String cleanArtifacts();\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/MacOS.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\n\npublic class MacOS implements Executor {\n    private String installerName;\n    private String version;\n\n    public MacOS(String version) {\n        this.version = version;\n        this.installerName = \"ballerina-macos-x64-\" + version + \".pkg\";\n    }\n\n\n    @Override\n    public String transferArtifacts() {\n        Utils.downloadFile(version, installerName);\n        return Utils.executeCommand(\"cp \" + installerName + \" ~\");\n    }\n\n    @Override\n    public String install() {\n        return Utils.executeCommand(\"sudo installer -pkg ~/\" + installerName + \" -target /\");\n    }\n\n    @Override\n    public String executeCommand(String command, boolean isAdminMode, String toolVersion) {\n        String sudoCommand = isAdminMode ? \"sudo \" : \"\";\n        Utils.executeCommand(\"sudo chmod 755 /Library/Ballerina/bin/bal\");\n        String exportCmd = \"export BAL_HOME=/Library/Ballerina && export PATH=$PATH:$BAL_HOME/bin && \";\n        String ballerinaStagingUpdate = Utils.BALLERINA_STAGING_UPDATE ? \"BALLERINA_STAGING_UPDATE=true \" : \"\";\n        return Utils.executeCommand(exportCmd + sudoCommand + ballerinaStagingUpdate +\n                Utils.getCommandName(toolVersion) + command);\n    }\n\n    @Override\n    public String uninstall() {\n        return Utils.executeCommand(\"sudo rm -rf /Library/Ballerina/\");\n    }\n\n    @Override\n    public String cleanArtifacts() {\n        return Utils.executeCommand(\"rm ~/\" + installerName + \" && sudo rm -rf ~/.ballerina\");\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/Ubuntu.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\n\npublic class Ubuntu implements Executor {\n    private String packageName;\n    private String installerName;\n    private String version;\n\n    public Ubuntu(String version) {\n        this.version = version;\n        this.installerName = \"ballerina-linux-x64-\" + version + \".deb\";\n        this.packageName = \"ballerina-\" + version;\n    }\n\n\n    @Override\n    public String transferArtifacts() {\n        Utils.downloadFile(version, installerName);\n        return Utils.executeCommand(\"cp \" + installerName + \" ~\");\n    }\n\n    @Override\n    public String install() {\n        return Utils.executeCommand(\"sudo dpkg -i ~/\" + installerName);\n    }\n\n    @Override\n    public String executeCommand(String command, boolean isAdminMode, String toolVersion) {\n        String sudoCommand = isAdminMode ? \"sudo \" : \"\";\n        String ballerinaStagingUpdate = Utils.BALLERINA_STAGING_UPDATE ? \"BALLERINA_STAGING_UPDATE=true \" : \"\";\n        return Utils.executeCommand(sudoCommand + ballerinaStagingUpdate + Utils.getCommandName(toolVersion) + command);\n    }\n\n    @Override\n    public String uninstall() {\n        return Utils.executeCommand(\"sudo apt-get --yes --force-yes remove \" + packageName);\n    }\n\n    @Override\n    public String cleanArtifacts() {\n        return Utils.executeCommand(\"rm ~/\" + installerName + \" && sudo rm -rf ~/.ballerina\");\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/Utils.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509TrustManager;\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.io.PrintWriter;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.sql.Timestamp;\nimport java.util.Locale;\n\npublic class Utils {\n    private static final String OS = System.getProperty(\"os.name\").toLowerCase(Locale.getDefault());\n    public static final boolean BALLERINA_STAGING_UPDATE = Boolean.parseBoolean(\n            System.getenv(\"BALLERINA_STAGING_UPDATE\"));\n    public static final PrintStream OUT = System.out;\n\n    public static final String DISTRIBUTION_LOCATION = \"https://dist-dev.ballerina.io/downloads/\";\n\n    public static void downloadFile(String version, String installerName) {\n        OUT.println(\"Downloading \" + installerName);\n        try {\n            String destination = getUserHome();\n            File output = new File(destination + File.separator + installerName);\n            if (!output.exists()) {\n                HttpURLConnection conn = (HttpURLConnection) new URL(\n                        DISTRIBUTION_LOCATION + version + \"/\" + installerName).openConnection();\n                conn.setRequestProperty(\"content-type\", \"binary/data\");\n\n                try (InputStream in = conn.getInputStream();\n                     FileOutputStream out = new FileOutputStream(output)) {\n                    byte[] b = new byte[1024];\n                    int count;\n                    while ((count = in.read(b)) > 0) {\n                        out.write(b, 0, count);\n                    }\n                } catch (IOException e) {\n                    OUT.println(e);\n                }\n            }\n        } catch (Exception e) {\n            OUT.println(\"Error occurred while downloading installer: \" + e.getMessage());\n        }\n    }\n\n    public static String executeCommand(String command) {\n        OUT.println(\"Executing: \" + command);\n        String output = \"\";\n        try {\n            ProcessBuilder processBuilder;\n            if (isWindows()) {\n                processBuilder = new ProcessBuilder(\"cmd\", \"/c\", command);\n            } else {\n                processBuilder = new ProcessBuilder(\"bash\", \"-c\", command);\n            }\n            Process process = processBuilder.start();\n            int exitCode = process.waitFor();\n            InputStream inputStream = process.getInputStream();\n            if (exitCode != 0) {\n                inputStream = process.getErrorStream();\n            }\n\n            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));\n            String line;\n            while ((line = reader.readLine()) != null) {\n                output += line + \"\\n\";\n            }\n            if (isWindows() && output.isEmpty()) {\n                inputStream = process.getErrorStream();\n                reader = new BufferedReader(new InputStreamReader(inputStream));\n                while ((line = reader.readLine()) != null) {\n                    output += line + \"\\n\";\n                }\n            }\n            OUT.println(output);\n        } catch (IOException | InterruptedException e) {\n            OUT.println(\"Error occurred while executing \" + command + \": \" + e.getMessage());\n        }\n        return output;\n    }\n\n    private static boolean isUnix() {\n        return OS.contains(\"nix\") || OS.contains(\"nux\") || OS.contains(\"aix\");\n    }\n\n    private static boolean isWindows() {\n        return OS.contains(\"win\");\n    }\n\n    /**\n     * Provide user home directory based on command.\n     *\n     * @return user home directory\n     */\n    public static String getUserHome() {\n        String userHome = System.getenv(\"HOME\");\n        if (isUnix() && userHome.contains(\"root\")) {\n            userHome = \"/home/\" + System.getenv(\"SUDO_USER\");\n        }\n        if (userHome == null) {\n            userHome = System.getProperty(\"user.home\");\n        }\n        return userHome;\n    }\n\n    /**\n     * Get the command name(ballerina or bal)\n     *\n     * @param toolVersion\n     * @return returns the command name\n     */\n    public static String getCommandName(String toolVersion) {\n        String[] version = toolVersion.split(\"\\\\.\");\n        //command will be ballerina if update tool version is less than 0.8.10.\n        return version[0].equals(\"0\") && Integer.parseInt(version[2]) <= 10 ? \"ballerina \" : \"bal \";\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/test-automation/src/main/java/io/ballerina/test/Windows.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.test;\n\npublic class Windows implements Executor {\n    private String installerName;\n    private String version;\n\n    public Windows(String version) {\n        this.version = version;\n        installerName = \"ballerina-windows-x64-\" + version + \".msi\";\n    }\n\n    @Override\n    public String transferArtifacts() {\n        Utils.downloadFile(version, installerName);\n        return \"\";\n    }\n\n    @Override\n    public String install() {\n        return Utils.executeCommand(\"msiexec /i \" + Utils.getUserHome() + \"\\\\\" + installerName\n                + \" /qn /l \\\"install-log.log\\\"\");\n    }\n\n    @Override\n    public String executeCommand(String command, boolean isAdminMode, String toolVersion) {\n        return Utils.executeCommand(Utils.getCommandName(toolVersion) + command);\n    }\n\n    @Override\n    public String uninstall() {\n        return Utils.executeCommand(\"wmic product where name=\\\"Ballerina \" + version + \"\\\" call uninstall/nointeractive\");\n    }\n\n    @Override\n    public String cleanArtifacts() {\n        return Utils.executeCommand(\"rmdir /Q /S \" + Utils.getUserHome() + \"\\\\.ballerina\");\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/update-tool-test/build.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id 'java'\n}\n\ngroup 'io.ballerina'\nversion '1.0-SNAPSHOT'\n\nsourceCompatibility = 1.8\n\ndependencies {\n    implementation project(':test-automation')\n    testImplementation project(path: ':installer-test', configuration: 'testClasses')\n    implementation 'org.testng:testng:6.14.3'\n    testImplementation 'org.testng:testng'\n}\n\nrepositories {\n    mavenCentral()\n}\n\ntest {\n    useTestNG()\n    options.suites('src/test/resources/testng.xml')\n    systemProperty 'BALLERINA_VERSION', project.properties['swan-lake-latest-version']\n    systemProperty 'SPEC_VERSION', project.properties['swan-lake-latest-spec-version']\n    systemProperty 'VERSION_DISPLAY_TEXT', project.properties['swan-lake-latest-version-display-text']\n    systemProperty 'TOOL_VERSION', project.properties['swan-lake-latest-tool-version']\n    systemProperty 'LATEST_TOOL_VERSION', project.properties['latest-tool-version']\n    systemProperty 'LATEST_PATCH_VERSION', project.properties['1-x-channel-latest-version']\n    systemProperty 'LATEST_PATCH_SPEC_VERSION', project.properties['1-x-channel-latest-spec-version']\n    testLogging {\n        showStandardStreams = true\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/update-tool-test/src/test/java/io/ballerina/tool/test/FetchDependencyTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.tool.test;\n\nimport io.ballerina.installer.test.TestUtils;\nimport io.ballerina.test.Executor;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class FetchDependencyTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String specVersion = System.getProperty(\"SPEC_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n    String VERSION_DISPLAY_TEXT = System.getProperty(\"VERSION_DISPLAY_TEXT\");\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testFetchDependency(Executor executor) throws InterruptedException {\n        executor.transferArtifacts();\n        executor.install();\n\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion, VERSION_DISPLAY_TEXT);\n        TestUtils.testDependencyFetch(executor, toolVersion);\n\n        executor.uninstall();\n        executor.cleanArtifacts();\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/update-tool-test/src/test/java/io/ballerina/tool/test/UpdateDistTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.tool.test;\n\nimport io.ballerina.installer.test.TestUtils;\nimport io.ballerina.test.Executor;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class UpdateDistTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String specVersion = System.getProperty(\"SPEC_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n    String latestToolVersion = System.getProperty(\"LATEST_TOOL_VERSION\");\n\n    String previousVersion = \"1.2.0\";\n    String previousSpecVersion = \"2020R1\";\n    String previousVersionsLatestPatch = System.getProperty(\"LATEST_PATCH_VERSION\");\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testDistCommands(Executor executor) throws InterruptedException {\n        executor.transferArtifacts();\n        executor.install();\n\n        TestUtils.testDistCommands(executor, version, specVersion, toolVersion, previousVersion, previousSpecVersion,\n                previousVersionsLatestPatch, latestToolVersion);\n\n        executor.uninstall();\n        executor.cleanArtifacts();\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/update-tool-test/src/test/java/io/ballerina/tool/test/UpdateToolTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage io.ballerina.tool.test;\n\nimport io.ballerina.installer.test.TestUtils;\nimport io.ballerina.test.Executor;\nimport org.testng.annotations.DataProvider;\nimport org.testng.annotations.Test;\n\n\npublic class UpdateToolTest {\n    String version = System.getProperty(\"BALLERINA_VERSION\");\n    String specVersion = System.getProperty(\"SPEC_VERSION\");\n    String toolVersion = System.getProperty(\"TOOL_VERSION\");\n    String latestToolVersion = System.getProperty(\"LATEST_TOOL_VERSION\");\n    String VERSION_DISPLAY_TEXT = System.getProperty(\"VERSION_DISPLAY_TEXT\");\n\n    String previousVersion = \"1.2.0\";\n    String previousSpecVersion = \"2020R1\";\n    String previousVersionsLatestPatch = System.getProperty(\"LATEST_PATCH_VERSION\");\n\n    @DataProvider(name = \"getExecutors\")\n    public Object[][] dataProviderMethod() {\n        Executor[][] result = new Executor[1][1];\n        result[0][0] = TestUtils.getExecutor(version);\n        return result;\n    }\n\n    @Test(dataProvider = \"getExecutors\")\n    public void testUpdateTool(Executor executor) throws InterruptedException {\n        executor.transferArtifacts();\n        executor.install();\n\n        //Test dist list\n        TestUtils.verifyDistList(executor, toolVersion);\n        //Test installation\n        TestUtils.testInstallation(executor, version, specVersion, toolVersion, VERSION_DISPLAY_TEXT);\n\n        //Test `ballerina update`\n        executor.executeCommand(\"update\", true, toolVersion);\n        TestUtils.testInstallation(executor, version, specVersion, latestToolVersion, VERSION_DISPLAY_TEXT);\n\n        //Execute all ballerina dist commands once updated\n        TestUtils.testDistCommands(executor, version, specVersion, latestToolVersion, previousVersion,\n                previousSpecVersion, previousVersionsLatestPatch, latestToolVersion);\n\n        executor.uninstall();\n        executor.cleanArtifacts();\n    }\n}\n"
  },
  {
    "path": "ballerina-test-automation/update-tool-test/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~\n  ~ WSO2 Inc. licenses this file to you under the Apache License,\n  ~ Version 2.0 (the \"License\"); you may not use this file except\n  ~ in compliance with the License.\n  ~ You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing,\n  ~ software distributed under the License is distributed on an\n  ~ \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  ~ KIND, either express or implied. See the License for the\n  ~ specific language governing permissions and limitations\n  ~ under the License.\n  ~\n  -->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Suite1\" verbose=\"1\">\n    <test name=\"io.ballerina.test\">\n        <classes>\n<!--            <class name=\"io.ballerina.installer.test.InstallerTest\"/>-->\n<!--            <class name=\"io.ballerina.tool.test.UpdateDistTest\"/>-->\n<!--            <class name=\"io.ballerina.tool.test.UpdateToolTest\"/>-->\n<!--            <class name=\"io.ballerina.tool.test.FetchDependencyTest\"/>-->\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "build-time-tests/build.gradle",
    "content": "/*\n ~ * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~ *\n ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ * you may not use this file except in compliance with the License.\n ~ * You may obtain a copy of the License at\n ~ *\n ~ * http://www.apache.org/licenses/LICENSE-2.0\n ~ *\n ~ * Unless required by applicable law or agreed to in writing, software\n ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ * See the License for the specific language governing permissions and\n ~ * limitations under the License.\n ~ */\n\ndescription = 'Ballerina - Build Time Tests'\n\napply plugin: 'java'\n\next.offline = \"false\"\ndef distPath = \"$projectDir/../ballerina/build/target/extracted-distributions/ballerina-${version}\"\n\nconfigurations {\n    ballerinaDistribution\n}\n\ndependencies {\n    ballerinaDistribution project(path: \":ballerina\", configuration: \"ballerinaDistribution\")\n    implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.12.3'\n    implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'\n}\n\ntask copySamples {\n    copy {\n        from file(\"$project.projectDir/samples\")\n        into file(\"$project.projectDir/build/samples\")\n    }\n}\n\ntask buildSamples {\n    dependsOn copySamples\n    dependsOn configurations.ballerinaDistribution\n    dependsOn (\":ballerina:unzipDistForTests\")\n    doLast {\n        exec {\n            workingDir \"${buildDir}/samples\"\n            commandLine 'sh', '-c', \"bash build-samples.sh $distPath\"\n        }\n    }\n}\n\ntask processData(type: JavaExec) {\n    dependsOn buildSamples\n    classpath = sourceSets.main.runtimeClasspath\n    setMain('org.ballerina.packages.buildtime.GenerateBuildDataCsv')\n    args \"$buildDir/../../ballerina/build/distributions\"\n}\n"
  },
  {
    "path": "build-time-tests/samples/build-samples.sh",
    "content": "#!/bin/bash\n# ---------------------------------------------------------------------------\n#  Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n#  Licensed under the Apache License, Version 2.0 (the \"License\");\n#  you may not use this file except in compliance with the License.\n#  You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n#  Unless required by applicable law or agreed to in writing, software\n#  distributed under the License is distributed on an \"AS IS\" BASIS,\n#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#  See the License for the specific language governing permissions and\n#  limitations under the License.\n# ----------------------------------------------------------------------------\n\nBAL_DIST_PATH=$1\nBAL_EXEC_PATH=$BAL_DIST_PATH/bin/bal\nARTEFACT_DIR=../build-time-data\n\nSAMPLES_LIST=$(ls -d */)\nmkdir -p \"$ARTEFACT_DIR/offline\"\nmkdir -p \"$ARTEFACT_DIR/online\"\n\nfor sample in $SAMPLES_LIST\ndo\n   sample_name=$(basename $sample)\n   echo \"Building sample '$sample'\"\n   $BAL_EXEC_PATH build --dump-build-time $sample\n   cp \"$sample/target/build-time.json\" \"$ARTEFACT_DIR/online/$sample_name-build-time.json\"\ndone\n\nfor sample in $SAMPLES_LIST\ndo\n   sample_name=$(basename $sample)\n   echo \"Building sample '$sample' offline\"\n   $BAL_EXEC_PATH build --dump-build-time --offline $sample\n   cp \"$sample/target/build-time.json\" \"$ARTEFACT_DIR/offline/$sample_name-build-time.json\"\ndone\n"
  },
  {
    "path": "build-time-tests/samples/helloservice/Ballerina.toml",
    "content": "[build-options]\nobservabilityIncluded = true\n"
  },
  {
    "path": "build-time-tests/samples/helloservice/service.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\n# A service representing a network-accessible API\n# bound to absolute path `/hello` and port `9090`.\nservice /hello on new http:Listener(9090) {\n\n    # A resource respresenting an invokable API method\n    # accessible at `/hello/sayHello`.\n    #\n    # + caller - the client invoking this resource\n    # + request - the inbound request\n    resource function get sayHello(http:Caller caller, http:Request request) {\n\n        // Send a response back to the caller.\n        error? result = caller->respond(\"Hello Ballerina!\");\n        if (result is error) {\n            io:println(\"Error in responding: \", result);\n        }\n    }\n}\n"
  },
  {
    "path": "build-time-tests/samples/helloworld/Ballerina.toml",
    "content": "[build-options]\nobservabilityIncluded = true\n"
  },
  {
    "path": "build-time-tests/samples/helloworld/helloworld.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    io:println(\"Hello World!\");\n}\n"
  },
  {
    "path": "build-time-tests/src/main/java/org/ballerina/packages/buildtime/GenerateBuildDataCsv.java",
    "content": "/*\n *  Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\npackage org.ballerina.packages.buildtime;\n\n//import com.google.gson.Gson;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.ObjectWriter;\nimport com.fasterxml.jackson.databind.node.ObjectNode;\nimport com.fasterxml.jackson.dataformat.csv.CsvMapper;\nimport com.fasterxml.jackson.dataformat.csv.CsvSchema;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n\n/**\n * Class with a main function to accumulate command generated JSON build time data to a CSV file.\n */\npublic class GenerateBuildDataCsv {\n    public static void main(String[] args) throws IOException {\n\n        Path artefactsDir = Paths.get(System.getProperty(\"user.dir\"), \"build\", \"build-time-data\");\n        Path outputCsvFile = artefactsDir.resolve(\"buildTimeData.csv\");\n        List<Path> jsonFiles = getJsonFiles(artefactsDir);\n\n        CsvSchema.Builder csvSchemaBuilder = CsvSchema.builder();\n        JsonNode jsonTree = new ObjectMapper().readTree(jsonFiles.get(0).toFile());\n        csvSchemaBuilder.addColumn(\"name\");\n        jsonTree.fieldNames().forEachRemaining(fieldName ->\n                csvSchemaBuilder.addColumn(fieldName, CsvSchema.ColumnType.NUMBER));\n        CsvSchema csvSchema;\n        CsvMapper csvMapper = new CsvMapper();\n\n        if (!Files.exists(outputCsvFile)) {\n            // This done to avoid duplication of the header in the CSV file\n            csvSchema = csvSchemaBuilder.build().withHeader();\n            csvMapper.writerFor(JsonNode.class).with(csvSchema).writeValue(outputCsvFile.toFile(), null);\n        }\n        csvSchema = csvSchemaBuilder.build().withoutHeader();\n\n        for (Path jsonFile : jsonFiles) {\n            JsonNode jsonTree1 = new ObjectMapper().readTree(jsonFile.toFile());\n            // additionally ass the name of the sample to the record\n            ((ObjectNode)jsonTree1).put(\"name\", jsonFile.getFileName().toString().split(\"-build-time.json\")[0]);\n            ObjectWriter writer = csvMapper.writerFor(JsonNode.class).with(csvSchema);\n            try (OutputStream outstream = new FileOutputStream(outputCsvFile.toFile(), true)) {\n                writer.writeValue(outstream, jsonTree1);\n            }\n        }\n    }\n\n    private static List<Path> getJsonFiles(Path artefactsDir) throws IOException {\n        try (Stream<Path> pathStream = Files.walk(artefactsDir, 2)) {\n            return pathStream\n                    .filter(path -> path.getFileName().toString().endsWith(\".json\"))\n                    .collect(Collectors.toList());\n        }\n    }\n}\n"
  },
  {
    "path": "build.gradle",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\nplugins {\n    id 'base'\n    id 'maven-publish'\n    id 'net.researchgate.release' version '2.8.0'\n    id 'de.undercouch.download' version '5.4.0'\n    id \"com.github.johnrengelman.shadow\" version \"8.1.1\"\n    id \"com.github.spotbugs\" version \"5.0.14\"\n}\n\ndescription = 'Ballerina - Tools - Parent'\n\next {\n    ballerinaLangVersion = project.ballerinaLangVersion\n    shortVersion = project.version.split(\"-\")[0]\n    c2cVersion = project.c2cVersion\n    ballerinaJreVersion = project.ballerinaJreVersion\n    ballerinaCommandVersion = project.ballerinaCommandVersion\n\n    picocliVersion = \"4.0.1\"\n    testngVersion = \"7.6.1\"\n    netLingalaZip4jVersion = \"2.8.0\"\n    commonsIoVersion = \"2.6\"\n    commonsLang3Version = \"3.9\"\n    lsp4jDebugVersion = \"0.7.1\"\n    puppycrawlCheckstyleVersion = \"10.12.1\"\n}\n\nallprojects {\n    apply plugin: 'maven-publish'\n\n    group = project.group\n    version = project.version\n\n    repositories {\n        mavenCentral()\n    }\n\n    release {\n        // Workaround to fix build task not found issue in release plugin\n        buildTasks = []\n        failOnSnapshotDependencies = true\n        failOnCommitNeeded = false\n        versionPropertyFile = 'gradle.properties'\n        tagTemplate = 'v${System.env.GIT_TAG}'\n        git {\n            // To release from any branch\n            requireBranch = ''\n        }\n    }\n\n    afterReleaseBuild.dependsOn publishToMavenLocal\n    afterReleaseBuild.dependsOn publish\n}\n\nsubprojects {\n    apply plugin: 'java'\n    sourceCompatibility = 21\n    targetCompatibility = 21\n    tasks.withType(JavaCompile) {\n        options.encoding = 'UTF-8'\n    }\n\n    buildscript {\n        repositories {\n            /* Central Repository */\n            maven { url \"https://repo.maven.apache.org/maven2\" }\n            /* CWSO2 Releases Repository */\n            maven { url \"http://maven.wso2.org/nexus/content/repositories/releases/\" }\n            /* WSO2 Snapshot Repository */\n            maven { url \"http://maven.wso2.org/nexus/content/repositories/snapshots/\" }\n            /* WSO2 internal Repository */\n            maven { url \"http://maven.wso2.org/nexus/content/groups/wso2-public/\" }\n\n        }\n    }\n\n    repositories {\n        /* local maven repository */\n        mavenLocal()\n        /* Central Repository */\n        maven { url \"https://repo.maven.apache.org/maven2\" }\n        /* WSO2 Releases Repository */\n        maven { url \"https://maven.wso2.org/nexus/content/repositories/releases/\" }\n        /* WSO2 internal Repository */\n        maven { url \"https://maven.wso2.org/nexus/content/groups/wso2-public/\" }\n        /* Github Package Repository */\n        maven {\n            url 'https://maven.pkg.github.com/ballerina-platform/*'\n            credentials {\n                username System.getenv('packageUser')\n                password System.getenv('packagePAT')\n            }\n        }\n\n    }\n\n    configurations {\n        jbalTools\n        awsLambdaBala\n        awsLambdaExamples\n        azFunctionsBala\n        azFunctionsExamples\n        kubernetesAnnotations\n        kubernetesExamples\n        ballerinaStdLibs\n        ballerinaC2cLibs\n        ballerinaC2cTooling\n        ballerinaTools\n        openapiModule\n        exten {\n            transitive = false\n        }\n        devTools\n        externalTestJars\n    }\n\n    dependencies {\n        jbalTools \"org.ballerinalang:jballerina-tools:${ballerinaLangVersion}@zip\"\n\n        /* Ballerina Dev Tools */\n        devTools \"org.ballerinalang:ballerina-dev-tools:${devToolsVersion}\"\n\n        externalTestJars (group: 'mysql', name: 'mysql-connector-java', version: \"8.0.21\") {\n            transitive = false\n        }\n\n        /* Standard libraries */\n        ballerinaStdLibs \"io.ballerina.lib:data.yaml-ballerina:${stdlibDataYamlVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:data.jsondata-ballerina:${stdlibDataJsonDataVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:data.xmldata-ballerina:${stdlibDataXmldataVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:data.csv-ballerina:${stdlibDataCsvVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:constraint-ballerina:${stdlibConstraintVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:io-ballerina:${stdlibIoVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:jballerina.java.arrays-ballerina:${stdlibJavaArraysVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:random-ballerina:${stdlibRandomVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:time-ballerina:${stdlibTimeVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:url-ballerina:${stdlibUrlVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:xmldata-ballerina:${stdlibXmldataVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:ldap-ballerina:${stdlibLdapVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:crypto-ballerina:${stdlibCryptoVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:log-ballerina:${stdlibLogVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:os-ballerina:${stdlibOsVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:task-ballerina:${stdlibTaskVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:xslt-ballerina:${stdlibXsltVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:protobuf-ballerina:${stdlibProtobufVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:cache-ballerina:${stdlibCacheVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:file-ballerina:${stdlibFileVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:ftp-ballerina:${stdlibFtpVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:mime-ballerina:${stdlibMimeVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:mqtt-ballerina:${stdlibMqttVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:tcp-ballerina:${stdlibTcpVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:udp-ballerina:${stdlibUdpVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:uuid-ballerina:${stdlibUuidVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:auth-ballerina:${stdlibAuthVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:avro-ballerina:${stdlibAvroVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:email-ballerina:${stdlibEmailVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:jwt-ballerina:${stdlibJwtVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:oauth2-ballerina:${stdlibOAuth2Version}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:http-ballerina:${stdlibHttpVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:messaging-ballerina:${stdlibMessagingVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:graphql-ballerina:${stdlibGraphqlVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:grpc-ballerina:${stdlibGrpcVersion}\"\n\n        ballerinaStdLibs \"org.ballerinalang:transaction-ballerina:${stdlibTransactionVersion}\"\n        ballerinaStdLibs \"io.ballerina:observe-ballerina:${observeInternalVersion}\"\n\n        ballerinaStdLibs \"io.ballerina.stdlib:websocket-ballerina:${stdlibWebsocketVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:websub-ballerina:${stdlibWebsubVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:websubhub-ballerina:${stdlibWebsubhubVersion}\"\n        ballerinaStdLibs \"io.ballerina.lib:ai.np-ballerina:${stdlibAiNpVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:ai-ballerina:${stdlibAiVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:mcp-ballerina:${stdlibMcpVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:sql-ballerina:${stdlibSqlVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:persist-ballerina:${stdlibPersistVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:yaml-ballerina:${stdlibYamlVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:toml-ballerina:${stdlibTomlVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:soap-ballerina:${stdlibSoapVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:observe-ballerina:${observeVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:math.vector-ballerina:${stdlibMathVectorVersion}\"\n        ballerinaStdLibs \"io.ballerina.stdlib:edi-ballerina:${stdlibEdiVersion}\"\n\n        /* OpenAPI Module */\n        openapiModule \"io.ballerina:module-ballerina-openapi:${openapiModuleVersion}\"\n\n        /* Code to cloud extensions */\n        ballerinaC2cLibs \"io.ballerina:cloud-ballerina:${c2cVersion}\"\n        ballerinaC2cTooling \"io.ballerina:cloud-tooling:${c2cVersion}\"\n\n        /* Bal tools */\n        ballerinaTools \"io.ballerina:graphql-tool:${graphqlToolVersion}\"\n        ballerinaTools \"io.ballerina:protoc-tool:${protocToolVersion}\"\n        ballerinaTools \"io.ballerina:openapi-tool:${openapiToolVersion}\"\n        ballerinaTools \"io.ballerina:asyncapi-tool:${asyncapiToolVersion}\"\n        ballerinaTools \"io.ballerina:persist-tool:${persistToolVersion}\"\n    }\n}\n"
  },
  {
    "path": "cache-generator/build.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\napply from: \"$rootDir/gradle/javaProject.gradle\"\napply plugin: \"java\"\napply plugin: \"com.github.johnrengelman.shadow\"\n\nconfigurations.all {\n    resolutionStrategy.preferProjectModules()\n}\n\nconfigurations {\n    balTools\n}\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation 'junit:junit:4.13.1'\n    implementation \"com.fasterxml.jackson.core:jackson-databind\"\n    implementation \"io.swagger.core.v3:swagger-models\"\n    implementation (\"io.swagger.parser.v3:swagger-parser-v2-converter\") {\n        exclude group: \"io.swagger\", module: \"swagger-compat-spec-parser\"\n        exclude group: \"org.slf4j\", module: \"slf4j-ext\"\n        exclude group: \"javax.validation\", module: \"validation-api\"\n    }\n\n    implementation \"javax.ws.rs:javax.ws.rs-api\"\n    implementation \"com.github.jknack:handlebars\"\n    implementation \"info.picocli:picocli\"\n    implementation \"org.ballerinalang:ballerina-lang\"\n    implementation \"org.ballerinalang:ballerina-parser\"\n    implementation \"org.ballerinalang:formatter-core\"\n    implementation \"org.ballerinalang:ballerina-cli\"\n    implementation \"org.ballerinalang:ballerina-tools-api\"\n    implementation \"io.ballerina.stdlib:http-native\"\n    implementation \"com.google.code.findbugs:jsr305\"\n    testImplementation \"org.testng:testng\"\n\n    balTools (\"org.ballerinalang:jballerina-tools:${ballerinaLangVersion}\") {\n        transitive = false\n    }\n}\ndef bDistribution = file(\"$project.buildDir/extracted-distribution/jballerina-tools-${ballerinaLangVersion}\")\n\nshadowJar {\n    configurations = [project.configurations.runtimeClasspath]\n    dependencies {\n        include(dependency('com.github.jknack:handlebars'))\n        include(dependency('org.antlr:antlr4:4.5'))\n        include(dependency('io.swagger.parser.v3:swagger-parser'))\n        include(dependency('com.atlassian.commonmark:commonmark'))\n        include(dependency('com.atlassian.commonmark:commonmark-ext-gfm-tables'))\n        exclude('META-INF/*.SF')\n        exclude('META-INF/*.DSA')\n        exclude('META-INF/*.RSA')\n    }\n}\n\ncompileJava {\n    doFirst {\n        options.compilerArgs = [\n                '--module-path', classpath.asPath,\n        ]\n        classpath = files()\n    }\n}\n\n"
  },
  {
    "path": "cache-generator/src/main/java/io/ballerina/gencache/cmd/GenCacheCmd.java",
    "content": "/*\n *  Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\npackage io.ballerina.gencache.cmd;\n\nimport io.ballerina.cli.BLauncherCmd;\nimport io.ballerina.projects.*;\nimport io.ballerina.projects.bala.BalaProject;\nimport io.ballerina.projects.repos.FileSystemCache;\nimport io.ballerina.tools.diagnostics.Diagnostic;\nimport picocli.CommandLine;\n\nimport java.io.PrintStream;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\n\n@CommandLine.Command(\n        name = \"gencache\",\n        description = \"Generates the Ballerina standard library caches\"\n)\n\npublic class GenCacheCmd implements BLauncherCmd{\n    private static final String CMD_NAME = \"gencache\";\n    private PrintStream outStream;\n    private PrintStream errStream;\n    private boolean exitWhenFinish;\n    private static final String BALLERINA_HOME_KEY = \"ballerina.home\";\n    private String balaPath;\n    private String workingDir;\n\n     @CommandLine.Parameters\n     private List<String> argList;\n\n    public GenCacheCmd() {\n        this.outStream = System.out;\n        this.errStream = System.err;\n        this.exitWhenFinish = true;\n    }\n\n    @Override\n    public void execute() {\n        balaPath = argList.get(0);\n        workingDir = argList.get(1);\n\n        if ( balaPath == null || workingDir == null ) {\n            errStream.println(\"missing input options\");\n            exitError(this.exitWhenFinish);\n            return;\n        }\n\n        try {\n            outStream.println(workingDir);\n            outStream.println(balaPath);\n            Path jBalToolsPath = Paths.get( workingDir);\n            Path repo = jBalToolsPath.resolve( \"repo\");\n            Path modulePath = Paths.get(balaPath);\n            System.setProperty(BALLERINA_HOME_KEY, repo.getParent().toString());\n            ProjectEnvironmentBuilder defaultBuilder = ProjectEnvironmentBuilder.getDefaultBuilder();\n            defaultBuilder.addCompilationCacheFactory(new FileSystemCache.FileSystemCacheFactory(repo.resolve(\"cache\")));\n            Project balaProject = BalaProject.loadProject(defaultBuilder, modulePath);\n            PackageCompilation packageCompilation = balaProject.currentPackage().getCompilation();\n            DiagnosticResult diagnosticResult = packageCompilation.diagnosticResult();\n            for (Diagnostic diagnostic : diagnosticResult.diagnostics()) {\n                outStream.println(diagnostic.toString());\n            }\n            if (diagnosticResult.hasErrors()) {\n                return;\n            }\n            JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21);\n            diagnosticResult = jBallerinaBackend.diagnosticResult();\n            for (Diagnostic diagnostic : diagnosticResult.diagnostics()) {\n                outStream.println(diagnostic.toString());\n            }\n            //TODO : Remove when regeneration is not required\n        } catch (Error e) {\n            //TODO : Ignore Error and continue generation as regeneration will be done\n            outStream.println(\"Error occurred \" + balaPath + \" \" + e);\n        } catch (Exception e) {\n            //TODO : Ignore Exception and continue generation as regeneration will be done\n            outStream.println(\"Exception occurred \" + balaPath + \" \" + e);\n        }\n    }\n\n    @Override\n    public String getName() {\n        return CMD_NAME;\n    }\n\n    @Override\n    public void printLongDesc(StringBuilder out) {\n        out.append(\"Build a Ballerina project and produce an executable JAR file. The \\n\");\n        out.append(\"executable \\\".jar\\\" file will be created in the <PROJECT-ROOT>/target/bin directory. \\n\");\n        out.append(\"\\n\");\n        out.append(\"Build a single Ballerina file. This creates an executable .jar file in the \\n\");\n        out.append(\"current directory. The name of the executable file will be \\n\");\n        out.append(\"<ballerina-file-name>.jar. \\n\");\n        out.append(\"\\n\");\n    }\n\n    @Override\n    public void printUsage( StringBuilder out ) {\n        out.append(\"  bal gencache [bala-path] [package-path] \");\n    }\n\n    @Override\n    public void setParentCmdParser( CommandLine parentCmdParser) {\n    }\n\n    private void exitError(boolean exitWhenFinish) {\n        if ( exitWhenFinish ) {\n            Runtime.getRuntime().exit(1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "cache-generator/src/main/java/module-info.java",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nmodule io.ballerina.gencache {\n    requires com.fasterxml.jackson.core;\n    requires com.fasterxml.jackson.databind;\n    requires handlebars;\n    requires info.picocli;\n    requires io.ballerina.lang;\n    requires io.ballerina.parser;\n    requires io.ballerina.stdlib.http;\n    requires io.ballerina.cli;\n    requires io.ballerina.tools.api;\n    requires io.ballerina.formatter.core;\n    requires io.swagger.v3.core;\n    requires io.swagger.v3.oas.models;\n    requires java.ws.rs;\n    requires jsr305;\n    requires org.apache.commons.io;\n    requires org.slf4j;\n    requires swagger.core;\n    requires swagger.parser;\n    requires swagger.models;\n    requires swagger.parser.core;\n    requires swagger.parser.v2.converter;\n    requires swagger.parser.v3;\n    requires org.apache.commons.lang3;\n//    exports io.ballerina.gencache.generators.gencache;\n//    exports io.ballerina.gencache.cmd;\n//    exports io.ballerina.gencache.exception;\n//    exports io.ballerina.gencache.cmd.model;\n//    exports io.ballerina.gencache.cmd.utils;\n}\n\n"
  },
  {
    "path": "cache-generator/src/main/resources/META-INF/services/io.ballerina.cli.BLauncherCmd",
    "content": "io.ballerina.gencache.cmd.GenCacheCmd"
  },
  {
    "path": "config/checkstyle/build.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id \"de.undercouch.download\"\n}\n\ntask downloadMultipleFiles(type: Download) {\n    src([\n            'https://raw.githubusercontent.com/wso2/code-quality-tools/v1.4/checkstyle/jdk-17/checkstyle.xml',\n            'https://raw.githubusercontent.com/wso2/code-quality-tools/v1.4/checkstyle/jdk-17/suppressions.xml'\n    ])\n    overwrite false\n    onlyIfNewer true\n    dest buildDir\n}\n\njar {\n    enabled = false\n}\n\nclean {\n    enabled = false\n}\n\nartifacts.add('default', file(\"${rootDir}/config/checkstyle/checkstyle.xml\")) {\n    builtBy('downloadMultipleFiles')\n}\n\nartifacts.add('default', file(\"${rootDir}/config/checkstyle/suppressions.xml\")) {\n    builtBy('downloadMultipleFiles')\n}\n"
  },
  {
    "path": "config/checkstyle/checkstyle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    # Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n    #\n    # WSO2 Inc. licenses this file to you under the Apache License,\n    # Version 2.0 (the \"License\"); you may not use this file except\n    # in compliance with the License.\n    # You may obtain a copy of the License at\n    #\n    #   http://www.apache.org/licenses/LICENSE-2.0\n    #\n    # Unless required by applicable law or agreed to in writing, software\n    # distributed under the License is distributed on an \"AS IS\" BASIS,\n    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    # See the License for the specific language governing permissions and\n    # limitations under the License.\n-->\n\n<!DOCTYPE module PUBLIC\n        \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\"\n        \"http://www.puppycrawl.com/dtds/configuration_1_3.dtd\">\n\n<!-- This is a checkstyle configuration file. For descriptions of\nwhat the following rules do, please see the checkstyle configuration\npage at http://checkstyle.sourceforge.net/config.html -->\n\n<module name=\"Checker\">\n\n    <property name=\"charset\" value=\"UTF-8\"/>\n\n    <module name=\"FileTabCharacter\">\n        <property name=\"severity\" value=\"error\" />\n        <!-- Checks that there are no tab characters in the file.\n        -->\n    </module>\n\n    <!--\n\n    LENGTH CHECKS FOR FILES\n\n    -->\n\n    <module name=\"FileLength\">\n        <property name=\"max\" value=\"3000\" />\n        <property name=\"severity\" value=\"warning\" />\n    </module>\n\n\n    <module name=\"NewlineAtEndOfFile\">\n        <property name=\"lineSeparator\" value=\"ignore\" />\n    </module>\n\n    <module name=\"RegexpSingleline\">\n        <!-- Checks that FIXME is not used in comments.  TODO is preferred.\n        -->\n        <property name=\"format\" value=\"((//.*)|(\\*.*))FIXME\" />\n        <property name=\"message\" value='TODO is preferred to FIXME.  e.g. \"TODO: (ENG-123) -  Refactor when v2 is released.\"' />\n    </module>\n\n    <module name=\"RegexpSingleline\">\n        <!-- Checks that TODOs are named with some basic formatting. Checks for the following pattern  TODO: (\n        -->\n        <property name=\"format\" value=\"((//.*)|(\\*.*))TODO[^: (]\" />\n        <property name=\"message\" value='All TODOs should be named.  e.g. \"TODO: (ENG-123) - Refactor when v2 is released.\"' />\n    </module>\n\n    <!--<module name=\"JavadocPackage\">-->\n    <!--&lt;!&ndash; Checks that each Java package has a Javadoc file used for\n    commenting.-->\n    <!--Only allows a package-info.java, not package.html. &ndash;&gt;-->\n    <!--<property name=\"severity\" value=\"warning\"/>-->\n    <!--</module>-->\n\n    <!-- All Java AST specific tests live under TreeWalker module. -->\n    <module name=\"TreeWalker\">\n\n        <!--\n\n        IMPORT CHECKS\n\n        -->\n\n        <module name=\"AvoidStarImport\">\n            <property name=\"allowClassImports\" value=\"false\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"RedundantImport\">\n            <!-- Checks for redundant import statements. -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"ImportOrder\">\n            <property name=\"groups\" value=\"*,java,javax\"/>\n            <property name=\"ordered\" value=\"true\"/>\n            <property name=\"separated\" value=\"true\"/>\n            <property name=\"option\" value=\"bottom\"/>\n            <property name=\"sortStaticImportsAlphabetically\" value=\"true\"/>\n        </module>\n\n        <module name=\"IllegalImport\">\n            <property name=\"illegalPkgs\" value=\"junit.framework\" />\n        </module>\n\n        <module name=\"UnusedImports\" />\n\n        <!--\n\n        METHOD LENGTH CHECKS\n\n        -->\n\n        <module name=\"MethodLength\">\n            <property name=\"tokens\" value=\"METHOD_DEF\" />\n            <property name=\"max\" value=\"300\" />\n            <property name=\"countEmpty\" value=\"false\" />\n            <property name=\"severity\" value=\"warning\" />\n        </module>\n\n        <!--\n\n        JAVADOC CHECKS\n\n        -->\n\n        <!-- Checks for Javadoc comments.                     -->\n        <!-- See http://checkstyle.sf.net/config_javadoc.html -->\n        <module name=\"JavadocMethod\">\n            <property name=\"scope\" value=\"protected\" />\n            <property name=\"severity\" value=\"error\" />\n            <property name=\"allowMissingJavadoc\" value=\"true\" />\n            <property name=\"allowMissingParamTags\" value=\"true\" />\n            <property name=\"allowMissingReturnTag\" value=\"true\" />\n            <property name=\"allowMissingThrowsTags\" value=\"true\" />\n            <property name=\"allowThrowsTagsForSubclasses\" value=\"true\" />\n            <property name=\"allowUndeclaredRTE\" value=\"true\" />\n        </module>\n\n        <module name=\"JavadocType\">\n            <property name=\"scope\" value=\"protected\" />\n            <property name=\"severity\" value=\"ignore\" />\n        </module>\n\n        <module name=\"JavadocStyle\">\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <!--\n\n        NAMING CHECKS\n\n        -->\n\n        <!-- Item 38 - Adhere to generally accepted naming conventions -->\n\n        <module name=\"PackageName\">\n            <!-- Validates identifiers for package names against the\n              supplied expression. -->\n            <!-- Here the default checkstyle rule restricts package name parts to\n              seven characters, this is not in line with common practice at Google.\n            -->\n            <property name=\"format\" value=\"^[a-z]+(\\.[a-z][a-z0-9]{1,})*$\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"TypeNameCheck\">\n            <!-- Validates static, final fields against the\n            expression \"^[A-Z][a-zA-Z0-9]*$\". -->\n            <metadata name=\"altname\" value=\"TypeName\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"ConstantNameCheck\">\n            <!-- Validates non-private, static, final fields against the supplied\n            public/package final fields \"^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$\". -->\n            <metadata name=\"altname\" value=\"ConstantName\" />\n            <property name=\"applyToPublic\" value=\"true\" />\n            <property name=\"applyToProtected\" value=\"true\" />\n            <property name=\"applyToPackage\" value=\"true\" />\n            <property name=\"applyToPrivate\" value=\"false\" />\n            <property name=\"format\" value=\"^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$\" />\n            <message key=\"name.invalidPattern\"\n                     value=\"Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise).\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"StaticVariableNameCheck\">\n            <!-- Validates static, non-final fields against the supplied\n            expression \"^[a-z][a-zA-Z0-9]*_?$\". -->\n            <metadata name=\"altname\" value=\"StaticVariableName\" />\n            <property name=\"applyToPublic\" value=\"true\" />\n            <property name=\"applyToProtected\" value=\"true\" />\n            <property name=\"applyToPackage\" value=\"true\" />\n            <property name=\"applyToPrivate\" value=\"true\" />\n            <property name=\"format\" value=\"^[a-z][a-zA-Z0-9]*_?$\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"MemberNameCheck\">\n            <!-- Validates non-static members against the supplied expression. -->\n            <metadata name=\"altname\" value=\"MemberName\" />\n            <property name=\"applyToPublic\" value=\"true\" />\n            <property name=\"applyToProtected\" value=\"true\" />\n            <property name=\"applyToPackage\" value=\"true\" />\n            <property name=\"applyToPrivate\" value=\"true\" />\n            <property name=\"format\" value=\"^[a-z][a-zA-Z0-9]*$\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"MethodNameCheck\">\n            <!-- Validates identifiers for method names. -->\n            <metadata name=\"altname\" value=\"MethodName\" />\n            <property name=\"format\" value=\"^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"ParameterName\">\n            <!-- Validates identifiers for method parameters against the\n              expression \"^[a-z][a-zA-Z0-9]*$\". -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"LocalFinalVariableName\">\n            <!-- Validates identifiers for local final variables against the\n              expression \"^[a-z][a-zA-Z0-9]*$\". -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"LocalVariableName\">\n            <!-- Validates identifiers for local variables against the\n              expression \"^[a-z][a-zA-Z0-9]*$\". -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n\n        <!--\n\n        LENGTH and CODING CHECKS\n\n        -->\n\n        <module name=\"LineLength\">\n            <!-- Checks if a line is too long. -->\n            <property name=\"max\" value=\"120\" default=\"120\" />\n            <property name=\"severity\" value=\"error\" />\n\n            <!--\n              The default ignore pattern exempts the following elements:\n                - import statements\n                - long URLs inside comments\n            -->\n\n            <property name=\"ignorePattern\" value=\"${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}\"\n                      default=\"^(package .*;\\s*)|(import .*;\\s*)|( *\\* *https?://.*)$\" />\n        </module>\n\n        <module name=\"LeftCurly\">\n            <!-- Checks for placement of the left curly brace ('{'). -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"RightCurly\">\n            <!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on\n            the same line. e.g., the following example is fine:\n            <pre>\n              if {\n                ...\n              } else\n            </pre>\n            -->\n            <!-- This next example is not fine:\n            <pre>\n              if {\n                ...\n              }\n              else\n            </pre>\n            -->\n            <property name=\"option\" value=\"same\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <!-- Checks for braces around if and else blocks -->\n        <module name=\"NeedBraces\">\n            <property name=\"severity\" value=\"error\" />\n            <property name=\"tokens\" value=\"LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO\" />\n        </module>\n\n        <module name=\"UpperEll\">\n            <!-- Checks that long constants are defined with an upper ell.-->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"FallThrough\">\n            <!-- Warn about falling through to the next case statement.  Similar to\n            javac -Xlint:fallthrough, but the check is suppressed if a single-line comment\n            on the last non-blank line preceding the fallen-into case contains 'fall through' (or\n            some other variants which we don't publicized to promote consistency).\n            -->\n            <property name=\"reliefPattern\"\n                      value=\"fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n\n        <!--\n\n        MODIFIERS CHECKS\n\n        -->\n\n        <module name=\"ModifierOrder\">\n            <!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and\n                 8.4.3.  The prescribed order is:\n                 public, protected, private, abstract, static, final, transient, volatile,\n                 synchronized, native, strictfp\n              -->\n        </module>\n\n\n        <!--\n\n        WHITESPACE CHECKS\n\n        -->\n        <module name=\"GenericWhitespace\" />\n\n        <module name=\"WhitespaceAround\">\n            <!-- Checks that various tokens are surrounded by whitespace.\n                 This includes most binary operators and keywords followed\n                 by regular or curly braces.\n            -->\n            <property name=\"tokens\"\n                      value=\"ASSIGN, BAND, BAND_ASSIGN, BOR,\n        BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,\n        EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,\n        LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,\n        LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,\n        MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,\n        SL, SLIST, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN\" />\n            <property name=\"allowEmptyConstructors\" value=\"true\" />\n            <property name=\"allowEmptyMethods\" value=\"true\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"WhitespaceAfter\">\n            <!-- Checks that commas, semicolons and typecasts are followed by\n                 whitespace.\n            -->\n            <property name=\"tokens\" value=\"COMMA, SEMI, TYPECAST\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"NoWhitespaceAfter\">\n            <!-- Checks that there is no whitespace after various unary operators.\n                 Linebreaks are allowed.\n            -->\n            <property name=\"tokens\" value=\"BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,\n        UNARY_PLUS\" />\n            <property name=\"allowLineBreaks\" value=\"true\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"NoWhitespaceBefore\">\n            <!-- Checks that there is no whitespace before various unary operators.\n                 Linebreaks are allowed.\n            -->\n            <property name=\"tokens\" value=\"SEMI, DOT, POST_DEC, POST_INC\" />\n            <property name=\"allowLineBreaks\" value=\"true\" />\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <module name=\"ParenPad\">\n            <!-- Checks that there is no whitespace before close parens or after\n                 open parens.\n            -->\n            <property name=\"severity\" value=\"error\" />\n        </module>\n\n        <!-- No System.out -->\n        <module name=\"Regexp\">\n            <property name=\"format\" value=\"System\\.out\\.println\" />\n            <property name=\"illegalPattern\" value=\"true\" />\n        </module>\n\n        <!-- No System.err -->\n        <module name=\"Regexp\">\n            <!-- . matches any character, so we need to escape it and use \\. to match dots. -->\n            <property name=\"format\" value=\"System\\.err\\.println\" />\n            <property name=\"illegalPattern\" value=\"true\" />\n        </module>\n\n        <!-- No printStackTrace -->\n        <module name=\"Regexp\">\n            <!-- . matches any character, so we need to escape it and use \\. to match dots. -->\n            <property name=\"format\" value=\"e\\.printStackTrace\\(\\)\" />\n            <property name=\"illegalPattern\" value=\"true\" />\n        </module>\n\n        <module name=\"SuppressionCommentFilter\">\n            <property name=\"offCommentFormat\" value=\"CHECKSTYLE OFF: (.+)\"/>\n            <property name=\"onCommentFormat\" value=\"CHECKSTYLE ON\"/>\n            <property name=\"checkFormat\" value=\"Javadoc.*\"/>\n            <property name=\"messageFormat\" value=\"$1\"/>\n        </module>\n\n    </module>\n\n</module>\n"
  },
  {
    "path": "config/checkstyle/suppressions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    # Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n    #\n    # WSO2 Inc. licenses this file to you under the Apache License,\n    # Version 2.0 (the \"License\"); you may not use this file except\n    # in compliance with the License.\n    # You may obtain a copy of the License at\n    #\n    #   http://www.apache.org/licenses/LICENSE-2.0\n    #\n    # Unless required by applicable law or agreed to in writing, software\n    # distributed under the License is distributed on an \"AS IS\" BASIS,\n    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    # See the License for the specific language governing permissions and\n    # limitations under the License.\n-->\n\n<!DOCTYPE suppressions PUBLIC\n        \"-//Puppy Crawl//DTD Suppressions 1.1//EN\"\n        \"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd\">\n\n<suppressions>\n\n    <suppress checks=\"Javadoc.*\" files=\".*/src/test/java/.*\" />\n\n    <suppress checks=\"JavadocPackage\" files=\".*/src/(main|integration)/java/.*\" />\n    <suppress checks=\"JavadocPackage\" files=\".*/src/.*/internal/.*\" />\n\n    <suppress checks=\"JavadocStyle\" files=\".*/src/(main|integration)/java/.*\" />\n    <suppress checks=\"JavadocStyle\" files=\".*/src/.*/internal/.*\" />\n\n    <suppress checks=\"MethodNameCheck\" files=\".*/*CommandProvider.java\" />\n    <suppress checks=\"Regexp\" files=\".*/*CommandProvider.java\" />\n\n\n    <!-- copied from apache hadoop, won't fix style to keep diff minimal -->\n    <suppress checks=\".*\" files=\".*/LocalJobRunnerWithFix.java\" />\n\n    <!-- do not check thrift generated files -->\n    <suppress checks=\".*\" files=\".*/transaction/distributed/thrift/.*\" />\n\n    <!-- do not check swagger generated files -->\n    <suppress checks=\".*\" files=\".*/src/gen/java/.*\" />\n\n</suppressions>\n"
  },
  {
    "path": "devtools-integration-tests/build.gradle",
    "content": " /*\n  ~ * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~ *\n  ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ * you may not use this file except in compliance with the License.\n  ~ * You may obtain a copy of the License at\n  ~ *\n  ~ * http://www.apache.org/licenses/LICENSE-2.0\n  ~ *\n  ~ * Unless required by applicable law or agreed to in writing, software\n  ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ * See the License for the specific language governing permissions and\n  ~ * limitations under the License.\n  ~ */\n  \ndescription = 'Ballerina - Dev Tools Test'\n\nconfigurations {\n    jBallerinaDistribution\n    ballerinaDistribution\n    ballerinaLinuxDistribution\n    ballerinaMacDistribution\n    ballerinaWindowsDistribution\n}\n\ndependencies {\n    testImplementation \"org.testng:testng:${testngVersion}\"\n    testImplementation \"net.lingala.zip4j:zip4j:${netLingalaZip4jVersion}\"\n    testImplementation \"commons-io:commons-io:${commonsIoVersion}\"\n    testImplementation \"org.apache.commons:commons-lang3:${commonsLang3Version}\"\n    testImplementation \"org.ballerinalang:jballerina-debugger-integration-test:${ballerinaLangVersion}\"\n    testImplementation \"org.ballerinalang:ballerina-test-utils:${ballerinaLangVersion}\"\n    testImplementation \"org.eclipse.lsp4j:org.eclipse.lsp4j.debug:${lsp4jDebugVersion}\"\n\n    jBallerinaDistribution project(path: \":ballerina\", configuration: \"jBallerinaDistribution\")\n    ballerinaDistribution project(path: \":ballerina\", configuration: \"ballerinaDistribution\")\n    ballerinaLinuxDistribution project(path: \":ballerina\", configuration: \"ballerinaLinuxDistribution\")\n    ballerinaMacDistribution project(path: \":ballerina\", configuration: \"ballerinaMacDistribution\")\n    ballerinaWindowsDistribution project(path: \":ballerina\", configuration: \"ballerinaWindowsDistribution\")\n}\n\ntask devToolsIntegrationTest {\n    dependsOn configurations.jBallerinaDistribution\n    dependsOn configurations.ballerinaDistribution\n    dependsOn configurations.ballerinaLinuxDistribution\n    dependsOn configurations.ballerinaLinuxDistribution\n    dependsOn configurations.ballerinaWindowsDistribution\n    test {\n        systemProperty \"distributions.dir\", \"$buildDir/../../ballerina/build/distributions\"\n        systemProperty \"target.dir\", \"$buildDir\"\n        systemProperty \"maven.version\", \"$version\"\n        systemProperty \"examples.dir\", \"$buildDir/../../examples\"\n        systemProperty \"line.check.extensions\", \".java, .bal\"\n        systemProperty \"short.version\", \"$version\".split(\"-\")[0]\n        systemProperty \"server.zip\", \"$buildDir/../../ballerina/build/distributions/ballerina-${shortVersion}.zip\"\n        systemProperty \"code.name\", \"$codeName\"\n\n        useTestNG() {\n            suites 'src/test/resources/testng.xml'\n        }\n        testLogging {\n            showStandardStreams = true\n        }\n    }\n}\n\ntest.dependsOn devToolsIntegrationTest\n"
  },
  {
    "path": "devtools-integration-tests/index.json",
    "content": "[\n    {\n        \"name\": \"Testerina Object mocking test\",\n        \"path\": \"testerina-object-mocking-test\"\n    } \n]\n"
  },
  {
    "path": "devtools-integration-tests/src/test/java/org/ballerina/devtools/debug/BaseTestCase.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.ballerina.devtools.debug;\n\nimport org.ballerinalang.debugger.test.utils.DebugTestRunner;\nimport org.ballerinalang.test.context.BallerinaTestException;\nimport org.testng.annotations.AfterSuite;\nimport org.testng.annotations.BeforeSuite;\n\nimport java.io.IOException;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\n\n/**\n * Parent test class for all debug integration test cases.\n */\npublic class BaseTestCase {\n\n    @BeforeSuite(alwaysRun = true)\n    public void initialize() throws BallerinaTestException, IOException {\n        Path projectResourcePath = Paths.get(\"src\", \"test\", \"resources\", \"debug\", \"project-based-tests\").toAbsolutePath();\n        Path singleFileResourcePath = Paths.get(\"src\", \"test\", \"resources\", \"debug\", \"single-file-tests\").toAbsolutePath();\n        DebugTestRunner.initialize(projectResourcePath, singleFileResourcePath);\n    }\n\n    @AfterSuite(alwaysRun = true)\n    public void destroy() {\n        DebugTestRunner.destroy();\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/java/org/ballerina/devtools/debug/ExpressionEvaluationTest.java",
    "content": "/*\n * Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.devtools.debug;\n\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.ballerinalang.debugger.test.utils.BallerinaTestDebugPoint;\nimport org.ballerinalang.debugger.test.utils.DebugTestRunner;\nimport org.ballerinalang.debugger.test.utils.DebugUtils;\nimport org.ballerinalang.test.context.BallerinaTestException;\nimport org.eclipse.lsp4j.debug.StoppedEventArguments;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.nio.file.Paths;\n\n/**\n * Test class for expression evaluation related scenarios.\n */\npublic class ExpressionEvaluationTest extends BaseTestCase {\n\n    private DebugTestRunner debugTestRunner;\n    private StoppedEventArguments context;\n\n    @BeforeClass\n    public void setup() throws BallerinaTestException {\n        prepareForEvaluation();\n    }\n\n    @Test(description = \"Test Ballerina standard library related remote method call evaluations\", enabled = false)\n    public void testRemoteCallEvaluation() throws BallerinaTestException {\n        debugTestRunner.assertExpression(context, \"httpClient->get(\\\"/args/ballerina-platform/repos\\\");\", \"Not Found\",\n                \"error\");\n    }\n\n    @Test(description = \"Test Ballerina standard library related object methods evaluations\")\n    public void testObjectMethodEvaluation() throws BallerinaTestException {\n        debugTestRunner.assertExpression(context, \"response.getContentType()\", \"\\\"application/json; charset=utf-8\\\"\",\n                \"string\");\n        debugTestRunner.assertExpression(context, \"response.getTextPayload()\", \"\\\"{\\\"message\\\":\\\"Not Found\\\",\" +\n                \"\\\"documentation_url\\\":\\\"https://docs.github.com/rest\\\"}\\\"\", \"string\");\n    }\n\n    @AfterClass(alwaysRun = true)\n    public void cleanUp() {\n        debugTestRunner.terminateDebugSession();\n        this.context = null;\n    }\n\n    protected void prepareForEvaluation() throws BallerinaTestException {\n        String testProjectName = \"evaluation-tests\";\n        String testModuleFileName = Paths.get(\"main.bal\").toString();\n        debugTestRunner = new DebugTestRunner(testProjectName, testModuleFileName, true);\n\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 24));\n        debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN);\n        Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(35000);\n        this.context = debugHitInfo.getRight();\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/java/org/ballerina/devtools/debug/ModuleBreakpointTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.ballerina.devtools.debug;\n\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.ballerinalang.debugger.test.utils.BallerinaTestDebugPoint;\nimport org.ballerinalang.debugger.test.utils.DebugTestRunner;\nimport org.ballerinalang.debugger.test.utils.DebugUtils;\nimport org.ballerinalang.test.context.BallerinaTestException;\nimport org.eclipse.lsp4j.debug.StoppedEventArguments;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterMethod;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport static org.ballerinalang.debugger.test.utils.DebugTestRunner.DebugResumeKind;\n\n/**\n * Test class for ballerina breakpoints related test scenarios.\n */\npublic class ModuleBreakpointTest extends BaseTestCase {\n\n    DebugTestRunner debugTestRunner;\n\n    @BeforeClass\n    public void setup() {\n        String testProjectName = \"breakpoint-tests\";\n        String testModuleFileName = \"main.bal\";\n        debugTestRunner = new DebugTestRunner(testProjectName, testModuleFileName, true);\n    }\n\n    @Test\n    public void testMultipleBreakpointsInSameFile() throws BallerinaTestException {\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 20));\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 26));\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 30));\n        debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN);\n\n        Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(25000);\n        Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(0));\n\n        debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugResumeKind.NEXT_BREAKPOINT);\n        debugHitInfo = debugTestRunner.waitForDebugHit(10000);\n        Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(1));\n\n        debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugResumeKind.NEXT_BREAKPOINT);\n        debugHitInfo = debugTestRunner.waitForDebugHit(10000);\n        Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(2));\n    }\n\n    @AfterMethod(alwaysRun = true)\n    public void cleanUp() {\n        debugTestRunner.terminateDebugSession();\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/java/org/ballerina/devtools/debug/ServiceDebugTest.java",
    "content": "/*\n * Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.devtools.debug;\n\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.ballerinalang.debugger.test.utils.BallerinaTestDebugPoint;\nimport org.ballerinalang.debugger.test.utils.DebugTestRunner;\nimport org.ballerinalang.debugger.test.utils.DebugUtils;\nimport org.ballerinalang.test.context.BallerinaTestException;\nimport org.eclipse.lsp4j.debug.StackFrame;\nimport org.eclipse.lsp4j.debug.StoppedEventArguments;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterMethod;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\n\n/**\n * Test class for service related debug scenarios.\n */\npublic class ServiceDebugTest extends BaseTestCase {\n\n    DebugTestRunner debugTestRunner;\n\n    @BeforeClass\n    public void setup() {\n        String testProjectName = \"service-tests\";\n        String testModuleFileName = Paths.get(\"tests\", \"hello_service_test.bal\").toString();\n        debugTestRunner = new DebugTestRunner(testProjectName, testModuleFileName, true);\n    }\n\n    @Test(description = \"Test for service module debug engage\")\n    public void testModuleServiceDebugScenarios() throws BallerinaTestException {\n        String fileName = \"hello_service.bal\";\n        Path filePath = debugTestRunner.testProjectPath.resolve(fileName);\n\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 23));\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 28));\n        debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.TEST);\n\n        // test for debug hits in service level variables\n        Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(30000);\n        Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(0));\n\n        // Timeout Exception is expected, since the service get started once the VM is resumed and resource\n        // function cannot have any debug hits until an HTTP request is received.\n        debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.NEXT_BREAKPOINT);\n        try {\n            debugTestRunner.waitForDebugHit(10000);\n        } catch (BallerinaTestException e) {\n            if (!e.getMessage().equals(\"Timeout expired waiting for the debug hit\")) {\n                throw e;\n            }\n        }\n    }\n\n    @Test(description = \"Test for service call stack representation\")\n    public void serviceCallStackDebugTest() throws BallerinaTestException {\n        String fileName = \"hello_service.bal\";\n        Path filePath = debugTestRunner.testProjectPath.resolve(fileName);\n\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(filePath, 23));\n        debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.TEST);\n\n        // Test for service call stack representation\n        Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(30000);\n        StackFrame[] frames = debugTestRunner.fetchStackFrames(debugHitInfo.getRight());\n        debugTestRunner.assertCallStack(frames[0], \"init\", 23, \"hello_service.bal\");\n    }\n\n    @Test(description = \"Test for single bal file debug engage\")\n    public void testSingleBalFileServiceDebugScenarios() throws BallerinaTestException {\n        String testProjectName = \"\";\n        String testSingleFileName = \"hello_service.bal\";\n        debugTestRunner = new DebugTestRunner(testProjectName, testSingleFileName, false);\n\n        debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(debugTestRunner.testEntryFilePath, 24));\n        debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.TEST);\n\n        Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(30000);\n        Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(0));\n    }\n\n    @AfterMethod(alwaysRun = true)\n    public void cleanUp() {\n        debugTestRunner.terminateDebugSession();\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/breakpoint-tests/Ballerina.toml",
    "content": "[package]\norg = \"debug_test_resources\"\nname = \"breakpoint_tests\"\nversion = \"0.1.0\"\n\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/breakpoint-tests/main.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\n\npublic function main() {\n    io:println(\"Hello Ballerina!!!\");\n    sayHello();\n    int x = intAdd(4, 5);\n}\n\npublic function sayHello() {\n    io:println(\"Hello\");\n}\n\npublic function intAdd(int a, int b) returns int {\n    return (a + b);\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/evaluation-tests/Ballerina.toml",
    "content": "[package]\norg = \"debug_test_resources\"\nname = \"evaluation_tests\"\nversion = \"0.1.0\"\n\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/evaluation-tests/main.bal",
    "content": "// Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/http;\n\npublic function main() {\n    do {\n        http:Client httpClient = check new (\"https://api.github.com\");\n        http:Response response = check httpClient->get(\"/args/ballerina-platform/repos\");\n        io:println(response.statusCode);\n    } on fail var e {\n        io:print(e);\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/service-tests/Ballerina.toml",
    "content": "[package]\norg = \"debug_test_resources\"\nname = \"service_tests\"\nversion = \"0.1.0\"\n\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/service-tests/hello_service.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\n\nservice / on new http:Listener(9191) {\n    final int x;\n\n    function init() {\n        self.x = 5;\n    }\n\n    resource function get sayHello() returns string {\n        return \"Hello, World!\";\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/project-based-tests/service-tests/tests/hello_service_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/test;\nimport ballerina/io;\nimport ballerina/http;\n\n# Before Suite Function\n@test:BeforeSuite\nfunction beforeSuiteServiceFunc () {\n    io:println(\"This will test if a service start during testing\");\n}\n\n# Test function\n@test:Config{}\nfunction testServiceFunction ()  {\n    http:Client httpClient = checkpanic new(\"http://localhost:9191\");\n    http:Response|error response = httpClient->get(\"/sayHello\");\n    if (response is http:Response) {\n        test:assertEquals(response.getTextPayload(), \"Hello, World!\", \"Service involation test\");\n    } else {\n        test:assertFail(\"Service invocation failed!\");\n    }\n}\n\n# After Suite Function\n@test:AfterSuite {}\nfunction afterSuiteServiceFunc () {\n    io:println(\"Service should stop after this.\");\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/debug/single-file-tests/hello_service.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/test;\n\nservice on new http:Listener(9090) {\n    resource function get sayHello(http:Caller caller, http:Request req) returns error? {\n            check caller->respond(\"Hello, World!\");\n    }\n}\n\n# Test function\n@test:Config{}\nfunction testServiceFunction ()  {\n    http:Client httpClient = checkpanic new(\"http://localhost:9090\");\n    http:Response|error response = httpClient->get(\"/sayHello\");\n    if (response is http:Response) {\n        test:assertEquals(response.getTextPayload(), \"Hello, World!\", \"Service involation test\");\n    } else {\n        test:assertFail(\"Service invocation failed!\");\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n ~ Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~      http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Ballerina-Dev-Tools-Test-Suite\">\n    <test name=\"ballerina-dev-tools-tests\" parallel=\"false\">\n        <classes>\n            <class name=\"org.ballerina.devtools.debug.ModuleBreakpointTest\"/>\n            <class name=\"org.ballerina.devtools.debug.ServiceDebugTest\"/>\n        </classes>\n    </test>\n</suite>\n"
  },
  {
    "path": "devtools-integration-tests/testerina-object-mocking-test/client.bal",
    "content": "import ballerina/http;\n\nhttp:Client orderManagementClient = checkpanic new (\"http://localhost:9117/ordermgt\");\n\njson responsePayload = {};\n\npublic function findOrder(string orderId) returns (json) {\n    http:Response|error response = orderManagementClient->get(\"/order/\" + orderId);\n\n    if (response is http:Response) {\n        return handleResponse(response);\n    } else {\n        return {\"Error\": \"Server error\"};\n    }\n}\n\npublic function addOrder(json orderPayload) returns (json) {\n\n    json|error IDJson = orderPayload.Order.ID;\n    if (IDJson is json) {\n        string ID = IDJson.toString();\n        json foundOrder = findOrder(ID);\n        if (foundOrder == {\"Error\": \"Order : \" + ID + \" cannot be found.\"}) {\n            http:Response|error response = orderManagementClient->post(\"/order\", orderPayload);\n            if (response is http:Response) {\n                return handleResponse(response);\n            } else {\n                return \"Server error\";\n            }\n        } else {\n            return \"Order with same ID already exists\";\n        }\n    } else {\n        return \"Server error\";\n    }\n}\n\nfunction handleResponse(http:Response response) returns (json) {\n    var jsonPayload = response.getJsonPayload();\n\n    if (jsonPayload is json) {\n        return <@untainted>jsonPayload;\n    } else {\n        return {\"Error\": \"Malformed Payload recieved\"};\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/testerina-object-mocking-test/service.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\n\nlistener http:Listener httpListener = new(9117);\n\nmap<json> ordersMap = {};\n\nservice /ordermgt on httpListener {\n\n    resource function get 'order/[string orderId](http:Caller caller, http:Request req) {\n        json? payload = ordersMap[orderId];\n        http:Response response = new;\n        if (payload == null) {\n            payload = { \"Error\" : \"Order : \" + orderId + \" cannot be found.\" };\n        }\n\n        response.setJsonPayload(<@untainted> payload);\n\n        var result = caller->respond(response);\n        if (result is error) {\n            log:printError(\"Error sending response\");\n        }\n    }\n\n    resource function post 'order(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        var orderReq = req.getJsonPayload();\n        if (orderReq is json) {\n            json|error orderIdJson = orderReq.Order.ID;\n            string orderId = \"\";\n\n            if (orderIdJson is json) {\n                orderId = orderIdJson.toString();\n            } else {\n                log:printError(\"Error sending response\");\n            }\n\n            ordersMap[orderId] = <@untainted> orderReq;\n\n            json payload = { status: \"Order Created.\", orderId: orderId };\n            response.setJsonPayload(payload);\n\n            response.statusCode = 201;\n\n            response.setHeader(\"Location\",\n                \"http://localhost:9117/ordermgt/order/\" + orderId);\n\n            var result = caller->respond(response);\n            if (result is error) {\n                log:printError(\"Error sending response\");\n            }\n        } else {\n            response.statusCode = 400;\n            response.setPayload(\"Invalid payload received\");\n            var result = caller->respond(response);\n            if (result is error) {\n                log:printError(\"Error sending response\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "devtools-integration-tests/testerina-object-mocking-test/tests/main_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\npublic client class MockHttpClient {\n    public string url = \"http://mockUrl\";\n\n     remote function get(@untainted string path, http:RequestMessage message = (),\n        http:TargetType targetType = http:Response) returns http:Response | anydata |http:ClientError {\n            http:Response res = new;\n            res.statusCode = 500;\n            return res;\n    }\n\n     remote function post(@untainted string path, http:RequestMessage message = (),\n        http:TargetType targetType = http:Response) returns http:Response|anydata|http:ClientError {\n            http:Response res = new;\n            res.statusCode = 500;\n            return res;\n    }\n}\n\n@test:Config {}\nfunction test_addOrderWithoutMock() {\n    json orderPayload = {\n        \"Order\": {\n            \"ID\": \"100500\",\n            \"Name\": \"XYZ\",\n            \"Description\": \"Sample order.\"\n        }\n    };\n\n    json actual = addOrder(orderPayload);\n    json expected = {\"status\":\"Order Created.\",\"orderId\":\"100500\"};\n\n    test:assertEquals(actual, expected, \"Add order test failed\");\n\n}\n\n@test:Config { dependsOn: [test_addOrderWithoutMock]}\nfunction test_addOrderAgain() {\n     json orderPayload = {\n        \"Order\": {\n            \"ID\": \"100500\",\n            \"Name\": \"XYZ\",\n            \"Description\": \"Sample order.\"\n        }\n    };\n\n    json actual = addOrder(orderPayload);\n    json expected = \"Order with same ID already exists\";\n\n    test:assertEquals(actual, expected, \"Add order test failed\");\n}\n\n// Create mock http client\nhttp:Client mockHttpClient = <http:Client> test:mock(http:Client);\n\njson getResponse1 = {\n    \"Order\": {\n        \"ID\": \"100\",\n        \"Name\": \"MOCK\",\n        \"Description\": \"Mock Order.\"\n    }\n};\n\njson getResponse2 = { \"Error\" : \"Order : 200 cannot be found.\" };\n\n@test:Config { dependsOn: [test_addOrderWithoutMock]}\nfunction test_findOrder() {\n\n    // Create a Specific response for get\n    http:Response mockGetResponse = new;\n    mockGetResponse.setJsonPayload(<@untainted> getResponse1);\n    test:prepare(mockHttpClient).when(\"get\").thenReturn(mockGetResponse);\n\n    mockGetResponse = new;\n    mockGetResponse.setJsonPayload(<@untainted> getResponse2);\n    test:prepare(mockHttpClient).when(\"get\").withArguments(\"/order/200\").thenReturn(mockGetResponse);\n\n    orderManagementClient = mockHttpClient;\n\n    // Try to find a non existing order\n    json actual = findOrder(\"100\");\n    json expected = getResponse1;\n    test:assertEquals(actual, expected, \"Correct mocked response not recieved\");\n\n    actual = findOrder(\"200\");\n    expected = getResponse2;\n    test:assertEquals(actual, expected, \"Correct mocked response not recieved\");\n\n}\n\n\njson postPayload = {\n    \"Order\": {\n        \"ID\": \"200\",\n        \"Name\": \"MOCK\",\n        \"Description\": \"Mock Order.\"\n    }\n};\n\njson postResponse1 = {\n    status : \"Order Created.\",\n    orderId : \"200\"\n};\n\n@test:Config {\n    dependsOn : [test_findOrder]\n}\nfunction test_addOrder() {\n    http:Response mockPostResponse = new;\n    mockPostResponse.setJsonPayload(<@untainted> postResponse1);\n    test:prepare(mockHttpClient).when(\"post\").withArguments(\"/order\", postPayload).thenReturn(mockPostResponse);\n\n    json actual = addOrder(postPayload);\n    json expected = postResponse1;\n    test:assertEquals(actual, expected, \"Correct mocked response not recieved\");\n}\n"
  },
  {
    "path": "dist-repo-builder/build.gradle",
    "content": "plugins {\n    id 'java'\n}\n\ngroup 'org.ballerinalang'\nversion '1.0.0'\n\ndependencies {\n    implementation \"org.ballerinalang:docerina:${ballerinaLangVersion}\"\n    implementation \"org.ballerinalang:ballerina-lang:${ballerinaLangVersion}\"\n\n}\n\n"
  },
  {
    "path": "dist-repo-builder/src/main/java/io/ballerina/dist/DistRepoBuilder.java",
    "content": "/*\n *  Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n *  WSO2 Inc. licenses this file to you under the Apache License,\n *  Version 2.0 (the \"License\"); you may not use this file except\n *  in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing,\n *  software distributed under the License is distributed on an\n *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n *  KIND, either express or implied.  See the License for the\n *  specific language governing permissions and limitations\n *  under the License.\n */\npackage io.ballerina.dist;\n\nimport io.ballerina.projects.ProjectEnvironmentBuilder;\nimport io.ballerina.projects.bala.BalaProject;\nimport io.ballerina.projects.repos.TempDirCompilationCache;\nimport org.ballerinalang.docgen.docs.BallerinaDocGenerator;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystems;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.PathMatcher;\nimport java.nio.file.Paths;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Utility class to build and populate distribution cache.\n *\n * @since 2.0.0\n */\npublic class DistRepoBuilder {\n\n    final static String balaGlob = \"glob:**/bala.json\";\n    final static String jarGlob = \"glob:**/*.jar\";\n    final static String docGlob = \"glob:**/api-docs.json\";\n    final static String MODULE_BALLERINAI_OBSERVE = \"ballerinai\" + File.separator +\"observe\";\n    final static String OS = System.getProperty(\"os.name\");\n\n    public static void main(String args[]) throws Exception {\n        System.out.println(\"Building Distribution Repo ...\");\n        if (args.length != 1) {\n            System.out.println(\"Invalid Inputs\");\n            System.exit(1);\n        }\n        Path jBalToolsPath = Paths.get(args[0]);\n        Path repo = jBalToolsPath.resolve(\"repo\");\n        System.setProperty(\"ballerina.home\", jBalToolsPath.toString());\n\n        // Find all bala files\n        List<Path> balas = findBalas(repo.resolve(\"bala\"));\n        // Extract platform libs\n        boolean valid = true;\n        // The following list will contain existing docs from ballerina-lang repo\n        List<Path> existingDocs = getExistingDocs(jBalToolsPath.resolve(\"docs\"));\n        for (Path bala : balas) {\n            // skipping in windows since character length of path is greater than maximum in windows\n            if (OS.contains(\"Windows\")) {\n                continue;\n            }\n\n            // skipping ballerinai-observe module since API docs are not generated for internal modules\n            if (bala.toString().contains(MODULE_BALLERINAI_OBSERVE)) {\n                continue;\n            }\n            generateDocsFromBala(bala, jBalToolsPath, existingDocs);\n            // following function was put in to validate if bir and jar exists for packed balas\n            valid = valid & validateCache(bala, repo);\n        }\n        if (!valid) {\n            System.exit(1);\n        }\n    }\n\n    private static List<Path> getExistingDocs(Path jBalToolsDocPath) throws IOException {\n        List<Path> existingDocs = new ArrayList<>();\n        final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(docGlob);\n        Files.walkFileTree(jBalToolsDocPath, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {\n                if (pathMatcher.matches(path)) {\n                    Path relativePath = jBalToolsDocPath.relativize(path.getParent());\n                    if (!relativePath.toString().equals(\"\")) {\n                        existingDocs.add(jBalToolsDocPath.relativize(path.getParent()));\n                    }\n                }\n                return FileVisitResult.CONTINUE;\n            }\n\n            @Override\n            public FileVisitResult visitFileFailed(Path file, IOException exc)\n                    throws IOException {\n                return FileVisitResult.CONTINUE;\n            }\n        });\n        return existingDocs;\n    }\n\n    private static void generateDocsFromBala(Path balaPath, Path jBalToolsPath, List<Path> existingDocs) throws Exception {\n        if (existingDocs.stream().noneMatch(path -> balaPath.toString().contains(path.toString()))) {\n            try {\n                ProjectEnvironmentBuilder defaultBuilder = ProjectEnvironmentBuilder.getDefaultBuilder();\n                defaultBuilder.addCompilationCacheFactory(TempDirCompilationCache::from);\n                BalaProject balaProject = BalaProject.loadProject(defaultBuilder, balaPath);\n                BallerinaDocGenerator.generateAPIDocs(balaProject, jBalToolsPath.toString() + \"/docs\", true);\n            } catch (Exception e) {\n                e.printStackTrace();\n                throw new Exception(\"Exception when generating docs from bala: \" + balaPath.toString());\n            }\n        }\n    }\n\n    private static boolean validateCache(Path bala, Path repo) {\n        boolean valid = true;\n        String version = bala.getParent().getFileName().toString();\n        String moduleName = bala.getParent().getParent().getFileName().toString();\n        String orgName = bala.getParent().getParent().getParent().getFileName().toString();\n\n        // Check if the bir exists\n        Path bir = repo.resolve(\"cache\").resolve(orgName).resolve(moduleName).resolve(version).resolve(\"bir\")\n                .resolve(moduleName + \".bir\");\n        if (!Files.exists(bir)) {\n            System.out.println(\"Bir missing for package :\" + orgName + \"/\" + moduleName);\n            valid = false;\n        }\n        // Check if module jar exists\n        Path jar = repo.resolve(\"cache\").resolve(orgName).resolve(moduleName).resolve(version).resolve(\"java21\")\n                .resolve(getJarName(orgName, moduleName, version));\n        if (!Files.exists(jar)) {\n            System.out.println(\"Jar missing for package :\" + orgName + \"/\" + moduleName);\n            valid = false;\n        }\n        return valid;\n    }\n\n    static List<Path> findBalas(Path repo) throws IOException {\n        List<Path> balas = new ArrayList<>();\n        final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(balaGlob);\n        Files.walkFileTree(repo, new SimpleFileVisitor<Path>() {\n            @Override\n            public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {\n                if (pathMatcher.matches(path)\n                        && Files.notExists(path.getParent().resolve(\"tool/bal-tool.json\"))) {\n                    balas.add(path.getParent());\n                }\n                return FileVisitResult.CONTINUE;\n            }\n\n            @Override\n            public FileVisitResult visitFileFailed(Path file, IOException exc)\n                    throws IOException {\n                return FileVisitResult.CONTINUE;\n            }\n        });\n        return balas;\n    }\n\n    private static String getJarName(String orgName, String moduleName, String version) {\n        return orgName + '-' + moduleName + '-' + version + \".jar\";\n    }\n\n    private static void setFilePermission(Path filepath) {\n        File file = filepath.toFile();\n        file.setReadable(true, false);\n        file.setWritable(true, true);\n    }\n\n    private static boolean isWindows() {\n        return System.getProperty(\"os.name\").startsWith(\"Windows\");\n    }\n}\n"
  },
  {
    "path": "doc-guidelines.md",
    "content": "# Ballerina Doc Guidelines\n\n- [Ballerina Documentation Components](#ballerina-documentation-components)\n- [Ballerina By Examples Guidelines](#ballerina-by-examples-guidelines)\n- [Ballerina API Documentation Guidelines](#ballerina-api-documentation-guidelines)\n\n## Ballerina Documentation Components\n\nBallerina language documentation consists of the main components below.\n\n- [Ballerina By Examples](https://ballerina.io/learn/by-example/) - play the role of a quick reference example for language features,libraries, and extensions that are used frequently. It can be thought of as a cut-down version of the User Guide, which tries to introduce the features with quick examples to get an in-depth but practical understanding of a feature.\n- [User Guide](https://ballerina.io/learn/) - provides detailed explanations on how a specific feature will work along with some comprehensive examples. It will not necessarily cover all the APIs that are available (that will be covered in API Docs). For example, when considering the I/O APIs, it will not be feasible to cover all the I/O types and operations supported by them.\n- [API Docs](https://ballerina.io/learn/api-docs/ballerina/) - include all the possible options and parameter information that are relevant when using an API along with suitable examples. \n\nTherefore, the combination of the Ballerina By Examples, User Guide, and API Docs represent the complete knowledge required for a Ballerina developer. There will be an overlap of content between these. For example, the User Guide has examples and functionality details to explain language-level features. \n\nThe below is a list of guidelines that must be followed when updating and adding new BBEs and API Docs.\n\n## Ballerina By Examples Guidelines\n\n1. Make the BBEs small, simple, and straight forward. Do not create examples with large lines of code. Otherwise, it will require to scroll through a large example to understand the use case. \n\n2. Create realistic examples whenever possible. Make sure the example, which explains some feature shows a practical scenario when it can be used. However, sometimes, it may not be possible to create a small-enough practical scenario. It will be required to use your judgement to decide that. \n\n3. Each new BBE should have its own directory named after it. The directory name should be in all lowercase letters. Use hyphens (`-`) in the directory names (e.g., `hello-world`) and underscores (`_`) in the file names (e.g., `hello_world.bal`).\n\n>**Note:** The first letter of every word in the title of the BBE should be uppercase. Never capitalize prepositions and conjunctions of four or fewer letters. Words with five or more letters, regardless of whether the word is a conjunction or preposition, must be capitalized.\n\n4. If a new example is added/deleted, update the `index.json` file as well.\n\n    >**Info:** Individual BBEs can be configured to disable the playground link generation and to override the default GitHub edit URL by setting the `disablePlayground` and `githubLink` properties accordignly in the `index.json` file. \n\n    For example,\n\n    ```json\n    {\n    \t\"title\": \"Ballerina Basics\",\n    \t\"column\": 0,\n    \t\"category\": \"Language concepts\",\n    \t\"samples\": [\n        \t{\n            \t\"name\": \"Functions\",\n            \t\"url\": \"functions\",\n            \t\"githubLink\": \"https://github.com/ballerina-platform/ballerina-lang/tree/ballerina-1.2.x/examples/functions/\",\n            \t\"disablePlayground\": true\n        \t}\n    \t]\n    }\n    ```\n\n5. Each new example should contain at least the following files.\n\n    - `.bal` - sample code to display in the Ballerina website.\n    - `.description` - sample description displayed at the top of each example in the Ballerina website. The name should be the same as the name of the directory with hyphens replaced by underscores.\n    - `.out` - output of the sample displayed at the bottom inside a black colour box in in the Ballerina website. The output file for a particular `.bal` file should have the same name as the `.bal` file but with the `.out` extension.\n    - `_test.bal` - Contains the test to validate the output of the BBE during the build time. \n\n        For example,\n\n        <img src=\"/images/bbe-folder-structure.png\" alt=\"BBE folder structure\" width=\"250\" height=\"150\">\n    - `.metatags` - Contains the meta description and keywords to build SEO in the webpage. The description should be 50-160 characters long, and there should be 3-5 keywords that are comma-separated.\n    \n        For example,\n        \n        [Hello World BBE .metatags file](https://github.com/ballerina-platform/ballerina-distribution/blob/master/examples/hello-world/hello_world.metatags)  \n        description: BBE on how to print “Hello, World!” using a main function in Ballerina. A public function named main is considered as an entry point to a Ballerina program.  \n        keywords: ballerina, ballerina by example, bbe, hello world main function\n        \n\n6. Break the `.description` file content into paragraphs when necessary and use `<br/>` tags to separate them. New lines in the content do not get translated into new lines in the final rendering.\n\n7. As a best practice, use the following format as a common pattern in the `.out` files and customize only when necessary (e.g., when it is needed to add more command line args etc).\n\n    For an example with main:\n\n    ```bash\n    # To run this sample, navigate to the directory that contains the\n    # `.bal` file and issue the `bal run` command.\n    bal run <sample_file_name>.bal\n    ```\n\n    For an example with a service:\n\n    ```bash\n    # To start the service, navigate to the directory that contains the\n    # `.bal` file and issue the `bal run` command.\n    bal run hello_world_service.bal\n    ```\n\n8. Service examples demonstrating client-server scenarios have a `.bal` file only for the server and two different output files. That is, one to display the server output (`.server.out` file) and the other (`.client.out` file) to display the cURL command and the output. These two separate output files can be introduced with `.server` and `.client` suffixed to the file names. \n\n    For example, see the  `hello_world_service.server.out` and `hello_world_service.client.out` files below of the [Hello World Service BBE](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/hello-world-service).\n\n    <img src=\"/images/service-examples.png\" alt=\"A service example\" width=\"250\" height=\"150\">\n\n    >**Note:** The `server.out` file will be displayed first on the website.\n    \n9. Unless it is really required, it is not encouraged to have multiple BAL files in the same sample. In that case, each BAL file can have its own name and the `.out` file should match with the name of the `.bal` file. For example,\n\n    <img src=\"/images/mulitple-bal-files.png\" alt=\"A service example\" width=\"350\" height=\"150\">\n\n    >**Note:** The `publisher.bal` file and its `publisher.out` file will be displayed first on the website (before the subscriber files).\n\n10. Currently, you can add `.proto`,`.conf`, and `.toml` files also to be displayed on the website. For example, see the [GRPC Bidirectional Streaming BBE](https://ballerina.io/learn/by-example/grpc-bidirectional-streaming.html).\n\n>**Note:** The `.proto` files will be displayed first on the website. The `.conf` and `.toml` files will be displayed just before the last `.out` file.\n\n11. Use language features to make the examples look elegant (and small). For example, string templates, functional iteration, anonymous functions, etc.\n\n12. Use meaningful variable names, function names, etc.\n\n13. Remove unused imports in `.bal` files.\n\n14. Format the Ballerina source using an IDE Plugin. \n\n15. Do not set (too many or any) optional properties in BBEs (e.g., JDBC connection pooling props). Users will figure it out with code assist or with additional documentation as those will be covered in the User Guide. Also, all the possible options will be covered in the API docs.\n\n16. All keywords and any other word, which needs to be highlighted should be used with backquotes (e.g.,  `xml`).  Do not use a single quote as it will not get highlighted in the Ballerina website. \n\n    For example, if the keywords are added with backquotes in the BAL file of the BBE as follows,\n\n    ![Code comment in BAL file](/images/bal-file-comment.png)\n\n    will get highlighted in the Ballerina website as follows.\n\n    ![Comment in the BBE](/images/bbe-comment.png)\n\n17. Simplify error handling. Use `check` whenever possible. These examples do not need to show all possible error-handling situations. These possibilities can be shown in the actual error-handling BBEs.\n\n18. As a practice, use `ballerina/io` methods in main examples and `ballerina/log` methods in the examples with services. Do not use both `io:println` and `log:printInfo` in the same sample.\n\n19. Keep the length of the code lines in BBEs to a maximum character count of 80 per line in BAL files. Else, they get wrapped and you get horizontal scroll bars in the code view in the website reducing the readibility.\n\n    <img src=\"/images/max-char-count.png\" alt=\"Max character count\" width=\"520\" height=\"70\">\n\n20. Add comments to the code blocks as much as possible with “//” as they are used as a mechanism to describe the code. They will be displayed in the RHS section in the Ballerina website. \n\n    For example, if a code comment is added in the BAL file of the BBE as follows,\n\n    ![Code comment in BAL file](/images/bal-file-comment.png)\n\n    it will be displayed in the Ballerina website as follows.\n\n    ![Comment in the BBE](/images/bbe-comment.png)\n\n21. Since comments are displayed in the RHS in the website, they should be valid sentences (i.e. start with an upper case letter and end with a full stop etc.)\n\n22. Try to keep the code-level comments short. If there are multiline large comments, the final website view would not be nice in which there will be large gaps between code lines to accommodate the comments in the right side of the code panel. \n\n23. A comment applies to the subsequent lines in the file until another comment or an empty line is found. Use comments/new lines appropriately to ensure that it applies only to the relevant lines.\n\n24. No restriction is applicable for the maximum character count in comment lines as they will go to RHS side and get wrapped automatically. However, since users can refer to the code in GitHub, it is better if we can have the same char limit as the code lines (i.e., 80) as it increases the readability of the code file.\n\n    For example, comments are significantly longer than the code line in the image below, which is not readable. \n\n    ![Length of comments](/images/comments-length.png)\n\n25. After any update to a BBE is done or a new BBE is added, please add Anjana Fernando (lafernando) and Praneesha as reviewers.\n\n## Running Ballerina By Examples\n\nAfter writing a Ballerina By Example, you can also run it to test and verify if the output is accurate. Follow the instuctions below to do this.\n\n1. Create a directory with the BBE directories, which you want to test and the `index.json` file (e.g., `/examples`).\n\n2. In the CLI, navigate to the `master` branch of the [ballerina-release](https://github.com/ballerina-platform/ballerina-release) GitHub repo (i.e., `<BALLERINA_RELEASE_REPO_HOME>`).\n\n3. Execute the command below to build the BBEs.\n\n    >**Info:** You need to change the properties of the above command accordingly. Also, the `<GEN_PLAYGROUND_LINKS>` property can be set to `false` while testing BBEs locally since with `true` it takes a longer time to run the tool. In the final run, you can set this to `true`.\n\n    ```bash\n    go run ballerinaByExample/tools/generate.go “<SOURCE-OF-THE-BBES>” “<RELEASE-VERSION>” “<OUTPUT-FOLDER>” “<WITH-OR-WITHOUT-FRONT-MATTER>” “<IF-LATEST-VERSION>” “<GEN_PLAYGROUND_LINKS>”\n    ```\n    For example,\n\n    ```bash\n    go run ballerinaByExample/tools/generate.go \"/Documents/examples\" \"1.2\" \"by-example\" \"true\" \"true\" \"true\"\n    ```\n\n4. Copy the generated `<BALLERINA_RELEASE_REPO_HOME>/by-example` directory.\n\n5. Replace the `<BALLERINA_DEV_WEBSITE_REPO_HOME>/<VERSION>/learn/by-example`directory with the directory you copied.\n\n6. In the CLI, navigate to the `master` branch of the [ballerina-dev-website](https://github.com/ballerina-platform/ballerina-dev-website) GitHub repo (i.e., `<BALLERINA_DEV_WEBSITE_REPO_HOME>`).\n\n7. Execute the `bundle exec jekyll serve` command to build the website locally.\n\n    >**Note:** Alternatively, execute the command below if you do not have Jekyll configured locally.\n\n    ```bash\n    docker run -p 4000:4000 --volume=\"/home/shaf/Documents/source/public/ballerina-dev-website:/srv/jekyll\" jekyll/builder:3.8 jekyll serve\n    ```\n\n 8. Navigate to the Ballerina By Examples in the dev website built locally and test the BBE updates you did.\n\n## Ballerina API Documentation Guidelines\n\nFor Ballerina API Documentation Guidelines, see the [Standard Library API Documentation Guide](https://github.com/ballerina-platform/ballerina-standard-library/blob/main/docs/api-documentation-guide.md).\n"
  },
  {
    "path": "docs/build-ballerina-from-source.md",
    "content": "# Build Ballerina from source\n\n## Overview\n\n[Building the complete Ballerina distribution](#building-the-complete-ballerina-distribution) provides you access to all the main features of Ballerina such as the runtime, corresponding tools, standard library modules etc.\n\n>**Info:** However, if you need just a plain Ballerina language build with only the basic language features and the JBallerina Java (Java Introp) API in it, you can [build only the Ballerina Runtime with the tools](#building-only-the-ballerina-runtime-with-the-tools)\n\n\n## Set up the prerequisites\n\nFollow the steps below to set up the prerequisites.\n\n1. Download and [set up](https://adoptopenjdk.net/installation.html) OpenJDK 21 ([Adopt OpenJDK](https://adoptopenjdk.net/) or any other OpenJDK distribution).\n\n   >**Info:** You can also use [Oracle JDK](https://www.oracle.com/java/technologies/javase-downloads.html).\n\n2. Set up a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token) for your GitHub account and configure the following environment variables (the access token should have the `read` package permission).\n\n   **For Unix/macOS:**\n\n    ```bash\n    export packageUser=\"<YOUR_GITHUB_USERNAME>\";\n    export packagePAT=\"<YOUR_PERSONAL_ACCESS_TOKEN>\";\n    ```\n\n   **For Windows:**\n\n    ```bash\n    set packageUser=<YOUR_GITHUB_USERNAME>\n    set packagePAT=<YOUR_PERSONAL_ACCESS_TOKEN>\n    ```\n\n## Build the complete Ballerina distribution\n\nFollow the steps below to build the [`ballerina-distribution` repository](https://github.com/ballerina-platform/ballerina-distribution) to get full access to the complete Ballerina distribution.\n\n1. Fork the `ballerina-distribution` repository to your GitHub account and execute following command to clone it.\n\n    ```bash\n    git clone --recursive https://github.com/<GITHUB_USERNAME>/ballerina-distribution.git\n    ```\n\n2. Navigate to the `<BALLERINA_DISTRIBUTION_PROJECT>` directory, and execute the command below to start the build (here, the tests are excluded to speed up the build).\n\n   **For Unix/macOS:**\n\n    ```bash\n    ./gradlew clean build -x test\n    ```\n\n   **For Windows:**\n\n    ```bash\n    gradlew clean build -x test\n    ```\n\n3. Extract the built Ballerina Language distribution (i.e., the `<BALLERINA_DISTRIBUTION_PROJECT>/ballerina/build/distributions/ballerina-<VERSION>.zip` file) to a preferred location.\n\n4. Configure the environment variables below.\n\n   **For Unix/macOS:**\n\n    ```bash\n    # Set up the `BALLERINA_HOME` environment variable.\n    export BALLERINA_HOME=\"<YOUR_LOCATION>/ballerina-<VERSION>\";\n\n    # Include the binaries to the system `PATH`.\n    PATH=$BALLERINA_HOME/bin:$PATH;\n    export PATH;\n    ```\n\n   **For Windows:**\n\n    ```bash\n    # Set up the `BALLERINA_HOME` environment variable.\n    set BALLERINA_HOME=\"<YOUR_LOCATION>\\ballerina-<VERSION>\";\n\n    # Include the binaries to the system `PATH`.\n    set PATH=%PATH%;%BALLERINA_HOME%\\bin;\n    ```\n\n### Test the distribution build\n\nSince this is a complete Ballerina distribution build, this will have all the Standard Library module dependencies included in it.\n\nTherefore, follow the steps below to write a simple program using the Ballerina [`io` module](https://github.com/ballerina-platform/module-ballerina-io/) to test the distribution build.\n\n1. Create a `hello_world_with_io.bal` file with the code below.\n\n    ```ballerina\n    import ballerina/io;\n\n    // ballerina hello world program\n    public function main() {\n          io:println(\"Hello, World with IO!\");\n    }\n    ```\n\n2. Execute the command below to build and run this program.\n\n    ```bash\n    bal run hello_world_with_io.bal\n    ```\n\n   If your build is successful, you view the output below.\n\n    ```bash\n    Hello, World with IO!\n    ```\n\n## Build only the Ballerina runtime with the tools\n\nFollow the steps below to build just the Ballerina runtime with the corresponding tools.\n\n1. Fork the [`ballerina-lang` repository](https://github.com/ballerina-platform/ballerina-lang) to your GitHub account and execute following command to clone it.\n\n    ```bash\n    git clone --recursive https://github.com/<GITHUB_USERNAME>/ballerina-lang.git\n    ```\n\n2. Navigate to the `<BALLERINA_LANG_PROJECT>` directory, and execute the command below to update the Git submodules.\n\n    ```bash\n    git submodule update --init\n    ```\n\n3. Execute one of the commands below to start the build process.\n\n   **For Unix/macOS:**\n\n    ```bash\n    ./gradlew clean build\n    ```\n\n   **For Windows:**\n\n    ```bash\n    gradlew clean build\n    ```\n\n4. Extract the built Ballerina Language distribution (i.e., the `<BALLERINA_LANG_PROJECT>/distribution/zip/jballerina-tools/build/distributions/jballerina-tools-<VERSION>.zip` file) to a preferred location.\n\n5. Configure the environment variables below.\n\n   **For Unix/macOS:**\n\n    ```bash\n    # Set up the `BALLERINA_HOME` environment variable.\n    export BALLERINA_HOME=\"<YOUR_LOCATION>/jballerina-tools-<VERSION>\";\n\n    # Include the binaries to the system `PATH`.\n    PATH=$BALLERINA_HOME/bin:$PATH;\n    export PATH;\n    ```\n\n   **For Windows:**\n\n    ```bash\n    # Set up the `BALLERINA_HOME` environment variable.\n    set BALLERINA_HOME=\"<YOUR_LOCATION>\\jballerina-tools-<VERSION>\";\n\n    # Include the binaries to the system `PATH`.\n    set PATH=%PATH%:%BALLERINA_HOME%\\bin;\n    ```\n\n### Test the runtime build\n\nSince this runtime build is just a plain Ballerina language build, you only have the basic language features and JBallerina Java (Java Introp) API in it.\n\nTherefore, follow the steps below to write a basic Ballerina program using only those functionalities to test the runtime build.\n\n1. Create a `hello_world.bal` file with the code below.\n\n    ```ballerina\n    import ballerina/jballerina.java;\n\n    public function main(string... args) {\n        var systemOut = out();\n        println(systemOut, java:fromString(\"Hello, World!\"));\n    }\n\n    // Retrieves the current System output stream\n    public function out() returns handle = @java:FieldGet {\n        name: \"out\",\n        'class: \"java.lang.System\"\n    } external;\n\n    // Calls `println` method of the  `PrintStream`\n    function println(handle receiver, handle message) = @java:Method {\n        paramTypes: [\"java.lang.String\"],\n        'class: \"java.io.PrintStream\"\n    } external;\n    ```\n\n2. Execute the command below to build and run this program.\n\n    ```bash\n    bal run hello_world.bal\n    ```\n\n   If your build is successful, you view the output below.\n\n    ```bash\n    Hello, World!\n    ```\n\n"
  },
  {
    "path": "examples/access-json-elements/access_json_elements.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.value;\n \npublic function main() returns error? {\n    json[] users = [\n        {\n            user: {\n                name: {\n                    firstName: \"John\",\n                    lastname: \"Smith\"\n                },\n                age: 24\n            }\n        },\n        null\n    ];\n\n    // Field access is allowed on the `json` typed variable. However, the return\n    // type would be a union of `json` and `error`.\n    json firstUserName = check users[0].user.name;\n    \n    // This is converted to `check value:ensureType(firstUserName.firstName, string)`.\n    // As the expected type is correct, the conversion is successful.\n    string firstName = check firstUserName.firstName;\n    io:println(\"Value of first name: \" + firstName);\n    \n    // This is same as above.\n    firstName = check value:ensureType(firstUserName.firstName, string);\n    io:println(\"Value of first name: \" + firstName);\n}\n"
  },
  {
    "path": "examples/access-json-elements/access_json_elements.md",
    "content": "# Access JSON elements\n\nBallerina defines certain types as lax types for which static typing rules are less strict. `json` is defined to be a lax type along with any `map<T>` where `T` is a lax type.\nFor example, field access (`.`) and optional field access (`?.`), which are generally allowed on records and objects for fields that are defined in the type descriptors, are also allowed additionally on lax types. For such operations, some of the type checkings are moved from compile time to runtime.\nThe best way of accessing JSON elements is to convert the `json` value to a user-defined type.\n\n`check Expr` is treated as `check val:ensureType(Expr, s)` when the `Expr` is a subtype of JSON and the expected type is a subtype of `()|boolean|int|float|decimal|string`. `s` is a typedesc value representing the expected type.\n\n::: code access_json_elements.bal :::\n\nRun the example as follows.\n\n::: out access_json_elements.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type)\n- [Check expression](/learn/by-example/check-expression)\n- [ensureType function](/learn/by-example/ensureType-function)"
  },
  {
    "path": "examples/access-json-elements/access_json_elements.metatags",
    "content": "description: This BBE demonstrates how to get elements in JSON, check whether a given element is available in JSON, handle errors when a member is not available, get members in JSON array, and access a JSON value in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, json type, json, check, ensureType, lax, access\n"
  },
  {
    "path": "examples/access-json-elements/access_json_elements.out",
    "content": "$ bal run access_json_elements.bal\nValue of first name: John\nValue of first name: John\n"
  },
  {
    "path": "examples/access-optional-json-elements/access_optional_json_elements.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    json user = {\n      name: {\n         firstName: \"John\",\n         lastname: \"Smith\"\n      },\n      age: 24\n    };\n\n    // Since the availability of `address` field is unknown, optional access is used\n    string? address = check user?.address;\n\n    if address is string {\n      io:println(\"Address: \" + address);\n    }\n\n    // Optional access can be used again on fields accessed with optional access\n    string? firstName = check user?.name?.firstName;\n\n    if firstName is string {\n      io:println(\"First name: \" + firstName);\n    }\n}\n"
  },
  {
    "path": "examples/access-optional-json-elements/access_optional_json_elements.md",
    "content": "# Accessing optional JSON elements\n\nIf there is no prior knowledge of the availability of a particular field, optional field access (`?.`) can be used on the `json` value. If the particular field is not available, it will return `nil`.\n\n::: code access_optional_json_elements.bal :::\n\nRun the example as follows.\n\n::: out access_optional_json_elements.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Check expression](/learn/by-example/check-expression/)\n- [Optional fields](/learn/by-example/optional-fields/)\n"
  },
  {
    "path": "examples/access-optional-json-elements/access_optional_json_elements.metatags",
    "content": "description: This BBE demonstrates how to get elements in json, check whether given element is available in json, handle errors when member is not available, get member in json array, access a json value, optional access on json members.\nkeywords: ballerina, ballerina by example, bbe, json type, json, check, lax, access\n"
  },
  {
    "path": "examples/access-optional-json-elements/access_optional_json_elements.out",
    "content": "$ bal run access_optional_json_elements.bal\nFirst name: John\n"
  },
  {
    "path": "examples/advanced-conflict-handling/advanced_conflict_handling.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    string name;\n    int score;\n|};\n\npublic function main() {\n    Student[] students = [\n        {name: \"John\", score: 100},\n        {name: \"Jane\", score: 150},\n        {name: \"John\", score: 200}\n    ];\n\n    // Create a map of the student `name` and the `score` where we replace the value of the duplicate key if the new `score` is even.\n    // The old `score` `100` of `John` will be replaced by the new `score` 200` since `replaceIfSafe()`returns `nil` for even scores.\n    map<int>|error studentScores = map from var {name, score} in students\n                                   select [name, score]\n                                   on conflict replaceIfSafe(score);\n    io:println(studentScores);\n\n    students = [\n        {name: \"John\", score: 100},\n        {name: \"Jane\", score: 150},\n        {name: \"John\", score: 211}\n    ];\n\n    // The result of this will be an error since the key `John` is duplicated and the `replaceIfSafe()`returns an error for odd `score` `211`.\n    map<int>|error studentScores2 = map from var {name, score} in students\n                                    select [name, score]\n                                    on conflict replaceIfSafe(score);\n    io:println(studentScores2);\n}\n\nfunction replaceIfSafe(int score) returns error? {\n    if score % 2 != 0 {\n        return error(\"Key Conflict\", message = \"Duplicate key has an odd score\");\n    }\n}\n\n"
  },
  {
    "path": "examples/advanced-conflict-handling/advanced_conflict_handling.md",
    "content": "# Advanced conflict handling\n\nWe can implement a custom conflict-handling policy to determine whether to replace a value or throw an error in the event of conflicting keys when constructing a map or table.\n\n::: code advanced_conflict_handling.bal :::\n\n::: out advanced_conflict_handling.out :::\n\n## Related links\n- [On conflict clause](/learn/by-example/on-conflict-clause)\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/advanced-conflict-handling/advanced_conflict_handling.metatags",
    "content": "description: This BBE demonstrates writing custom conflict handling logic when constructing a map or a table.\nkeywords: ballerina, ballerina by example, bbe, duplicate, key, map, table, query, on conflict, error\n"
  },
  {
    "path": "examples/advanced-conflict-handling/advanced_conflict_handling.out",
    "content": "$ bal run advanced_conflict_handling.bal\n{\"John\":200,\"Jane\":150}\nerror(\"Key Conflict\",message=\"Duplicate key has an odd score\")\n"
  },
  {
    "path": "examples/aggregation/aggregation.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    var orders = [\n        {orderId: 1, itemName: \"A\", price: 23.4, quantity: 2},\n        {orderId: 1, itemName: \"A\", price: 20.4, quantity: 1},\n        {orderId: 2, itemName: \"B\", price: 21.5, quantity: 3},\n        {orderId: 1, itemName: \"B\", price: 21.5, quantity: 3}\n    ];\n\n    var items = from var {orderId, itemName} in orders\n        // The `group by` clause create groups for each `orderId`.\n        // The `itemName` is a non-grouping key and it becomes a sequence variable.\n        group by orderId\n        select [itemName];\n    \n    // List of items per `orderId`\n    io:println(items);\n\n    var quantities = from var {itemName, quantity} in orders\n        // The `group by` clause create groups for each `itemName`.\n        // The `quantity` is a non-grouping key and it becomes a sequence variable.\n        group by itemName\n        select {itemName, quantity: sum(quantity)};\n\n    // List of quantity per item\n    io:println(quantities);\n\n    var income = from var {price, quantity} in orders\n        let var totPrice = price*quantity\n        // The `collect` clause creates a single group and all variables become\n        // non-grouping keys\n        collect sum(totPrice);\n    \n    // Total Income from orders\n    io:println(income);\n}\n"
  },
  {
    "path": "examples/aggregation/aggregation.md",
    "content": "# Aggregation\n\nThe `group by` clause in the query expression can group the elements in a collection. Grouping happens based on the grouping keys provided in `group by` clause. For each group, grouping keys are unique. All other variables other than grouping keys are called non-grouping keys. For each group, non-grouping keys become sequence variables. Those variables can be used as a list or an argument to a rest parameter of a langlib function.\n\nThe `collect` clause collects the collection into one group. All the variables become aggregated variables and those variables can be used as a list or an argument to a rest parameter of a langlib function same as in `group by`.\n\n::: code aggregation.bal :::\n\n::: out aggregation.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/aggregation/aggregation.metatags",
    "content": "description: This BBE demonstrates how to group a collection, how to handle non grouping keys.\nkeywords: ballerina, ballerina by example, bbe, group, non-grouping keys, aggregate, collect\n"
  },
  {
    "path": "examples/aggregation/aggregation.out",
    "content": "$ bal run aggregation.bal\n[[\"A\",\"A\",\"B\"],[\"B\"]]\n[{\"itemName\":\"A\",\"quantity\":3},{\"itemName\":\"B\",\"quantity\":6}]\n196.2\n"
  },
  {
    "path": "examples/ai-agent-external-endpoint-integration/ai_agent_external_endpoint_integration.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\nimport ballerinax/googleapis.calendar;\nimport ballerinax/googleapis.gmail;\n\n// Configuration for external endpoints.\nconfigurable string refreshToken = ?;\nconfigurable string clientId = ?;\nconfigurable string clientSecret = ?;\nconfigurable string refreshUrl = ?;\n\nconfigurable string userEmail = ?;\n\n// Create clients for Gmail and Calendar APIs.\nfinal gmail:Client gmailClient = check new ({\n    auth: {refreshToken: refreshToken, clientId, clientSecret, refreshUrl}\n});\n\nfinal calendar:Client calendarClient = check new (config = {\n    auth: {clientId, clientSecret, refreshToken: refreshToken, refreshUrl}\n});\n\n// Define tools for the agent to interact with Gmail and Calendar APIs.\n@ai:AgentTool\nisolated function readUnreadEmails() returns gmail:Message[]|error {\n    gmail:ListMessagesResponse messageList =\n        check gmailClient->/users/me/messages(q = \"label:INBOX is:unread\");\n    gmail:Message[]? messages = messageList.messages;\n\n    if messages is () {\n        return [];\n    }\n\n    gmail:Message[] completeMessages = from gmail:Message message in messages\n        select check gmailClient->/users/me/messages/[message.id](format = \"full\");\n    return completeMessages;\n}\n\n@ai:AgentTool\nisolated function sendEmail(string[] to, string subject, string body) \n        returns gmail:Message|error {\n    return gmailClient->/users/me/messages/send.post({to, subject, bodyInText: body});\n}\n\n@ai:AgentTool\nisolated function getCalendarEvents() \n        returns stream<calendar:Event, error?>|error {\n    return calendarClient->getEvents(userEmail);\n}\n\n@ai:AgentTool\nisolated function createCalendarEvent(calendar:InputEvent event) \n        returns calendar:Event|error {\n    return calendarClient->createEvent(userEmail, event);\n}\n\nfinal ai:Agent personalAssistantAgent = check new (\n    systemPrompt = {\n        role: \"Personal Assistant\",\n        instructions: string `You are an intelligent personal AI assistant \n            designed to help users stay organized and efficient. You have \n            access to the user's email and calendar through secure API \n            integrations.\n            \n            Your tasks may require reading and summarizing unread emails,\n            sending emails on behalf of the user, helping schedule meetings, \n            and managing calendar events.\n\n            When interacting with the user, always adhere to the following:\n            - Respond in a natural and professional tone.\n            - Always confirm before making changes to the user's calendar or \n                sending emails.\n            - Provide concise summaries when retrieving information unless the \n                user requests details.\n            - Prioritize clarity, efficiency, and user convenience in all tasks.`\n    },\n    // Use the default model provider (with configuration added via a \n    // Ballerina VS Code command).\n    model = check ai:getDefaultModelProvider(),\n    // Specify the tools the agent can use.\n    tools = [readUnreadEmails, sendEmail, getCalendarEvents, createCalendarEvent]\n);\n\npublic function main() returns error? {\n    while true {\n        string userInput = io:readln(\"User (or 'exit' to quit): \");\n        if userInput == \"exit\" {\n            break;\n        }\n        // Pass the user input to the agent and get a response.\n        string response = check personalAssistantAgent.run(userInput);\n        io:println(\"Agent: \", response);\n    }\n}\n"
  },
  {
    "path": "examples/ai-agent-external-endpoint-integration/ai_agent_external_endpoint_integration.md",
    "content": "# AI agents with external endpoints as tools\n\nBallerina enables developers to easily create intelligent AI agents powered by large language models (LLMs) and integrated with tools, including local tools, MCP tools, and external APIs. These AI agents can automate complex workflows, interact with users through natural language, and seamlessly connect with internal and external systems.\n\nThis example demonstrates how to create an AI agent that can access Gmail and Google Calendar by integrating with Google APIs as external endpoints. The agent functions as a personal assistant that can read emails, send emails, view calendar events, and create new calendar entries.\n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation. \n\n> Note: Follow the [connector setup guide](https://central.ballerina.io/ballerinax/googleapis.gmail/latest#setup-guide) to obtain the connector configuration.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code ai_agent_external_endpoint_integration.bal :::\n\n::: out ai_agent_external_endpoint_integration.out :::\n\n## Related links\n- [The Agent with local tools example](/learn/by-example/ai-agent-local-tools)\n- [The Agent with MCP integration example](/learn/by-example/ai-agent-mcp-integration)\n- [The Agent with tool kits example](/learn/by-example/ai-agent-tool-kit)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/ai-agent-external-endpoint-integration/ai_agent_external_endpoint_integration.metatags",
    "content": "description: This BBE demonstrates AI agents integrated with external endpoints as tools.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, agent\n"
  },
  {
    "path": "examples/ai-agent-external-endpoint-integration/ai_agent_external_endpoint_integration.out",
    "content": "$ bal run ai_agent_external_endpoint_integration.bal\nUser (or 'exit' to quit): Do I have any meetings today?\nAgent: You have one meeting scheduled for today:\n\n- **Event:** Sync up on the monthly meet up\n- **Time:** 3:30 PM to 4:30 PM (Asia/Colombo timezone)\n\nIf you need any further assistance regarding this meeting, just let me know!\nUser (or 'exit' to quit): Can you check my mail to see if I've missed any meeting requests?\nAgent: You have an unread email regarding a meeting request:\n\n- **From:** Emma (<email-address>)\n- **Subject:** Catch up\n- **Message:** Emma wants to discuss Ballerina's Gen AI app building capabilities with you. She is available at 4 PM today (September 27th) or on Monday (September 29th) at 10 AM.\n\nWould you like to respond to Emma and confirm a time?\nUser (or 'exit' to quit): Yes, please schedule the meeting. The time is okay with me, but can you check my calendar to see if I have any appointments already?\nAgent: You have a meeting scheduled today from 3:30 PM to 4:30 PM. Since Emma's proposed time for the meeting is at 4 PM today, it would overlap with your existing appointment.\n\nWould you prefer to schedule the meeting with Emma for Monday, September 29th at 10 AM instead?\nUser (or 'exit' to quit): Yes, please\nAgent: The meeting with Emma has been successfully scheduled for Monday, September 29th from 10:00 AM to 11:00 AM. \n\nYou can view the event [here](<event-link>).\n\nIf there's anything else you need, feel free to ask!\nUser (or 'exit' to quit): exit\n"
  },
  {
    "path": "examples/ai-agent-local-tools/ai_agent_local_tools.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\nimport ballerina/time;\nimport ballerina/uuid;\n\ntype Task record {|\n    string description;\n    time:Date dueBy?;\n    time:Date createdAt = time:utcToCivil(time:utcNow());\n    time:Date completedAt?;\n    boolean completed = false;\n|};\n\n// Simple in-memory task management.\nisolated map<Task> tasks = {\n    \"a2af0faa-3b73-4184-9be1-87b29a963be6\": {\n        description: \"Buy groceries\",\n        dueBy: time:utcToCivil(time:utcAddSeconds(time:utcNow(), 60 * 5))\n    }\n};\n\n// Define the functions that the agent can use as tools.\n// The LLM will identify the arguments to pass to these functions\n// based on the user input and the tool (function) signatures.\n@ai:AgentTool\nisolated function addTask(string description, time:Date? dueBy) returns error? {\n    lock {\n        tasks[uuid:createRandomUuid()] = {description, dueBy: dueBy.clone()};\n    }\n}\n\n@ai:AgentTool\nisolated function listTasks() returns Task[] {\n    lock {\n        return tasks.toArray().clone();\n    }\n}\n\n@ai:AgentTool\nisolated function getCurrentDate() returns time:Date {\n    time:Civil {year, month, day} = time:utcToCivil(time:utcNow());\n    return {year, month, day};\n}\n\n// Define an AI agent with a system prompt and a set of tools.\n// The agent will use these tools to help manage a task list,\n// following the system prompt instructions.\nfinal ai:Agent taskAssistantAgent = check new ({\n    systemPrompt: {\n        role: \"Task Assistant\",\n        instructions: string `You are a helpful assistant for \n            managing a to-do list. You can manage tasks and\n            help a user plan their schedule.`\n    },\n    // Specify the functions the agent can use as tools.\n    tools: [addTask, listTasks, getCurrentDate],\n    // Use the default model provider (with configuration added\n    // via a Ballerina VS Code command).\n    model: check ai:getDefaultModelProvider()\n});\n\npublic function main() returns error? {\n    while true {\n        string userInput = io:readln(\"User (or 'exit' to quit): \");\n        if userInput == \"exit\" {\n            break;\n        }\n        // Pass the user input to the agent and get a response.\n        string response = check taskAssistantAgent.run(userInput);\n        io:println(\"Agent: \", response);\n    }\n}\n"
  },
  {
    "path": "examples/ai-agent-local-tools/ai_agent_local_tools.md",
    "content": "# AI agents with local tools\n\nBallerina enables developers to easily create intelligent AI agents powered by large language models (LLMs) and integrated with tools, including local tools, MCP tools, and external APIs. These AI agents can automate complex workflows, interact with users through natural language, and seamlessly connect with internal and external systems.\n\nThis example demonstrates how to create an AI agent that can manage a to-do list by using local functions as tools, while maintaining a conversation with the user.\n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code ai_agent_local_tools.bal :::\n\n::: out ai_agent_local_tools.out :::\n\n## Related links\n- [The Agent with MCP integration example](/learn/by-example/ai-agent-mcp-integration)\n- [The Agent with external endpoint integration example](/learn/by-example/ai-agent-external-endpoint-integration)\n- [The Agent with tool kits example](/learn/by-example/ai-agent-tool-kit)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/ai-agent-local-tools/ai_agent_local_tools.metatags",
    "content": "description: This BBE demonstrates AI agents.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, agent\n"
  },
  {
    "path": "examples/ai-agent-local-tools/ai_agent_local_tools.out",
    "content": "$ bal run ai_agent_local_tools.bal\nUser (or 'exit' to quit): What do I have on my plate today?\nAgent: You have the following task on your plate today:\n\n- **Buy groceries** (Due on September 26, 2025, at 5:44 AM UTC)\n\nLet me know if you need help with anything else!\nUser (or 'exit' to quit): What about the rest of the week?\nAgent: Currently, you only have one task for the week:\n\n- **Buy groceries** (Due today, September 26, 2025, at 5:44 AM UTC)\n\nIf you have any other tasks to add or if you need help planning your week, just let me know!\nUser (or 'exit' to quit): I have to pay my WiFi bill by tomorrow and meet Jane for tea at 4pm on the 28th.\nAgent: Your tasks have been successfully added! Here’s your updated to-do list for the week:\n\n1. **Buy groceries** (Due today, September 26, 2025, at 5:44 AM UTC)\n2. **Pay WiFi bill** (Due tomorrow, September 27, 2025)\n3. **Meet Jane for tea** (Scheduled for September 28, 2025, at 4:00 PM UTC)\n\nLet me know if you need any further assistance!\nUser (or 'exit' to quit): exit\n"
  },
  {
    "path": "examples/ai-agent-mcp-integration/ai_agent_mcp_integration.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Define an MCP toolkit to connect to the MCP service.\n// This allows using all the tools registered with the MCP service.\n// Alternatively, specific tools can be used by specifying them as the second \n// argument (e.g., `check new (\"http://localhost:9090/mcp\", [\"getCurrentWeather\"])`).\nfinal ai:McpToolKit weatherMcpConn = check new (\"http://localhost:9090/mcp\");\n\nfinal ai:Agent weatherAgent = check new (\n    systemPrompt = {\n        role: \"Weather-aware AI Assistant\",\n        instructions: string `You are a smart AI assistant that can assist \n            a user based on accurate and timely weather information.`\n    }, \n    tools = [weatherMcpConn],\n    // Use the default model provider (with configuration added\n    // via a Ballerina VS Code command).\n    model = check ai:getDefaultModelProvider()\n);\n\npublic function main() returns error? {\n    while true {\n        string userInput = io:readln(\"User (or 'exit' to quit): \");\n        if userInput == \"exit\" {\n            break;\n        }\n        // Pass the user input to the agent and get a response.\n        string response = check weatherAgent.run(userInput);\n        io:println(\"Agent: \", response);\n    }\n}\n"
  },
  {
    "path": "examples/ai-agent-mcp-integration/ai_agent_mcp_integration.md",
    "content": "# AI agents with MCP tools\n\nBallerina enables developers to easily create intelligent AI agents powered by large language models (LLMs) and integrated with tools, including local tools, MCP tools, and external APIs. These AI agents can automate complex workflows, interact with users through natural language, and seamlessly connect with internal and external systems.\n\nThis example demonstrates how to create an AI agent that can access weather information by integrating with a Model Context Protocol (MCP) service, by simply defining an MCP toolkit.\n\n> Note: You can use this agent with the [MCP service example](/learn/by-example/mcp-service/).\n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code ai_agent_mcp_integration.bal :::\n\n::: out ai_agent_mcp_integration.out :::\n\n## Related links\n- [The Agent with local tools example](/learn/by-example/ai-agent-local-tools)\n- [The Agent with external endpoint integration example](/learn/by-example/ai-agent-external-endpoint-integration)\n- [The Agent with tool kits example](/learn/by-example/ai-agent-tool-kit)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/ai-agent-mcp-integration/ai_agent_mcp_integration.metatags",
    "content": "description: This BBE demonstrates AI agents integrated with MCP tools.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, agent, mcp\n"
  },
  {
    "path": "examples/ai-agent-mcp-integration/ai_agent_mcp_integration.out",
    "content": "$ bal run ai_agent_mcp_integration.bal\nUser (or 'exit' to quit): Should I go for a walk in Colombo today?\nAgent: The current weather in Colombo is sunny with a temperature of 27°C and humidity at 80%. It seems like a great day for a walk! Enjoy your time outdoors!\nUser (or 'exit' to quit): What about tomorrow?\nAgent: Tomorrow in Colombo, the weather is expected to be cloudy with a high of 30°C and a low of 26°C. There's a 65% chance of precipitation, and wind speeds will be around 17 km/h. \n\nWhile it may not be as sunny as today, you could still go for a walk, but keep an eye on the clouds and the potential for light rain. Enjoy!\nUser (or 'exit' to quit): exit\n"
  },
  {
    "path": "examples/ai-agent-tool-kit/ai_agent_tool_kit.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\nimport ballerina/time;\nimport ballerina/uuid;\n\ntype Task record {|\n    string description;\n    time:Date dueBy?;\n    time:Date createdAt = time:utcToCivil(time:utcNow());\n    time:Date completedAt?;\n    boolean completed = false;\n|};\n\n// A tool kit to manage a set of tasks.\npublic isolated class TaskManagerToolkit {\n    *ai:BaseToolKit;\n    \n    private final map<Task> tasks = {};\n\n    // The `getTools` method describes the tools provided by this tool kit.\n    public isolated function getTools() returns ai:ToolConfig[] => \n        // The `ai:getToolConfigs` function generates the tool configurations for the specified tools.\n        ai:getToolConfigs([self.addTask, self.listTasks]);\n    \n    // Tool to add a new task.\n    @ai:AgentTool\n    isolated function addTask(string description, time:Date? dueBy = ()) {\n        lock {\n            self.tasks[uuid:createRandomUuid()] = {\n                description: description, \n                dueBy: dueBy.clone()\n            };\n        }\n    }\n\n    // Tool to list all current tasks.\n    @ai:AgentTool\n    isolated function listTasks() returns map<Task> {\n        lock {\n            return self.tasks.clone();\n        }\n    }\n}\n\n@ai:AgentTool\nisolated function getCurrentDate() returns time:Date {\n    time:Civil {year, month, day} = time:utcToCivil(time:utcNow());\n    return {year, month, day};\n}\n\n// Define an AI agent with a system prompt and a set of tools.\n// The agent will use these tools to help manage a task list,\n// following the system prompt instructions.\nfinal ai:Agent taskAssistantAgent = check new ({\n    systemPrompt: {\n        role: \"Task Assistant\",\n        instructions: string `You are a helpful assistant for \n            managing a to-do list. You can manage tasks and\n            help a user plan their schedule.`\n    },\n    // Include the tool kit in tools the agent can use.\n    tools: [new TaskManagerToolkit(), getCurrentDate],\n    // Use the default model provider (with configuration added\n    // via a Ballerina VS Code command).\n    model: check ai:getDefaultModelProvider(),\n    maxIter: 10\n});\n\npublic function main() returns error? {\n    while true {\n        string userInput = io:readln(\"User (or 'exit' to quit): \");\n        if userInput == \"exit\" {\n            break;\n        }\n        // Pass the user input to the agent and get a response.\n        string response = check taskAssistantAgent.run(userInput);\n        io:println(\"Agent: \", response);\n    }\n}\n"
  },
  {
    "path": "examples/ai-agent-tool-kit/ai_agent_tool_kit.md",
    "content": "# AI agents with tool kits\n\nBallerina enables developers to easily create intelligent AI agents powered by large language models (LLMs) and integrated with tools, including local tools, MCP tools, and external APIs. These AI agents can automate complex workflows, interact with users through natural language, and seamlessly connect with internal and external systems.\n\nThis example demonstrates how to create an AI agent that can manage a to-do list by using a toolkit that encapsulates related tools and state. Toolkits allow for better encapsulation and reusability compared to using standalone functions, especially when building complex agents with multiple related capabilities.\n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code ai_agent_tool_kit.bal :::\n\n::: out ai_agent_tool_kit.out :::\n\n## Related links\n- [The Agent with local tools example](/learn/by-example/ai-agent-local-tools)\n- [The Agent with MCP integration example](/learn/by-example/ai-agent-mcp-integration)\n- [The Agent with external endpoint integration example](/learn/by-example/ai-agent-external-endpoint-integration)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/ai-agent-tool-kit/ai_agent_tool_kit.metatags",
    "content": "description: This BBE demonstrates AI agents with tool kits.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, agent\n"
  },
  {
    "path": "examples/ai-agent-tool-kit/ai_agent_tool_kit.out",
    "content": "$ bal run ai_agent_tool_kit.bal\nUser (or 'exit' to quit): Hello\nAgent: Hello! How can I assist you today? Do you need help with your to-do list or planning your schedule?\nUser (or 'exit' to quit): I have to pay my WiFi bill today and meet Jane for tea at 4pm on the 28th.\nAgent: I've added your tasks to the to-do list:\n\n1. Pay WiFi bill (due today)\n2. Meet Jane for tea at 4 PM on the 28th of October 2025\n\nWould you like to do anything else, such as check your current tasks or add more?\nUser (or 'exit' to quit): What do I have on my plate today?\nAgent: Today, you have the following task:\n\n1. **Pay WiFi bill** (due today)\n\nWould you like to mark it as completed or do anything else?\nUser (or 'exit' to quit): exit\n"
  },
  {
    "path": "examples/alternate-receive/alternate_receive.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/lang.runtime;\n\ntype Response record {\n    record {\n        string 'worker;\n    } args;\n};\n\n// Concurrently fetch content from two URLs using workers and\n// return the first non-error value received.\nfunction getFirstFetched(string url1, string url2) returns string? {\n    // Workers `w1` and `w2` fetch content from `url1` and `url2` respectively.\n    worker w1 {\n        string|error result = fetch(url1);\n        result -> w3;\n    }\n\n    worker w2 {\n        runtime:sleep(3);\n        string|error result = fetch(url2);\n        result -> w3;\n    }\n\n    // Worker `w3` waits until one of the workers sends a non-error value. \n    worker w3 returns string? {\n        // The value of the variable `result` is set as soon as\n        // a non-error message is received from either worker `w1` or `w2`.\n        string|error result = <- w1 | w2;\n        return result is error ? () : result;\n    }\n\n    // The value returned from worker `w3` is set to the variable `w3Result`.\n    string? w3Result = wait w3;\n    return w3Result;\n}\n\nfunction fetch(string url) returns string|error {\n    http:Client cl = check new (url);\n    Response response = check cl->get(\"\");\n    return response.args.'worker;\n}\n\npublic function main() {\n    // Both arguments passed to the `getFirstFetched` function are valid URLs.\n    // Thus, the alternate receive action in worker `w3` sets the\n    // first value it receives from a worker as the result.\n    string? firstFetched = getFirstFetched(\"https://postman-echo.com/get?worker=w1\",\n            \"https://postman-echo.com/get?worker=w2\");\n    io:println(firstFetched);\n\n    // The first argument passed to the `getFirstFetched` function is an invalid URL.\n    // Therefore, the worker `w1` in the `getFirstFetched` function returns an error.\n    // Thus, the alternate receive action in worker `w3` waits further\n    // and sets the value that is received from `w2` as the result.\n    firstFetched = getFirstFetched(\"https://postman-echo.com/ge?worker=w4\",\n            \"https://postman-echo.com/get?worker=w5\");\n    io:println(firstFetched);\n}\n"
  },
  {
    "path": "examples/alternate-receive/alternate_receive.md",
    "content": "# Alternate receive\n\nThe alternate receive action can be used to receive one of multiple values corresponding to multiple send actions. It operates by waiting until it receives a non-error message, a panic termination status on a closed channel, or the closure of all channels. The alternative receive action sets the first non-error value it receives as the result. If all the channels return errors, it sets the last received error as the result.\n\n::: code alternate_receive.bal :::\n\n::: out alternate_receive.out :::\n"
  },
  {
    "path": "examples/alternate-receive/alternate_receive.metatags",
    "content": "description: This BBE demonstrates the use of the alternate receive action in inter-worker communication\nkeywords: ballerina, ballerina by example, bbe, worker, alternate receive\n"
  },
  {
    "path": "examples/alternate-receive/alternate_receive.out",
    "content": "$ bal run alternate_receive.bal\nw1\nw5\n"
  },
  {
    "path": "examples/alternate-wait/alternate_wait.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\n// Fetch from A or B.\nfunction altFetch(string urlA, string urlB) returns string|error {\n\n    worker A returns string|error {\n        return fetch(urlA);\n    }\n\n    worker B returns string|error {\n        return fetch(urlB);\n    }\n\n    // The `wait` action can be used to wait for one of several workers.\n    // This function will return as soon as the return value of either\n    // `A` or `B` is available.\n    return wait A | B;\n\n}\n\npublic function main() returns error? {\n    string res = \n        check altFetch(\"https://postman-echo.com/get?lang=ballerina\",\n                       \"https://postman-echo.com/get?greeting=hello\");\n    io:println(res);\n}\n\nfunction fetch(string url) returns string|error {\n    http:Client cl = check new (url);\n    map<json> payload = check cl->get(\"\");\n    return payload[\"args\"].toString();\n}\n"
  },
  {
    "path": "examples/alternate-wait/alternate_wait.md",
    "content": "# Alternate wait\n\nThe `wait` action can be used to wait for one of several workers.\n\n::: code alternate_wait.bal :::\n\n::: out alternate_wait.out :::"
  },
  {
    "path": "examples/alternate-wait/alternate_wait.metatags",
    "content": "description: This BBE demonstrates the alternate wait action\nkeywords: ballerina, ballerina by example, bbe, worker, alternate wait\n"
  },
  {
    "path": "examples/alternate-wait/alternate_wait.out",
    "content": "$ bal run alternate_wait.bal\n{\"lang\":\"ballerina\"}\n"
  },
  {
    "path": "examples/annotations/annotations.bal",
    "content": "import ballerina/io;\n\n// The `@display` annotation is applied to the `transform` function.\n@display {\n    label: \"Transform\",\n    iconPath: \"transform.png\"\n}\npublic function transform(string s) returns string {\n    return s.toUpperAscii();\n}\n\ntype AnnotRecord record {|\n    string value;\n|};\n\n// Declares an annotation tag on the type.\nannotation AnnotRecord annot on type;\n\n// The `@annot` annotation applies to the `T1` record type.\n@annot {\n    value: \"T1\"\n}\ntype T1 record {\n    string name;\n};\n\npublic function main() {\n    T1 a = {name: \"John\"};\n\n    typedesc<any> t = typeof a;\n    // Access annotation.\n    AnnotRecord? ann = t.@annot;\n\n    io:println(ann);\n}\n"
  },
  {
    "path": "examples/annotations/annotations.md",
    "content": "# Annotations\n\nAnnotations start with `@tag` and they come before what they apply to. Unprefixed tags refer to standard platform-defined annotations and prefixed tags refer to annotations declared in modules. The `@tag` can be followed by a record constructor expression.\n\n::: code annotations.bal :::\n\n::: out annotations.out :::"
  },
  {
    "path": "examples/annotations/annotations.metatags",
    "content": "description: This BBE demonstrates how to use annotations in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, annotations,\n"
  },
  {
    "path": "examples/annotations/annotations.out",
    "content": "$ bal run annotations.bal\n{\"value\":\"T1\"}\n"
  },
  {
    "path": "examples/anonymous-function/anonymous_function.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Infer anonymous function.\n    // The type of `x` is inferred from the function signature in the expected type.\n    function (int) returns int increment = x => x + 1;\n    io:println(increment(1));\n\n    // The type of `x` and `y` are inferred from the function signature in the expected type.\n    function (int, int) returns int add = (x, y) => x + y;\n    io:println(add(1, 2));\n\n    // The explicit anonymous function.\n    // The type of the `x` parameter is explicitly defined in the function signature.\n    var incrementByTwo = function(int x) returns int => x + 2;\n    io:println(incrementByTwo(1));\n\n    // The type of the `x` and `y` parameters are explicitly defined in the function signature.\n    var subtract = function(int x, int y) returns int {\n        return x - y;\n    };\n    io:println(subtract(2, 1));\n}\n"
  },
  {
    "path": "examples/anonymous-function/anonymous_function.md",
    "content": "# Anonymous function\n\nThe anonymous function is used to create function values. There are two different kinds of syntaxes in Ballerina to create anonymous functions. One is an explicit anonymous function of which the function is specified explicitly as usual with a function signature. The second is to infer an anonymous function of which the function type is inferred from the expected type.\n\n::: code anonymous_function.bal :::\n\n::: out anonymous_function.out :::\n\n## Related links\n- [Functions values](/learn/by-example/function-values/)\n- [Function types](/learn/by-example/function-types/)\n"
  },
  {
    "path": "examples/anonymous-function/anonymous_function.metatags",
    "content": "description: This BBE demonstrates creating an anonymous function, which is commonly known as an arrow function or lambda function in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, anonymous function, lambda function, arrow function, function values\n"
  },
  {
    "path": "examples/anonymous-function/anonymous_function.out",
    "content": "$ bal run anonymous_function.bal\n2\n3\n3\n1\n"
  },
  {
    "path": "examples/any-type/any_type.bal",
    "content": "import ballerina/io;\n\n// A variable of type `any` can hold any value except an `error` value.\nany x = 1;\n\npublic function main() {\n    // Can cast `any` to specific type.\n    int n = <int>x;\n    \n    io:println(n);\n\n    // The `lang.value` lang library contains functions that apply to multiple basic types.\n    // `x.toString()` converts `x` to a `string`.\n    string s = x.toString();\n\n    io:println(s == \"1\");\n\n    // Can test its type with the `is` operator.\n    float f = x is int|float ? <float>x : 0.0;\n\n    io:println(f);\n}\n"
  },
  {
    "path": "examples/any-type/any_type.md",
    "content": "# Any type\n\n`any` means any value except an `error` value. Equivalent to a union of all non-error basic types. Use `any|error` for absolutely any value. The `lang.value` lang library contains functions that apply to multiple basic types.\n\n::: code any_type.bal :::\n\n::: out any_type.out :::"
  },
  {
    "path": "examples/any-type/any_type.metatags",
    "content": "description: This BBE demonstrates the any type in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, any, any type\n"
  },
  {
    "path": "examples/any-type/any_type.out",
    "content": "$ bal run any_type.bal\n1\ntrue\n1.0\n"
  },
  {
    "path": "examples/anydata-to-yaml-string/anydata_to_yaml_string.bal",
    "content": "import ballerina/data.yaml;\nimport ballerina/io;\n\ntype ServerConfig record {|\n    string host;\n    int port;\n    DatabaseConfig database;\n|};\n\ntype DatabaseConfig record {|\n    string dbName;\n    string username;\n|};\n\npublic function main() returns error? {\n\n    ServerConfig serverConfig = {\n        database: {\n            dbName: \"userDB\",\n            username: \"testUser\"\n        },\n        port: 3000,\n        host: \"localhost\"\n    };\n\n    // Serialize a Ballerina value to a string in YAML format.\n    string serverConfigYamlStr = check yaml:toYamlString(serverConfig);\n    io:println(serverConfigYamlStr);\n}\n"
  },
  {
    "path": "examples/anydata-to-yaml-string/anydata_to_yaml_string.md",
    "content": "# Serialize a Ballerina value to a string in YAML format\n\nThe `data.yaml` library provides the `toYamlString` function to serialize a value belonging to `anydata` to a string in YAML format.\n\nFor more information on the underlying module, see the [`data.yaml` module](https://lib.ballerina.io/ballerina/data.yaml/latest/).\n\n::: code anydata_to_yaml_string.bal :::\n\n::: out anydata_to_yaml_string.out :::\n"
  },
  {
    "path": "examples/anydata-to-yaml-string/anydata_to_yaml_string.metatags",
    "content": "description: This BBE demonstrates how to serialize a value belonging to `anydata` to a string in YAML format.\nkeywords: ballerina, ballerina by example, BBE, yaml, yaml to string, record to yaml\n"
  },
  {
    "path": "examples/anydata-to-yaml-string/anydata_to_yaml_string.out",
    "content": "$ bal run anydata_to_yaml_string.bal\nhost: localhost\nport: 3000\ndatabase:\n  dbName: userDB\n  username: testUser\n"
  },
  {
    "path": "examples/anydata-type/anydata_type.bal",
    "content": "import ballerina/io;\n\nanydata x1 = [1, \"string\", true];\n// `x1.clone()` returns a deep copy with the same mutability.\nanydata x2 = x1.clone();\n\n// Checks deep equality.\nboolean eq = (x1 == x2);\n\npublic function main() {\n    io:println(x2);\n    io:println(eq);\n}\n"
  },
  {
    "path": "examples/anydata-type/anydata_type.md",
    "content": "# Anydata type\n\nThe type for plain data is `anydata`. It is a subtype of `any`. `==` and `!=` operators test for deep equality. `x.clone()` returns a deep copy with the same mutability. `x.cloneReadOnly()` returns a deep copy that is immutable. \n\nBallerina syntax uses `readonly` to mean immutable. Both `x.clone()` and `x.cloneReadOnly()` do not copy immutable parts of `x`. `const` structures are allowed. Equality and cloning handle cycles.\n\n::: code anydata_type.bal :::\n\n::: out anydata_type.out :::"
  },
  {
    "path": "examples/anydata-type/anydata_type.metatags",
    "content": "description: This BBE demonstrates anydata type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, anydata type\n"
  },
  {
    "path": "examples/anydata-type/anydata_type.out",
    "content": "$ bal run anydata_type.bal\n[1,\"string\",true]\ntrue\n"
  },
  {
    "path": "examples/array-map-symmetry/array_map_symmetry.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // List constructors are used to construct list values.\n    // Arrays are lists with a uniform member type.\n    string[] list = [\"foo\", \"bar\"];\n\n    // Mapping constructors are used to construct mapping values.\n    // Maps are mappings with a uniform member type.\n    map<int> mapping = {x: 1, y: 2};\n\n    // Indexing is used with lists and mappings to access members.\n    // Index type of lists is `int`.\n    string listMember = list[0];\n    io:println(listMember);\n\n    // Index type of mappings is `string`.\n    int? mapIndex = mapping[\"x\"];\n    io:println(mapIndex);\n\n    // A tuple type can be used to define per-index member types in a list.\n    [int, string, boolean] tuple = [1, \"John\", true];\n\n    int firstTupleMember = tuple[0];\n    string secondTupleMember = tuple[1];\n    boolean thirdTupleMember = tuple[2];\n\n    io:println(`Tuple [${firstTupleMember}, ${secondTupleMember}, ${thirdTupleMember}]`);\n\n    // A record type can be used to define per-index member types in a mapping.\n    record {\n        int id;\n        string name;\n        boolean checked;\n    } rec = {id: 1, name: \"John\", checked: true};\n\n    int id = rec.id;\n    string name = rec.name;\n    boolean checked = rec.checked;\n\n    io:println(`record {id: ${id}; name: ${name}; checked: ${checked}}`);\n\n    // Declares a tuple type as an open type.\n    // Tuple type with zero or more boolean values after the first two members.\n    [int, string, boolean...] openList = [1, \"John\"];\n    io:println(openList);\n\n    [int, string, boolean...] openList2 = [1, \"John\", true, false];\n    io:println(openList2);\n\n    // Declares a record type as an open type.\n    // Record type with zero or more boolean fileds after the first two fields.\n    record {|\n        int id;\n        string name;\n        boolean...;\n    |} openRecord = {id: 1, name: \"John\"};\n    io:println(openRecord);\n\n    record {|\n        int id;\n        string name;\n        boolean...;\n    |} openRecord2 = {id: 1, name: \"John\", \"checked\": true};\n    io:println(openRecord2);\n}\n"
  },
  {
    "path": "examples/array-map-symmetry/array_map_symmetry.md",
    "content": "# Array/map symmetry\n\nBallerina provides a fine symmetry between lists and mappings. Lists are indexed by integers and mappings are indexed by strings. In terms of the JSON format, lists are represented by arrays and mappings are represented by objects.\n\nThe constructor for lists uses square brackets and the constructor for mappings uses curly brackets. Both list and mappings types can be described in two ways using uniform member types and per-index member types. A list with a uniform  `T` member type is an array declared as `T[]`. A mapping with a uniform `T` type member is a map declared as `map<T>`. Similarly, a list with per-index member types `T0` and `T1` is a tuple, declared as `[T0, T1]`, and a mapping with per-index member types is a record declared as `record { Tx x; Ty y; }`. You can have an open type using the `...` notation. In the case of lists, an open type is declared as a tuple type as `[T0, Tr...]`. In the case of mappings, it is a record type declared as `record {| Tx x; Tr...; |}`.\n\n::: code array_map_symmetry.bal :::\n\n::: out array_map_symmetry.out :::"
  },
  {
    "path": "examples/array-map-symmetry/array_map_symmetry.metatags",
    "content": "description: This BBE demonstrates array map symmetry in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, array, map, array map symmetry\n"
  },
  {
    "path": "examples/array-map-symmetry/array_map_symmetry.out",
    "content": "$ bal run array_map_symmetry.bal\nfoo\n1\nTuple [1, John, true]\nrecord {id: 1; name: John; checked: true}\n[1,\"John\"]\n[1,\"John\",true,false]\n{\"id\":1,\"name\":\"John\"}\n{\"id\":1,\"name\":\"John\",\"checked\":true}\n"
  },
  {
    "path": "examples/arrays/arrays.bal",
    "content": "import ballerina/io;\n \nconst LENGTH = 3;\n \npublic function main() {\n    // Declare an int array of length 3.\n    int[3] numbers = [1, 2, 3];\n    io:println(numbers);\n \n    // Use a constant reference as the array length.\n    string[LENGTH] animals = [\"cat\", \"dog\", \"mouse\"];\n    io:println(animals);\n \n    // Declare a variable-length array.\n    int[] indexes = [1, 2];\n    indexes = [1, 2, 3, 4];\n    io:println(indexes);\n \n    // Length of the array can be inferred using `*`. The example below will declare an array of length 3.\n    string[*] colors = [\"red\", \"green\", \"blue\"];\n    io:println(colors);\n \n    // Elements of an array can be accessed using member access expression.\n    string firstColor = colors[0];\n    io:println(firstColor);\n \n    // Members of an array can be updated using member access expression in the LHS of an assignment.\n    colors[0] = \"pink\";\n    io:println(colors);\n \n    string[] names = [\"Mike\", \"Amy\", \"Korina\"];\n    // New members can be pushed to an open array by using the `array:push()` method.\n    names.push(\"Peter\");\n    io:println(names);\n \n    int length = names.length();\n    // The `array:length()` method can be used to get the length of an array.\n    io:println(length);\n \n    // An element can be removed using the `array:remove(n)` method by passing the index.\n    string secondPerson = names.remove(1);\n    io:println(secondPerson);\n    io:println(names.length());\n \n    string[] fullNames = [];\n    // Array can be iterated using a foreach statement.\n    // There are other ways like query expressions for the same purpose.\n    // This will iterate over the `names` array and create a new array by adding the surnames to each name.\n    foreach string name in names {\n        fullNames.push(string `${name} Johnson`);\n    }\n\n    io:println(fullNames);\n}\n"
  },
  {
    "path": "examples/arrays/arrays.md",
    "content": "# Arrays\n\nAn array can be used to hold a set of values of the same type. The array type can be defined as `T[n]` in which `T` is the element type and `n` is the fixed length of the array. `n` must be an integer literal or constant reference of type `int`. Optionally, you can create a variable-length array by defining an array without `n` as `T[]`.\n\nThe length of the array can be inferred from the context by defining the array as `T[*]`. The length of the array should be known in compile time.\nAn array with an inferred length is also a fixed-length array, where the length, inferred from the context, cannot be changed afterward.\n\n::: code arrays.bal :::\n\n::: out arrays.out :::\n\n## Related links\n- [Manipulating an array `(lang.array)`](https://lib.ballerina.io/ballerina/lang.array)\n- [Tuples](/learn/by-example/tuples)\n- [Nested arrays](/learn/by-example/nested-arrays)\n- [Filler values of a list](/learn/by-example/filler-values-of-a-list)\n- [List sub typing](/learn/by-example/list-subtyping)\n- [List equality](/learn/by-example/list-equality)\n"
  },
  {
    "path": "examples/arrays/arrays.metatags",
    "content": "description: Create a collection in Ballerina, Create an array, Create fixed length collection, Create a variable length array, Create array without length, Get array size from the context, Accessing an array, Iterating an array, Updating an array.\nkeywords: ballerina, ballerina by example, bbe, arrays, mutable list, collection, length, size, list, array type, list type, infer length, access, remove, push, delete\n\n"
  },
  {
    "path": "examples/arrays/arrays.out",
    "content": "$ bal run arrays.bal\n[1,2,3]\n[\"cat\",\"dog\",\"mouse\"]\n[1,2,3,4]\n[\"red\",\"green\",\"blue\"]\nred\n[\"pink\",\"green\",\"blue\"]\n[\"Mike\",\"Amy\",\"Korina\",\"Peter\"]\n4\nAmy\n3\n[\"Mike Johnson\",\"Korina Johnson\",\"Peter Johnson\"]\n"
  },
  {
    "path": "examples/asynchronize-message-passing/asynchronize_message_passing.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    worker A {\n        int num = 10;\n\n        // Sends the `10` integer value to the `B` worker asynchronously.\n        num -> B;\n        \n        // Receives the `Hello` string from the `B` worker.\n        string msg = <- B;\n        io:println(string `Received string \"${msg}\" from worker B`);\n    }\n\n    worker B {\n        int num;\n\n        // Receives the `10` integer value from the `A` worker.\n        num = <- A;\n        io:println(string `Received integer \"${num}\" from worker A`);\n\n        // Sends the `Hello` string to the `A` worker asynchronously.\n        string msg = \"Hello\";\n        msg -> A;\n    }\n}\n"
  },
  {
    "path": "examples/asynchronize-message-passing/asynchronize_message_passing.md",
    "content": "# Asynchronize message passing\n\nUse `-> W` to send a message asynchronously to a `W` worker.  These messages should be of the `anydata` type. The sending worker will send all messages even though the receiving worker panics or returns an error.\n\n::: code asynchronize_message_passing.bal :::\n\n::: out asynchronize_message_passing.out :::\n"
  },
  {
    "path": "examples/asynchronize-message-passing/asynchronize_message_passing.metatags",
    "content": "desdescription: This BBE demonstrates how the `async send` action can be used for concurrency in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, async send, concurrency, worker\n"
  },
  {
    "path": "examples/asynchronize-message-passing/asynchronize_message_passing.out",
    "content": "$ bal run async_send.bal\nReceived integer \"10\" from worker A\nReceived string \"Hello\" from worker B\n"
  },
  {
    "path": "examples/asynchronous-function-calls/asynchronous_function_calls.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // `start` calls a function asynchronously.\n    future<int> fut = start foo();\n\n    // `wait` for `future<T>` gives `T|error`.\n    int|error x = wait fut;\n\n    io:println(x);\n}\n\nfunction foo() returns int {\n    return 10;\n}\n"
  },
  {
    "path": "examples/asynchronous-function-calls/asynchronous_function_calls.md",
    "content": "# Asynchronous function calls\n\n`start` calls a function asynchronously and the function runs on a separate logical thread (`strand`). It is cooperatively multitasked by default.\n\nThe result will be of type `future<T>` and `future` is a separate basic type. Waiting for the same `future` more than once gives an `error`. Use `f.cancel()` to terminate a `future`.\n\n::: code asynchronous_function_calls.bal :::\n\n::: out asynchronous_function_calls.out :::"
  },
  {
    "path": "examples/asynchronous-function-calls/asynchronous_function_calls.metatags",
    "content": "description: This BBE demonstrates how to use start action to call a function asynchronouly.\nkeywords:  ballerina, ballerina by example, bbe, start, Asynchronous function call\n"
  },
  {
    "path": "examples/asynchronous-function-calls/asynchronous_function_calls.out",
    "content": "$ bal run asynchronous_function_calls.bal\n10\n"
  },
  {
    "path": "examples/avro-serdes/avro_serdes.bal",
    "content": "import ballerina/avro;\nimport ballerina/io;\n\n// Define a type, which is a subtype of anydata.\ntype Student record {\n    int id;\n    string name;\n};\n\npublic function main() returns error? {\n    // Assign the value to the variable.\n    Student student = {\n        id: 1,\n        name: \"John\"\n    };\n\n    // Create a schema instance by passing the string value of an Avro schema.\n    avro:Schema schema = check new (string `{\n        \"namespace\": \"example.avro\",\n        \"type\": \"record\",\n        \"name\": \"Student\",\n        \"fields\": [\n            {\n                \"name\": \"id\", \n                \"type\": \"int\"\n            },\n            {\n                \"name\": \"name\",\n                \"type\": \"string\"\n            }\n        ]\n    }`);\n\n    // Serialize the record value to bytes.\n    byte[] serializedData = check schema.toAvro(student);\n\n    // Deserialize the record value to bytes. \n    Student studentResult = check schema.fromAvro(serializedData);\n\n    // Print deserialized data.\n    io:println(\"Student ID: \", studentResult.id);\n    io:println(\"Student Name: \", studentResult.name);\n}\n"
  },
  {
    "path": "examples/avro-serdes/avro_serdes.md",
    "content": "# Avro - Serialization/Deserialization\n\nThe `avro` module allows serializing and deserializing data with the `anydata` type. Initially, an `avro:Schema` instance must be created by providing a `string` value representing an Avro schema. The `toAvro()` and `fromAvro()` methods of the `avro` module serialize and deserialize data using the given Avro schema.\n\nThe `toAvro()` method serializes the data according to the specified Avro schema. The `fromAvro()` method accepts a `byte[]` argument containing serialized data and binds the deserialized value to the inferred data type determined by the user.\n\n::: code avro_serdes.bal :::\n\nRun the program by executing the following command.\n\n::: out avro_serdes.out :::\n\n## Related links\n\n- [`avro` - API documentation](https://central.ballerina.io/ballerina/avro/)\n- [`avro` - Specification](/spec/avro)\n"
  },
  {
    "path": "examples/avro-serdes/avro_serdes.metatags",
    "content": "description: This example demonstrates data serialization/deserialization using Avro schemas.\nkeywords: ballerina, ballerina by example, avro, serdes, serialization, deserialization\n"
  },
  {
    "path": "examples/avro-serdes/avro_serdes.out",
    "content": "$ bal run avro_serdes.bal\nStudent ID: 1\nStudent Name: John\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/aws_deploy.out",
    "content": "$ aws lambda create-function --function-name dynamoDBTrigger --zip-file fileb://aws-ballerina-lambda-functions.zip --handler aws-lambda-dynamodb-trigger.dynamoDBTrigger --runtime provided --role arn:aws:iam::908363916111:role/lambda-role--layers arn:aws:lambda:us-west-1:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/aws_lambda_dynamodb_trigger.bal",
    "content": "import ballerina/io;\nimport ballerinax/aws.lambda;\n\n@lambda:Function\npublic function dynamoDBTrigger(lambda:Context ctx,\n        lambda:DynamoDBEvent event) returns json {\n    io:println(event.Records[0].dynamodb.Keys.toString());\n    return event.Records[0].dynamodb.Keys.toString();\n}\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/aws_lambda_dynamodb_trigger.md",
    "content": "# AWS Lambda - DynamoDB trigger\n\nThis example creates a function, which will be executed for each entry added to a database in the [DynamoDB](https://aws.amazon.com/dynamodb/).\n\nFor more information, see the [AWS Lambda learn guide](https://ballerina.io/learn/aws-lambda/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/aws-lambda/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code aws_lambda_dynamodb_trigger.bal :::\n\n## Build the function \n\nExecute the command below to generate the AWS Lambda artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the AWS CLI command given by the compiler to create and publish the functions by replacing the respective AWS `$LAMBDA_ROLE_ARN`, `$REGION_ID`, and `$FUNCTION_NAME` values given in the command with your values.\n\n::: out aws_deploy.out :::\n\n## Invoke the function\n\nFollow the instructions below to create a DynamoDB table for invoking this function.\n\n1. In the IAM Console, click the corresponding role in the list, and click **Add permissions**.\n2. Select **attach policies** from the drop-down menu, and add the **AWSLambdaDynamoDBExecutionRole** to the role.\n3. Go to [DynamoDB](https://console.aws.amazon.com/dynamodbv2), and from the drop-down menu at the top RHS of the screen, select the **AWS region** in which you created the user and role.\n4. Click **Create Table**, enter a table name and a partition key, and create the table (if you already have a table created, you can skip this step).\n5. Click on the DynamoDB table you created, and then click the **Exports and streams** tab.\n6. Click **Turn on** under **DynamoDB stream details**, select **Key attributes only** for the event type, and click **Turn on stream**.\n8. Under the **Trigger** section, click **Create trigger**, select the `dynamoDBTrigger` from the drop-down, and click **Create trigger**.\n9. Click **Explore table items**, and click **Create items** under the **Items returned** section.\n10. Enter a value under the **Attributes** section to add an entry to the DynamoDB table to invoke the Lambda function, and click **Create item**.\n11. Click the **Monitor** tab of the Lambda function in the AWS Management Console, and click **View CloudWatch logs** to check the logs via CloudWatch.\n11. Under **Log streams** in CloudWatch, click on the topmost stream in the list and verify the object name in the logs.\n12. Go to the AWS Lambda function and check the logs via CloudWatch to see the object identifier in the logs.\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/aws_lambda_dynamodb_trigger.metatags",
    "content": "description: This example creates a function, which will be executed for each entry added to a database in the DynamoDB.\nkeywords:  ballerina, ballerina by example, aws lambda, dynamodb, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/bal_build.out",
    "content": "$ bal build\nCompiling source\n        wso2/aws_lambda_dynamodb_trigger:0.1.0\n\nGenerating executable\n        @awslambda:Function: dynamoDBTrigger\n\n        Run the following command to deploy each Ballerina AWS Lambda function:\n        aws lambda create-function --function-name $FUNCTION_NAME --zip-file fileb://<project-dir>/aws-lambda-s3-trigger/target/bin/aws-ballerina-lambda-functions.zip --handler aws-lambda-dynamodb-trigger.$FUNCTION_NAME --runtime provided --role $LAMBDA_ROLE_ARN --layers arn:aws:lambda:$REGION_ID:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n\n        Run the following command to re-deploy an updated Ballerina AWS Lambda function:\n        aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://aws-ballerina-lambda-functions.zip\n"
  },
  {
    "path": "examples/aws-lambda-dynamodb-trigger/bal_new.out",
    "content": "$ bal new aws_lambda_dynamodb_trigger\nCreated new package 'aws_lambda_dynamodb_trigger' at /Users/wso2/aws_lambda_dynamodb_trigger.\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/aws_deploy.out",
    "content": "$ aws lambda create-function --function-name ctxinfo --zip-file fileb://aws-ballerina-lambda-functions.zip --handler aws-lambda-execution-context.ctxinfo --runtime provided --role arn:aws:iam::908363916111:role/lambda-role --layers arn:aws:lambda:us-west-1:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/aws_lambda_execution_context.bal",
    "content": "import ballerinax/aws.lambda;\n\n// The `lambda:Context` object contains request execution context information.\n@lambda:Function\npublic function ctxinfo(lambda:Context ctx, json input) returns json|error {\n    return {\n        RequestID: ctx.getRequestId(),\n        DeadlineMS: ctx.getDeadlineMs(),\n        InvokedFunctionArn: ctx.getInvokedFunctionArn(),\n        TraceID: ctx.getTraceId(),\n        RemainingExecTime: ctx.getRemainingExecutionTime()\n    };\n}\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/aws_lambda_execution_context.md",
    "content": "# AWS Lambda - Execution context\n\nThe example below demonstrates how the execution context information of an AWS function can be retrieved.\n\nFor more information, see the [AWS Lambda learn guide](https://ballerina.io/learn/aws-lambda/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/aws-lambda/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code aws_lambda_execution_context.bal :::\n\n## Build the function\n\nExecute the command below to generate the AWS Lambda artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the AWS CLI command given by the compiler to create and publish the functions by replacing the respective AWS `$LAMBDA_ROLE_ARN`, `$REGION_ID`, and `$FUNCTION_NAME` values given in the command with your values. \n\n::: out aws_deploy.out :::\n\n## Invoke the function\n\nExecute the commands below to invoke the function.\n\n::: out invoke_functions.out :::\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/aws_lambda_execution_context.metatags",
    "content": "description: The example below demonstrates how the execution context information of an AWS function can be retrieved.\nkeywords:  ballerina, ballerina by example, aws lambda, execution context, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/bal_build.out",
    "content": "$ bal build\nCompiling source\n        wso2/aws_lambda_execution_context:0.1.0\n\nGenerating executable\n        @awslambda:Function: ctxinfo\n\n        Run the following command to deploy each Ballerina AWS Lambda function:\n        aws lambda create-function --function-name $FUNCTION_NAME --zip-file fileb://<project-dir>/aws-lambda-execution-context/target/bin/aws-ballerina-lambda-functions.zip --handler aws_lambda_deployment.$FUNCTION_NAME --runtime provided --role $LAMBDA_ROLE_ARN --layers arn:aws:lambda:$REGION_ID:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n\n        Run the following command to re-deploy an updated Ballerina AWS Lambda function:\n        aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://aws-ballerina-lambda-functions.zip\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/bal_new.out",
    "content": "$ bal new aws_lambda_execution_context\nCreated new package 'aws_lambda_execution_context' at /Users/wso2/aws_lambda_execution_context.\n"
  },
  {
    "path": "examples/aws-lambda-execution-context/invoke_functions.out",
    "content": "$ echo '{\"MESSAGE\":\"HELLO\"}' > input.json\n$ aws lambda invoke --function-name ctxinfo ctxinfo-response.txt\n{\n\"ExecutedVersion\": \"$LATEST\",\n\"StatusCode\": 200\n}\n$ cat ctxinfo-response.txt\n{\"RequestID\":\"d55f7d06-f2ab-4b6e-8606-482607785a91\", \"DeadlineMS\":1548069389978, \"InvokedFunctionArn\":\"arn:aws:lambda:us-west-2:908363916138:function:ctxinfo\", \"TraceID\":\"Root=1-5c45aa03-f8aff4c9e24dc4fbf48f2990;Parent=17ad3b290def98fd;Sampled=0\", \"RemainingExecTime\":9946}\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/aws_deploy.out",
    "content": "$ aws lambda create-function --function-name echo --zip-file fileb://aws-ballerina-lambda-functions.zip --handler aws-lambda-hello-world.echo --runtime provided --role arn:aws:iam::908363916111:role/lambda-role--layers arn:aws:lambda:us-west-1:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/aws_lambda_hello_world.bal",
    "content": "import ballerina/io;\nimport ballerinax/aws.lambda;\n\n// The `@lambda:Function` annotation marks a function to generate an AWS Lambda function.\n@lambda:Function\npublic function echo(lambda:Context ctx, json input) returns json {\n    io:println(input.toJsonString());\n    return input;\n}\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/aws_lambda_hello_world.md",
    "content": "# AWS Lambda - Hello world\n\nThis example demonstrates how to write a simple echo function in AWS Lambda.\n\nFor more information, see the [AWS Lambda learn guide](https://ballerina.io/learn/aws-lambda/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/aws-lambda/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code aws_lambda_hello_world.bal :::\n\n## Build the function\n\nExecute the command below to generate the AWS Lambda artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the AWS CLI command given by the compiler to create and publish the functions by replacing the respective AWS `$LAMBDA_ROLE_ARN`, `$REGION_ID`, and `$FUNCTION_NAME` values given in the command with your values.\n\n::: out aws_deploy.out :::\n\n## Invoke the function\n\nExecute the commands below to invoke the function.\n\n::: out invoke_functions.out :::\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/aws_lambda_hello_world.metatags",
    "content": "description: This example demonstrates how to write a simple echo function in AWS Lambda.\nkeywords:  ballerina, ballerina by example, serverless, aws lambda, cloud, function as a service\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/bal_build.out",
    "content": "$ bal build\nCompiling source\n        wso2/aws_lambda_hello_world:0.1.0\n\nGenerating executable\n        @awslambda:Function: echo\n\n        Run the following command to deploy each Ballerina AWS Lambda function:\n        aws lambda create-function --function-name $FUNCTION_NAME --zip-file fileb://<project-dir>/aws-lambda-hello-world/target/bin/aws-ballerina-lambda-functions.zip --handler aws-lambda-hello-world.$FUNCTION_NAME --runtime provided --role $LAMBDA_ROLE_ARN --layers arn:aws:lambda:$REGION_ID:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n\n        Run the following command to re-deploy an updated Ballerina AWS Lambda function:\n        aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://aws-ballerina-lambda-functions.zip\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/bal_new.out",
    "content": "$ bal new aws_lambda_hello_world\nCreated new package 'aws_lambda_hello_world' at /Users/wso2/aws_lambda_hello_world.\n"
  },
  {
    "path": "examples/aws-lambda-hello-world/invoke_functions.out",
    "content": "$ echo '{\"MESSAGE\":\"HELLO\"}' > input.json\n$ aws lambda invoke --function-name echo --payload fileb://input.json echo-response.txt\n{\n\"ExecutedVersion\": \"$LATEST\",\n\"StatusCode\": 200\n}\n$ cat echo-response.txt\n{\"MESSAGE\":\"HELLO\"}\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/aws_deploy.out",
    "content": "$ aws lambda create-function --function-name s3Trigger --zip-file fileb://aws-ballerina-lambda-functions.zip --handler aws-lambda-s3-trigger.s3Trigger --runtime provided --role arn:aws:iam::908363916111:role/lambda-role--layers arn:aws:lambda:us-west-1:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/aws_lambda_s3_trigger.bal",
    "content": "import ballerina/io;\nimport ballerinax/aws.lambda;\n\n@lambda:Function\npublic function s3Trigger(lambda:Context ctx,\n        lambda:S3Event event) returns json {\n    io:println(event.Records[0].s3.'object.key);\n    return event.Records[0].s3.'object.key;\n}\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/aws_lambda_s3_trigger.md",
    "content": "# AWS Lambda - S3 trigger\n\nThis example creates a function, which will be executed for each object creation in AWS S3.\n\nFor more information, see the [AWS Lambda learn guide](https://ballerina.io/learn/aws-lambda/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/aws-lambda/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code aws_lambda_s3_trigger.bal :::\n\n## Build the function\n\nExecute the command below to generate the AWS Lambda artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the AWS CLI command given by the compiler to create and publish the functions by replacing the respective AWS `$LAMBDA_ROLE_ARN`, `$REGION_ID`, and `$FUNCTION_NAME` values given in the command with your values.\n\n::: out aws_deploy.out :::\n\n## Invoke the function\n\nFollow the instructions below to create an S3 bucket in AWS for invoking this function.\n\n1. Go to the [AWS S3](https://s3.console.aws.amazon.com/s3/) portal and create a bucket.\n   >**Note:** Make sure to select the same **AWS region** in which you created the AWS user and role when creating the S3 bucket.\n2. Click on the created bucket, go to the **Properties** tab, and click **Create event notification** under the **Event notifications** section.\n3. Enable **All object create events** under event types. \n4. Under the **Destination** section, select the AWS Lambda function (i.e., `s3Trigger` in this example) from the dropdown.\n5. Select the created bucket under the **Buckets** list, click **Upload**, and upload an object to the S3 bucket.\n6. Under the **Functions** list of the AWS Management Console, click the AWS Lambda function, and click the **Monitor** tab.\n7. If you get a **Missing permissions** notice at the top, click the **Open the IAM Console** in it.\n8. In the IAM Console, click the corresponding role in the list, and click **Add permissions**.\n9. Select **attach policies** from the drop-down menu, and add the **AWSLambdaBasicExecutionRole** to the role.\n10. Click the **Monitor** tab of the Lambda function in the AWS Management Console, and click **View CloudWatch logs** to check the logs via CloudWatch.\n11. Under **Log streams** in CloudWatch, click on the topmost stream in the list and verify the object name in the logs.\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/aws_lambda_s3_trigger.metatags",
    "content": "description: This example creates a function, which will be executed for each object creation in AWS S3.\nkeywords:  ballerina, ballerina by example, aws lambda, s3, trigger, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/bal_build.out",
    "content": "$ bal build\nCompiling source\n        wso2/aws_lambda_s3_trigger:0.1.0\n\nGenerating executable\n        @awslambda:Function: s3Trigger\n\n        Run the following command to deploy each Ballerina AWS Lambda function:\n        aws lambda create-function --function-name $FUNCTION_NAME --zip-file fileb://<project-dir>/aws-lambda-s3-trigger/target/bin/aws-ballerina-lambda-functions.zip --handler aws-lambda-s3-trigger.$FUNCTION_NAME --runtime provided --role $LAMBDA_ROLE_ARN --layers arn:aws:lambda:$REGION_ID:134633749276:layer:ballerina-jre11:6 --memory-size 512 --timeout 10\n\n        Run the following command to re-deploy an updated Ballerina AWS Lambda function:\n        aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://aws-ballerina-lambda-functions.zip\n"
  },
  {
    "path": "examples/aws-lambda-s3-trigger/bal_new.out",
    "content": "$ bal new aws_lambda_s3_trigger\nCreated new package 'aws_lambda_s3_trigger' at /Users/wso2/aws_lambda_s3_trigger.\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/az_deploy.out",
    "content": "$ func azure functionapp publish <function_app_name> --script-root target/azure_functions\nGetting site publishing info...\nCreating archive for current directory...\nUploading 32.71 MB [##############################################################################]\nUpload completed successfully.\nDeployment completed successfully.\nSyncing triggers...\nFunctions in <function_app_name>:\n    cosmos - [cosmosDBTrigger]\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/azure_functions_cosmosdb_trigger.bal",
    "content": "import ballerina/io;\nimport ballerinax/azure.functions;\n\npublic type DBEntry record {\n    string id;\n    string name;\n};\n\n@functions:CosmosDBTrigger {connectionStringSetting: \"CosmosDBConnection\", databaseName: \"db1\", collectionName: \"c1\"}\nlistener functions:CosmosDBListener cosmosEp = new ();\n\nservice \"cosmos\" on cosmosEp {\n    remote function onUpdate(DBEntry[] entries) returns @functions:QueueOutput {queueName: \"people\"} string {\n        string name = entries[0].name;\n        io:println(entries.toJsonString());\n        return \"Hello, \" + name;\n    }\n}\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/azure_functions_cosmosdb_trigger.md",
    "content": "# Azure Functions - Cosmos DB trigger\n\nThis example demonstrates using a Cosmos DB trigger to invoke an Azure function and a queue output binding to write an entry to a queue.\n\nFor more information, see the [Azure Functions deployment guide](https://ballerina.io/learn/azure-functions/).\n\n## Set up the prerequisites\n\nFollow the steps below to create a Cosmos DB and a queue to make use of those services later in this example.\n\n1. Set up the [general prerequisites](https://ballerina.io/learn/azure-functions/#set-up-the-prerequisites).\n2. Create the queue in the [HTTP trigger](/learn/by-example/azure-functions/http-trigger/) example to resue it in this one.\n3. In the [**Azure Cosmos DB** service of the Azure Portal](https://portal.azure.com/#create/Microsoft.DocumentDB), click **Create**, and select **Azure Cosmos DB for NoSQL**.\n4. Enter an account name and a resource group name, and click **Review + Create**, and then, click **Create**.\n5. Once the database is created, go to the **Data Explorer**, and select **Create Container**.\n6. Enter `db1` as the Database ID, `c1` as the collection ID, and click **Ok**.\n    >**Note:** If you want to change these values, change them in the code as well.\n7. Go to the **Keys** tab of the Cosmos DB page.\n8. Copy the value of the `PRIMARY CONNECTION STRING`.\n9. Click the **Configuration** tab on the function app page.\n10. Select **New Application Setting**, and paste the data you copied above as the value. \n    >**Tip:** For the key, use the value of the `connectionStringSetting` key and save.\n\n    Example application settings are as follows.\n\n    - Name - `CosmosDBConnection`\n    - Value - `AccountEndpoint=https://db-cosmos.documents.azure.com:443/;AccountKey=12345asda;`\n\nNow, as all the infrastructure required is up and running and configured, start building and deploying the Azure function.\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code azure_functions_cosmosdb_trigger.bal :::\n\n## Build the function\n\nExecute the command below to generate the Azure Functions artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the Azure CLI command given by the compiler to create and publish the functions by replacing `<function_app_name>` with your respective function app name.\n\n## Invoke the function\n\nOnce the function is deployed, add an item to the collection.\n\n1. Navigate to the collection created in the **Data Explorer**.\n2. Click **New Item** to add a new item to the collection.\n3. Go to the queue page and observe the added new entry.\n\n>**Info:** Additionally, for debugging purposes, view the logs under the **Logs stream** in the function app.\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/azure_functions_cosmosdb_trigger.metatags",
    "content": "description: This example demonstrates using a Cosmos DB trigger to invoke an AWS Lambda function and a queue output binding to write an entry to a queue.\nkeywords:  ballerina, ballerina by example, aws lambda, cosmos db, trigger, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/bal_build.out",
    "content": "$ bal build --cloud=\"azure_functions\"\nCompiling source\n\twso2/azure_functions_cosmosdb_trigger:0.1.0\n\nGenerating executable\n\n\t@azure.functions:Function: cosmos\n\n\tExecute the command below to deploy the function locally:\n\t$ func start --script-root target/azure_functions --java\n\n\tExecute the command below to deploy Ballerina Azure Functions:\n\t$ func azure functionapp publish <function_app_name> --script-root target/azure_functions \n\n\ttarget/bin/azure_functions_cosmosdb_trigger.jar\n"
  },
  {
    "path": "examples/azure-functions-cosmosdb-trigger/bal_new.out",
    "content": "$ bal new azure_functions_cosmosdb_trigger\nCreated new package 'azure_functions_cosmosdb_trigger' at /Users/wso2/azure_functions_cosmosdb_trigger.\n"
  },
  {
    "path": "examples/azure-functions-hello-world/az_deploy.out",
    "content": "$ func azure functionapp publish <function_app_name> --script-root target/azure_functions\nGetting site publishing info...\nCreating archive for current directory...\nUploading 32.69 MB [##############################################################################]\nUpload completed successfully.\nDeployment completed successfully.\nSyncing triggers...\nFunctions in <function_app_name>:\n    get-hello - [httpTrigger]\n        Invoke url: https://azurecosmosdbfunctionapp.azurewebsites.net/hello\n"
  },
  {
    "path": "examples/azure-functions-hello-world/azure_functions_hello_world.bal",
    "content": "import ballerinax/azure.functions;\n\n// This function gets triggered by an HTTP call with the name query parameter and \n// returns a processed HTTP output to the caller.\nservice / on new functions:HttpListener() {\n    resource function get hello(string name) returns string {\n        return string `Hello,  ${name}!`;\n    }\n}\n"
  },
  {
    "path": "examples/azure-functions-hello-world/azure_functions_hello_world.md",
    "content": "# Azure Functions - Hello world\n\nThis example demonstrates how to write a simple echo function in Azure Functions.\n\nIn Ballerina, triggers are represented by listeners. When the `af:HttpListener` gets attached to the service, it implies that the function is an HTTP Trigger. The resource method behaves exactly the same as a service written from `ballerina/http`. It supports the `http:Payload` and `http:Header` annotations for parameters. Input binding annotations can be used to annotate parameters to make use of external services in Azure. If no annotations are specified for a parameter, it is identified as a query parameter.\n\nOutput bindings are defined in the return type definition. For services with the `HttpListener` attachment, `HttpOutput` is the default output binding. You can override the default behavior by specifying them explicitly in the return type. \n\nIn the code sample shown above, it has an empty service path and resource path named `hello`. The accessor is `get`. It expects a request with a query parameter for the field name. The required artifact generation and data binding will be handled by the `ballerinax/azure_functions` package automatically.\n\nFor more information, see the [Azure deployment guide](https://ballerina.io/learn/azure-functions/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/azure-functions/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code azure_functions_hello_world.bal :::\n\n## Build the function\n\nExecute the command below to generate the Azure Functions artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the Azure CLI command given by the compiler to create and publish the functions by replacing `<function_app_name>` with your respective function app name.\n\n::: out az_deploy.out :::\n\n## Invoke the function\n\nExecute the command below to invoke the function by replacing `<function_app_name>` with your respective function app name.\n\n::: out execute_function.out :::\n"
  },
  {
    "path": "examples/azure-functions-hello-world/azure_functions_hello_world.metatags",
    "content": "description: This example demonstrates how to write a hello world function with http trigger and output in Azure Functions.\nkeywords:  ballerina, ballerina by example, azure functions, function as a service, serverless\n"
  },
  {
    "path": "examples/azure-functions-hello-world/bal_build.out",
    "content": "$ bal build --cloud=\"azure_functions\"\nCompiling source\n\twso2/azure_functions_hello_world:0.1.0\n\nGenerating executable\n\n\t@azure.functions:Function: get-hello\n\n\tExecute the command below to deploy the function locally:\n\t$ func start --script-root target/azure_functions --java\n\n\tExecute the command below to deploy Ballerina Azure Functions:\n\t$ func azure functionapp publish <function_app_name> --script-root target/azure_functions \n\n\ttarget/bin/azure_functions_hello_world.jar\n"
  },
  {
    "path": "examples/azure-functions-hello-world/bal_new.out",
    "content": "$ bal new azure_functions_hello_world\nCreated new package 'azure_functions_hello_world' at /Users/wso2/azure_functions_hello_world.\n"
  },
  {
    "path": "examples/azure-functions-hello-world/execute_function.out",
    "content": "$ curl https://<function_app_name>.azurewebsites.net/hello\\?name\\=Jack\nHello, Jack!\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/az_deploy.out",
    "content": "$ func azure functionapp publish <function_app_name> --script-root target/azure_functions\nGetting site publishing info...\nCreating archive for current directory...\nUploading 32.71 MB [##############################################################################]\nUpload completed successfully.\nDeployment completed successfully.\nSyncing triggers...\nFunctions in <function_app_name>:\n    post-queue - [httpTrigger]\n        Invoke url: https://azurecosmosdbfunctionapp.azurewebsites.net/queue\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/azure_functions_http_trigger_with_queue.bal",
    "content": "import ballerina/http;\nimport ballerinax/azure.functions;\n\npublic type Person record {\n    string name;\n    int age;\n};\n\nservice / on new functions:HttpListener() {\n    resource function post queue(@http:Payload Person person) returns\n    [@functions:HttpOutput http:Created, @functions:QueueOutput {queueName: \"people\"}\n    string] {\n        http:Created httpRes = {\n            body: person.name + \" Added to the Queue!\"\n        };\n        return [httpRes, string `${person.name} is ${person.age.toString()} years old.`];\n    }\n}\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/azure_functions_http_trigger_with_queue.md",
    "content": "# Azure Functions - HTTP trigger with queue\n\nThis example demonstrates using an HTTP trigger to invoke an Azure function with multiple output bindings to return the HTTP response and queue output binding to write an entry to a queue.\n\nFor more information, see the [Azure Functions deployment guide](https://ballerina.io/learn/azure-functions/).\n\n## Set up the prerequisites\n\n1. Set up the [general prerequisites](https://ballerina.io/learn/azure-functions/#set-up-the-prerequisites).\n2. In the AWS Portal, click **Storage accounts** to create a queue to hold the outputs of the function.\n2. From the list, click on the storage account entry that corresponds with your function app.\n3. Click **Queues** in the sidebar, and click **+ Queue**.\n4. Enter a name in the **Add queue** pop-up, and click **Add**.\n   >**Note:** For the **Queue name**, enter the same value of the `queueName` property in the `QueueOutput` annotation in the [Ballerina source below](https://ballerina.io/learn/by-example/azure-functions-trigger/#write-the-function)\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code azure_functions_http_trigger_with_queue.bal :::\n\n## Build the function\n\nExecute the command below to generate the Azure Functions artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the Azure CLI command given by the compiler to create and publish the functions by replacing `<function_app_name>` with your respective function app name.\n\n## Invoke the function\n\nExecute the command below by replacing `<function_app_name>` with your respective function app name to invoke the function.\n\n::: out execute_function.out :::\n\n>**Tip:** Refresh the page of the `people` queue in the Azure portal and view the entry added with the message text: `Jack is 21 years old.`\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/azure_functions_http_trigger_with_queue.metatags",
    "content": "description: This example demonstrates using an HTTP trigger to invoke an Azure function with multiple output bindings to return the HTTP response and queue output binding to write an entry to a queue.\nkeywords:  ballerina, ballerina by example, aws lambda, http, trigger, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/bal_build.out",
    "content": "$ bal build --cloud=\"azure_functions\"\nCompiling source\n\twso2/azure_functions_http_trigger_with_queue:0.1.0\n\nGenerating executable\n\n\t@azure.functions:Function: post-queue\n\n\tExecute the command below to deploy the function locally:\n\t$ func start --script-root target/azure_functions --java\n\n\tExecute the command below to deploy Ballerina Azure Functions:\n\t$ func azure functionapp publish <function_app_name> --script-root target/azure_functions \n\n\ttarget/bin/azure_functions_http_trigger_with_queue.jar\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/bal_new.out",
    "content": "$ bal new azure_functions_http_trigger_with_queue\nCreated new package 'azure_functions_http_trigger_with_queue' at /Users/wso2/azure_functions_http_trigger_with_queue.\n"
  },
  {
    "path": "examples/azure-functions-http-trigger-with-queue/execute_function.out",
    "content": "$ curl --header \"Content-Type: application/json\" \\\n  --request POST \\\n  --data '{\"name\":\"Jack\",\"age\":21}' \\\n  \"https://<function_app_name>.azurewebsites.net/queue\"\nJack Added to the Queue!\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/az_deploy.out",
    "content": "$ func azure functionapp publish <function_app_name> --script-root target/azure_functions\nGetting site publishing info...\nCreating archive for current directory...\nUploading 32.7 MB [###############################################################################]\nUpload completed successfully.\nDeployment completed successfully.\nSyncing triggers...\nFunctions in <function_app_name>:\n    timer - [timerTrigger]\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/azure_functions_timer_trigger.bal",
    "content": "import ballerina/time;\nimport ballerinax/azure.functions;\n\n// This function gets executed every 10 seconds by the Azure Functions app. Once the function is executed, the timer \n// details will be stored in the selected queue storage for every invocation.\n@functions:TimerTrigger {schedule: \"*/10 * * * * *\"}\nlistener functions:TimerListener timerListener = new functions:TimerListener();\n\nservice \"timer\" on timerListener {\n    remote function onTrigger(functions:TimerMetadata metadata) returns\n    @functions:QueueOutput {queueName: \"timer-queue\"} string|error {\n        time:Utc utc = time:utcNow();\n        return \"Hello from timer: \" + time:utcToEmailString(utc);\n    }\n}\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/azure_functions_timer_trigger.md",
    "content": "# Azure Functions - Timer trigger\n\nThis example demonstrates how a function can be scheduled to execute periodically by the Azure Functions app. Once the function is executed, the timer details will be stored in the selected queue storage for every invocation.\n\nFor more information, see the [Azure deployment guide](https://ballerina.io/learn/azure-functions/).\n\n## Set up the prerequisites\n\nFor instructions, see [Set up the prerequisites](https://ballerina.io/learn/azure-functions/#set-up-the-prerequisites).\n\n## Write the function\n\nFollow the steps below to write the function.\n\n1. Execute the command below to create a new Ballerina package.\n\n::: out bal_new.out :::\n\n2. Replace the content of the generated Ballerina file with the content below.\n\n::: code azure_functions_timer_trigger.bal :::\n\n## Build the function\n\nExecute the command below to generate the Azure Functions artifacts.\n\n::: out bal_build.out :::\n\n## Deploy the function\n\nExecute the Azure CLI command given by the compiler to create and publish the functions by replacing `<function_app_name>` with your respective function app name.\n\n## Invoke the function\n\nThe `timer` function is triggered by the Azure Functions app from a timer. Follow the steps below to verify the output in the queue storage of the function app.\n\n1. In the AWS Portal, click **Storage accounts** to view the created queue.\n2. From the list, click on the storage account entry that corresponds with your function app.\n3. Click ***Queues***, and click on the **queue3** queue.\n4. You view the output below getting logged every 10 seconds.\n   `Hello from timer: <CURRENT_TIME>`\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/azure_functions_timer_trigger.metatags",
    "content": "description: This example demonstrates how a function can be scheduled to execute periodically by the Azure Functions app.\nkeywords:  ballerina, ballerina by example, aws lambda, timer, trigger, serverless, cloud, function as a service\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/bal_build.out",
    "content": "$ bal build --cloud=\"azure_functions\"\nCompiling source\n\twso2/azure_functions_timer_trigger:0.1.0\n\nGenerating executable\n\n\t@azure.functions:Function: timer\n\n\tExecute the command below to deploy the function locally:\n\t$ func start --script-root target/azure_functions --java\n\n\tExecute the command below to deploy Ballerina Azure Functions:\n\t$ func azure functionapp publish <function_app_name> --script-root target/azure_functions \n\n\ttarget/bin/azure_functions_timer_trigger.jar\n"
  },
  {
    "path": "examples/azure-functions-timer-trigger/bal_new.out",
    "content": "$ bal new azure_functions_timer_trigger\nCreated new package 'azure_functions_timer_trigger' at /Users/wso2/azure_functions_timer_trigger.\n"
  },
  {
    "path": "examples/binary-data/binary_data.bal",
    "content": "import ballerina/io;\n \npublic function main() {\n    // Creates a `byte` array using the `base16` byte array literal.\n    byte[] arr1 = base16 `55 EE 66 FF 77 AB`;\n    io:println(arr1);\n    \n    // Creates a `byte` array using the `base64` byte array literal.\n    byte[] arr2 = base64 `ABCD pqrs 5678 +/12`;\n    io:println(arr2);\n}\n"
  },
  {
    "path": "examples/binary-data/binary_data.md",
    "content": "# Binary data\n\nBinary data is represented by arrays of byte values. It is a special syntax for byte arrays in `Base16` and `Base64`. The encoding tables of both `Base16` and `Base64` are the same as `RFC 4648`. A byte is an int in the range `0` to `0xFF` and it is a subtype of `int`.\n\n::: code binary_data.bal :::\n\n::: out binary_data.out :::\n\n## Related links\n- [Arrays](/learn/by-example/arrays)\n- [Byte type](/learn/by-example/byte-type)\n- [Integers](/learn/by-example/integers)\n"
  },
  {
    "path": "examples/binary-data/binary_data.metatags",
    "content": "description: Byte array literal, binary data, base16 data format, base64 data format.\nkeywords: ballerina, ballerina by example, bbe, binary data, byte, Base16, Base64, literal\n\n"
  },
  {
    "path": "examples/binary-data/binary_data.out",
    "content": "$ bal run binary_data.bal\n[85,238,102,255,119,171]\n[0,16,131,166,170,236,231,174,252,251,253,118]"
  },
  {
    "path": "examples/binary-operators/binary_operators.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int a = 10;\n    int b = 20;\n\n    // Perform integer addition.\n    int sum = a + b;\n    io:println(sum);\n\n    // Perform integer subtraction.\n    int difference = a - b;\n    io:println(difference);\n\n    // Perform integer multiplication.\n    int product = a * b;\n    io:println(product);\n\n    // Perform integer division.\n    int quotient = b / a;\n    io:println(quotient);\n\n    // Perform integer remainder.\n    int remainder = b % a;\n    io:println(remainder);\n\n    // `>`, `<`, `>=` and `<=` are used to test the relative order of two values.\n    // Check if `a` is less than `b`.\n    boolean isLessThan = a < b;\n    io:println(isLessThan);\n\n    // Check if `a` is greater than or equal to `b`.\n    boolean isGreaterThanOrEqual = a >= b;\n    io:println(isGreaterThanOrEqual);\n\n    float e = 10.5;\n    float f = 20.5;\n\n    // Perform floating-point addition.\n    float floatSum = e + f;\n    io:println(floatSum);\n\n    // Perform floating-point subtraction.\n    float floatDifference = e - f;\n    io:println(floatDifference);\n\n    // Perform floating-point multiplication.\n    float floatProduct = e * f;\n    io:println(floatProduct);\n\n    // Perform floating-point division.\n    float floatQuotient = e / f;\n    io:println(floatQuotient);\n\n    // Check if `e` is less than or equal to `f`.\n    boolean isLessOrEqual = e <= f;\n    io:println(isLessOrEqual);\n\n    // Check if `e` is greater than `f`.\n    boolean isGreaterThan = e > f;\n    io:println(isGreaterThan);\n\n    boolean c = true;\n    boolean d = false;\n\n    // Perform the logical AND operation between two boolean values.\n    boolean logicalAnd = c && d;\n    io:println(logicalAnd);\n\n    // Perform logical OR between two boolean values.\n    boolean logicalOr = c || d;\n    io:println(logicalOr);\n\n    // For the `<` operator, `d < c` evaluates to `true` when `d` is `false` and `c` is `true`.\n    boolean isLessThanBoolean = d < c;\n    io:println(isLessThanBoolean);\n\n    int g = 10;\n    int h = 20;\n\n    // Perform bitwise AND between two integers.\n    int bitwiseAnd = g & h;\n    io:println(bitwiseAnd);\n\n    // Perform bitwise OR between two integers.\n    int bitwiseOr = g | h;\n    io:println(bitwiseOr);\n\n    // Perform bitwise XOR between two integers.\n    int bitwiseXor = g ^ h;\n    io:println(bitwiseXor);\n\n    // Left shift an integer by 2 bits.\n    int leftShift = g << 2;\n    io:println(leftShift);\n\n    // Right shift an integer by 2 bits (signed).\n    int signedRightShift = g >> 2;\n    io:println(signedRightShift);\n\n    // Right shift an integer by 2 bits (unsigned).\n    int unsignedRightShift = g >>> 2;\n    io:println(unsignedRightShift);\n\n    string i = \"Hello\";\n    string j = \"Ballerina\";\n\n    // Concatenate two strings.\n    string concatenatedString = i + \" \" + j;\n    io:println(concatenatedString);\n\n    // Check if `i` is lexicographically greater than `j` in Unicode code point order.\n    boolean isGreaterThanString = i > j;\n    io:println(isGreaterThanString);\n}\n"
  },
  {
    "path": "examples/binary-operators/binary_operators.md",
    "content": "# Binary operators\n\nBallerina provides several binary operators to perform operations on values of various types such as integers, floats, booleans, and strings. Binary arithmetic operators (`+`, `-`, `*`, `/`, and `%`) allow basic mathematical calculations between two values. The operators to compare values (`<`, `>`, `<=`, and `>=`) produce a boolean result.\n\nBallerina also supports binary logical operators (`&&` and `||`) to perform logical operations on boolean values and bitwise operators (`&`, `|`, `^`, `<<`, `>>`, and `>>>`) to manipulate bits in integer values.\n\n::: code binary_operators.bal :::\n\n::: out binary_operators.out :::\n"
  },
  {
    "path": "examples/binary-operators/binary_operators.metatags",
    "content": "description: This BBE introduces binary operators in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, operators, binary operators, bitwise operators, int, float, string, boolean, +, -, /, %, *, , <, >, <=, >=, >>, <<, >>>, ||, &&, |, &, ^\n"
  },
  {
    "path": "examples/binary-operators/binary_operators.out",
    "content": "$ bal run binary_operators.bal\n30\n-10\n200\n2\n0\ntrue\nfalse\n31.0\n-10.0\n215.25\n0.5121951219512195\ntrue\nfalse\nfalse\ntrue\ntrue\n0\n30\n30\n40\n2\n2\nHello Ballerina\ntrue\n"
  },
  {
    "path": "examples/binding-patterns/binding_patterns.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    string name;\n    int age;\n\n    // The following example uses a list binding pattern to destructure the  \n    // returned list and assign it to the two variables, `name` and `age`.\n    // However, other binding patterns can also be used similarly.\n    [name, age] = getDetails();\n\n    io:println(name);\n    io:println(age);\n}\n\nfunction getDetails() returns [string, int] {\n    return [\"John\", 30];\n}\n"
  },
  {
    "path": "examples/binding-patterns/binding_patterns.md",
    "content": "# Binding Patterns\n\nBinding patterns make it easier to extract information, especially from structured values. The destructuring syntax allows different parts of a single structured value to be assigned to separate variables at the same time. All the variables in a binding pattern must be distinct.\n\n::: code binding_patterns.bal :::\n\n::: out binding_patterns.out :::\n\n## Related links\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Wildcard binding pattern](/learn/by-example/wildcard-binding-pattern/)\n- [List binding pattern](/learn/by-example/list-binding-pattern/)\n- [Mapping binding pattern](/learn/by-example/mapping-binding-pattern/)\n- [Error binding pattern](/learn/by-example/error-binding-pattern/)"
  },
  {
    "path": "examples/binding-patterns/binding_patterns.metatags",
    "content": "description: This BBE introduces extracting information from structured values and destructuring information using binding patterns\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, destructuring\n"
  },
  {
    "path": "examples/binding-patterns/binding_patterns.out",
    "content": "$ bal run binding_patterns.bal\nJohn\n30\n"
  },
  {
    "path": "examples/binding-patterns-in-match-statement/binding_patterns_in_match_statement.bal",
    "content": "import ballerina/io;\n\ntype Position record {\n    int x;\n    int y;\n};\n\ntype PositionRecord record {\n    Position p;\n};\n\nfunction matchFn1(Position position) {\n    match position {\n        // The binding pattern below matches mappings that contain at least the fields with the `x` and `y` keys.\n        // The values of these fields can be accessed via the `x` and `y` variables within this block.\n        var {x, y} => {\n            io:println(x, \", \", y);\n        }\n    }\n}\n\nfunction matchFn2(Position position) {\n    match position {\n        // The binding pattern below also has a rest binding pattern to capture the additional fields\n        // that may be specified in the open record value assigned to the `position` variable.\n        // Type of the `rest` variable can be considered a map of `anydata`. However, it cannot contain the\n        // `x` or `y` keys. This can be represented using the `never` type as explained in the example for\n        // the `never` type.\n        var {x, y, ...rest} => {\n            io:println(x, \", \", y, \", \", rest);\n        }\n    }\n}\n\nfunction matchFn3(PositionRecord r) {\n    match r {\n        // The pattern below matches a mapping that has a field with the `p` key and a value that is another\n        // mapping that contains at least the fields with `x` and `y` keys.\n        var {p: {x, y}} => {\n            io:println(x, \", \", y);\n        }\n    }\n}\n\npublic function main() {\n    Position position = {x: 1, y: 2, \"u\": 3 , \"v\": 4};\n    matchFn1(position);\n    matchFn2(position);\n\n    PositionRecord r = {p: position};\n    matchFn3(r);\n\n}\n"
  },
  {
    "path": "examples/binding-patterns-in-match-statement/binding_patterns_in_match_statement.md",
    "content": "# Binding patterns in the `match` statement\n\nBinding patterns can be used in a match statement to bind parts of a successful match to variables.\nYou can use the rest binding pattern (`...r`) in a binding pattern of a `match` statement to bind the fields that are not explicitly bound in the binding pattern. This is particularly useful when working with open records.\n\n::: code binding_patterns_in_match_statement.bal :::\n\n::: out binding_patterns_in_match_statement.out :::\n\n## Related links\n- [Match statement](/learn/by-example/match-statement/)\n- [If statement](/learn/by-example/if-statement/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern)\n"
  },
  {
    "path": "examples/binding-patterns-in-match-statement/binding_patterns_in_match_statement.metatags",
    "content": "description: This BBE demonstrates how to use binding patterns in a `match` statement and matching mapping values in a `match` statement in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, spread operator, binding pattern, match\n"
  },
  {
    "path": "examples/binding-patterns-in-match-statement/binding_patterns_in_match_statement.out",
    "content": "$ bal run binding_patterns_in_match_statement.bal\n1, 2\n1, 2, {\"u\":3,\"v\":4}\n1, 2\n"
  },
  {
    "path": "examples/boolean/boolean.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    boolean flag = true;\n    io:println(flag);\n\n    int x1 = 3;\n    int x2 = 2;\n\n    // The example below will output `false`.\n    io:println(x1 < x2);\n}\n"
  },
  {
    "path": "examples/boolean/boolean.md",
    "content": "# Boolean\n\nThe `boolean` type has two values: `true`, `false`. The `!` operator works on booleans only.  `&&` and `||` operators short-circuit - the second operand is not evaluated if the result of evaluating the first operand is sufficient to identify the result of the logical expression. Usual comparison operators (`==`, `!=`, `<`, `>`, `<=`, and `>=`) produce boolean values.\n\n::: code boolean.bal :::\n\n::: out boolean.out :::\n\n## Related links\n- [If statement](/learn/by-example/if-statement/)\n- [Match guard in match statement](/learn/by-example/match-guard-in-match-statement/)\n"
  },
  {
    "path": "examples/boolean/boolean.metatags",
    "content": "description: This BBE introduces the boolean type.\nkeywords:  ballerina, ballerina by example, bbe, boolean, bool, true, false\n"
  },
  {
    "path": "examples/boolean/boolean.out",
    "content": "$ bal run boolean.bal\ntrue\nfalse\n"
  },
  {
    "path": "examples/break-statement/break_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    foreach int i in 0...9 {\n        // Loop breaks when the condition is satisfied.\n        if (i > 5) {\n            break;\n        }\n\n        io:println(i);\n    }\n\n    int i = 0;\n    while true {\n        // Loop breaks when the condition is satisfied.\n        if i > 5 {\n            break;\n        }\n\n        io:println(i);\n        i = i + 1;\n    }\n}\n"
  },
  {
    "path": "examples/break-statement/break_statement.md",
    "content": "# Break statement\n\nA `break` statement can be used to terminate the execution within the nearest enclosing `while` or `foreach` statement.\n\n::: code break_statement.bal :::\n\n::: out break_statement.out :::\n\n## Related links\n- [Continue statement](/learn/by-example/continue-statement/)\n- [While statement](/learn/by-example/while-statement/)\n- [Foreach statement](/learn/by-example/foreach-statement/)\n"
  },
  {
    "path": "examples/break-statement/break_statement.metatags",
    "content": "description: This BBE demonstrates how to terminate a loop using the `break` statement in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, foreach, loops, iterate, iterable, break, terminate loop, while, repeat\n"
  },
  {
    "path": "examples/break-statement/break_statement.out",
    "content": "$ bal run break_statement.bal\n0\n1\n2\n3\n4\n5\n0\n1\n2\n3\n4\n5\n"
  },
  {
    "path": "examples/built-in-integer-subtypes/built_in_integer_subtypes.bal",
    "content": "import ballerina/io;\n\n// The `fn` function accepts an argument that belongs to `int:Unsigned32`\n// and prints the result of performing the bitwise `&` operation with \n// the `int:Unsigned16` maximum value.\nfunction fn(int:Unsigned32 val) {\n    int:Unsigned16 max = 65535;\n\n    // Bitwise operations have special typing. Since using `&` with operands\n    // of types `int:Unsigned32` and `int:Unsigned16` will result in a value\n    // that belongs to `int:Unsigned16`, the static type of `val & max` is \n    // considered to be `int:Unsigned16`, which allows the following.\n    int:Unsigned16 res = val & max;\n    io:println(res);\n}\n\npublic function main() {\n    // Since `72` belongs to `int:Unsigned32`, it can directly be passed as\n    // an argument to the `fn` function.\n    fn(72);\n\n    // The cast done in the `intFn` function will be successful since `43543`\n    // belongs to `int:Unsigned32`.\n    intFn(43543);\n\n    // The cast to `int:Unsigned32` panics since `4294967296` is out of range.\n    intFn(4294967296);\n}\n\nfunction intFn(int m) {\n    // Since an argument of type `int` cannot be passed to the `fn` function \n    // which only accepts values that belong to `int:Unsigned32`, a cast is attempted\n    // before passing `m` as an argument to `fn`. The cast attempt will panic if the \n    // value is out of range for `int:Unsigned32`.\n    fn(<int:Unsigned32> m);\n}\n"
  },
  {
    "path": "examples/built-in-integer-subtypes/built_in_integer_subtypes.md",
    "content": "# Built-in integer subtypes\n\nBallerina has one integer type (`int`), which is a 64-bit, signed type. \n\nThe `ballerina/lang.int` lang library defines the following built-in subtypes of this `int` type.\n\n- `int:Signed32`\n- `int:Unsigned32`\n- `int:Signed16`\n- `int:Unsigned16`\n- `int:Signed8`\n- `int:Unsigned8` (same as `byte`)\n\nThe runtime behavior of operations on these subtypes are the same as for the `int` type. Bitwise operations with operands of these types have special typing, which allows using a more specific type for the operation.\n\nInteger subtypes are useful for interfacing with external systems that use these types. They also allow implementations to optimize storage, particularly for arrays.\n\n::: code built_in_integer_subtypes.bal :::\n\n::: out built_in_integer_subtypes.out :::\n"
  },
  {
    "path": "examples/built-in-integer-subtypes/built_in_integer_subtypes.metatags",
    "content": "description: This BBE demonstrates built-in integer subtypes in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, int, int subtypes, signed, unsigned\n"
  },
  {
    "path": "examples/built-in-integer-subtypes/built_in_integer_subtypes.out",
    "content": "$ bal run built_in_integer_subtypes.bal\n72\n43543\nerror: {ballerina}NumberConversionError {\"message\":\"'int' value '4,294,967,296' cannot be converted to 'lang.int:Unsigned32'\"}\n        at built_in_integer_subtypes:intFn(built_in_integer_subtypes.bal:35)\n           built_in_integer_subtypes:main(built_in_integer_subtypes.bal:27)\n"
  },
  {
    "path": "examples/built-in-string-subtype/built_in_string_subtype.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // A variable of type `string:Char` to which only strings of length 1 can be assigned.\n    string:Char ch = \"x\";\n    io:println(ch);\n    \n    // The `lang.string:toCodePoint` lang library function can be used with \n    // an expression of the `string:Char` type to retrieve the relevant code point value.\n    int cp = ch.toCodePointInt();\n    io:println(cp);\n}\n"
  },
  {
    "path": "examples/built-in-string-subtype/built_in_string_subtype.md",
    "content": "# Built-in string subtype\n\nThe `ballerina/lang.string` lang library defines the `Char` type, which is a built-in subtype of `string`. A string belongs to the `string:Char` type if it has a length of 1.\n\nThis subtype is analogous to built-in subtypes of `int` and `xml`.\n\nA `string:Char` value can be converted to a code point, which is represented as an `int` value.\n\n::: code built_in_string_subtype.bal :::\n\n::: out built_in_string_subtype.out :::\n"
  },
  {
    "path": "examples/built-in-string-subtype/built_in_string_subtype.metatags",
    "content": "description: This BBE demonstrates the built-in string subtype string:Char in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, string, string subtype, Char\n"
  },
  {
    "path": "examples/built-in-string-subtype/built_in_string_subtype.out",
    "content": "$ bal run built_in_string_subtype.bal\nx\n120\n"
  },
  {
    "path": "examples/byte-type/byte_type.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // The `byte` type consists of integers ranging from `0` to `255`.\n    byte b = 255;\n    io:println(b);\n\n    // Since the set of possible `byte` values is a subset of `int` values,\n    // the `byte` type is a subtype of the `int` type.\n    int i = b;\n    io:println(i);\n}\n"
  },
  {
    "path": "examples/byte-type/byte_type.md",
    "content": "# Byte type\n\nThe byte type in Ballerina represents an 8-bit unsigned integer, with values ranging from 0 to 255.\n\n::: code byte_type.bal :::\n\n::: out byte_type.out :::\n\n## Related links\n- [Built-in integer subtypes](/learn/by-example/built-in-integer-subtypes/)"
  },
  {
    "path": "examples/byte-type/byte_type.metatags",
    "content": "description: This BBE introduces the Ballerina byte type.\nkeywords:  ballerina, ballerina by example, bbe, bytes, byte, byte type, unsigned8\n"
  },
  {
    "path": "examples/byte-type/byte_type.out",
    "content": "$ bal run byte_type.bal\n255\n255\n"
  },
  {
    "path": "examples/c2c-docker-deployment/Cloud.toml",
    "content": "[container.image]\nrepository=\"wso2inc\"\nname=\"hello\"\ntag=\"v0.1.0\"\n"
  },
  {
    "path": "examples/c2c-docker-deployment/build_output.out",
    "content": "$ bal build --cloud=\"docker\"\n\nCompiling source\n        wso2/hello:0.1.0\n\nGenerating executable\n\nGenerating artifacts...\n\n        @kubernetes:Docker                       - complete 2/2 \n\n        Execute the below command to run the generated Docker image: \n        docker run -d -p 9090:9090 wso2inc/hello:v0.1.0\n"
  },
  {
    "path": "examples/c2c-docker-deployment/c2c_docker_deployment.bal",
    "content": "import ballerina/http;\n\n// This code is completely focused on the business logic and it does not specify anything related to operations.\nlistener http:Listener helloEP = new(9090);\n\nservice http:Service /helloWorld on helloEP {\n    resource function get sayHello() returns string {\n        return \"Hello from Docker!\";\n    }\n}\n"
  },
  {
    "path": "examples/c2c-docker-deployment/c2c_docker_deployment.md",
    "content": "# Docker\n\nBallerina supports generating Docker artifacts from code without any additional configuration. This simplifies the experience of developing and deploying Ballerina code in the cloud. Code to Cloud builds the containers and required artifacts by deriving the required values from the code. If you want to override the default values taken by the compiler, you can use a `Cloud.toml` file.\nFor more information, see [Code to Cloud Deployment](/learn/code-to-cloud-deployment/).\n\n::: code c2c_docker_deployment.bal :::\n\nBefore you build the package, you need to override some default values taken by the compiler. To do this, create a filed named `Cloud.toml` in the package directory, and add the content below to it.\nFor all the supported key value properties, see [Code to Cloud specification](https://github.com/ballerina-platform/ballerina-spec/blob/master/c2c/code-to-cloud-spec.md).\n\n::: code Cloud.toml :::\n\nExecute the `bal build` command to build the Ballerina package. Code to Cloud generates only one container per package.\n::: out build_output.out :::\n\nVerify if the Docker image is generated.\n::: out docker_images.out :::\n\nRun the generated Docker image.\n::: out docker_run.out :::\n\nInvoke the service.\n::: out execute_curl.out:::\n"
  },
  {
    "path": "examples/c2c-docker-deployment/docker_images.out",
    "content": "$ docker images\n\nREPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE\nwso2inc/hello                 v0.1.0              60d95f0928b2        About a minute ago  228MB\n"
  },
  {
    "path": "examples/c2c-docker-deployment/docker_run.out",
    "content": "$ docker run -d -p 9090:9090 wso2inc/hello:v0.1.0\nc04194eb0b4d0d78cbc8ca55e0527d381d8ab4a1a68f8ea5dd3770a0845d5fbb\n"
  },
  {
    "path": "examples/c2c-docker-deployment/execute_curl.out",
    "content": "$ curl http://localhost:9090/helloWorld/sayHello\nHello from Docker!\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/Cloud.toml",
    "content": "[container.image]\nrepository=\"wso2inc\"\nname=\"hello\"\ntag=\"v0.1.0\"\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/build_output.out",
    "content": "$ bal build --cloud=\"k8s\"\n\nCompiling source\n        wso2/hello:0.1.0\n\nGenerating executable\n\nGenerating artifacts...\n\n        @kubernetes:Service                      - complete 1/1\n        @kubernetes:Deployment                   - complete 1/1\n        @kubernetes:HPA                          - complete 1/1\n        @kubernetes:Docker                       - complete 2/2 \n\n        Execute the below command to deploy the Kubernetes artifacts: \n        kubectl apply -f /home/anjana/bbe-make/k8s/target/kubernetes/hello\n\n        Execute the below command to access service via NodePort: \n        kubectl expose deployment hello-deployment --type=NodePort --name=hello-svc-local\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/c2c_k8s_deployment.bal",
    "content": "import ballerina/http;\n\n// This code is completely focused on the business logic and it does not specify anything related to the operations.\nlistener http:Listener helloEP = new(9090);\n\nservice http:Service /helloWorld on helloEP {\n    resource function get sayHello() returns string {\n        return \"Hello from Kubernetes!\";\n    }\n}\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/c2c_k8s_deployment.md",
    "content": "# Kubernetes\n\nBallerina supports generating Kubernetes artifacts from code without any additional configuration. This simplifies the experience of developing and deploying Ballerina code in the cloud. Code to Cloud builds the containers and required artifacts by deriving the required values from the code. If you want to override the default values taken by the compiler, you can use a `Cloud.toml` file.\nFor more information, see [Code to Cloud Deployment](/learn/code-to-cloud-deployment/).\n\n::: code c2c_k8s_deployment.bal :::\n\nBefore you build the package, you need to override some default values taken by the compiler. To do this, create a filed named `Cloud.toml` in the package directory, and add the content below to it.\nFor all the supported key value properties, see [Code to Cloud Specification](https://github.com/ballerina-platform/ballerina-spec/blob/master/c2c/code-to-cloud-spec.md).\n\n::: code Cloud.toml :::\n\nExecute the `bal build` command to build the Ballerina package. Code to Cloud generates only one container per package.\n::: out build_output.out :::\n\nPush the created Docker image to Docker Hub.\n::: out docker_push.out :::\n\nCreate the deployment using the Kubernetes artifacts.\n::: out kubectl_apply.out :::\n\nVerify the Kubernetes pods.\n::: out kubectl_pods.out :::\n\nExpose via NodePort to test in the developer environment.\n::: out kubectl_expose.out :::\n\nGet the External IP and port of the Kubernetes service.\n::: out kubectl_svc.out :::\n\nIf the External IP of the `hello-svc-local` service is `<none>`, you need to follow cluster-specific steps to obtain the external IP. If you are using Minikube, you can use the `minikube ip` command to obtain the IP.\n::: out minikube_ip.out :::\n\nAccess the deployed service via CURL.\n::: out execute_curl.out :::\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/docker_push.out",
    "content": "$ docker push wso2inc/hello:v0.1.0\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/execute_curl.out",
    "content": "$ curl http://192.168.49.2:31360/helloWorld/sayHello\nHello from Kubernetes!\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/kubectl_apply.out",
    "content": "$ kubectl apply -f /home/wso2/project/target/kubernetes/hello-0.1.0\nservice/helloep-svc created\ndeployment.apps/wso2-hello-0--deployment created\nhorizontalpodautoscaler.autoscaling/wso2-hello-0--hpa created\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/kubectl_expose.out",
    "content": "$ kubectl expose deployment hello-deployment --type=NodePort --name=hello-svc-local\nservice/hello-svc-local exposed\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/kubectl_pods.out",
    "content": "$ kubectl get pods\nNAME                                          READY   STATUS    RESTARTS   AGE\nwso2-hello-0--deployment-7d4d56457b-7jlzx       1/1     Running   0          57s\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/kubectl_svc.out",
    "content": "$ kubectl get svc\nNAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE\nhello-svc               ClusterIP       10.97.140.84        <none>        9090/TCP         13m\nhello-svc-local         NodePort        10.108.87.21        <none>        9090:31360/TCP   2m18s\n"
  },
  {
    "path": "examples/c2c-k8s-deployment/minikube_ip.out",
    "content": "$ minikube ip\n192.168.49.2\n"
  },
  {
    "path": "examples/cache-basics/cache_basics.bal",
    "content": "import ballerina/cache;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // This creates a new cache instance with the default configurations.\n    cache:Cache cache = new();\n\n    // Adds new entries to the cache.\n    check cache.put(\"key1\", \"value1\");\n    check cache.put(\"key2\", \"value2\");\n\n    // Checks for the cached key availability.\n    if (cache.hasKey(\"key1\")) {\n        // Fetches the cached value.\n        string value = <string> check cache.get(\"key1\");\n        io:println(\"The value of the key1: \" + value);\n    }\n    // Gets the keys of the cache entries.\n    string[] keys = cache.keys();\n    io:println(\"The existing keys in the cache: \" + keys.toString());\n\n    // Gets the size of the cache.\n    int size = cache.size();\n    io:println(\"The cache size: \", size);\n}\n"
  },
  {
    "path": "examples/cache-basics/cache_basics.md",
    "content": "# Cache basics\n\nThe `cache` library provides in-memory cache implementation APIs and uses the `Least Recently Used` algorithm-based eviction policy.\n\nFor more information on the underlying module, see the [`cache` module](https://lib.ballerina.io/ballerina/cache/latest/).\n\nThis example illustrates the basic operations provided by the `cache` library.\n\n::: code cache_basics.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out cache_basics.out :::\n"
  },
  {
    "path": "examples/cache-basics/cache_basics.metatags",
    "content": "description: This BBE shows how to perform basic in-memory caching operations with the \"Least Recently Used\" algorithm in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, cache, put, get, size, hasKey\n"
  },
  {
    "path": "examples/cache-basics/cache_basics.out",
    "content": "$ bal run cache_basic.bal\nThe value of the key1: value1\nThe existing keys in the cache: [\"key1\",\"key2\"]\nThe cache size: 2\n"
  },
  {
    "path": "examples/cache-basics/tests/cache_test.bal",
    "content": "import ballerina/test;\n\nstring[] outputs = [];\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any|error... val) {\n    any|error value = val.reduce(getStringValue, \"\");\n    if (value is error) {\n        outputs.push(value.message());\n    } else {\n        outputs.push(value.toString());\n    }\n}\n\n@test:Config{}\nfunction testFunc() {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function.\n    error? output = main();\n    if (output is error) {\n        test:assertFail(\"Test failed\");\n    } else {\n        test:assertEquals(outputs[0].toString(), \"The value of the key1: value1\");\n        test:assertEquals(outputs[1].toString(), \"The existing keys in the cache: [\\\"key1\\\",\\\"key2\\\"]\");\n        test:assertEquals(outputs[2].toString(), \"The cache size: 2\");\n    }\n}\n\nfunction getStringValue(any|error a, any|error b) returns string {\n    string aValue = a is error ? a.toString() : a.toString();\n    string bValue = b is error ? b.toString() : b.toString();\n    return (aValue + bValue);\n}\n"
  },
  {
    "path": "examples/cache-invalidation/cache_invalidation.bal",
    "content": "import ballerina/cache;\nimport ballerina/io;\n\npublic function main() returns error? {\n\n    // This creates a new cache with the advanced configuration.\n    cache:Cache cache = new ({\n        // The maximum size of the cache is 10.\n        capacity: 10,\n        // The eviction factor is set to 0.2, which means at the\n        // time of eviction 10*0.2=2 entries get removed from the cache.\n        evictionFactor: 0.2,\n        // The default max age of the cache entry is set to 2 seconds.\n        defaultMaxAge: 2,\n        // The cache cleanup task runs every 3 seconds and clears all\n        // the expired entries.\n        cleanupInterval: 3\n    });\n\n    // Adds the new entries to the cache.\n    check cache.put(\"key1\", \"value1\");\n    check cache.put(\"key2\", \"value2\");\n    // Adds a new entry to the cache by overriding the default max age.\n    check cache.put(\"key3\", \"value3\", 3600);\n\n    // Gets the keys of the cache entries.\n    string[] keys = cache.keys();\n    io:println(\"The existing keys in the cache: \", keys);\n\n    // Discards the given cache entry.\n    _ = check cache.invalidate(\"key2\");\n\n    // Gets the keys of the cache entries.\n    io:println(\"The existing keys in after invalidating a given key: \",\n                cache.keys());\n\n    // Discards all the cache entries of the cache.\n    _ = check cache.invalidateAll();\n\n    // Gets the keys of the cache entries after all the keys are invalidated.\n    io:println(\"The keys after invalidating all the keys: \", cache.keys());\n}\n"
  },
  {
    "path": "examples/cache-invalidation/cache_invalidation.md",
    "content": "# Cache invalidation\n\nThe `cache` library provides in-memory cache implementation APIs and uses the `Least Recently Used` algorithm-based eviction policy.\n\nFor more information on the underlying module, see the [`cache` module](https://lib.ballerina.io/ballerina/cache/latest/).\n\n::: code cache_invalidation.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out cache_invalidation.out :::\n"
  },
  {
    "path": "examples/cache-invalidation/cache_invalidation.metatags",
    "content": "description: This BBE shows how to perform an in-memory caching invalidate operation with the \"Least Recently Used\" algorithm in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, cache, put, hasKey, invalidate, invalidateAll\n"
  },
  {
    "path": "examples/cache-invalidation/cache_invalidation.out",
    "content": "$ bal run cache_invalidation.bal\nThe existing keys in the cache: [\"key1\",\"key2\",\"key3\"]\nThe existing keys in after invalidating a given key: [\"key1\",\"key3\"]\nThe keys after invalidating all the keys: []\n"
  },
  {
    "path": "examples/cache-invalidation/tests/cache_test.bal",
    "content": "import ballerina/test;\n\nstring[] outputs = [];\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any|error... val) {\n    any|error value = val.reduce(getStringValue, \"\");\n    if (value is error) {\n        outputs.push(value.message());\n    } else {\n        outputs.push(value.toString());\n    }\n}\n\n@test:Config{}\nfunction testFunc() {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function.\n    error? output = main();\n    if (output is error) {\n        test:assertFail(\"Test failed\");\n    } else {\n        test:assertEquals(outputs[0].toString(), \"The existing keys in the cache: [\\\"key1\\\",\\\"key2\\\",\\\"key3\\\"]\");\n        test:assertEquals(outputs[1].toString(), \"The existing keys in after invalidating a given key: [\\\"key1\\\",\\\"key3\\\"]\");\n        test:assertEquals(outputs[2].toString(), \"The keys after invalidating all the keys: []\");\n    }\n}\n\nfunction getStringValue(any|error a, any|error b) returns string {\n    string aValue = a is error ? a.toString() : a.toString();\n    string bValue = b is error ? b.toString() : b.toString();\n    return (aValue + bValue);\n}\n"
  },
  {
    "path": "examples/casting-json-to-user-defined-type/casting_json_to_user_defined_type.bal",
    "content": "import ballerina/io;\n \ntype Coord record {\n    float x;\n    float y;\n};\n \npublic function main() {\n    json j = {x: 1.0, y: 2.0};\n    \n    // Here, the inherent type of `j` is not a subtype of `Coord`. \n    // Therefore, `j` cannot be directly converted to `Coord`.\n    // Use `cloneReadOnly()` to create a read-only copy of the mutable value `j`.\n    // Then, the resulting immutable value can be casted successfully.\n    json k = j.cloneReadOnly();\n    Coord c = <Coord> k;\n    \n    io:println(c.x);\n    io:println(c.y);\n}\n"
  },
  {
    "path": "examples/casting-json-to-user-defined-type/casting_json_to_user_defined_type.md",
    "content": "# Casting JSON to user-defined type\n\nIn order to access the field in the `json` value, the easiest way is to convert the `json` value to a user-defined type. \nThe type-casting can be used to do that. However, if the cast fails, the program panics with an error. The recommended way to do this is by using langlib functions.\nCasting to a user-defined type will work on mutable structure only if the inherent type (a structured value has an inherent type, which is a type descriptor that is part of the structured value's runtime value) of that structure is a subtype of the user-defined type.\nCasting immutable values will work. However, it does not do numeric conversions.\n\n::: code casting_json_to_user_defined_type.bal :::\n\n::: out casting_json_to_user_defined_type.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Open records](/learn/by-example/open-records/)\n- [Control openness](/learn/by-example/controlling-openness/)\n- [Anydata type](/learn/by-example/anydata-type/)\n- [Converting from JSON to user defined type with langlib functions](/learn/by-example/converting-from-json-to-user-defined-type-with-langlib-functions/)\n- [Check expression](/learn/by-example/check-expression/)"
  },
  {
    "path": "examples/casting-json-to-user-defined-type/casting_json_to_user_defined_type.metatags",
    "content": "description: This BBE demonstrates how to convert from JSON to record, convert JSON to user-defined type, cast mutable structures, do the numeric conversion on JSON elements, access JSON data, manipulate JSON data, and cast JSON to a user-defined type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, conversion, json, record, cast, access, manipulate\n"
  },
  {
    "path": "examples/casting-json-to-user-defined-type/casting_json_to_user_defined_type.out",
    "content": "$ bal run casting_json_to_user_defined_type.bal\n1.0\n2.0\n"
  },
  {
    "path": "examples/cdc-advanced-service/cdc_advanced_service.bal",
    "content": "import ballerina/log;\nimport ballerinax/cdc;\nimport ballerinax/mysql;\nimport ballerinax/mysql.cdc.driver as _;\n\nlistener mysql:CdcListener mysqlListener = new (\n    database = {\n        username: \"root\",\n        password: \"Test@123\",\n        includedDatabases: \"store_db\"\n    }\n);\n\ntype Entity record {\n    int id;\n};\n\ntype ProductReviews record {\n    int product_id;\n    int rating;\n};\n\n@cdc:ServiceConfig {\n    tables: [\"store_db.products\", \"store_db.vendors\"]\n}\nservice on mysqlListener {\n\n    remote function onRead(Entity after, string tableName) returns cdc:Error? {\n        log:printInfo(`'${tableName}' cache entry created for Id: ${after.id}`);\n    }\n\n    remote function onCreate(Entity after, string tableName) returns cdc:Error? {\n        log:printInfo(`'${tableName}' cache entry created for Id: ${after.id}`);\n    }\n\n    remote function onUpdate(Entity before, Entity after, string tableName) returns cdc:Error? {\n        log:printInfo(`'${tableName}' cache entry updated for Id: ${after.id}.`);\n    }\n\n    remote function onDelete(Entity before, string tableName) returns cdc:Error? {\n        if tableName == \"products\" {\n            log:printInfo(`'products' cache entry deleted for Id: ${before.id}.`);\n        } else {\n            log:printInfo(`'vendors' cache entry deleted for Id: ${before.id}.`);\n        }\n    }\n}\n\n@cdc:ServiceConfig {\n    tables: [\"store_db.product_reviews\"]\n}\nservice on mysqlListener {\n\n    remote function onRead(ProductReviews after, string tableName) returns cdc:Error? {\n        log:printInfo(`'product_tot_rating' cache added for Product Id: ${after.product_id}.`);\n        log:printInfo(`'product_reviews' cache entry added for Product Id: ${after.product_id}.`);\n    }\n\n    remote function onCreate(ProductReviews after, string tableName) returns cdc:Error? {\n        log:printInfo(`'product_tot_rating' cache added for Product Id: ${after.product_id}.`);\n        log:printInfo(`'product_reviews' cache entry added for Product Id: ${after.product_id}.`);\n    }\n\n    remote function onUpdate(ProductReviews before, ProductReviews after, string tableName) returns cdc:Error? {\n        int ratingDiff = after.rating - before.rating;\n        log:printInfo(`'product_tot_rating' cache updated for Product Id: ${after.product_id}.`);\n    }\n\n    remote function onDelete(ProductReviews before, string tableName) returns cdc:Error? {\n        log:printInfo(`'product_tot_rating' cache deleted for Product Id: ${before.product_id}.`);\n        log:printInfo(`'product_reviews' cache entry deleted for Product Id: ${before.product_id}.`);\n    }\n}\n"
  },
  {
    "path": "examples/cdc-advanced-service/cdc_advanced_service.md",
    "content": "# Change Data Capture - Group Events by Table\n\nThe `cdc:Service` connects to a MySQL database using the `mysql:CdcListener`, allowing you to handle change data capture (CDC) events as typed records. The listener detects database changes and calls the relevant remote method (`onRead`, `onCreate`, `onUpdate`, or `onDelete`) in your service, passing the event data.\n\nYou can attach multiple `cdc:Service` instances to a single `mysql:CdcListener`. This lets you group related event handling logic into separate services, making your code easier to organize and maintain. Each service can focus on a specific set of tables or event types, improving readability and separation of concerns.\n\n::: code cdc_advanced_service.bal :::\n\n## Prerequisites\n\n- To set up the database, see the [Change Data Capture Ballerina By Example - Prerequisites and Test Data](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/cdc-prerequisite).\n\nRun the program by executing the following command.\n\n::: out cdc_advanced_service.out :::\n\n> **Tip:** To insert additional records for testing, run the `test_cdc_advance_listener.bal` file provided in the [Change Data Capture Ballerina By Example - Prerequisites and Test Data](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/cdc-prerequisite).\n\n## Related links\n- [`mysql:CdcListener` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest#CdcListener)\n- [`cdc:Service` - API documentation](https://lib.ballerina.io/ballerinax/cdc/latest#Service)\n- [`cdc:Service` - Specification](https://github.com/ballerina-platform/module-ballerinax-cdc/blob/main/docs/spec/spec.md#22-service)\n"
  },
  {
    "path": "examples/cdc-advanced-service/cdc_advanced_service.metatags",
    "content": "description: This BBE demonstrates how to use a CDC (Change Data Capture) service in Ballerina to capture and process real-time changes from a MySQL database.\nkeywords: ballerina, ballerina by example, bbe, mysql, cdc, change data capture, realtime, database, service, data streaming\n"
  },
  {
    "path": "examples/cdc-advanced-service/cdc_advanced_service.out",
    "content": "$ bal run cdc_advanced_service.bal\ntime=2025-05-27T22:26:20.509+05:30 level=INFO module=\"\" message=\"\\'product_tot_rating\\' cache added for Product Id: 1001.\"\ntime=2025-05-27T22:26:20.520+05:30 level=INFO module=\"\" message=\"\\'product_reviews\\' cache entry added for Product Id: 1001.\"\ntime=2025-05-27T22:26:20.522+05:30 level=INFO module=\"\" message=\"\\'product_tot_rating\\' cache added for Product Id: 1001.\"\ntime=2025-05-27T22:26:20.523+05:30 level=INFO module=\"\" message=\"\\'product_reviews\\' cache entry added for Product Id: 1001.\"\ntime=2025-05-27T22:26:20.525+05:30 level=INFO module=\"\" message=\"\\'product_tot_rating\\' cache added for Product Id: 1002.\"\ntime=2025-05-27T22:26:20.526+05:30 level=INFO module=\"\" message=\"\\'product_reviews\\' cache entry added for Product Id: 1002.\"\ntime=2025-05-27T22:26:20.532+05:30 level=INFO module=\"\" message=\"\\'products\\' cache entry created for Id: 1001\"\ntime=2025-05-27T22:26:20.534+05:30 level=INFO module=\"\" message=\"\\'products\\' cache entry created for Id: 1002\"\ntime=2025-05-27T22:26:20.536+05:30 level=INFO module=\"\" message=\"\\'vendors\\' cache entry created for Id: 1\"\ntime=2025-05-27T22:26:20.538+05:30 level=INFO module=\"\" message=\"\\'vendors\\' cache entry created for Id: 2\"\n"
  },
  {
    "path": "examples/cdc-prerequisite/README.md",
    "content": "# Change Data Capture Ballerina By Example - Prerequisites and Test Data\n\nThe Change Data Capture (CDC) BBEs are based on a fraud detection use case.\n\n## Setting up the MySQL Databases\n\nTo set up the required MySQL databases for the BBEs, run the following Ballerina files using the command `bal run`:\n\n1. `setup_finance_db.bal` – Creates the `finance_db` database and its tables.\n2. `setup_store_db.bal` – Creates the `store_db` database and its tables.\n\n## Inserting Test Data\n\nTo insert test data for the CDC service BBEs, run the following files with `bal run`:\n\n1. `test_cdc_service.bal` – Inserts records into the `finance_db.transactions` table.\n2. `test_cdc_advanced_service.bal` – Inserts additional records for advanced CDC scenarios.\n"
  },
  {
    "path": "examples/cdc-prerequisite/setup_finance_db.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Initializes the database as a prerequisite to `Change Data Capture` samples.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (host = \"localhost\", port = 3306, user = \"root\",\n        password = \"Test@123\"\n    );\n\n    // Creates a database.\n    _ = check mysqlClient->execute(`CREATE DATABASE finance_db;`);\n\n    // Creates `transactions` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE finance_db.transactions (\n                                        tx_id INT AUTO_INCREMENT PRIMARY KEY,\n                                        user_id INT,\n                                        amount DECIMAL(10,2),\n                                        status VARCHAR(50),\n                                        created_at DATETIME\n                                    )`);\n\n    // Adds the records to the `transactions` table.\n    _ = check mysqlClient->execute(`INSERT INTO finance_db.transactions (user_id, amount, status, created_at)\n                                    VALUES(10, 9000.00, 'COMPLETED', '2025-04-01 08:00:00');`);\n    _ = check mysqlClient->execute(`INSERT INTO finance_db.transactions (user_id, amount, status, created_at)\n                                    VALUES(11, 12000.00, 'COMPLETED', '2025-04-01 08:10:00');`);\n    _ = check mysqlClient->execute(`INSERT INTO finance_db.transactions (user_id, amount, status, created_at) \n                                    VALUES(12, 4500.00, 'PENDING', '2025-04-01 08:30:00');`);\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/cdc-prerequisite/setup_store_db.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Initializes the database as a prerequisite to `Change Data Capture` samples.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (host = \"localhost\", port = 3306, user = \"root\",\n        password = \"Test@123\"\n    );\n\n    // Creates a database.\n    _ = check mysqlClient->execute(`CREATE DATABASE store_db;`);\n\n    // Creates `vendors` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE store_db.vendors (\n                                        id INT PRIMARY KEY,\n                                        name VARCHAR(255),\n                                        contact_info TEXT\n                                    );`);\n\n    // Adds the records to the `vendors` table.\n    _ = check mysqlClient->execute(`INSERT INTO store_db.vendors VALUES (1, 'Samsung', 'contact@samsung.com');`);\n    _ = check mysqlClient->execute(`INSERT INTO store_db.vendors VALUES (2, 'Apple', 'contact@apple.com');`);\n\n    // Creates `products` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE store_db.products (\n                                        id INT PRIMARY KEY,\n                                        name VARCHAR(255),\n                                        price DECIMAL(10,2),\n                                        description TEXT,\n                                        vendor_id INT,\n                                        FOREIGN KEY (vendor_id) REFERENCES vendors(id)\n                                    );`);\n\n    // Adds the records to the `products` table.\n    _ = check mysqlClient->execute(`INSERT INTO store_db.products VALUES \n                                    (1001, 'Samsung Galaxy S24', 999.99, 'Flagship phone with AI camera', 1);`);\n    _ = check mysqlClient->execute(`INSERT INTO store_db.products VALUES \n                                    (1002, 'Apple iPhone 15 Pro', 1099.00, 'New titanium design', 2);`);\n\n    // Creates `product_reviews` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE store_db.product_reviews (\n                                        review_id INT PRIMARY KEY,\n                                        product_id INT,\n                                        rating INT CHECK (rating BETWEEN 1 AND 5),\n                                        comment TEXT,\n                                        FOREIGN KEY (product_id) REFERENCES products(id)\n                                    );`);\n\n    // Adds the records to the `product_reviews` table.\n    _ = check mysqlClient->execute(`INSERT INTO store_db.product_reviews VALUES (1, 1001, 5, 'Amazing camera');`);\n    _ = check mysqlClient->execute(`INSERT INTO store_db.product_reviews VALUES (2, 1001, 4, 'Great battery life');`);\n    _ = check mysqlClient->execute(`INSERT INTO store_db.product_reviews VALUES (3, 1002, 5, 'Best iPhone yet');`);\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/cdc-prerequisite/test_cdc_advanced_service.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Insert test data for `Change Data Capture` samples.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (host = \"localhost\", port = 3306, user = \"root\",\n        password = \"Test@123\"\n    );\n\n    _ = check mysqlClient->execute(\n        `UPDATE store_db.products SET price = price * 0.9 WHERE id = 1002;`\n        );\n    _ = check mysqlClient->execute(\n        `UPDATE store_db.product_reviews SET rating = rating - 1 WHERE product_id = 1002;`\n        );\n    _ = check mysqlClient->execute(\n        `INSERT store_db.products VALUES (1003, \"Samsung Galaxy S20\", 499.99, \"Old Smartphone\", 2);`\n        );\n    _ = check mysqlClient->execute(\n        `DELETE FROM store_db.products WHERE id = 1003;`\n        );\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/cdc-prerequisite/test_cdc_service.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Insert test data for `Change Data Capture` samples.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (host = \"localhost\", port = 3306, user = \"root\",\n        password = \"Test@123\"\n    );\n\n    // Adds the records to the `transactions` table.\n    _ = check mysqlClient->execute(`INSERT INTO finance_db.transactions (user_id, amount, status, created_at)\n                                    VALUES (11, 2000.00, 'COMPLETED', '2025-04-01 08:10:00');`);\n    _ = check mysqlClient->execute(`INSERT INTO finance_db.transactions (user_id, amount, status, created_at)\n                                    VALUES (11, 12000.00, 'COMPLETED', '2025-04-01 08:10:00');`);\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/cdc-service/cdc_service.bal",
    "content": "import ballerina/log;\nimport ballerinax/cdc;\nimport ballerinax/mysql;\nimport ballerinax/mysql.cdc.driver as _;\n\ntype Transactions record {|\n    int tx_id;\n    int user_id;\n    float amount;\n    string status;\n    int created_at;\n|};\n\nlistener mysql:CdcListener financeDBListener = new (\n    database = {\n        username: \"root\",\n        password: \"Test@123\",\n        includedDatabases: \"finance_db\"\n    }\n);\n\nservice on financeDBListener {\n\n    isolated remote function onRead(Transactions trx) returns cdc:Error? {\n        if trx.amount > 10000.00 {\n            string fraudAlert = \n                string `Fraud detected! Id: ${trx.tx_id}, User Id: ${trx.user_id}, Amount: $${trx.amount}`;\n            log:printInfo(fraudAlert);\n        }\n    }\n\n    isolated remote function onCreate(Transactions trx) returns cdc:Error? {\n        if trx.amount > 10000.00 {\n            string fraudAlert = \n                string `Fraud detected! Id: ${trx.tx_id}, User Id: ${trx.user_id}, Amount: $${trx.amount}`;\n            log:printInfo(fraudAlert);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/cdc-service/cdc_service.md",
    "content": "# Change Data Capture - Listen to Database\n\nThe `cdc:Service` connects to a MySQL database using the `mysql:CdcListener`, allowing you to bind change data capture (CDC) events directly to subtypes of `record{}`. \n\nThe listener captures database changes and dispatches them as records to one of the `onRead`, `onCreate`, `onUpdate`, or `onDelete` remote methods in your service. To use this, specify the required payload type as the argument to these methods, which should be a subtype of `record{}`. When new CDC events are received, the method corresponding to the operation is invoked. \n\nIf the payload does not match the defined type, a `cdc:PayloadBindingError` will be logged. You can customize error handling by implementing the optional `onError` remote method in your service.\n\n::: code cdc_service.bal :::\n\n## Prerequisites\n\n- To set up the database, see the [Change Data Capture Ballerina By Example - Prerequisites and Test Data](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/cdc-prerequisite).\n\nRun the program by executing the following command.\n\n::: out cdc_service.out :::\n\n> **Tip:** To insert additional records for testing, run the `test_cdc_listener.bal` file provided in the [Change Data Capture Ballerina By Example - Prerequisites and Test Data](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/cdc-prerequisite).\n\n## Related links\n- [`mysql:CdcListener` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest#CdcListener)\n- [`cdc:Service` - API documentation](https://lib.ballerina.io/ballerinax/cdc/latest#Service)\n- [`cdc:Service` - Specification](https://github.com/ballerina-platform/module-ballerinax-cdc/blob/main/docs/spec/spec.md#22-service)\n"
  },
  {
    "path": "examples/cdc-service/cdc_service.metatags",
    "content": "description: This BBE demonstrates how to use a CDC (Change Data Capture) service in Ballerina to capture and process real-time changes from a MySQL database.\nkeywords: ballerina, ballerina by example, bbe, mysql, cdc, change data capture, realtime, database, service, data streaming\n"
  },
  {
    "path": "examples/cdc-service/cdc_service.out",
    "content": "$ bal run cdc_service.bal\ntime=2025-05-27T22:17:45.632+05:30 level=INFO module=\"\" message=\"Fraud detected! Id: 2, User Id: 11, Amount: $12000.0\"\n"
  },
  {
    "path": "examples/chat-agents/chat_agents.bal",
    "content": "import ballerina/ai;\nimport ballerina/http;\nimport ballerina/time;\nimport ballerina/uuid;\n\n// Declare a service attached to an `ai:Listener` listener \n// to interact with the agent.\nservice /tasks on new ai:Listener(8080) {\n    resource function post chat(@http:Payload ai:ChatReqMessage request) \n\t\t\t\t\t\treturns ai:ChatRespMessage|error {\n        string response = check taskAssistantAgent.run(request.message, request.sessionId);\n        return {message: response};\n    }\n}\n\ntype Task record {|\n    string description;\n    time:Date dueBy?;\n    time:Date createdAt = time:utcToCivil(time:utcNow());\n    time:Date completedAt?;\n    boolean completed = false;\n|};\n\n// Simple in-memory task management.\nisolated map<Task> tasks = {\n    \"a2af0faa-3b73-4184-9be1-87b29a963be6\": {\n        description: \"Buy groceries\",\n        dueBy: time:utcToCivil(time:utcAddSeconds(time:utcNow(), 60 * 5))\n    }\n};\n\n// Define the functions that the agent can use as tools.\n// The LLM will identify the arguments to pass to these functions\n// based on the user input and the tool (function) signatures.\n@ai:AgentTool\nisolated function addTask(string description, time:Date? dueBy) returns error? {\n    lock {\n        tasks[uuid:createRandomUuid()] = {description, dueBy: dueBy.clone()};\n    }\n}\n\n@ai:AgentTool\nisolated function listTasks() returns Task[] {\n    lock {\n        return tasks.toArray().clone();\n    }\n}\n\n@ai:AgentTool\nisolated function getCurrentDate() returns time:Date {\n    time:Civil {year, month, day} = time:utcToCivil(time:utcNow());\n    return {year, month, day};\n}\n\n// Define an AI agent with a system prompt and a set of tools.\n// The agent will use these tools to help manage a task list,\n// following the system prompt instructions.\nfinal ai:Agent taskAssistantAgent = check new ({\n    systemPrompt: {\n        role: \"Task Assistant\",\n        instructions: string `You are a helpful assistant for \n            managing a to-do list. You can manage tasks and\n            help a user plan their schedule.`\n    },\n    // Specify the functions the agent can use as tools.\n    tools: [addTask, listTasks, getCurrentDate],\n    // Use the default model provider (with configuration added\n    // via a Ballerina VS Code command).\n    model: check ai:getDefaultModelProvider()\n});\n"
  },
  {
    "path": "examples/chat-agents/chat_agents.md",
    "content": "# Chat agents\n\nBallerina enables developers to easily create intelligent chat agents powered by large language models (LLMs) and integrated with tools, including local tools, MCP tools, and external APIs. These chat agents can maintain conversations across multiple sessions, handle concurrent users, and seamlessly integrate with web services and external systems.\n\nThis example demonstrates how to create a chat agent service that manages to-do lists while maintaining separate conversation sessions for different users through externally managed session IDs.\n\nCopy the source to a Ballerina project and use the `Try it` CodeLens above the service declaration to use a chat interface within VS Code. \n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code chat_agents.bal :::\n\n::: out chat_agents.out :::\n\n## Related links\n- [The Agent with local tools example](/learn/by-example/ai-agent-local-tools)\n- [The Agent with MCP integration example](/learn/by-example/ai-agent-mcp-integration)\n- [The Agent with external endpoint integration example](/learn/by-example/ai-agent-external-endpoint-integration)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/chat-agents/chat_agents.metatags",
    "content": "description: This BBE demonstrates chat agents.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, agent, chat\n"
  },
  {
    "path": "examples/chat-agents/chat_agents.out",
    "content": "$ bal run chat_agents.bal\n"
  },
  {
    "path": "examples/check-expression/check_expression.bal",
    "content": "import ballerina/io;\n\n// Convert `bytes` to a `string` value and then to an `int` value.\nfunction intFromBytes(byte[] bytes) returns int|error {\n    string|error res = string:fromBytes(bytes);\n    // Explicitly check if the result is an error and \n    // immediately return if so.\n    if res is error {\n        return res;\n    }\n    return int:fromString(res);\n}\n\n// Same as `intFromBytes` but with `check` instead of explicitly checking for error and returning.\nfunction intFromBytesWithCheck(byte[] bytes) returns int|error {\n    string str = check string:fromBytes(bytes);\n    return int:fromString(str);\n}\n\npublic function main() {\n    int|error res1 = intFromBytesWithCheck([104, 101, 108, 108, 111]);\n    io:println(res1);\n    int|error res2 = intFromBytes([104, 101, 108, 108, 111]);\n    io:println(res2);\n}\n"
  },
  {
    "path": "examples/check-expression/check_expression.md",
    "content": "# Check expression\n\nIf an expression can evaluate to an error value, you can use the `check` expression to indicate that you want the execution of the current block to terminate with that error as the result. This results in the error value being returned from the current function/worker, unless the `check` expression is used in a failure-handling statement (e.g., statement with on fail, retry statement).\n\n::: code check_expression.bal :::\n\n::: out check_expression.out :::\n\n+ [`check` semantics](https://ballerina.io/learn/concurrency/#check-semantics)\n"
  },
  {
    "path": "examples/check-expression/check_expression.metatags",
    "content": "description: This BBE demonstrates how the check expression is used in Ballerina to handle errors\nkeywords:  ballerina, ballerina by example, bbe, error, check\n"
  },
  {
    "path": "examples/check-expression/check_expression.out",
    "content": "$ bal run check_expression.bal\nerror(\"{ballerina/lang.int}NumberParsingError\",message=\"'string' value 'hello' cannot be converted to 'int'\")\nerror(\"{ballerina/lang.int}NumberParsingError\",message=\"'string' value 'hello' cannot be converted to 'int'\")\n"
  },
  {
    "path": "examples/check-semantics/check_semantics.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    do {\n        // If  `check` gets an error from either `foo()` or `bar()` invocations, the error will be caught at the `on fail`\n        check foo();\n        check bar();\n\n        if !isOK() {\n            // Fails explicitly with an error.\n            fail error(\"not OK\");\n\n        }\n    }\n    // Failure with the respective error is caught by the `on fail` block.\n    on fail var e {\n        io:println(e.toString());\n        return e;\n    }\n\n    return;\n}\n\nfunction foo() returns error? {\n    io:println(\"OK\");\n    return;\n}\n\nfunction bar() returns error? {\n    io:println(\"OK\");\n    return;\n}\n\nfunction isOK() returns boolean {\n    // Returns `false`.\n    return false;\n\n}\n"
  },
  {
    "path": "examples/check-semantics/check_semantics.md",
    "content": "# Check semantics\n\n`check` semantics is not to simply return on an `error` value. When `check` gets an `error` value, it fails. The enclosing block decides how to handle the failure. Most blocks pass the failure up to the enclosing block.\n\nFunction definition handles the failure by returning the error. `on fail` can catch the error. `fail` statement is like `check`, but it always fails. Differs from exceptions in that control flow is explicit.\n\n::: code check_semantics.bal :::\n\n::: out check_semantics.out :::"
  },
  {
    "path": "examples/check-semantics/check_semantics.metatags",
    "content": "description: This BBE explains the `check` semantics in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, check, fail, exceptions, on fail, error\n"
  },
  {
    "path": "examples/check-semantics/check_semantics.out",
    "content": "$ bal run check_semantics.bal\nOK\nOK\nerror(\"not OK\")\nerror: not OK\n"
  },
  {
    "path": "examples/child-loggers-with-context/child_loggers_with_context.bal",
    "content": "import ballerina/log;\n\nfunction processUserRequest(string userId, string requestId) returns error? {\n    // Get the root logger\n    log:Logger rootLogger = log:root();\n\n    // Create a child logger with request-specific context\n    log:Logger requestLogger = check rootLogger.withContext(userId = userId, requestId = requestId);\n\n    // All logs from this logger will include the userId and requestId context\n    requestLogger.printInfo(\"User permissions validated successfully\");\n\n    // Create a nested logger with additional context for a specific operation\n    log:Logger operationLogger = check requestLogger.withContext(operation = \"dataTransformation\");\n    operationLogger.printWarn(\"Using fallback transformation method\", reason = \"primary method unavailable\");\n    operationLogger.printInfo(\"Data transformation completed\", duration = \"250ms\");\n}\n\npublic function main() returns error? {\n    // Process multiple requests with different contexts\n    check processUserRequest(\"alice123\", \"req-001\");\n\n    check processUserRequest(\"bob456\", \"req-002\");\n}\n"
  },
  {
    "path": "examples/child-loggers-with-context/child_loggers_with_context.md",
    "content": "# Child loggers with context\n\nThis example demonstrates how to create child loggers with specific additional context using the Ballerina logging module. Child loggers inherit context from their parent loggers, allowing for hierarchical logging with layered context.\n\n::: code child_loggers_with_context.bal :::\n\n::: out child_loggers_with_context.out :::\n\nThe contextual logging APIs make it easy to trace complete request flows and correlate related log entries without manually managing context in each log statement.\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#431-loggers-with-additional-context)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/child-loggers-with-context/child_loggers_with_context.metatags",
    "content": "description: BBE on how to create child loggers with context in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, log, context, contextual logging, context, child logger\n"
  },
  {
    "path": "examples/child-loggers-with-context/child_loggers_with_context.out",
    "content": "$ bal run child_loggers_with_context.bal\n\ntime=2025-08-29T12:28:56.385+05:30 level=INFO module=tharmigan/log_test message=\"User permissions validated successfully\" env=\"prod\" nodeId=\"server-001\" userId=\"alice123\" requestId=\"req-001\"\ntime=2025-08-29T12:28:56.395+05:30 level=WARN module=tharmigan/log_test message=\"Using fallback transformation method\" reason=\"primary method unavailable\" env=\"prod\" nodeId=\"server-001\" userId=\"alice123\" requestId=\"req-001\" operation=\"dataTransformation\"\ntime=2025-08-29T12:28:56.397+05:30 level=INFO module=tharmigan/log_test message=\"Data transformation completed\" duration=\"250ms\" env=\"prod\" nodeId=\"server-001\" userId=\"alice123\" requestId=\"req-001\" operation=\"dataTransformation\"\ntime=2025-08-29T12:28:56.399+05:30 level=INFO module=tharmigan/log_test message=\"User permissions validated successfully\" env=\"prod\" nodeId=\"server-001\" userId=\"bob456\" requestId=\"req-002\"\ntime=2025-08-29T12:28:56.401+05:30 level=WARN module=tharmigan/log_test message=\"Using fallback transformation method\" reason=\"primary method unavailable\" env=\"prod\" nodeId=\"server-001\" userId=\"bob456\" requestId=\"req-002\" operation=\"dataTransformation\"\ntime=2025-08-29T12:28:56.402+05:30 level=INFO module=tharmigan/log_test message=\"Data transformation completed\" duration=\"250ms\" env=\"prod\" nodeId=\"server-001\" userId=\"bob456\" requestId=\"req-002\" operation=\"dataTransformation\"\n"
  },
  {
    "path": "examples/client-class/client_class.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\npublic type Album readonly & record {|\n    string title;\n    string artist;\n|};\n\npublic client class Client {\n    // The HTTP client to access the HTTP services.\n    private final http:Client httpClient;\n\n    function init(string url) returns error? {\n        self.httpClient = check new (url);\n    }\n\n    resource function get [string path]() returns Album[]|error {\n        return check self.httpClient->/[path];\n    }\n\n    resource function post [string path](Album album) returns error? {\n        Album updatedAlbum = check self.httpClient->/[path].post(album);\n        io:println(\"\\nPOST request: \", updatedAlbum);\n    }\n}\n\npublic function main() returns error? {\n    Client albumClient = check new (\"localhost:9090\");\n\n    // `->` is used to access the resource/remote methods in the client class.\n    // Sends a `GET` request to the `/albums` resource.\n    Album[] albums = check albumClient->/[\"albums\"];\n    io:println(albums);\n\n    Album newAlbum = {\"title\": \"Sarah Vaughan and Clifford Brown\", \"artist\": \"Sarah Vaughan\"};\n\n    // Sends a `POST` request to the `/albums` resource.\n    check albumClient->/[\"albums\"].post(newAlbum);\n}\n"
  },
  {
    "path": "examples/client-class/client_class.md",
    "content": "# Client class\n\nThe `client` keyword is used with class definition to define a client class. Ballerina supports defining client objects to allow a program to interact with remote network services. They are a special kind of object that contain `remote` and `resource` methods in addition to regular methods.\n\nSimilarly, class objects can be constructed using an object constructor as well.\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\n::: code client_class.bal :::\n\nRun the client program by executing the following command.\n\n::: out client_class.out :::\n\n## Related links\n- [Resource methods](/learn/by-example/resource-methods/)\n- [Defining classes](/learn/by-example/defining-classes/)\n- [Object types](/learn/by-example/object-types/)\n"
  },
  {
    "path": "examples/client-class/client_class.metatags",
    "content": "description: This BBE demonstrates creating a client object from a client class definition, and sending `get` and `post` requests to an HTTP client.\nkeywords: ballerina, ballerina by example, bbe, class, client, http, remote, resource\n"
  },
  {
    "path": "examples/client-class/client_class.out",
    "content": "$ bal run client_class.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n\nPOST request: {\"title\":\"Sarah Vaughan and Clifford Brown\",\"artist\":\"Sarah Vaughan\"}\n"
  },
  {
    "path": "examples/combining-isolated-functions-and-lock/combining_isolated_functions_and_lock.bal",
    "content": "import ballerina/io;\n\ntype R record {\n    int v;\n};\n\n// The initialization expression of an `isolated` variable\n// has to be an `isolated` expression, which itself will be\n// an `isolated` root.\nisolated R r = {v: 0};\n\nisolated function setGlobal(int n) {\n    // An `isolated` variable can be accessed within\n    // a `lock` statement.\n    lock {\n        r.v = n;\n    }\n}\n\npublic function main() {\n    setGlobal(200);\n    // Accesses the `isolated` variable within a\n    // `lock` statement.\n    lock {\n       io:println(r);\n    }\n}\n"
  },
  {
    "path": "examples/combining-isolated-functions-and-lock/combining_isolated_functions_and_lock.md",
    "content": "# Combining isolated functions and lock\n\nCombining `isolated` functions and `lock` allows `isolated` functions to use `lock` to access mutable module-level state. Key concept is `isolated` root. A value `r` is an `isolated` root if mutable state reachable from `r` cannot be reached from outside except through `r`. \n\nAn expression is an `isolated` expression if it follows rules that guarantee that its value will be an `isolated` root. E.g.,\n\n- an expression with a type that is a subtype of `readonly` is always `isolated`\n- an expression `[E1, E2]` is isolated if `E1` and `E2` are `isolated`\n- an expression `f(E1, E2)` is `isolated` if `E1` and `E1` are `isolated`, and the type of `f` is an `isolated` function.\n\n::: code combining_isolated_functions_and_lock.bal :::\n\nExecuting the above code changes the value of `V` to 200 as shown below.\n\n::: out combining_isolated_functions_and_lock.out :::"
  },
  {
    "path": "examples/combining-isolated-functions-and-lock/combining_isolated_functions_and_lock.metatags",
    "content": "description: This BBE demonstrates combining isolated functions and lock in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, isolated functions, lock\n"
  },
  {
    "path": "examples/combining-isolated-functions-and-lock/combining_isolated_functions_and_lock.out",
    "content": "$ bal run combining_isolated_functions_and_lock.bal\n{\"v\":200}\n"
  },
  {
    "path": "examples/commit-rollback-handlers/commit_rollback_handlers.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    transaction {\n        check update();\n        check commit;\n    }\n    return;\n}\n\ntransactional function update() returns error? {\n    check updateDatabase();\n    // Registers a commit handler to be invoked when `commit` is executed.\n    transaction:onCommit(sendEmail);\n    transaction:onRollback(logError);\n}\n\nfunction updateDatabase() returns error? {\n    io:println(\"Database updated\");\n    return;\n}\n\nisolated function sendEmail('transaction:Info info) {\n    io:println(\"Email sent.\");\n}\n\nisolated function logError(transaction:Info info, error? cause, boolean willRetry) {\n    io:println(\"Logged database update failure\");\n}\n"
  },
  {
    "path": "examples/commit-rollback-handlers/commit_rollback_handlers.md",
    "content": "# Commit/rollback handlers\n\nOften code needs to get executed depending on whether a transaction is committed. Testing the result of the `commit` within the transaction statement works. However, it is inconvenient from a modularity perspective, particularly, when you want to undo changes on `rollback`.\n\nThis seems much worse in a distributed transaction when the transaction statement is in another program. Ballerina provides `commit`/`rollback` handlers, which are functions that get executed when the decision whether to commit is known.\n\n::: code commit_rollback_handlers.bal :::\n\n::: out commit_rollback_handlers.out :::"
  },
  {
    "path": "examples/commit-rollback-handlers/commit_rollback_handlers.metatags",
    "content": "description: This BBE introduces commit/rollback handlers in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, transactions, commit, rollback, handlers, commit handlers, rollback handlers\n"
  },
  {
    "path": "examples/commit-rollback-handlers/commit_rollback_handlers.out",
    "content": "$ bal run commit_rollback_handlers.bal\nDatabase updated\nEmail sent.\n"
  },
  {
    "path": "examples/computed-field-key/computed_field_key.bal",
    "content": "import ballerina/io;\n\nconst ID = \"unique-identifier\";\n\nfunction getStudentDetails(string studentId,\n        string name,\n        string org,\n        string orgName) returns map<string> {\n    return {\n        // The `unique-identifier` value is substituted from the constant `ID` as the key.\n        [ID] : studentId,\n        \"name\": name,\n        // The key computed at runtime will be the concatenation of `_` and\n        // the argument passed for `org`.\n        [\"_\" + org] : orgName\n    };\n}\n\npublic function main() {\n    map<string> studentDetails = getStudentDetails(\"stu123\", \"John\", \"school\", \"West High\");\n    io:println(studentDetails);\n}\n"
  },
  {
    "path": "examples/computed-field-key/computed_field_key.md",
    "content": "# Computed field key\n\nBallerina allows you to have computed values as keys in a map. This can be done by specifying the key as an expression within square brackets.\nThis is particularly useful when you want to define and use constants for key values.\n\n::: code computed_field_key.bal :::\n\n::: out computed_field_key.out :::\n\n## Related links\n- [Maps](/learn/by-example/maps/)\n"
  },
  {
    "path": "examples/computed-field-key/computed_field_key.metatags",
    "content": "description: This BBE demonstrates the use of computed field keys in mapping constructors, computed values as keys, and constants for key values in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, computed key, mapping constructor, map, record, computed field key, computed name field\n"
  },
  {
    "path": "examples/computed-field-key/computed_field_key.out",
    "content": "$ bal run computed_field_key.bal\n{\"name\":\"John\",\"unique-identifier\":\"stu123\",\"_school\":\"West High\"}\n"
  },
  {
    "path": "examples/conditional-send/conditional_send.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    boolean isDataReady = true;\n\n    worker w1 {\n        // A send action can be used in a conditional context.\n        if isDataReady {\n            10 -> function;\n        }\n    }\n    worker w2 {\n        if isDataReady {\n            1 -> function;\n        } else {\n            0 -> function;\n        }\n    }\n\n    // The send action corresponding to this receive action is conditionally executed.\n    // Thus, there is a possibility that the send action may not get executed.\n    // Therefore, the static type of the receive includes the `error:NoMessage` type\n    // indicating the absence of a message in such cases.\n    int|error:NoMessage w1Message = <- w1;\n    io:println(w1Message);\n\n    // Two different conditional send actions exist within the worker `w3`.\n    // Therefore, an alternate receive action can be used to receive them.\n    int|error:NoMessage w2Message = <- w2 | w2;\n    io:println(w2Message);\n}\n"
  },
  {
    "path": "examples/conditional-send/conditional_send.md",
    "content": "# Conditional send\n\nThe send action in workers can be used in a conditional context, allowing for more flexible and dynamic inter-worker communication based on specific conditions. The receiver side in a conditional send might not always receive a message. Thus, to handle such scenarios, the static type of the receive action includes the `error:NoMessage` type.\n\n::: code conditional_send.bal :::\n\n::: out conditional_send.out :::\n"
  },
  {
    "path": "examples/conditional-send/conditional_send.metatags",
    "content": "description: This BBE demonstrates the use of conditional send within workers in Ballerina\nkeywords: ballerina, ballerina by example, bbe, workers, conditional send\n"
  },
  {
    "path": "examples/conditional-send/conditional_send.out",
    "content": "$ bal run conditional_send.bal\n10\n1\n"
  },
  {
    "path": "examples/configurable-variables/configurable_variables.bal",
    "content": "// The host of the database server. The default value is `localhost`.\nconfigurable string dbHost = \"localhost\";\n\n// This specifies that the password must be supplied in a configuration file.\nconfigurable string password = ?;\n"
  },
  {
    "path": "examples/configurable-variables/configurable_variables.md",
    "content": "# Configurable variables\n\nA module-level variable can be declared as configurable. The initializer of a configurable variable can be overridden at runtime (e.g., by a TOML file). A variable for which a configuration is required can use an initializer of `?`. The type of a configurable variable must be a subtype of `anydata`.\n\nFor more information, see [Configure a sample Ballerina service](/learn/configure-a-sample-ballerina-service/).\n\n::: code configurable_variables.bal :::\n\n::: out configurable_variables.out :::\n"
  },
  {
    "path": "examples/configurable-variables/configurable_variables.metatags",
    "content": "description: This BBE demonstrates configurable variables in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, configurable, variable\n"
  },
  {
    "path": "examples/configurable-variables/configurable_variables.out",
    "content": "$ bal run configurable_variables.bal\n"
  },
  {
    "path": "examples/configuring-via-cli/configuring_via_cli.bal",
    "content": " import ballerina/io;\n\nenum HttpVersion {\n   HTTP_1_0 = \"1.0\",\n   HTTP_1_1 = \"1.1\",\n   HTTP_2_0 = \"2.0\"\n}\n\n// The configurable variables of `float`, `union`, and `enum` types are initialized.\nconfigurable float maxPayload = 1.0;\nconfigurable string|int localId = ?;\nconfigurable HttpVersion httpVersion = HTTP_1_0;\n\npublic function main() {\n   io:println(\"maximum payload (in MB): \", maxPayload);\n   io:println(\"local ID: \", localId);\n   io:println(\"HTTP version: \", httpVersion);\n}\n"
  },
  {
    "path": "examples/configuring-via-cli/configuring_via_cli.md",
    "content": "# Configure via command-line arguments\n\nThe values of the configurable variables can be configured through the command-line arguments when executing the Ballerina program. The provided value is expected to be the `toString()` representation of the intended value.\n\nThe command-line-based configuration is only supported for configurable variables of types `int`, `byte`, `float`, `boolean`, `string`, `decimal`, `enum`, and `xml`.\nThe `-Ckey=value` syntax can be used to provide values through the command-line parameters.\n\nFor more information, see [Configure via command-line arguments](/learn/provide-values-to-configurable-variables/#provide-via-command-line-arguments/).\n\n::: code configuring_via_cli.bal :::\n\n::: out configuring_via_cli.out :::\n"
  },
  {
    "path": "examples/configuring-via-cli/configuring_via_cli.metatags",
    "content": "description: This BBE demonstrates how to configure configurable variables in Ballerina via command-line arguments.\nkeywords: ballerina, ballerina by example, bbe, configurable, variable, cli\n"
  },
  {
    "path": "examples/configuring-via-cli/configuring_via_cli.out",
    "content": "$ bal run configuring_via_cli.bal -- -CmaxPayload=2.5 -ClocalId=ID-1 -ChttpVersion=2.0\nmaximum payload (in MB): 2.5\nlocal ID: ID-1\nHTTP version: 2.0\n"
  },
  {
    "path": "examples/configuring-via-toml/configuring-via-toml.md",
    "content": "# Configure via TOML files\n\nThe values of the configurable variables can be configured through the configuration files in the TOML(v0.4) format.\n\nThe file location can be specified through an environment variable with the name `BAL_CONFIG_FILES`. Specifying multiple configuration files is supported using this environment variable with the OS-specific separator. If an environment variable is not specified, a file named `Config.toml` will be sought in the current working directory.\n\nAn environment variable with the name `BAL_CONFIG_DATA` can be used to provide the configuration file content instead of a separate file.\n\nFor more information, see [Configure via TOML syntax](/learn/provide-values-to-configurable-variables/#provide-via-toml-syntax/).\n\n::: code configuring_via_toml.bal :::\n\nTo run the example, copy the following content to a file named `Config.toml` in the current directory.\n\n::: code Config.toml :::\n\n::: out configuring_via_toml.out :::\n"
  },
  {
    "path": "examples/configuring-via-toml/configuring_via_toml.bal",
    "content": "import ballerina/io;\n\ntype UserInfo record {|\n   readonly string username;\n   string password;\n|};\n\ntype UserTable table<UserInfo> key(username);\n\nenum HttpVersion {\n   HTTP_1_0 = \"1.0\",\n   HTTP_1_1 = \"1.1\",\n   HTTP_2_0 = \"2.0\"\n}\n\n// The configurable variables of `float`, `string[]`, enum, `record`, and `table` types are initialized.\nconfigurable float maxPayload = 1.0;\nconfigurable string[] acceptTypes = [\"text/plain\"];\nconfigurable HttpVersion httpVersion = HTTP_1_0;\nconfigurable UserInfo & readonly admin = ?;\nconfigurable UserTable & readonly users = ?;\n\npublic function main() {\n   io:println(\"maximum payload (in MB): \", maxPayload);\n   io:println(\"accepted content types: \", acceptTypes);\n   io:println(\"HTTP version: \", httpVersion);\n   io:println(\"admin details: \", admin);\n   io:println(\"users: \", users);\n}\n"
  },
  {
    "path": "examples/configuring-via-toml/configuring_via_toml.metatags",
    "content": "description: This BBE demonstrates how to configure configurable variables in Ballerina via a TOML file.\nkeywords: ballerina, ballerina by example, bbe, configurable, variable, toml\n"
  },
  {
    "path": "examples/configuring-via-toml/configuring_via_toml.out",
    "content": "$ bal run configuring_via_toml.bal\nmaximum payload (in MB): 3.21\naccepted content types: [\"application/xml\",\"application/json\",\"text/plain\"]\nHTTP version: 1.0\nadmin details: {\"username\":\"admin\",\"password\":\"password\"}\nusers: [{\"username\":\"John\",\"password\":\"abc123\"},{\"username\":\"Bob\",\"password\":\"cde456\"}]\n"
  },
  {
    "path": "examples/const-and-final/const_and_final.bal",
    "content": "import ballerina/io;\n\nconst int MAX_VALUE = 1000;\n\n// Constants can be defined without the type. Then, the type is inferred from the right-hand side.\nconst URL = \"https://ballerina.io\";\n\n// Mapping and list constants can also be defined.\nconst HTTP_OK = {httpCode: 200, message: \"OK\"};\nconst ERROR_CODES = [200, 202, 400];\n\n// The value for the `msg` variable can only be assigned once.\nfinal string msg = loadMessage();\n\npublic function main() {\n    io:println(MAX_VALUE);\n    io:println(URL);\n    io:println(HTTP_OK);\n    io:println(ERROR_CODES);\n    io:println(msg);\n}\n\nfunction loadMessage() returns string {\n    return \"Hello World\";\n}\n"
  },
  {
    "path": "examples/const-and-final/const_and_final.md",
    "content": "# Const and final \n\n`const` means immutable and known at compile-time. Its type is singleton: a set containing a single value. A variable or a class field can be declared as `final`, which means it cannot be assigned after it has been initialized.\n\n::: code const_and_final.bal :::\n\n::: out const_and_final.out :::"
  },
  {
    "path": "examples/const-and-final/const_and_final.metatags",
    "content": "description: This BBE demonstrates how `const` and `final` values are used in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, const, final, map const, list const\n"
  },
  {
    "path": "examples/const-and-final/const_and_final.out",
    "content": "$ bal run const_and_final\n1000\nhttps://ballerina.io\n{\"httpCode\":200,\"message\":\"OK\"}\n[200,202,400]\nHello World\n"
  },
  {
    "path": "examples/constraint-validations/constraint_validations.bal",
    "content": "import ballerina/constraint;\n\n// Constraint on the `int` type.\n@constraint:Int {\n    minValue: 18\n}\ntype Age int;\n\ntype Student record {|\n    // Constraint on the `string`-typed record field.\n    @constraint:String {\n        pattern: re`[0-9]{6}[A-Z|a-z]`\n    }\n    string id;\n    string name;\n    // Constrained type used as a record field.\n    Age age;\n    // Constraint on the `string[]`-typed record field.\n    @constraint:Array {\n        minLength: 1,\n        maxLength: 10\n    }\n    string[] subjects;\n|};\n\npublic function main() returns error? {\n    Student student = {\n        id: \"200146B\",\n        name: \"David John\",\n        age: 25,\n        subjects: [\"Maths\", \"Science\", \"English\"]\n    };\n    // To validate the constraints on the `Student` record, the `validate` function should be \n    // called explicitly. If the validation is successful, then, this function returns the type \n    // descriptor of the value that is validated.\n    student = check constraint:validate(student);\n\n    // Set the student's age to 17, which will violate the `minValue` constraint on `Age`.\n    student.age = 17;\n\n    // When the validation fails, the `validate` function returns a `constraint:Error`.\n    student = check constraint:validate(student);\n}\n"
  },
  {
    "path": "examples/constraint-validations/constraint_validations.md",
    "content": "# Constraint validations\n\nValidating user input is a common requirement in most applications.  This can prevent user entry errors before the app attempts to process the data. \n\nThe `constraint` library provides such validations for the following Ballerina types: `int`, `float`, `decimal`, `string`, and `anydata[]`.\n\nFor more information on the underlying module, see the [`constraint` module](https://lib.ballerina.io/ballerina/constraint/latest/).\n\n::: code constraint_validations.bal :::\n\n::: out constraint_validations.out :::"
  },
  {
    "path": "examples/constraint-validations/constraint_validations.metatags",
    "content": "description: This BBE shows how to apply and validate constraints in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, constraint, validation\n"
  },
  {
    "path": "examples/constraint-validations/constraint_validations.out",
    "content": "$ bal run constraint_validations.bal\nerror: Validation failed for '$.age:minValue' constraint(s).\n"
  },
  {
    "path": "examples/consuming-services/consuming_services.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // A client object is created by applying `new` to a client class.\n    http:Client httpClient = check new (\"https://api.github.com\");\n\n    // The remote method calls use the `->` syntax. This enables the sequence diagram view.\n    http:Response resp = check httpClient->get(\"/orgs/ballerina-platform/repos\");\n\n    io:println(resp.statusCode);\n}\n"
  },
  {
    "path": "examples/consuming-services/consuming_services.md",
    "content": "# Consume services: client objects\n\nBallerina has a language construct called client objects.  They are a special kind of objects that contain `remote` methods in addition to regular methods.  `remote` methods are used to interact with a remote service. \n\nApplications typically do not need to write client classes, which are either provided by library modules or generated from some flavor of IDL.\n\n::: code consuming_services.bal :::\n\n::: out consuming_services.out :::"
  },
  {
    "path": "examples/consuming-services/consuming_services.metatags",
    "content": "description: This BBE explains basics of consuming services in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, Client, Client Objects, HTTP Client, Consuming services\n"
  },
  {
    "path": "examples/consuming-services/consuming_services.out",
    "content": "$ bal run consuming_services.bal\n200\n"
  },
  {
    "path": "examples/continue-statement/continue_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    foreach int i in 0...5 {\n        if (i == 2) {\n            // A `continue` statement can be used to skip the current iteration.\n            continue;\n        }\n\n        io:println(i);\n    }\n\n    int i = 0;\n    while i <= 5 {\n        if i == 2 {\n            i = i + 1;\n            // A `continue` statement can be used to skip the current iteration.\n            continue;\n        }\n\n        io:println(i);\n        i = i + 1;\n    }\n}\n"
  },
  {
    "path": "examples/continue-statement/continue_statement.md",
    "content": "# Continue statement\n\n`continue` statements can be used to skip the current iteration within a nearest enclosing `while` and `foreach` statement.\n\n::: code continue_statement.bal :::\n\n::: out continue_statement.out :::\n\n## Related links\n- [Break statement](/learn/by-example/break-statement/)\n- [While statement](/learn/by-example/while-statement/)\n- [Foreach statement](/learn/by-example/foreach-statement/)\n"
  },
  {
    "path": "examples/continue-statement/continue_statement.metatags",
    "content": "description: This BBE demonstrates how to use the `continue` statement to skip the current iteration in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, foreach, loops, iterate, iterable, break, skip loop, while, repeat\n"
  },
  {
    "path": "examples/continue-statement/continue_statement.out",
    "content": "$ bal run continue_statement.bal\n0\n1\n3\n4\n5\n0\n1\n3\n4\n5\n"
  },
  {
    "path": "examples/controlling-openness/controlling_openness.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    string name;\n    string country;\n|};\n\ntype PartTimeStudent record {|\n    string name;\n    string country;\n    // Rest descriptor of type `string` allows additional fields with `string` values.\n    string...;\n|};\n\npublic function main() {\n    // `s1` can only have fields exclusively specified in `Student`.\n    Student s1 = {name: \"Anne\", country: \"UK\"};\n\n    // `s1` is a `map` with `string` values.\n    map<string> s2 = s1;\n    io:println(s2);\n\n    // `s3` has an additional `faculty` field.\n    PartTimeStudent s3 = {\n        name: \"Anne\",\n        country: \"UK\",\n        \"faculty\": \"Science\"\n    };\n\n    // Accesses the `faculty` field in `s3`.\n    string? faculty = s3[\"faculty\"];\n    io:println(faculty);\n\n    // `s3` is a `map` with `string` values.\n    map<string> s4 = s3;\n    io:println(s4);\n}\n"
  },
  {
    "path": "examples/controlling-openness/controlling_openness.md",
    "content": "# Controlling openness\n\nUse `record {| ... |}` to describe a record type that allows exclusively what is specified in the body. Use an open record of type `record {| T...; |}`  to allow other fields of type `T`. `map<T>` is the same as `record {| T...; |}`.\n\n::: code controlling_openness.bal :::\n\n::: out controlling_openness.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)\n- [Open Records](/learn/by-example/open-records/)\n- [Maps](/learn/by-example/maps/)\n"
  },
  {
    "path": "examples/controlling-openness/controlling_openness.metatags",
    "content": "description: This BBE demonstrates controlling openness, open records, creating an open record, creating a closed record, inclusive record type, creating a record with unspecified fields, and allowing unspecified fields of a certain type in a record.\nkeywords: ballerina, ballerina by example, bbe, open record, closed record, record, record type, record field, rest type, rest field, inclusive record, unspecified fields\n"
  },
  {
    "path": "examples/controlling-openness/controlling_openness.out",
    "content": "$ bal run controlling_openness.bal\n{\"name\":\"Anne\",\"country\":\"UK\"}\nScience\n{\"name\":\"Anne\",\"country\":\"UK\",\"faculty\":\"Science\"}\n"
  },
  {
    "path": "examples/convert-from-json-to-user-defined-type/convert_from_json_to_user_defined_type.bal",
    "content": "import ballerina/io;\n\ntype Coord record {\n    float x;\n    float y;\n};\n\ntype Book record {\n    xml book;\n    float price;\n};\n\npublic function main() returns error? {\n    json j = {x: 1, y: 2};\n    \n    // Argument is a `typedesc` value.\n    // The static return type depends on the argument.\n    // Even if `x` and `y` are `int` in `j` they will automatically convert to `float`\n    Coord c = check j.cloneWithType(Coord);\n    io:println(c.x);\n    \n    // Argument defaulted from the context.\n    Coord d = check j.cloneWithType();\n    io:println(d.x);\n    \n    Book book = {book: xml `<book> The Treasure Island </book>`, price: 200.0};\n    \n    json bookJson = book.toJson();\n    io:println(bookJson);\n    \n    // `fromJsonWithType()` can be used to reverse conversions done by `toJson()`.\n    book = check bookJson.fromJsonWithType();\n    io:println(book);\n    \n    // Below will result in an error, because the type of the field `book` in `bookJson` is `string`.\n    Book|error result = bookJson.cloneWithType();\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/convert-from-json-to-user-defined-type/convert_from_json_to_user_defined_type.md",
    "content": "# Convert from JSON to user-defined type\n\nThe `cloneWithType()` langlib function can be used to convert a value to a user-defined type. Result recursively uses specified type as inherent type of new value. Automatically performs numeric conversions as necessary.\n\nEvery part of the value is cloned including immutable structural values. Also `fromJsonWithType()` langlib function can be used for the same purpose and it also does the reverse of conversions done by toJson.\n\n::: code convert_from_json_to_user_defined_type.bal :::\n\n::: out convert_from_json_to_user_defined_type.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Open records](/learn/by-example/open-records/)\n- [Controlling openess](/learn/by-example/controlling-openness)\n- [Check expression](/learn/by-example/check)\n- [Casting JSON to user-defined type](/learn/by-example/casting-json-to-user-defined-type)\n"
  },
  {
    "path": "examples/convert-from-json-to-user-defined-type/convert_from_json_to_user_defined_type.metatags",
    "content": "description: This BBE demonstrates how to convert JSON to a user-defined type, do the numeric conversion on JSON elements, convert JSON to record, access JSON data, and manipulate JSON data in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, json, record, cast, access, manipulate\n"
  },
  {
    "path": "examples/convert-from-json-to-user-defined-type/convert_from_json_to_user_defined_type.out",
    "content": "$ bal run convert_from_json_to_user_defined_type.bal\n\n1.0\n1.0\n{\"book\":\"<book> The Treasure Island </book>\",\"price\":200.0}\n{\"book\":`<book> The Treasure Island </book>`,\"price\":200.0}\nerror(\"{ballerina/lang.value}ConversionError\",message=\"'map<json>' value cannot be converted to 'Book': \n\t\tfield 'book' in record 'Book' should be of type 'xml<(lang.xml:Element|lang.xml:Comment|lang.xml:ProcessingInstruction|lang.xml:Text)>', found '\"<book> The Treasure...'\")\n"
  },
  {
    "path": "examples/converting-from-table-and-xml-to-json/converting_from_table_and_xml_to_json.bal",
    "content": "import ballerina/io;\n \npublic function main() {\n    table<record {| int id; string name;|}> users = table [{id: 1, name: \"John\"}, {id: 2, name: \"Sam\"}];\n    // `users` is converted to a JSON array.\n    json usersAsJson = users.toJson();\n    io:println(usersAsJson is json[]);\n    io:println(usersAsJson);\n    \n    xml book = xml `<book>The Lost World</book>`;\n    // `book` is converted to a string.\n    json s = book.toJson();\n    io:println(s is string);\n    io:println(s);\n}\n"
  },
  {
    "path": "examples/converting-from-table-and-xml-to-json/converting_from_table_and_xml_to_json.md",
    "content": "# Converting from `table` and `xml` to JSON\n\n`toJson()` recursively converts `anydata` to `json`. Table values are converted to `json` arrays and `xml` values are converted to strings.\n\n::: code converting_from_table_and_xml_to_json.bal :::\n\n::: out converting_from_table_and_xml_to_json.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type)\n- [toJson](https://lib.ballerina.io/ballerina/lang.value/0.0.0#toJson)"
  },
  {
    "path": "examples/converting-from-table-and-xml-to-json/converting_from_table_and_xml_to_json.metatags",
    "content": "description: This BBE demonstrates how to convert table to JSON and convert XML to JSON in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, conversion, json, table, toJson, xml\n"
  },
  {
    "path": "examples/converting-from-table-and-xml-to-json/converting_from_table_and_xml_to_json.out",
    "content": "$ bal run converting_from_table_and_xml_to_json.bal \ntrue\n[{\"id\":1,\"name\":\"John\"},{\"id\":2,\"name\":\"Sam\"}]\ntrue\n<book>The Lost World</book>\n"
  },
  {
    "path": "examples/converting-from-user-defined-type-to-json/converting_from_user_defined_type_to_json.bal",
    "content": "import ballerina/io;\n \n// Closed type.\ntype ClosedCoord record {|\n    string name;\n    [float, float] cords;\n|};\n \n// Open type can have additional `anydata` fields.\ntype OpenCoord record {\n    string name;\n    [float, float] cords;\n};\n \npublic function main() {\n    ClosedCoord a = {name: \"Colombo\", cords: [6.95, 79.84]};\n    // The conversion happens automatically because `a` is a subtype of `anydata`.\n    json j = a;\n    io:println(j);\n    \n    OpenCoord b = {name: \"Colombo\", cords: [6.94, 79.83], \"area\": \"03\"};\n    // Use `toJson()` to convert `anydata` to `json`.\n    // Usually happens automatically with closed records.\n    json k = b.toJson();\n    io:println(k);\n}\n"
  },
  {
    "path": "examples/converting-from-user-defined-type-to-json/converting_from_user_defined_type_to_json.md",
    "content": "# Convert from user-defined type to JSON\n\nConversion of a `json` value to JSON format is straightforward. Converting from an application-specific, user-defined subtype of `anydata` to `json` is also possible.\n\nIn many cases, the conversion happens automatically when the user-defined type is a subtype of JSON as well as of `anydata`. With tables, XML or records that are open to `anydata` use `toJson()` to convert `anydata` to `json`. APIs that generate JSON typically accept `anydata` and automatically apply `toJson()`.\n\n::: code converting_from_user_defined_type_to_json.bal :::\n\n::: out converting_from_user_defined_type_to_json.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Open records](/learn/by-example/open-records/)\n- [Controlling openess](/learn/by-example/controlling-openness)"
  },
  {
    "path": "examples/converting-from-user-defined-type-to-json/converting_from_user_defined_type_to_json.metatags",
    "content": "description: This BBE demonstrates how to convert user-defined type to JSON and convert JSON to record type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, conversion, json, record, toJson\n"
  },
  {
    "path": "examples/converting-from-user-defined-type-to-json/converting_from_user_defined_type_to_json.out",
    "content": "$ bal run converting_from_user_defined_type_to_json.bal\n{\"name\":\"Colombo\",\"cords\":[6.95,79.84]}\n{\"name\":\"Colombo\",\"cords\":[6.94,79.83],\"area\":\"03\"}\n"
  },
  {
    "path": "examples/counter-metrics/counter_metrics.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/log;\nimport ballerina/observe;\nimport ballerinax/prometheus as _;\n\n//Create a counter as a global variable in the service with the optional field description.\nobserve:Counter globalCounter = new (\"total_orders\",\n                                    desc = \"Total quantity required\");\n\nservice /onlineStoreService on new http:Listener(9090) {\n\n    resource function get makeOrder(http:Caller caller, http:Request req) {\n        //Incrementing the global counter defined with the default value 1.\n        globalCounter.increment();\n\n        //Create a counter with simply a name.\n        observe:Counter localCounter = new (\"local_operations\");\n        localCounter.increment();\n        //Increment the value of the counter by 20.\n        localCounter.increment(20);\n\n        //Create a counter with optional fields description, and tags.\n        observe:Counter registeredCounter = new (\"total_product_order_quantity\",\n            desc = \"Total quantity required\",\n            tags = {prodName: \"HeadPhone\", prodType: \"Electronics\"});\n\n        //Register the counter instance, therefore it is stored in the global registry and can be reported to the\n        //metrics server such as Prometheus. Additionally, this operation will register to the global registry for the\n        //first invocation and will throw an error if there is already a registration of different metrics instance\n        //or type. Subsequent invocations of register() will simply retrieve the stored metrics instance\n        //for the provided name and tags fields, and use that instance for the subsequent operations on the\n        //counter instance.\n        error? result = registeredCounter.register();\n        if (result is error) {\n            log:printError(\"Error in registering counter\", 'error = result);\n        }\n\n        //Increase the amount of the registered counter instance by amount 10.\n        registeredCounter.increment(10);\n\n        //Get the value of the counter instances.\n        io:println(\"------------------------------------------\");\n        io:println(\"Global Counter = \", globalCounter.getValue());\n        io:println(\"Local Counter = \", localCounter.getValue());\n        io:println(\"Registered Counter = \", registeredCounter.getValue());\n        io:println(\"------------------------------------------\");\n\n        //Send reponse to the client.\n        http:Response res = new;\n        // Use a util method to set a string payload.\n        res.setPayload(\"Order Processed!\");\n\n        // Send the response back to the caller.\n        result = caller->respond(res);\n        if (result is error) {\n            log:printError(\"Error sending response\", 'error = result);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/counter-metrics/counter_metrics.client.out",
    "content": "$ curl http://localhost:9090/onlineStoreService/makeOrder\nOrder Processed!\n"
  },
  {
    "path": "examples/counter-metrics/counter_metrics.md",
    "content": "# Counter-based metrics\n\nBallerina supports Observability out of the box and Metrics is one of the three important aspects of  Observability.To observe Ballerina code, the `--observability-included` build time flag should be given along with the `Config.toml` file when starting the service. The `Config.toml` file contains the required runtime configurations related to observability.\n\nYou can define and use metrics to measure your own logic. A counter is one type of the metrics that is supported by default in Ballerina, and it is a cumulative metric that represents a single monotonically-increasing counter whose value can only increase or be reset to zero.\n\nFor more information about configs and observing applications, see [Observe Ballerina programs](/learn/observe-ballerina-programs/).\n\n::: code counter_metrics.bal :::\n\nInvoke the service using the cURL command below.\n\n::: out counter_metrics.client.out :::\n\nTo start the service, navigate to the directory that contains the\n`.bal` file, and execute the `bal run` command below with the `--observability-included` build time flag and the `Config.toml` runtime configuration file.\n\n::: out counter_metrics.server.out :::\n"
  },
  {
    "path": "examples/counter-metrics/counter_metrics.metatags",
    "content": "description: BBE on how to use the default Counter Metrics Observability feature in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, observability, tracing, opentracing, counter\n"
  },
  {
    "path": "examples/counter-metrics/counter_metrics.server.out",
    "content": "$ BAL_CONFIG_FILES=Config.toml bal run --observability-included counter_metrics.bal\nballerina: started Prometheus HTTP listener 0.0.0.0:9797\n------------------------------------------\nGlobal Counter = 1\nLocal Counter = 21\nRegistered Counter = 10\n------------------------------------------\n------------------------------------------\nGlobal Counter = 2\nLocal Counter = 21\nRegistered Counter = 20\n------------------------------------------\n------------------------------------------\nGlobal Counter = 3\nLocal Counter = 21\nRegistered Counter = 30\n------------------------------------------\n"
  },
  {
    "path": "examples/counter-metrics/tests/counter_metrics_test.bal",
    "content": "import ballerina/test;\nimport ballerina/io;\nimport ballerina/http;\n\n@test:Config { }\nfunction testFunc() returns error? {\n    // Invoking the main function\n    http:Client httpEndpoint = check new(\"http://localhost:9090\");\n\n    string response1 = \"Order Processed!\";\n\n    // Send a GET request to the specified endpoint.\n    string response = check httpEndpoint->get(\"/onlineStoreService/makeOrder\");\n    test:assertEquals(response, response1);\n}\n"
  },
  {
    "path": "examples/covariance/covariance.bal",
    "content": "int[] iv = [1, 2, 3];\n\n// Assigning `int[]` to `any[]` is allowed.\n// The set of values allowed by `int` is a subset of set of values allowed by `any`\n// The set of values allowed by `int[]` is a subset of set of values allowed by `any[]`\nany[] av = iv;\n\npublic function main() {\n    // A runtime error or else `iv[0]` would have the wrong type.\n    av[0] = \"str\";\n}\n"
  },
  {
    "path": "examples/covariance/covariance.md",
    "content": "# Covariance\n\nArrays and maps are covariant. Static type-checking guarantees that the result of a read from a mutable structure will be consistent with the static type.\n\nCovariance means that a write to a mutable structure may result in a runtime error. Arrays, maps, and records have an `inherent` type that constrains mutation.\n\n::: code covariance.bal :::\n\n::: out covariance.out :::"
  },
  {
    "path": "examples/covariance/covariance.metatags",
    "content": "description: This BBE demonstrates covariance in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, covariance, arrays, maps\n"
  },
  {
    "path": "examples/covariance/covariance.out",
    "content": "$ bal run covariance.bal\nerror: {ballerina/lang.array}InherentTypeViolation {\"message\":\"incompatible types: expected 'int', found 'string'\"}\n        at covariance:main(covariance.bal:10)\n"
  },
  {
    "path": "examples/create-maps-with-query/create_maps_with_query.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    readonly int id;\n    string firstName;\n    string lastName;\n    int score;\n|};\n\npublic function main() returns error? {\n    table<Student> key(id) students = table [\n            {id: 1, firstName: \"John\", lastName: \"Smith\", score: 100},\n            {id: 2, firstName: \"Jane\", lastName: \"Smith\", score: 150},\n            {id: 4, firstName: \"Fred\", lastName: \"Bloggs\", score: 200},\n            {id: 7, firstName: \"Bobby\", lastName: \"Clark\", score: 300},\n            {id: 9, firstName: \"Cassie\", lastName: \"Smith\", score: 250}\n        ];\n\n    // The type of the value in the `select` clause must belong to the\n    // `[string, T]` tuple type, where the type of the constructed value is `map<T>`. \n    map<int> studentScores = map from var student in students\n                        select [student.firstName, student.score];\n    io:println(studentScores);\n}\n"
  },
  {
    "path": "examples/create-maps-with-query/create_maps_with_query.md",
    "content": "# Create maps with query expressions\n\nA query expressions can be used to create a map from an iterable value. A query expression should be preceded by the `map` keyword in this case.\n\nThe type of the value in the `select` clause must belong to the tuple type `[string, T]`, where the type of the constructed value is `map<T>`.\n\n::: code create_maps_with_query.bal :::\n\n::: out create_maps_with_query.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/create-maps-with-query/create_maps_with_query.metatags",
    "content": "description: This BBE demonstrates creating a map, filtering a map, creating a sub-map from a map, and creating a map from a table.\nkeywords: ballerina, ballerina by example, bbe, map, table, query, var\n"
  },
  {
    "path": "examples/create-maps-with-query/create_maps_with_query.out",
    "content": "$ bal run create_maps_with_query.bal\n{\"John\":100,\"Jane\":150,\"Fred\":200,\"Bobby\":300,\"Cassie\":250}\n"
  },
  {
    "path": "examples/create-streams-with-query/create_streams_with_query.bal",
    "content": "import ballerina/io;\n\nstring[] students = [\"John\", \"Mike\", \"Mia\"];\n \npublic function main() {\n    int[] studentIds = [0, 1, 2];\n    // The `getStudentAPI()` is not invoked at the time of the stream creation.\n    var studentsStream = stream from var id in studentIds\n                            select getStudentAPI(id);\n \n    // The `getStudentAPI()` is invoked when calling the `next()` method of the constructed stream.\n    var student = studentsStream.next();\n    // The `next()` will return an error if an evaluation of a query clause results in an error.\n    while (student !is error?) {\n        io:println(student.value);\n        student = studentsStream.next();\n    }\n}\n \nfunction getStudentAPI(int studentId) returns string {\n    io:println(\"request to get student name API\");\n    return students[studentId];\n}\n"
  },
  {
    "path": "examples/create-streams-with-query/create_streams_with_query.md",
    "content": "# Create stream with query\n\nA query expression can be used to create streams. The query expression should be preceded by the `stream` keyword in this case. If the expected stream type is `stream<T>`, then, the `select` clause must return values belonging to `T`.\n\nWhen constructing a stream from a query expression, clauses in the query expression are executed lazily that are called as a result of the next operations being performed on the constructed stream. The failure of the `check` within the query will cause the stream to produce an error termination value.\n\n::: code create_streams_with_query.bal :::\n\n::: out create_streams_with_query.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)"
  },
  {
    "path": "examples/create-streams-with-query/create_streams_with_query.metatags",
    "content": "description: This BBE demonstrates creating a stream of values, loading values lazily, saving resources by loading values when needed, the stream construct type, and handling the termination value of a stream.\nkeywords: ballerina, ballerina by example, bbe, stream, lazy, value, next, while\n"
  },
  {
    "path": "examples/create-streams-with-query/create_streams_with_query.out",
    "content": "$ bal run create_streams_with_query.bal\nrequest to get student name API\nJohn\nrequest to get student name API\nMike\nrequest to get student name API\nMia\n"
  },
  {
    "path": "examples/create-tables-with-query/create_tables_with_query.bal",
    "content": "import ballerina/io;\n\ntype Employee record {|\n    readonly int id;\n    string firstName;\n    string lastName;\n    int salary;\n|};\n\npublic function main() {\n    table<Employee> key(id) employees = table [\n            {id: 1, firstName: \"John\", lastName: \"Smith\", salary: 100},\n            {id: 2, firstName: \"Fred\", lastName: \"Bloggs\", salary: 2000}\n        ];\n\n    // The `key(id)` key specifier specifies the key sequence of the constructed table.\n    // `select` clause must emit values belonging to `map<any|error>`.\n    var highPaidEmployees = table key(id) from var e in employees\n                            where e.salary >= 1000\n                            select e;\n    io:println(highPaidEmployees);\n\n    // A table can also be constructed by providing the contextually expected type.\n    // `table<Employee>` is the contextually expected type.\n    // `select` clause must emit values belonging to `Employee`.\n    table<Employee> highPaidEmployees2 = from var e in employees\n                                         where e.salary >= 1000\n                                         select e;\n    io:println(highPaidEmployees2);\n}\n"
  },
  {
    "path": "examples/create-tables-with-query/create_tables_with_query.md",
    "content": "# Create tables with a query\n\nA query expressions can be used to create tables from an iterable value. One way of doing this is specifying `table` keyword as the query construct type before the query expression. The key of the created table can  be specified explicitly. Second way is to provide a contextually expected type. The `select` clause must emit values belonging to `map<any|error>`.\n\n::: code create_tables_with_query.bal :::\n\n::: out create_tables_with_query.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/create-tables-with-query/create_tables_with_query.metatags",
    "content": "description: This BBE demonstrates creating tables with a query in Ballerina, creating a table, filtering a table, and creating a sub table from a table.\nkeywords: ballerina, ballerina by example, bbe, creating table, query expression, query, where, key, var\n"
  },
  {
    "path": "examples/create-tables-with-query/create_tables_with_query.out",
    "content": "$ bal run create_tables_with_query.bal\n[{\"id\":2,\"firstName\":\"Fred\",\"lastName\":\"Bloggs\",\"salary\":2000}]\n[{\"id\":2,\"firstName\":\"Fred\",\"lastName\":\"Bloggs\",\"salary\":2000}]\n"
  },
  {
    "path": "examples/csv-streams-to-record-array/csv_streams_to_record_array.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\ntype Book record {\n    string name;\n    string author;\n    decimal price;\n    string publishedDate;\n};\n\ntype BookMinimal record {|\n    string name;\n    string author;\n|};\n\nconst csvFilePath = \"./files/csv_file.csv\";\n\npublic function main() returns error? {\n    // Write a CSV file.\n    check io:fileWriteCsv(csvFilePath, [[\"name\", \"author\", \"price\", \"publishedDate\"],\n                                        [\"Effective Java\", \"Joshua Bloch\", \"45.99\", \"2018-01-01\"],\n                                        [\"Clean Code\", \"Robert C. Martin\", \"37.5\", \"2008-08-01\"]]);\n\n    // Read the CSV file as a byte stream.\n    stream<byte[], error?> bookStream = check io:fileReadBlocksAsStream(csvFilePath);\n\n    // Parse as CSV byte stream to an array of records.\n    Book[] bookArray = check csv:parseStream(bookStream);\n    io:println(bookArray);\n\n    bookStream = check io:fileReadBlocksAsStream(csvFilePath);\n\n    // Parse the CSV byte stream as an array of records with data projection.\n    // Here only the fields specified in the target record type (`name` and `author` fields)  \n    // are included in the constructed value. \n    BookMinimal[] briefBookArray = check csv:parseStream(bookStream);\n    io:println(briefBookArray);\n}\n"
  },
  {
    "path": "examples/csv-streams-to-record-array/csv_streams_to_record_array.md",
    "content": "# Parse CSV byte stream to Ballerina record array\n\nThe Ballerina `data.csv` library allows parsing the CSV byte streams as arrays of Ballerina records, making it easier to process CSV data directly from `streams`. This functionality supports data projection, enabling developers to extract and map only the required fields to the target `record` type.\n\n::: code csv_streams_to_record_array.bal :::\n\n::: out csv_streams_to_record_array.out :::\n"
  },
  {
    "path": "examples/csv-streams-to-record-array/csv_streams_to_record_array.metatags",
    "content": "description: This BBE demonstrates the parsing of CSV byte streams into Ballerina record arrays, both with and without data projection.\nkeywords: ballerina, ballerina by example, bbe, csv, csv byte streams, csv streams, record, record array, parseStream, csv data module, data.csv, data projection, csv to stream\n"
  },
  {
    "path": "examples/csv-streams-to-record-array/csv_streams_to_record_array.out",
    "content": "$ bal run csv_streams_to_record_array.bal\n[{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\",\"price\":45.99,\"publishedDate\":\"2018-01-01\"},{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"price\":37.5,\"publishedDate\":\"2008-08-01\"}]\n[{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\"},{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\"}]\n"
  },
  {
    "path": "examples/csv-string-to-anydata-array/csv_string_to_anydata_array.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\npublic function main() returns error? {\n    string csvString = string `name,author,price,publishedDate\n                               Effective Java,Joshua Bloch,45.99,2018-01-01\n                               Clean Code,Robert C. Martin,37.50,2008-08-01`;\n\n    // Parse the CSV string as an array of `string` arrays.\n    string[][] bookArray = check csv:parseString(csvString);\n    io:println(bookArray);\n\n    // Parse the CSV string to an array of `anydata` arrays.\n    anydata[][] bookArray2 = check csv:parseString(csvString);\n    io:println(bookArray2);\n\n    // Parse the CSV string to an array of `string` arrays with data projection.\n    // Here only the first two headers are extracted to the resulting array,  \n    // based on the array member size specified in the expected type. \n    string[][2] bookArray3 = check csv:parseString(csvString);\n    io:println(bookArray3);\n}\n"
  },
  {
    "path": "examples/csv-string-to-anydata-array/csv_string_to_anydata_array.md",
    "content": "# Parse CSV string to arrays\n\nThe Ballerina `data.csv` library offers a number of functions for parsing CSV strings to subtypes of `anydata[][]`, enabling developers to effectively parse CSV string data into flexible data structures. Additionally, it provides the option to select specific fields for inclusion in the resulting arrays of `anydata` arrays, allowing developers to extract only the required data.\n\n::: code csv_string_to_anydata_array.bal :::\n\n::: out csv_string_to_anydata_array.out :::\n"
  },
  {
    "path": "examples/csv-string-to-anydata-array/csv_string_to_anydata_array.metatags",
    "content": "description: This BBE demonstrates the parsing of a CSV string into an array of anydata arrays, both with and without data projection.\nkeywords: ballerina, ballerina by example, bbe, csv, csv to array, csv string, anydata, anydata array, parseString, csv data module, data.csv, data projection\n"
  },
  {
    "path": "examples/csv-string-to-anydata-array/csv_string_to_anydata_array.out",
    "content": "$ bal run csv_string_to_anydata_array.bal\n[[\"Effective Java\",\"Joshua Bloch\",\"45.99\",\"2018-01-01\"],[\"Clean Code\",\"Robert C. Martin\",\"37.50\",\"2008-08-01\"]]\n[[\"Effective Java\",\"Joshua Bloch\",45.99,\"2018-01-01\"],[\"Clean Code\",\"Robert C. Martin\",37.5,\"2008-08-01\"]]\n[[\"Effective Java\",\"Joshua Bloch\"],[\"Clean Code\",\"Robert C. Martin\"]]\n"
  },
  {
    "path": "examples/csv-string-to-record-array/csv_string_to_record_array.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\ntype Book record {\n    string name;\n    string author;\n    decimal price;\n    string publishedDate;\n};\n\ntype BookMinimal record {|\n    string name;\n    string author;\n|};\n\npublic function main() {\n    string csvString = string `name,author,price,publishedDate\n                               Effective Java,Joshua Bloch,45.99,2018-01-01\n                               Clean Code,Robert C. Martin,37.50,2008-08-01`;\n\n    // Parse CSV string to a array of records.\n    Book[]|csv:Error bookRecords = csv:parseString(csvString);\n    io:println(bookRecords);\n\n    // Parse CSV string to a array of records with data projection.\n    // Here only the fields specified in the target record type (`name` and `author` fields)  \n    // are included in the constructed value. \n    BookMinimal[]|csv:Error briefBookRecords = csv:parseString(csvString);\n    io:println(briefBookRecords);\n}\n"
  },
  {
    "path": "examples/csv-string-to-record-array/csv_string_to_record_array.md",
    "content": "# Parse CSV string to array of records\n\nThe ballerina `data.csv` library offers a range of functions for parsing CSV strings to array of records, enabling developers to parse CSV string data to structured records while allowing for the selection of specific fields within the expected record array.\n\n::: code csv_string_to_record_array.bal :::\n\n::: out csv_string_to_record_array.out :::\n"
  },
  {
    "path": "examples/csv-string-to-record-array/csv_string_to_record_array.metatags",
    "content": "description: This BBE demonstrates conversion of CSV string to array of records with and without data projection.\nkeywords: ballerina, ballerina by example, bbe, csv, csv string, record, record array, parseString, csv data module, data.csv, data projection\n"
  },
  {
    "path": "examples/csv-string-to-record-array/csv_string_to_record_array.out",
    "content": "$ bal run csv_string_to_record_array.bal\n[{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\",\"price\":45.99,\"publishedDate\":\"2018-01-01\"},{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"price\":37.5,\"publishedDate\":\"2008-08-01\"}]\n[{\"name\":\"Effective Java\",\"author\":\"Joshua Bloch\"},{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\"}]\n"
  },
  {
    "path": "examples/csv-user-configurations/csv_user_configurations.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\n// Defines the structure of an `Employee` record.\ntype Employee record {|\n    int id;\n    string name;\n    string department;\n|};\n\n// Defines the structure of an `EmployeeDepartment` record.\ntype EmployeeDepartment record {|\n    int id;\n    string department;\n|};\n\npublic function main() returns error? {\n    // This CSV string contains `|` separated values and a comment.\n    // The `\"` character in `O\\\"Connor` value is escaped using the `\\` character.\n    string csvString = string `id|name|department # This is a comment\n                                1|O\\\"Connor|Engineering\n                                2|Doe|HR\n                                3|Jane|Finance\n                                4|John|Engineering`; \n\n    // Defines the options for parsing the CSV string.                            \n    // The `|` character is used as the delimiter for separating fields.\n    // The `\\` character is used to escape characters (e.g., quotes) within the data.\n    // The `#` character indicates the start of a comment, lines starting with `#` will be ignored.\n    // The second and fourth data rows will be skipped during parsing.\n    csv:ParseOptions parseOptions = {\n        delimiter: \"|\",\n        escapeChar: \"\\\\\",\n        comment: \"#\",\n        skipLines: [2, 4]\n    };\n\n    // Parse the CSV string into an array of `Employee` records with specified options.\n    Employee[] employees = check csv:parseString(csvString, parseOptions);\n    io:println(employees);\n\n    Employee[] employeeRecords = [\n        {id: 1, name: \"John\", department: \"Engineering\"},\n        {id: 2, name: \"Doe\", department: \"HR\"},\n        {id: 3, name: \"Jane\", department: \"Finance\"},\n        {id: 4, name: \"John\", department: \"Engineering\"}\n    ];\n    \n    // Defines the options for transforming the `Employee` records.\n    // The second and fourth data rows will be skipped during transformation.\n    csv:TransformOptions transformOptions = {\n        skipLines: [2, 4]\n    };\n\n    // Transform the `employee` records into `EmployeeDepartment` records with specified options.\n    EmployeeDepartment[] employeeDepartments = check csv:transform(employeeRecords, transformOptions);\n    io:println(employeeDepartments);\n}\n"
  },
  {
    "path": "examples/csv-user-configurations/csv_user_configurations.md",
    "content": "# Handle CSV with custom configurations\n\nBallerina provides flexible CSV data handling through custom configurations, enabling developers to define delimiters, escape characters, and skip specific lines. This approach allows efficient parsing and transformation of CSV files, streamlining the integration process.\n\n::: code csv_user_configurations.bal :::\n\n::: out csv_user_configurations.out :::\n"
  },
  {
    "path": "examples/csv-user-configurations/csv_user_configurations.metatags",
    "content": "description: This BBE demonstrates how to process CSV data using custom configurations.\nkeywords: ballerina, ballerina by example, bbe, csv, csv records, record, record array, transform, parseString, csv data module, data.csv, data projection, csv configs, csv configurations\n"
  },
  {
    "path": "examples/csv-user-configurations/csv_user_configurations.out",
    "content": "$ bal run csv_user_configurations.bal\n[{\"id\":1,\"name\":\"O\"Connor\",\"department\":\"Engineering\"},{\"id\":3,\"name\":\"Jane\",\"department\":\"Finance\"}]\n[{\"id\":1,\"department\":\"Engineering\"},{\"id\":3,\"department\":\"Finance\"}]\n"
  },
  {
    "path": "examples/custom-logger/custom_logger.bal",
    "content": "import ballerina/log;\n\nfinal map<int> & readonly logLevelWeight = {\n    ERROR: 1000,\n    WARN: 900,\n    INFO: 800,\n    DEBUG: 700\n};\n\n// Custom logger implementation that implements the Logger type\npublic isolated class ApplicationLogger {\n    *log:Logger;\n\n    private final string applicationName;\n    private final string version;\n    private final readonly & log:KeyValues context;\n    private log:Level currentLevel;\n    private final ApplicationLogger? parent;\n\n    public isolated function init(string applicationName, string version, log:KeyValues context = {},\n        ApplicationLogger? parent = ()) {\n        self.applicationName = applicationName;\n        self.version = version;\n        self.parent = parent;\n        self.currentLevel = log:INFO;\n        self.context = context.cloneReadOnly();\n    }\n\n    public isolated function printInfo(string|log:PrintableRawTemplate msg, error? 'error = (),\n            error:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n        if logLevelWeight[self.getLevel()] > logLevelWeight[log:INFO] {\n            return;\n        }\n        string evaluatedMsg = msg is string ? msg : log:evaluateTemplate(msg);\n        string printableMsg = string `[Application: ${self.applicationName} v${self.version}] ${evaluatedMsg}`;\n        log:KeyValues newKeyValues = {...self.context};\n        foreach [string, log:Value] [k, v] in keyValues.entries() {\n            newKeyValues[k] = v;\n        }\n        log:printInfo(printableMsg, 'error, stackTrace, newKeyValues);\n    }\n\n    public isolated function printWarn(string|log:PrintableRawTemplate msg, error? 'error = (),\n            error:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n        // Add similar implementation or a custom logic for warnings\n    }\n\n    public isolated function printError(string|log:PrintableRawTemplate msg, error? 'error = (),\n            error:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n        // Add similar implementation or a custom logic for warnings\n    }\n\n    public isolated function printDebug(string|log:PrintableRawTemplate msg, error? 'error = (),\n            error:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n        // Add similar implementation or a custom logic for warnings\n    }\n\n    public isolated function withContext(*log:KeyValues keyValues) returns log:Logger|error {\n        log:KeyValues newContext = {...self.context};\n        foreach [string, log:Value] [k, v] in keyValues.entries() {\n            newContext[k] = v;\n        }\n        return new ApplicationLogger(self.applicationName, self.version, newContext, self);\n    }\n\n    public isolated function getLevel() returns log:Level {\n        ApplicationLogger? p = self.parent;\n        if p is ApplicationLogger {\n            return p.getLevel();\n        }\n        lock {\n            return self.currentLevel;\n        }\n    }\n\n    public isolated function setLevel(log:Level level) returns error? {\n        if self.parent is ApplicationLogger {\n            return error(\"unsupported operation: cannot set level on a child logger\");\n        }\n        lock {\n            self.currentLevel = level;\n        }\n    }\n}\n\npublic function main() returns error? {\n    // Use custom application logger\n    ApplicationLogger appLogger = new (\"OrderService\", \"2.1.0\");\n    appLogger.printInfo(\"Application logger initialized\", feature = \"order_processing\");\n\n    // Create contextual logger from custom logger\n    log:Logger orderLogger = check appLogger.withContext(orderId = \"ORDER-12345\",\n                                                         customerId = \"CUST-67890\");\n    orderLogger.printInfo(\"Processing order\");\n    orderLogger.printDebug(\"Validating order details\");\n\n    appLogger.printInfo(\"Application processing completed\");\n}\n"
  },
  {
    "path": "examples/custom-logger/custom_logger.md",
    "content": "# Custom logger\n\nThis example demonstrates how to implement custom loggers that conform to the `log:Logger` type. Custom loggers can automatically include specific context and provide specialized logging behavior for different components.\n\n::: code custom_logger.bal :::\n\n::: out custom_logger.out :::\n\n> **Note:** In this example, the log module print methods are used to simulate the logging behaviour. So the root logger configurations will be applied to the log messages. But in a real world scenario, you would implement the actual logging logic inside the custom logger methods with custom log formats and destinations.\n\nThe custom logger implementation allows for flexible and reusable logging strategies tailored to specific application needs.\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#41-logger)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/custom-logger/custom_logger.metatags",
    "content": "description: BBE on how to implement custom logger that conform to the Logger type in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, log, custom logger, logger type\n"
  },
  {
    "path": "examples/custom-logger/custom_logger.out",
    "content": "$ bal run custom_logger.bal\n\ntime=2025-08-26T09:04:14.761+05:30 level=INFO module=\"\" message=\"[Application: OrderService v2.1.0] Application logger initialized\" feature=\"order_processing\"\ntime=2025-08-26T09:04:14.776+05:30 level=INFO module=\"\" message=\"[Application: OrderService v2.1.0] Processing order\" orderId=\"ORDER-12345\" customerId=\"CUST-67890\"\ntime=2025-08-26T09:04:14.778+05:30 level=INFO module=\"\" message=\"[Application: OrderService v2.1.0] Application processing completed\"\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.bal",
    "content": "import ballerina/graphql;\nimport ballerina/graphql.dataloader;\nimport ballerina/http;\n\npublic type Book record {|\n    int id;\n    string title;\n|};\n\ntype BookRow record {|\n    readonly int id;\n    string title;\n    int author;\n|};\n\ntype AuthorRow record {|\n    readonly int id;\n    string name;\n|};\n\nfinal readonly & table<AuthorRow> key(id) authorTable = table [\n    {id: 1, name: \"J.K. Rowling\"},\n    {id: 2, name: \"Stephen King\"}\n];\n\nfinal readonly & table<BookRow> key(id) bookTable = table [\n    {id: 1, title: \"Harry Potter and the Sorcerer's Stone\", author: 1},\n    {id: 2, title: \"The Shining\", author: 2},\n    {id: 3, title: \"Harry Potter and the Chamber of Secrets\", author: 1},\n    {id: 4, title: \"It\", author: 2},\n    {id: 5, title: \"Harry Potter and the Prisoner of Azkaban\", author: 1},\n    {id: 6, title: \"The Stand\", author: 2}\n];\n\nisolated function bookLoaderFunction(readonly & anydata[] ids) returns BookRow[][]|error {\n    final readonly & int[] keys = check ids.ensureType();\n    return keys.'map(isolated function(readonly & int key) returns BookRow[] {\n        return bookTable.'filter(book => book.author == key).toArray();\n    });\n}\n\n@graphql:ServiceConfig {\n    contextInit\n}\nservice /graphql on new graphql:Listener(9090) {\n    resource function get authors() returns Author[] {\n        return from AuthorRow authorRow in authorTable\n            select new (authorRow);\n    }\n}\n\npublic isolated distinct service class Author {\n    private final readonly & AuthorRow author;\n\n    isolated function init(readonly & AuthorRow author) {\n        self.author = author;\n    }\n\n    isolated resource function get name() returns string {\n        return self.author.name;\n    }\n\n    // Define a prefetch function with a custom name.\n    isolated function prefetchBooks(graphql:Context ctx) {\n        dataloader:DataLoader bookLoader = ctx.getDataLoader(\"bookLoader\");\n        bookLoader.add(self.author.id);\n    }\n\n    // Annotate the resource function to use a prefetch function having a custom name.\n    // This configuration instructs the GraphQL engine to call the `prefetchBooks` function\n    // before calling the `books` resource function.\n    @graphql:ResourceConfig {\n        prefetchMethodName: \"prefetchBooks\"\n    }\n    isolated resource function get books(graphql:Context ctx) returns Book[]|error {\n        dataloader:DataLoader bookLoader = ctx.getDataLoader(\"bookLoader\");\n        BookRow[] bookrows = check bookLoader.get(self.author.id);\n        return from BookRow bookRow in bookrows\n            select {id: bookRow.id, title: bookRow.title};\n    }\n}\n\nisolated function contextInit(http:RequestContext requestContext, http:Request request)  returns graphql:Context {\n    graphql:Context ctx = new;\n    ctx.registerDataLoader(\"bookLoader\", new dataloader:DefaultDataLoader(bookLoaderFunction));\n    return ctx;\n}\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.client.out",
    "content": "$ curl 'http://localhost:9090/graphql' -H 'Content-Type: application/json' -d '{\"query\": \"{ authors { name books { title } } }\"}'\n{\"data\":{\"authors\":[{\"name\":\"J.K. Rowling\", \"books\":[{\"title\":\"Harry Potter and the Sorcerer's Stone\"}, {\"title\":\"Harry Potter and the Chamber of Secrets\"}, {\"title\":\"Harry Potter and the Prisoner of Azkaban\"}]}, {\"name\":\"Stephen King\", \"books\":[{\"title\":\"The Shining\"}, {\"title\":\"It\"}, {\"title\":\"The Stand\"}]}]}}\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.graphql",
    "content": "{\n  authors {\n    name\n    books {\n      title\n    }\n  }\n}\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.md",
    "content": "# GraphQL service - Custom prefetch methods\n\nA prefetch method in the context of Ballerina GraphQL is a method that is invoked before the actual resolver method. By default the prefetch method name has the convention of having the prefix `pre` followed by the resolver method name. \n\nIf you want to use a custom prefetch method, the `prefetchMethodName` field of the `graphql:ResourceConfig` annotation can be used to override the default prefetch method name. This configuration is useful when the Query and Mutation operations have fields with the same name, and when it is required to use different prefetch methods for each field. To override the default prefetch method name, annotate the target field with the `graphql:ResourceConfig` annotation and specify the prefetch method name as the value of the `prefetchMethodName` field.\n\n::: code custom_prefetch_methods.bal :::\n\nRun the service by executing the following command.\n\n::: out custom_prefetch_methods.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code custom_prefetch_methods.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out custom_prefetch_methods.client.out :::\n\n## Related links\n- [`graphql:ResourceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ResourceConfig)\n- [Prefetch Method Name Configuration - Specification](/spec/graphql/#722-prefetch-method-name-configuration)\n- [The `prefetch` Method - Specification](/spec/graphql/#10633-define-the-corresponding-prefetch-method)\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.metatags",
    "content": "description: BBE on overriding a default prefetch method name.\nkeywords: ballerina, ballerina by example, bbe, graphql, dataloader, prefetch method\n"
  },
  {
    "path": "examples/custom-prefetch-methods/custom_prefetch_methods.server.out",
    "content": "$ bal run graphql_prefetch_config.bal\n"
  },
  {
    "path": "examples/decimal-type/decimal_type.bal",
    "content": "import ballerina/io;\n\n// The `decimal` type represents the set of 128-bits IEEE 754R decimal floating point numbers.\ndecimal nanos = 1d/1000000000d;\n\nfunction floatSurprise() {\n    float f = 100.10 - 0.01;\n    io:println(f);\n}\n\npublic function main() {\n    floatSurprise();\n    io:println(nanos);\n\n    // Numeric literals can use `d` or `D` suffix for them to be interpreted as `decimal` values.\n    // (Similarly, the `f` or `F` suffix can be used for `float`).\n    var d = 12345d;\n    io:println(d is decimal);\n}\n"
  },
  {
    "path": "examples/decimal-type/decimal_type.md",
    "content": "# Decimal type\n\nThe `decimal` type is the third numeric type. It works like `int` and `float` types. It is a separate basic type and belongs to the `anydata` type.\n\nThere is no implicit conversions between `decimal` and other numeric types. It can represent `decimal` fractions exactly and it preserves precision. The `decimal` type does not include infinity, NaN, or negative zero. It supports floating-point precision to 34 decimal digits.\n\n::: code decimal_type.bal :::\n\n::: out decimal_type.out :::"
  },
  {
    "path": "examples/decimal-type/decimal_type.metatags",
    "content": "description: This BBE demonstrates decimal type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, decimal type, decimal\n"
  },
  {
    "path": "examples/decimal-type/decimal_type.out",
    "content": "$ bal run decimal_type.bal\n100.08999999999999\n1E-9\ntrue\n"
  },
  {
    "path": "examples/default-values-for-function-parameters/default_values_for_function_parameters.bal",
    "content": "import ballerina/io;\n\n// Use the value of the preceding `str` parameter to initialize the `end` parameter.\nfunction subString(string str, int 'start = 0, int end = str.length()) returns string {\n    return str.substring('start, end);\n}\n\npublic function main() {\n    // Call the `subString` function using the default values of `start` and `end` parameters.\n    io:println(subString(\"Ballerina Language\"));\n\n    // Call the `subString` function by passing a value for the `start` default parameter.\n    io:println(subString(\"Ballerina Language\", 10));\n\n    // Call the `subString` function by passing values for `start` and `end` default parameters.\n    io:println(subString(\"Ballerina Language\", 10, 14));\n}\n"
  },
  {
    "path": "examples/default-values-for-function-parameters/default_values_for_function_parameters.md",
    "content": "# Default values for function parameters\n\nBallerina allows specifying default values for function parameters. You can use any expression such as a literal or a function call as the default value of a parameter. Additionally, the default value expressions can use the values of the preceding parameters.\n\n::: code default_values_for_function_parameters.bal :::\n\n::: out default_values_for_function_parameters.out :::\n\n## Related links\n- [Rest Parameters](/learn/by-example/rest-parameters/)\n- [Provide function arguments by name](/learn/by-example/provide-function-arguments-by-name/)\n- [Rest arguments](/learn/by-example/rest-arguments/)\n"
  },
  {
    "path": "examples/default-values-for-function-parameters/default_values_for_function_parameters.metatags",
    "content": "description: This BBE demonstrates defining default parameter values in a function using the preceding parameter value as the default parameter value in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, default parameter, default value, functions\n"
  },
  {
    "path": "examples/default-values-for-function-parameters/default_values_for_function_parameters.out",
    "content": "$ bal default_values_for_function_parameters.bal\nBallerina Language\nLanguage\nLang\n"
  },
  {
    "path": "examples/default-values-for-record-fields/default_values_for_record_fields.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    string name;\n    int age;\n    // Specifies a default value for `code`.\n    string code = \"Admitted\";\n|};\n\ntype PartTimeStudent record {|\n    *Student;\n    int studyHours;\n|};\n\npublic function main() returns error? {\n    // Creates a `Student` record without explicitly specifying a value for the `code` field.\n    Student s1 = {name: \"Anne\", age: 23};\n    io:println(s1);\n\n    json j = {name: \"Anne\", age: 23};\n    // Calling the `value:cloneWithType()` function with `Student` will make use of the default values\n    // in `Student`.\n    Student s2 = check j.cloneWithType(Student);\n    io:println(s2);\n\n    // `*Student` copies the default values.\n    PartTimeStudent s3 = {name: \"Anne\", age: 23, studyHours: 6};\n    io:println(s3);\n}\n"
  },
  {
    "path": "examples/default-values-for-record-fields/default_values_for_record_fields.md",
    "content": "# Default values for record fields\n\nBallerina allows default values for record fields as part of the record's type descriptor. A default value is an expression. Default values do not affect static typing. They only affect the use of type descriptors to construct records. Calling the `value:cloneWithType()` function with a record type descriptor `T` will make use of the default values in `T` if required. Similarly, using `*T` in type inclusions also copies the default values.\n\n::: code default_values_for_record_fields.bal :::\n\n::: out default_values_for_record_fields.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)\n- [Type inclusion for records](/learn/by-example/type-inclusion-for-records/)\n- [Maps](/learn/by-example/maps/)\n"
  },
  {
    "path": "examples/default-values-for-record-fields/default_values_for_record_fields.metatags",
    "content": "description: This BBE demonstrates the default values for record fields, adding default values to record fields, and default values in inclusions.\nkeywords: ballerina, ballerina by example, bbe, record, record type, record field, inclusion, record inclusion, default values\n"
  },
  {
    "path": "examples/default-values-for-record-fields/default_values_for_record_fields.out",
    "content": "$ bal run default_values_for_record_fields.bal\n{\"name\":\"Anne\",\"age\":23,\"code\":\"Admitted\"}\n{\"name\":\"Anne\",\"age\":23,\"code\":\"Admitted\"}\n{\"studyHours\":6,\"name\":\"Anne\",\"age\":23,\"code\":\"Admitted\"}\n"
  },
  {
    "path": "examples/defining-classes/defining_classes.bal",
    "content": "import ballerina/io;\n\nclass Engineer {\n    // A `final` field must be assigned exactly once.\n    final string name;\n\n    int age;\n\n    // The `init` method initializes the object.\n    function init(string name, int age) {\n        // The `init` method can initialize the `final` field.\n        self.name = name;\n        self.age = age;\n    }\n\n    function getName() returns string {\n        // Methods use `self` to access their fields.\n        return self.name;\n    }\n\n    function getAge() returns int {\n        return self.age;\n    }\n}\n\npublic function main() {\n    // Arguments to `new` are passed as arguments to `init`.\n    Engineer engineer = new Engineer(\"Alice\", 52);\n\n    io:println(engineer.getName());\n    io:println(engineer.getAge());\n}\n"
  },
  {
    "path": "examples/defining-classes/defining_classes.md",
    "content": "# Defining classes\n\nClasses provide a template for bundling data and functionality together. In Ballerina, classes are defined at the module level. The `init` method is used to initialize an object and any arguments passed to the `new` expression are passed as arguments to the `init` method. The `init` method can also be used to initialize the `final` fields.\n\nThe `self` variable is bound to the object and can be used to access the fields and methods of the object.\n\n::: code defining_classes.bal :::\n\n::: out defining_classes.out :::\n\n## Related links\n- [Object](/learn/by-example/object/)\n- [Init return type](/learn/by-example/init-return-type/)\n- [Object value from class definition](/learn/by-example/object-value-from-class-definition/)\n"
  },
  {
    "path": "examples/defining-classes/defining_classes.metatags",
    "content": "description: This BBE demonstrates defining classses, invoking object methods, and initializing object fields in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, class, object, init method, new\n"
  },
  {
    "path": "examples/defining-classes/defining_classes.out",
    "content": "$ bal run defining_classes.bal\nAlice\n52\n"
  },
  {
    "path": "examples/dependent-types/dependent_types.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    string|int s1 =  \"Ballerina\";\n    // `lang.value:ensureType()` is a  is a dependently-typed function.\n    // The return type of `ensureType` function is dependent on the\n    // value of the parameter, which is `string` type descriptor here.\n    string s2 = check s1.ensureType(string);\n    io:println(s2);\n\n    json j = 12.5d;\n    // `ensureType()` function is called on `j`, and it returns a `float` value which is\n    // assigned to `f`, which is of the `float` type.  This happens because the function parameter\n    // `t` of `ensureType` has a default value of `<>` which causes the compiler to infer the\n    // argument for `t` from the function call context.\n    float f = check j.ensureType();\n    io:println(f);\n}\n"
  },
  {
    "path": "examples/dependent-types/dependent_types.md",
    "content": "# Dependent types\n\nBallerina supports a concept called dependent types that makes the return type of a function dependent on the value of a parameter. Unlike the normal convention where the return type is defined independently, here the return type depends on a parameter which is a type descriptor. When the parameter has a default value of `<>` the compiler infers the argument for the parameter from the function call context.\n\n::: code dependent_types.bal :::\n\n::: out dependent_types.out :::\n"
  },
  {
    "path": "examples/dependent-types/dependent_types.metatags",
    "content": "description: This BBE demonstrates dependent types in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, dependent type\n"
  },
  {
    "path": "examples/dependent-types/dependent_types.out",
    "content": "$ bal run dependent_types.bal\nBallerina\n12.5\n"
  },
  {
    "path": "examples/destructure-records-using-query/destructure_records_using_query.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    string first;\n    string last;\n    anydata...;\n|};\n\npublic function main() {\n    Person[] persons = [\n        {first: \"Melina\", last: \"Kodel\", \"yearOfBirth\": 1994},\n        {first: \"Tom\", last: \"Riddle\", \"yearOfBirth\": 1926}\n    ];\n\n    // A `Person` record is destructured here as a projection with the `first` and `last` fields.\n    // `{first, last}` is the mapping binding pattern. It is the same as `{first:first, last:last}`.\n    var names = from var {first, last} in persons\n                select {first, last};\n    io:println(names);\n\n    // Specify the type explicitly before the binding pattern instead of `var`.\n    names = from Person {first, last} in persons\n                 select {first, last};\n    io:println(names);\n\n    // This maps all the remaining fields of the `Person` record other than the field `first`\n    // using the rest binding pattern.\n    var lastNameAndDOB = from var {first: _, ...restDetail} in persons\n                         select restDetail;\n    io:println(lastNameAndDOB);\n}\n"
  },
  {
    "path": "examples/destructure-records-using-query/destructure_records_using_query.md",
    "content": "# Destructure records using queries\n\nDestructuring records is particularly useful with the query expressions. But works anywhere you can have `var`. `var` is followed by a binding pattern. You can also specify the type explicitly before the binding pattern without using `var`.\n\n`{x}` is short for `{x: x}` in both binding patterns and record constructors.\n\n::: code destructure_records_using_query.bal :::\n\n::: out destructure_records_using_query.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/destructure-records-using-query/destructure_records_using_query.metatags",
    "content": "description: This BBE demonstrates using binding patterns in a query expression, record destructuring in a query expression and accessing values in a query iteration.\nkeywords: ballerina, ballerina by example, bbe, query, var, binding pattern, from, access\n"
  },
  {
    "path": "examples/destructure-records-using-query/destructure_records_using_query.out",
    "content": "$ bal run destructuring_records_with_query.bal\n[{\"first\":\"Melina\",\"last\":\"Kodel\"},{\"first\":\"Tom\",\"last\":\"Riddle\"}]\n[{\"first\":\"Melina\",\"last\":\"Kodel\"},{\"first\":\"Tom\",\"last\":\"Riddle\"}]\n[{\"last\":\"Kodel\",\"yearOfBirth\":1994},{\"last\":\"Riddle\",\"yearOfBirth\":1926}]\n"
  },
  {
    "path": "examples/direct-llm-calls/direct_llm_calls.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Use the default model provider (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider model = check ai:getDefaultModelProvider();\n\ntype JokeResponse record {|\n    string setup;\n    string punchline;\n|};\n\npublic function main(string subject) returns error? {\n    // Use an insertion to insert the subject into the prompt.\n    // The response is expected to be a string.\n    string joke = check model->generate(`Tell me a joke about ${subject}!`);\n    io:println(joke);\n\n    // An LLM call with a structured response type.\n    JokeResponse jokeResponse = check model->generate(`Tell me a joke about ${subject}!`);\n    io:println(\"Setup: \", jokeResponse.setup);\n    io:println(\"Punchline: \", jokeResponse.punchline);\n}\n"
  },
  {
    "path": "examples/direct-llm-calls/direct_llm_calls.md",
    "content": "# Direct large language model (LLM) calls\n\nThe `ai:ModelProvider` type is a unified abstraction to integrate with large language models (LLMs) through provider-specific modules such as [ballerinax/ai.openai](https://central.ballerina.io/ballerinax/ai.openai/latest), [ballerinax/ai.anthropic](https://central.ballerina.io/ballerinax/ai.anthropic/latest), etc.\n\nThe `generate` method of the model provider accepts a prompt in natural language, generates a JSON schema corresponding to the type descriptor argument (generally, the expected type), makes the call to the LLM, and binds the relevant content from the response to the expected type, allowing seamless integration with LLMs.\n\nThis example demonstrates how to make direct calls to LLMs using the model provider, enabling type-safe AI integrations across different providers. \n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code direct_llm_calls.bal :::\n\n::: out direct_llm_calls.out :::\n\n## Related links\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/direct-llm-calls/direct_llm_calls.metatags",
    "content": "description: This BBE demonstrates how to do direct LLM calls.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider\n"
  },
  {
    "path": "examples/direct-llm-calls/direct_llm_calls.out",
    "content": "$ bal run direct_llm_calls.bal -- subject=programming \nWhy do programmers prefer dark mode?\n\nBecause light attracts bugs!\nSetup: Why do programmers prefer dark mode?\nPunchline: Because light attracts bugs!\n"
  },
  {
    "path": "examples/direct-llm-calls-with-history/direct_llm_calls_with_history.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Use the default model provider (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider model = check ai:getDefaultModelProvider();\n\npublic function main(string subject) returns error? {\n    // Create a user message with the prompt as the content.\n    ai:ChatUserMessage userMessage = {\n        role: ai:USER,\n        content: `Tell me a joke about ${subject}!`\n    };\n\n    // Use an array to hold the conversation history.\n    ai:ChatMessage[] messages = [userMessage];\n\n    // Use the `chat` method to make a call with the conversation history.\n    // Alternatively, you can pass a single message (`userMessage`) too.\n    ai:ChatAssistantMessage assistantMessage = check model->chat(messages);\n\n    // Update the conversation history with the assistant's response.\n    messages.push(assistantMessage);\n\n    // Print the joke from the assistant's response.\n    string? joke = assistantMessage?.content;\n    io:println(joke);\n\n    // Continue the conversation by asking for an explanation.\n    messages.push({\n        role: ai:USER,\n        content: \"Can you explain it?\"\n    });\n    ai:ChatAssistantMessage assistantMessage2 = check model->chat(messages);\n\n    // Since the conversation history is passed, the model can provide a relevant explanation.\n    string? explanation = assistantMessage2?.content;\n    io:println(explanation);\n}\n"
  },
  {
    "path": "examples/direct-llm-calls-with-history/direct_llm_calls_with_history.md",
    "content": "# Direct large language model (LLM) calls with history\n\nThe `ai:ModelProvider` type is a unified abstraction to integrate with large language models (LLMs) through provider-specific modules such as [ballerinax/ai.openai](https://central.ballerina.io/ballerinax/ai.openai/latest), [ballerinax/ai.anthropic](https://central.ballerina.io/ballerinax/ai.anthropic/latest), etc.\n\nThe `chat` method of the model provider accepts a user message or an array of chat messages, makes the call to the LLM with the message(s), and returns the relevant content of the response from the LLM.\n\nThis example demonstrates how to make direct calls to LLMs using the model provider, maintaining the chat history. \n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code direct_llm_calls_with_history.bal :::\n\n::: out direct_llm_calls_with_history.out :::\n\n## Related links\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/direct-llm-calls-with-history/direct_llm_calls_with_history.metatags",
    "content": "description: This BBE demonstrates how to do direct LLM calls, maintaining the chat history.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, history, model-provider\n"
  },
  {
    "path": "examples/direct-llm-calls-with-history/direct_llm_calls_with_history.out",
    "content": "$ bal run direct_llm_calls_with_history.bal -- subject=programming\nWhy do programmers prefer dark mode?\n\nBecause light attracts bugs!\nSure! The joke plays on two concepts:\n\n1. **Dark Mode vs. Light Mode**: Many programmers prefer using \"dark mode\" in their coding environments because it's easier on the eyes, especially during long coding sessions. Dark mode features a dark background with lighter text, while light mode has a light background with darker text.\n\n2. **Bugs**: In programming, a \"bug\" refers to an error or flaw in the code that can cause it to behave unexpectedly. In a more literal sense, bugs (like insects) are often attracted to light sources.\n\nSo the humor comes from the double meaning of \"bugs.\" The joke suggests that if programmers use light mode (which is bright), they might attract actual bugs, just like real insects are drawn to light. Therefore, by using dark mode, they’re avoiding both programming errors and actual bugs!\n\n"
  },
  {
    "path": "examples/direct-llm-calls-with-multimodal-input/direct_llm_calls_with_multimodal_input.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Use the default model provider (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider model = check ai:getDefaultModelProvider();\n\n// The type representing the expected response from the model.\n// The generated JSON schema will also include the documentation.\n# Description of an image.\ntype Description record {|\n    # A sentence describing the image.\n    string description;\n    # The confidence of the description, on a scale of 0 to 1.\n    decimal confidence;\n    # Categories that the image falls into.\n    string[] categories;\n|};\n\npublic function main() returns error? {\n    // Define an `ai:ImageDocument` value with a URL to an image.\n    ai:ImageDocument image = {\n        content: \"https://ballerina.io/img/branding/ballerina_logo_dgrey_png.png\"\n    };\n\n    // Use the `generate` method with an image document as an interpolation.\n    // The model provider implementation will detect the multimodal input and handle\n    // constructing the request appropriately.\n    Description? description = check model->generate(`\n        Describe this image.\n\n        ${image}\n        \n        If it is not possible to describe the image, respond with null`);\n\n    // Handle the case where the model could not describe the image.\n    if description is () {\n        io:println(\"Could not describe the image\");\n        return;\n    }\n    \n    // Print the description.\n    io:println(description);\n}\n"
  },
  {
    "path": "examples/direct-llm-calls-with-multimodal-input/direct_llm_calls_with_multimodal_input.md",
    "content": "# Direct large language model (LLM) calls with multimodal input\n\nThe `ai:ModelProvider` type is a unified abstraction to integrate with large language models (LLMs) through provider-specific modules such as [ballerinax/ai.openai](https://central.ballerina.io/ballerinax/ai.openai/latest), [ballerinax/ai.anthropic](https://central.ballerina.io/ballerinax/ai.anthropic/latest), etc.\n\nIf multimodal input is supported by an LLM, the model provider implementation for the LLM handles insertions of the `ai:Document` types (`ai:ImageDocument`, `ai:AudioDocument`, and `ai:FileDocument`) as multimodal input, and creates the request as expected by the LLM API.\n\nThis example demonstrates how to make direct calls to LLMs using the model provider, with multimodal input. \n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code direct_llm_calls_with_multimodal_input.bal :::\n\n::: out direct_llm_calls_with_multimodal_input.out :::\n\n## Related links\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/direct-llm-calls-with-multimodal-input/direct_llm_calls_with_multimodal_input.metatags",
    "content": "description: This BBE demonstrates how to do direct LLM calls with multimodal input.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, multimodal, model-provider\n"
  },
  {
    "path": "examples/direct-llm-calls-with-multimodal-input/direct_llm_calls_with_multimodal_input.out",
    "content": "$ bal run direct_llm_calls_with_multimodal_input.bal \n{\"description\":\"The word 'Ballerina' written in black text, with the letter 'l' stylized to look like a ballet dancer\",\"confidence\":0.98,\"categories\":[\"text\",\"logo\",\"typography\"]}\n"
  },
  {
    "path": "examples/directories/directories.bal",
    "content": "import ballerina/file;\nimport ballerina/io;\n\npublic function main() returns error? {\n\n    // Creates a new directory with any non-existent parents.\n    string dirPath = check file:joinPath(\"foo\", \"bar\");\n    check file:createDir(dirPath, file:RECURSIVE);\n    io:println(\"The \" + dirPath + \" directory created successfully.\");\n\n    // Checks whether the directory of the provided path exists.\n    boolean dirExists = check file:test(\"foo\", file:EXISTS);\n    io:println(\"Is foo directory exist: \", dirExists.toString());\n\n    // Copies the directory with another name.\n    check file:copy(dirPath, \"test\", file:REPLACE_EXISTING);\n    io:println(\"The \" + dirPath + \" directory copied successfully.\");\n\n    // Renames the directory to another new name.\n    check file:rename(\"foo\", \"test1\");\n    io:println(\"The foo directory renamed successfully.\");\n\n    // Gets the list of files/directories in the given directory.\n    file:MetaData[] readDirResults = check file:readDir(\"test1\");\n    io:println(\"Directory path: \", readDirResults[0].absPath);\n    io:println(\"Directory size: \", readDirResults[0].size.toString());\n    io:println(\"Is directory: \", readDirResults[0].dir.toString());\n    io:println(\"Modified at \", readDirResults[0].modifiedTime.toString());\n\n    // Removes the directory in the specified file path.\n    check file:remove(\"test\");\n\n    // Removes the directory in the specified file path with all its children.\n    check file:remove(\"test1\", file:RECURSIVE);\n    io:println(\"Directories removed successfully.\");\n}\n"
  },
  {
    "path": "examples/directories/directories.md",
    "content": "# Directories\n\nThe `file` library provides APIs to perform directory operations.\n\nFor more information on the underlying module, see the [`file` module](https://lib.ballerina.io/ballerina/file/latest/).\n\n::: code directories.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out directories.out :::\n"
  },
  {
    "path": "examples/directories/directories.metatags",
    "content": "description: This BBE shows how to perform directory operations in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, directory, file, path\n"
  },
  {
    "path": "examples/directories/directories.out",
    "content": "$ bal run directories.bal\nThe foo/bar directory created successfully.\nIs foo directory exist: true\nThe foo/bar directory copied successfully.\nThe foo directory renamed successfully.\nDirectory path: /A/B/C/test1/bar\nDirectory size: 64\nIs directory: true\nModified at 1621859440 0.871000000\nDirectories removed successfully.\n"
  },
  {
    "path": "examples/directory-listener/directory_listener.bal",
    "content": "import ballerina/file;\nimport ballerina/log;\n\n// The listener monitors any modifications done to a specific directory.\nlistener file:Listener inFolder = new ({\n    path: \"/home/ballerina/fs-server-connector/observed-dir\",\n    recursive: false\n});\n\n// The directory listener should have at least one of these predefined resources.\nservice \"localObserver\" on inFolder {\n\n    // This function is invoked once a new file is created in the listening directory.\n    remote function onCreate(file:FileEvent m) {\n        log:printInfo(\"Create: \" + m.name);\n    }\n\n    // This function is invoked once an existing file is deleted from the listening directory.\n    remote function onDelete(file:FileEvent m) {\n        log:printInfo(\"Delete: \" + m.name);\n    }\n\n    // This function is invoked once an existing file is modified in the listening directory.\n    remote function onModify(file:FileEvent m) {\n        log:printInfo(\"Modify: \" + m.name);\n    }\n}\n"
  },
  {
    "path": "examples/directory-listener/directory_listener.md",
    "content": "# Directory listener\n\nThe `file` library provides a `Directory Listener`, which is used to listen to the given directory in the local file system.\nIt notifies when new files are created in the directory or when the existing files are deleted or modified.\n\nFor more information on the underlying module, see the [`file` module](https://lib.ballerina.io/ballerina/file/latest/).\n\nBefore running this, change the value of the `path` field to indicate the path of the directory that you want to monitor.\nAs the recursive property is set to false, the listener does not monitor the child directories of the main directory that it listens to.\n\n::: code directory_listener.bal :::\n\nTo run this sample, use the `bal run` command. After running the sample,\ncreate a new file called `test1.txt` in the directory called `observed-dir`, modify it, and delete it.\n\n::: out directory_listener.out :::\n"
  },
  {
    "path": "examples/directory-listener/directory_listener.metatags",
    "content": "description: This BBE shows how the Ballerina directory service monitors any modifications done to files inside a specific directory.\nkeywords: ballerina, ballerina by example, BBE, file, directory, directory listener\n"
  },
  {
    "path": "examples/directory-listener/directory_listener.out",
    "content": "$ bal run directory_listener.bal\ntime = 2020-12-12 13:49:08,497 level = INFO  module = \"\" message = \"Create: /home/ballerina/fs-server-connector/observed-dir/test1.txt\"\ntime = 2020-12-12 13:49:41,709 level = INFO  module = \"\" message = \"Modify: /home/ballerina/fs-server-connector/observed-dir/test1.txt\"\ntime = 2020-12-12 13:50:04,997 level = INFO  module = \"\" message = \"Delete: /home/ballerina/fs-server-connector/observed-dir/test1.txt\"\n"
  },
  {
    "path": "examples/distinct-object-types/distinct_object_types.bal",
    "content": "import ballerina/io;\n\nclass Person {\n    public string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n};\n\n// The `DistinctPerson` type is a proper subtype of the `Person` type.\ndistinct class DistinctPerson {\n    public string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n}\n\n// The `SomeWhatDistinctPerson` type is a subtype of the `DistinctPerson` type\n// since it includes the `DistinctPerson` type's type IDs via inclusion.\nclass SomeWhatDistinctPerson {\n    *DistinctPerson;\n\n    public string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n}\n\n// The `EvenMoreDistinctPerson` type is a proper subtype of the `DistinctPerson` \n// type since it has an additional type ID.\ndistinct class EvenMoreDistinctPerson {\n    *DistinctPerson;\n\n    public string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n}\n\npublic function main() {\n    Person person = new (\"John Smith\");\n    io:println(person is DistinctPerson);\n\n    DistinctPerson distinctPerson = new (\"Alice Johnson\");\n    io:println(distinctPerson is Person);\n\n    SomeWhatDistinctPerson someWhatDistinctPerson = new (\"Michael Brown\");\n    io:println(someWhatDistinctPerson is DistinctPerson);\n    io:println(distinctPerson is SomeWhatDistinctPerson);\n\n    EvenMoreDistinctPerson evenMoreDistinctPerson = new (\"Sarah Wilson\");\n    io:println(evenMoreDistinctPerson is DistinctPerson);\n    io:println(distinctPerson is EvenMoreDistinctPerson);\n}\n"
  },
  {
    "path": "examples/distinct-object-types/distinct_object_types.md",
    "content": "# Distinct object types\n\nFor more explicit control over object type relations you can use `distinct` object types. Each distinct object type declaration has a unique type ID. When you include a distinct object type within another object type declaration, the new type's type ID set will include the type IDs of the included type. When checking if a given object type `OSub` is a subtype of a distinct object type `OSuper` there is the additional requirement that the `OSub` type must contain all the type IDs of the `OSuper` type.\n\nThis way you can achieve the same behavior as a nominal type system within Ballerina's structured type system, which is useful to support features such as GraphQL API interfaces.\n\n::: code distinct_object_types.bal :::\n\n::: out distinct_object_types.out :::\n\n## Related links\n- [Object types](/learn/by-example/object-types/)\n- [Error subtyping](/learn/by-example/error-subtyping/)\n- [Defining classes](/learn/by-example/defining-classes/)\n- [Flexibly typed](https://ballerina.io/why-ballerina/flexibly-typed/)\n- [GraphQL service - Interfaces](https://ballerina.io/learn/by-example/graphql-interfaces/)\n"
  },
  {
    "path": "examples/distinct-object-types/distinct_object_types.metatags",
    "content": "description: This BBE demonstrates distinct object types, defining nominal typing, object subtyping, and defining a class in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object, class, distinct, self, new\n"
  },
  {
    "path": "examples/distinct-object-types/distinct_object_types.out",
    "content": "$ bal distinct_object_types.bal\nfalse\ntrue\ntrue\ntrue\ntrue\nfalse\n"
  },
  {
    "path": "examples/docker-hello-world/Cloud.toml",
    "content": "[container.image]\nrepository=\"wso2inc\"\nname=\"hello\"\ntag=\"v0.1.0\"\n"
  },
  {
    "path": "examples/docker-hello-world/build_output.out",
    "content": "$ bal build --cloud=\"docker\"\n\nCompiling source\n        wso2/hello:0.1.0\n\nGenerating executable\n\nGenerating artifacts...\n\n        @kubernetes:Docker                       - complete 2/2 \n\n        Execute the below command to run the generated Docker image: \n        docker run -d -p 9090:9090 wso2inc/hello:v0.1.0\n"
  },
  {
    "path": "examples/docker-hello-world/docker_hello_world.bal",
    "content": "import ballerina/http;\n\n// This code is completely focused on the business logic and it does not depend on the deployment.\n\nlistener http:Listener helloEP = new(9090);\n\nservice http:Service /helloWorld on helloEP {\n    resource function get sayHello() returns string {\n        return \"Hello from Docker!\";\n    }\n}\n"
  },
  {
    "path": "examples/docker-hello-world/docker_hello_world.md",
    "content": "# Docker - Hello world\n\nBallerina supports generating Docker artifacts from code without any additional configuration. This simplifies the experience of developing and deploying Ballerina code in the cloud. Code to Cloud builds the containers and required artifacts by deriving the required values from the code. If you want to override the default values taken by the compiler, you can use a `Cloud.toml` file.\nFor more information, see [Code to Cloud Deployment](/learn/code-to-cloud-deployment/).\n\n::: code docker_hello_world.bal :::\n\nBefore you build the package, you need to override some default values taken by the compiler. To do this, create a file named `Cloud.toml` in the package directory, and add the content below to it.\nFor all the supported key value properties, see [Code to Cloud specification](https://github.com/ballerina-platform/ballerina-spec/blob/master/c2c/code-to-cloud-spec.md).\n\n::: code Cloud.toml :::\n\nExecute the `bal build` command to build the Ballerina package. Code to Cloud generates only one container per package.\n>**Note:** macOS users with Apple Silicon chips need to set an environment variable named `DOCKER_DEFAULT_PLATFORM` to `linux/amd64`, before building the image. This is because the Ballerina Docker image is not supported on Apple Silicon chips yet. Run `export DOCKER_DEFAULT_PLATFORM=linux/amd64` to set the environment variable.\n\n::: out build_output.out :::\n\nVerify if the Docker image is generated.\n::: out docker_images.out :::\n\nRun the generated Docker image.\n::: out docker_run.out :::\n\nInvoke the service.\n::: out execute_curl.out:::\n"
  },
  {
    "path": "examples/docker-hello-world/docker_images.out",
    "content": "$ docker images\n\nREPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE\nwso2inc/hello                 v0.1.0              60d95f0928b2        About a minute ago  228MB\n"
  },
  {
    "path": "examples/docker-hello-world/docker_run.out",
    "content": "$ docker run -d -p 9090:9090 wso2inc/hello:v0.1.0\nc04194eb0b4d0d78cbc8ca55e0527d381d8ab4a1a68f8ea5dd3770a0845d5fbb\n"
  },
  {
    "path": "examples/docker-hello-world/execute_curl.out",
    "content": "$ curl http://localhost:9090/helloWorld/sayHello\nHello from Docker!\n"
  },
  {
    "path": "examples/documentation/documentation.bal",
    "content": "// Lines starting with `#` contain structured documentation in Markdown format.\n# Adds two integers.\n// Documents the parameters of the function.\n# + x - an integer\n# + y - another integer\n// Documents the return parameter of the function.\n# + return - the sum of `x` and `y`\npublic function add(int x, int y) returns int {\n    return x + y;\n}\n"
  },
  {
    "path": "examples/documentation/documentation.md",
    "content": "# Documentation\n\nAnnotations would be inconvenient for specifying structured documentation. Ballerina-flavored Markdown (BFM) is an additional convention on top of Markdown, which makes it more convenient for documenting Ballerina code.\n\n::: code documentation.bal :::\n\n::: out documentation.out :::"
  },
  {
    "path": "examples/documentation/documentation.metatags",
    "content": "description: This BBE demonstrates documentation in Ballerina, which is a Markdown format with additional conventions to write structured documentations in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, documentation, Ballerina-flavored Markdown, BFM\n"
  },
  {
    "path": "examples/documentation/documentation.out",
    "content": "$ bal run documentation.bal\n"
  },
  {
    "path": "examples/dynamic-listener/dynamic_listener.bal",
    "content": "import ballerina/http;\nimport ballerina/lang.runtime;\n\nhttp:Listener httpListener = check new (9090);\n\nhttp:Service helloService =  service object {\n\n    resource function get greeting() returns string {\n        // Send a response back to the caller.\n        return \"Hello, World!\";\n    }\n\n    // The resource function that will shutdown the server.\n    resource function post shutdown(http:Caller caller) returns error? {\n        // Send a response back to the caller.\n        check caller->respond(\"Shutting down the server\");\n        // Stop the listener.\n        // This will be called automatically if the program exits by means of a system call.\n        check httpListener.gracefulStop();\n        // Deregister the listener dynamically.\n        runtime:deregisterListener(httpListener);\n    }\n};\n\npublic function main() returns error? {\n    // Attach the service to the listener along with the resource path.\n    check httpListener.attach(helloService, \"foo/bar\");\n    // Start the listener.\n    check httpListener.'start();\n    // Register the listener dynamically.\n    runtime:registerListener(httpListener);\n}\n"
  },
  {
    "path": "examples/dynamic-listener/dynamic_listener.client.out",
    "content": "$ curl http://localhost:9090/foo/bar/greeting\nHello, World!\n\n# Invoke the shutdown resource to deregister the listener.\n$ curl http://localhost:9090/foo/bar/shutdown -X POST\nShutting down the server\n"
  },
  {
    "path": "examples/dynamic-listener/dynamic_listener.md",
    "content": "# Dynamic listener\n\nDynamic listeners allow registering/deregistering a module listener dynamically. This example demonstrates how to register and deregister an HTTP listener and terminate it in the process.\n\n::: code dynamic_listener.bal :::\n\nRun the service as follows.\n\n::: out dynamic_listener.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out dynamic_listener.client.out :::\n"
  },
  {
    "path": "examples/dynamic-listener/dynamic_listener.metatags",
    "content": "description: Registering/deregistering a module listener dynamically.\nkeywords: ballerina, ballerina by example, listener, dynamic listener, bbe, service\n"
  },
  {
    "path": "examples/dynamic-listener/dynamic_listener.server.out",
    "content": "$ bal run dynamic_listener.bal\n"
  },
  {
    "path": "examples/edi-to-record/bal_project.out",
    "content": "$ bal new edi_to_record\n$ cd edi_to_record\n$ bal add sorder\n"
  },
  {
    "path": "examples/edi-to-record/codegen_command.out",
    "content": "$ bal edi codegen -i resources/simple_order_schema.json -o modules/sorder/sorder.bal\n"
  },
  {
    "path": "examples/edi-to-record/edi_to_record.bal",
    "content": "import ballerina/io;\nimport edi_to_record.sorder;\n\npublic function main() returns error? {\n    string ediText = check io:fileReadString(\"resources/order.edi\");\n    sorder:SimpleOrder simpleOrder = check sorder:fromEdiString(ediText);\n    io:println(\"Order Id: \", simpleOrder.header.orderId);\n\n    foreach sorder:Items_Type item in simpleOrder.items {\n        io:println(\"Item: \", item.item, \", Quantity: \", item.quantity);\n    }\n}\n"
  },
  {
    "path": "examples/edi-to-record/edi_to_record.md",
    "content": "# EDI to record conversion\n\nEDI is a widely used message format for business-to-business (B2B) communications. Ballerina simplifies working with EDI data by converting them to Ballerina records, so that all operations related to Ballerina records can be applied on EDI data as well (e.g. transforming EDI data, writing EDI data to databases, transering EDI data over various network protocols, etc.).\n\nFirst, it is necessary to write a schema for the EDI data type that needs to be processed. Below is a simple EDI schema for sales order data. According to the schema, data must begin with a `HDR` segment followed by zero or more `ITM` segments. `HDR` segment contains four fields: `code`, `orderId`, `organization`, and `date`. `ITM` segment has three fields: `code`, `item`, and `quantity`.\n\n::: code schema.json :::\n\nBelow is an example EDI text that can be parsed using the above schema.\n\n::: code order.edi :::\n\nCreate a new Ballerina project named `edi_to_record` and create a module named `sorder` inside that project by using the below commands.\n\n::: code bal_project.out :::\n\nCreate a new folder named `resources` in the root of the project and copy the schema file into it. At this point, directory structure of the project would look like below:\n\n::: out package_structure.out :::\n\nGet the EDI tool from the Ballerina central using the below command:\n\n::: out tool_pull_command.out :::\n\nRun the below command from the project root directory to generate the Ballerina parser for the above schema.\n\n::: out codegen_command.out :::\n\n>Note that it is recommended to place generated code for each EDI schema in a separate module in order to avoid conflicts.\n\nWrite a Ballerina program by using generated methods and records to work with EDI data.\n\n::: code edi_to_record.bal :::\n\nRun the program using the command below:\n\n::: out output.out :::\n"
  },
  {
    "path": "examples/edi-to-record/edi_to_record.metatags",
    "content": "description: This BBE demonstrates how convert EDI text into Ballerina records based on an EDI schema.\nkeywords: ballerina, ballerina by example, bbe, edi, electronic data interchange, b2b, integration\n"
  },
  {
    "path": "examples/edi-to-record/order.edi",
    "content": "HDR*ORDER_1201*ABC_Store*2008-01-01~\nITM*A-250*12~\nITM*A-45*100~\nITM*D-10*58~\nITM*K-80*250~\nITM*T-46*28~\n"
  },
  {
    "path": "examples/edi-to-record/output.out",
    "content": "$ bal run\nOrder Id: ORDER_1201\nItem: A-250, Quantity: 12\nItem: A-45, Quantity: 100\nItem: D-10, Quantity: 58\nItem: K-80, Quantity: 250\nItem: T-46, Quantity: 28\n"
  },
  {
    "path": "examples/edi-to-record/package_structure.out",
    "content": "└── edi_to_record\n    ├── Ballerina.toml\n    ├── Dependencies.toml\n    ├── main.bal\n    ├── modules\n    │   └── sorder\n    │       ├── Module.md\n    │       ├── resources\n    │       ├── sorder.bal\n    │       └── tests\n    │           └── lib_test.bal\n    └── resources\n        └── simple_order_schema.json\n"
  },
  {
    "path": "examples/edi-to-record/schema.json",
    "content": "{\n    \"name\": \"SimpleOrder\",\n    \"delimiters\" : {\"segment\" : \"~\", \"field\" : \"*\", \"component\": \":\", \"repetition\": \"^\"},\n    \"segments\" : [\n        {\n            \"code\": \"HDR\",\n            \"tag\" : \"header\",\n            \"minOccurances\": 1,\n            \"fields\" : [{\"tag\": \"code\"}, {\"tag\" : \"orderId\", \"required\": true}, {\"tag\" : \"organization\"}, {\"tag\" : \"date\"}]\n        },\n        {\n            \"code\": \"ITM\",\n            \"tag\" : \"items\",\n            \"maxOccurances\" : -1,\n            \"fields\" : [{\"tag\": \"code\"}, {\"tag\" : \"item\", \"required\": true}, {\"tag\" : \"quantity\", \"required\": true, \"dataType\" : \"int\"}]\n        }\n    ]\n}\n"
  },
  {
    "path": "examples/edi-to-record/tool_pull_command.out",
    "content": "$ bal tool pull edi\n"
  },
  {
    "path": "examples/email-client-ssl-tls/email_client_ssl_tls.bal",
    "content": "import ballerina/email;\nimport ballerina/log;\n\npublic function main() returns error? {\n    email:ImapClient imapClient = check new (\n        \"imap.email.com\", \n        \"reader@email.com\", \n        \"pass456\",\n        security = email:SSL,\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    do {\n        while true {\n            email:Message? email = check imapClient->receiveMessage(timeout = 30);\n            if email is email:Message {\n                log:printInfo(\"Received an email\", subject = email.subject, body = email?.body);\n            }\n        }\n    } on fail var err {\n        log:printError(err.message(), stackTrace = err.stackTrace());\n        check imapClient->close();\n    }\n}\n"
  },
  {
    "path": "examples/email-client-ssl-tls/email_client_ssl_tls.md",
    "content": "# Email client - SSL/TLS \n\nThe `email:ImapClient` can be configured to communicate through SSL/TLS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the client configuration. In addition to the certificate configuration, an optional `security` configuration is available to define the underlying transport protocol which needs to be used. The Ballerina `email` module supports both `STARTTLS` and `SSL` as the transport protocol. Use this to interact with email servers based on SSL/TLS encrypted secured connection.\n\n>**Note:** The Ballerina `email` module also provides an `email:PopClient` which can be used likewise.\n\n::: code email_client_ssl_tls.bal :::\n\n## Prerequisites\n- The email server should be up and running.\n\nRun the sample code by executing the following command.\n\n::: out email_client_ssl_tls.out :::\n\n## Related links\n- [`email:SecureSocket` - API documentation](https://lib.ballerina.io/ballerina/email/latest#SecureSocket)\n- [`email:Security` enum - API documentation](https://lib.ballerina.io/ballerina/email/latest#Security)\n"
  },
  {
    "path": "examples/email-client-ssl-tls/email_client_ssl_tls.metatags",
    "content": "description: This BBE is about receiving emails over SSL/TLS secured connection. It has the client functionality for receiving emails.\nkeywords: ballerina, ballerina by example, bbe, email, POP3, POP, IMAP, ssl, tls\n"
  },
  {
    "path": "examples/email-client-ssl-tls/email_client_ssl_tls.out",
    "content": "$ bal run email_client_ssl_tls.bal\n"
  },
  {
    "path": "examples/email-service-ssl-tls/email_service_ssl_tls.bal",
    "content": "import ballerina/email;\nimport ballerina/log;\n\nlistener email:ImapListener emailListener = new ({\n    host: \"imap.email.com\",\n    username: \"reader@email.com\",\n    password: \"pass456\",\n    security: email:SSL,\n    secureSocket: {\n        cert: \"../resource/path/to/public.crt\"\n    }\n});\n\nservice \"observer\" on emailListener {\n\n    remote function onMessage(email:Message email) {\n        log:printInfo(\"Received an email\", subject = email.subject, content = email?.body);\n    }\n\n    remote function onError(email:Error emailError) {\n        log:printError(emailError.message(), stackTrace = emailError.stackTrace());\n    }\n\n    remote function onClose(email:Error? closeError) {\n        if closeError is email:Error {\n            log:printInfo(closeError.message(), stackTrace = closeError.stackTrace());\n        }\n    }\n}\n"
  },
  {
    "path": "examples/email-service-ssl-tls/email_service_ssl_tls.md",
    "content": "# Email service - SSL/TLS \n\nThe `email:Service` receives messages from an email server via IMAP using the `email:ImapListener`. An `email:ImapListener` secured with SSL/TLS is created by providing the `secureSocket` configuration which requires the certificate of the email server as the `cert`. In addition to the certificate configuration, an optional `security` configuration is available to define the underlying transport protocol which needs to be used. The Ballerina `email` module supports both `STARTTLS` and `SSL` as the transport protocol. Use this to interact with email servers based on SSL/TLS encrypted secured connection.  \n\n>**Note:** The Ballerina `email` module also provides an `email:PopListener` which can be used likewise.\n\n::: code email_service_ssl_tls.bal :::\n\n## Prerequisites\n- Email server should be up and running.\n\nRun the service by executing the command below.\n\n::: out email_service_ssl_tls.out :::\n\n## Related links\n- [`email:SecureSocket` - API documentation](https://lib.ballerina.io/ballerina/email/latest#SecureSocket)\n- [`email:Security` enum - API documentation](https://lib.ballerina.io/ballerina/email/latest#Security)\n"
  },
  {
    "path": "examples/email-service-ssl-tls/email_service_ssl_tls.metatags",
    "content": "description: This BBE is about receiving emails over SSL/TLS secured connection. It has a listener-based functionality for receiving emails.\nkeywords: ballerina, ballerina by example, bbe, email, POP3, POP, IMAP, listener, ssl, tls\n"
  },
  {
    "path": "examples/email-service-ssl-tls/email_service_ssl_tls.out",
    "content": "$ bal run email_service_ssl_tls.bal\n"
  },
  {
    "path": "examples/ensureType-function/ensureType_function.bal",
    "content": "import ballerina/io;\n\nfunction demo(anydata v) returns float|error {\n    // `v` is cast to the `float` type by calling `ensureType()`.\n    // `ensureType()` returns an error if the cast is not possible unlike the usual cast operation,\n    // which panics.\n    return v.ensureType(float);\n}\n\npublic function main() {\n    float|error f1 = demo(12.5d);\n    io:println(f1);\n\n    float|error f2 = demo(\"12.5\");\n    io:println(f2);\n}\n"
  },
  {
    "path": "examples/ensureType-function/ensureType_function.md",
    "content": "# `ensureType` function\n\nThe `ensureType()` function is a lang library function that is similar to a cast. It takes a `typedesc` value as an argument. It returns an error if the cast is not possible.\n\n::: code ensureType_function.bal :::\n\n::: out ensureType_function.out :::\n"
  },
  {
    "path": "examples/ensureType-function/ensureType_function.metatags",
    "content": "description: This BBE demonstrates ensureType function in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, ensureType\n"
  },
  {
    "path": "examples/ensureType-function/ensureType_function.out",
    "content": "$ bal run ensureType_function.bal\n12.5\nerror(\"{ballerina}TypeCastError\",message=\"incompatible types: 'string' cannot be cast to 'float'\")\n"
  },
  {
    "path": "examples/enumerations/enumerations.bal",
    "content": "import ballerina/io;\n\n// This is shorthand for,\n// const RED = \"RED\";\n// const GREEN = \"GREEN\";\n// const BLUE = \"BLUE\";\n// type Color RED|GREEN|BLUE;\nenum Color {\n    RED,\n    GREEN,\n    BLUE\n}\n\n// An `enum` member can explicitly specify an associated expression.\nenum Language {\n    ENG = \"English\",\n    TL = \"Tamil\",\n    SI = \"Sinhala\"\n}\n\npublic function main() {\n    io:println(RED);\n    io:println(ENG);\n}\n"
  },
  {
    "path": "examples/enumerations/enumerations.md",
    "content": "# Enumerations\n\n`Enumerations` are shorthand for unions of `string` constants. A `const` can be used as a singleton type. An `enum` is not a distinct type. You can specify the string constants explicitly.\n\n::: code enumerations.bal :::\n\n::: out enumerations.out :::"
  },
  {
    "path": "examples/enumerations/enumerations.metatags",
    "content": "description: This BBE demonstrates enumerations in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, enum, enumerations\n"
  },
  {
    "path": "examples/enumerations/enumerations.out",
    "content": "$ bal run enumerations.bal\nRED\nEnglish\n"
  },
  {
    "path": "examples/environment-variables/environment_variables.bal",
    "content": "import ballerina/io;\nimport ballerina/os;\n\npublic function main() {\n    // Returns the environment variable value associated with the `HTTP_PORT`.\n    string port = os:getEnv(\"HTTP_PORT\");\n    io:println(\"HTTP_PORT: \", port);\n\n    // Returns the username of the current user.\n    string username = os:getUsername();\n    io:println(\"Username: \", username);\n\n    // Returns the current user's home directory path.\n    string userHome = os:getUserHome();\n    io:println(\"Userhome: \", userHome);\n}\n"
  },
  {
    "path": "examples/environment-variables/environment_variables.md",
    "content": "# Environment variables\n\nThe `os` library provides functions to retrieve information about the OS and the current users of the OS.\n\nFor more information on the underlying module, see the [`os` module](https://lib.ballerina.io/ballerina/os/latest/).\n\n::: code environment_variables.bal :::\n\nTo run this sample use the `bal run` command.\n\n::: out environment_variables.out :::"
  },
  {
    "path": "examples/environment-variables/environment_variables.metatags",
    "content": "description: BBE on how to to retrieve information about the OS.\nkeywords: ballerina, ballerina by examples, BBE, OS, environment\n"
  },
  {
    "path": "examples/environment-variables/environment_variables.out",
    "content": "$ bal run environment_variables.bal\nHTTP_PORT: 5005\nUsername: Alex\nUserhome: /Users/Alex\n"
  },
  {
    "path": "examples/error-binding-pattern/error_binding_pattern.bal",
    "content": "import ballerina/io;\n\ntype SampleErrorData record {|\n    int code;\n    string reason;\n|};\n\ntype SampleError error<SampleErrorData>;\n\npublic function main() {\n    // The value of the error message is ignored by using `_`.\n    // The value of the error cause is set to the `cause` variable.\n    // The values in the error detail mapping is set to the `code` and `reason` variables.\n    var error(_, cause, code = code, reason = reason) = getSampleError();\n    io:println(\"Cause: \", cause);\n    io:println(\"Info: \", code);\n    io:println(\"Fatal: \", reason);\n\n    // The values in the cause and detail mapping are ignored in this binding.\n    SampleError error(message2) = getSampleError();\n    io:println(\"Message: \", message2);\n\n    error? errorCause;\n    int errorCode;\n\n    // The error value is destructured and assigned to the variable references.\n    // The values of the error cause and `code` are assigned to the `errorCause` and `errorCode` variables.\n    // The error message and the `reason` field in the detail mapping are ignored.\n    error(_, errorCause, code = errorCode) = getSampleError();\n    io:println(\"Cause: \", errorCause);\n    io:println(\"Code: \", errorCode);\n}\n\nfunction getSampleError() returns SampleError {\n    return error(\"Transaction Failure\", error(\"Database Error\"), code = 20,\n                            reason = \"deadlock condition\");\n}\n"
  },
  {
    "path": "examples/error-binding-pattern/error_binding_pattern.md",
    "content": "# Error binding pattern\n\nAn error binding pattern matches the different elements of an error value such as the error message, error cause, and error detail mapping. It can also be used to destructure the reason, cause, and detail mapping values from an error value, and assign them to the existing variable references.\n\n::: code error_binding_pattern.bal :::\n\n::: out error_binding_pattern.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Rest binding pattern in error binding pattern](/learn/by-example/rest-binding-pattern-in-error-binding-pattern/)\n"
  },
  {
    "path": "examples/error-binding-pattern/error_binding_pattern.metatags",
    "content": "description: This BBE demonstrates the error binding pattern, error typed binding, and error destructuring with binding patterns.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, error binding pattern, error binding, error typed binding, error destructuring\n"
  },
  {
    "path": "examples/error-binding-pattern/error_binding_pattern.out",
    "content": "$ bal run error_binding_pattern.bal\nCause: error(\"Database Error\")\nInfo: 20\nFatal: deadlock condition\nMessage: Transaction Failure\nCause: error(\"Database Error\")\nCode: 20\n"
  },
  {
    "path": "examples/error-binding-pattern-in-match-statement/error_binding_pattern_in_match_statement.bal",
    "content": "import ballerina/io;\n\ntype DatabaseErrorDetail record {|\n    int code;\n    string reason;\n|};\n\ntype NetworkErrorDetail record {|\n    string 'type;\n    string phase;\n    int elapsedTime;\n|};\n\ntype DatabaseError error<DatabaseErrorDetail>;\n\ntype NetworkError error<NetworkErrorDetail>;\n\nconst ERROR = \"Generic Error\";\n\nfunction errorMatch(error e) {\n    match e {\n        // This error binding pattern matches a `DatabaseError` type error value and\n        // binds its `code` detail mapping to the `code` variable.\n        var error DatabaseError(code = code) => {\n            io:println(\"Matched DatabaseError with code:\", code);\n        }\n        // This error binding pattern matches an error value with an `ERROR` error message and\n        // binds its `code` detail mapping to the `code` variable.\n        var error(ERROR, code = code) => {\n            io:println(\"Matched Generic Error with message:\", ERROR, \" and code:\", code);\n        }\n        // This error binding pattern matches the value of the error message in an error with the `message`\n        // variable, the value of the `type` field in the detail mapping is matched with the `errorType` variable, and\n        // the `...otherDetails` rest parameter is matched with the remaining detail fields.\n        var error(message, 'type = errorType, ...otherDetails) => {\n            io:println(\"Matched NetworkError with message:\", message, \", type:\", errorType, \", phase:\",\n                    otherDetails[\"phase\"], \" and elapsedTime:\", otherDetails[\"elapsedTime\"]);\n        }\n    }\n}\n\npublic function main() {\n    error e1 = error(\"Generic Error\", code = 20);\n    DatabaseError e2 = error(\"Database Error\", code = 2, reason = \"connection failure\");\n    NetworkError e3 = error NetworkError(\"Bad Request\", 'type = \"http error\", phase = \"application\",\n                                    elapsedTime = 338);\n    errorMatch(e1);\n    errorMatch(e2);\n    errorMatch(e3);\n}\n"
  },
  {
    "path": "examples/error-binding-pattern-in-match-statement/error_binding_pattern_in_match_statement.md",
    "content": "# Error binding pattern in match statement\n\nError binding patterns can be used in a match statement to bind parts of a successful match of an error value to variables. You can use the rest binding pattern (`...r`) in the error binding pattern of a match statement to bind the detail mapping fields that are not explicitly bound in the binding pattern.\n\n::: code error_binding_pattern_in_match_statement.bal :::\n\n::: out error_binding_pattern_in_match_statement.out :::\n\n## Related links\n- [Match statement](/learn/by-example/match-statement/)\n- [Error binding pattern](/learn/by-example/error-binding-pattern/)\n"
  },
  {
    "path": "examples/error-binding-pattern-in-match-statement/error_binding_pattern_in_match_statement.metatags",
    "content": "description: This BBE demonstrates matching error values in a match statement and using the error binding pattern in a match statement\nkeywords: ballerina, ballerina by example, bbe, binding pattern, error binding pattern, error binding, error typed binding, error, error value, match statement, match\n"
  },
  {
    "path": "examples/error-binding-pattern-in-match-statement/error_binding_pattern_in_match_statement.out",
    "content": "$ bal run error_binding_pattern_in_match_statement.bal\nMatched Generic Error with message:Generic Error and code:20\nMatched DatabaseError with code:2\nMatched NetworkError with message:Bad Request, type:http error, phase:application and elapsedTime:338\n"
  },
  {
    "path": "examples/error-cause/error_cause.bal",
    "content": "import ballerina/io;\n\nfunction foo(string s) returns error|int {\n    var res = int:fromString(s);\n    if res is error {\n        // The error constructor is called with the additional argument `res`, which is the\n        // error returned in case the `int:fromString()` function returns an error.\n        // This creates an error with a specified error and cause.\n        return error(\"not an integer\", res);\n    } else {\n        return res;\n    }\n}\n\npublic function main() {\n    error|int result = foo(\"1.1\");\n    io:println(result);\n\n    if (result is error) {\n        // The `error:cause()` lang library function can be used to extract the cause\n        // from an error.\n        io:println(result.cause());\n    }\n}\n"
  },
  {
    "path": "examples/error-cause/error_cause.md",
    "content": "# Error cause\n\nBallerina facilitates having a cause in an error value. It can be passed as a positional argument to the error constructor. The cause argument is optional in the error constructor.\n\n::: code error_cause.bal :::\n\n::: out error_cause.out :::\n"
  },
  {
    "path": "examples/error-cause/error_cause.metatags",
    "content": "description: This BBE demonstrates how to add a cause to the error and access it.\nkeywords:  ballerina, ballerina by example, bbe, error cause\n"
  },
  {
    "path": "examples/error-cause/error_cause.out",
    "content": "$ bal run error_cause.bal\nerror(\"not an integer\",error(\"{ballerina/lang.int}NumberParsingError\",message=\"'string' value '1.1' cannot be converted to 'int'\"))\nerror(\"{ballerina/lang.int}NumberParsingError\",message=\"'string' value '1.1' cannot be converted to 'int'\")\n"
  },
  {
    "path": "examples/error-detail/error_detail.bal",
    "content": "import ballerina/io;\n\n// `err` is an error type constructed from named arguments to add some details to the error value.\nerror err = error(\"Whoops\", httpCode = 27);\n\n// The `HttpDetail` type is a record type that defines the`httpCode` field  of type `int`.\ntype HttpDetail record {\n    int httpCode;\n};\n\n// When included in the declaration of the `error<HttpDetail>` error type, it uses the\n// `HttpDetail` record type as the error detail record.\nerror<HttpDetail> httpError = error(\"Whoops\", httpCode = 27);\n\n// The `error:detail()` lang library function facilitates extracting the detail value\n// out of the error.\nHttpDetail d = httpError.detail();\n\npublic function main() {\n    io:println(d);\n}\n"
  },
  {
    "path": "examples/error-detail/error_detail.md",
    "content": "# Error detail\n\nError detail is a map that contains arbitrary extra details about the context of the error. The `error<T>` type describes an error value with a detail map that has the type `T`. Named arguments of the error constructor specify the fields of the detail record. An immutable copy of each field is made in the detail record using the `cloneReadOnly` function.\n\n::: code error_detail.bal :::\n\n::: out error_detail.out :::\n"
  },
  {
    "path": "examples/error-detail/error_detail.metatags",
    "content": "description: This BBE demonstrates how to add a detail component to the error and access it.\nkeywords:  ballerina, ballerina by example, bbe, error detail\n"
  },
  {
    "path": "examples/error-detail/error_detail.out",
    "content": "$ bal run error_detail.bal\n{\"httpCode\":27}\n"
  },
  {
    "path": "examples/error-handling/error_handling.bal",
    "content": "import ballerina/io;\n\n// Converts `bytes` to a `string` value and then to an `int` value.\nfunction intFromBytes(byte[] bytes) returns int|error {\n\n    string|error ret = string:fromBytes(bytes);\n\n    // The `is` operator can be used to distinguish errors from other values.\n    if ret is error {\n        return ret;\n    } else {\n        return int:fromString(ret);\n    }\n}\n\n// The `main` function can return an `error` value.\npublic function main() returns error? {\n\n    int|error res = intFromBytes([104, 101, 108, 108, 111]);\n    \n    if res is error {\n        // The `check` expression is the shorthand for this pattern of\n        // checking if a value is an `error` value and it is returning that value.\n        return res;\n    } else {\n        io:println(\"result: \", res);\n        return;\n    }\n}\n"
  },
  {
    "path": "examples/error-handling/error_handling.md",
    "content": "# Error handling\n\nUsually, a function handles errors by passing them up to its caller. The `main` function can also return an `error` value.\n\n::: code error_handling.bal :::\n\n::: out error_handling.out :::"
  },
  {
    "path": "examples/error-handling/error_handling.metatags",
    "content": "description: This BBE demonstrates how errors are handled in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, error, error handling\n"
  },
  {
    "path": "examples/error-handling/error_handling.out",
    "content": "$ bal run error_handling.bal\nerror: {ballerina/lang.int}NumberParsingError {\"message\":\"'string' value 'hello' cannot be converted to 'int'\"}\n"
  },
  {
    "path": "examples/error-logging/error_logging.bal",
    "content": "import ballerina/log;\n\nfunction processOrder(int orderId) returns error? {\n    if orderId <= 0 {\n        return error(\"Invalid order ID\", orderId = orderId);\n    }\n    // Simulate processing logic here\n}\n\nfunction connectToDatabase() returns error? {\n    error dbError = error(\"Connection timeout\");\n    return error(\"Failed to connect to database\", dbError, retryCount = 3);\n}\n\npublic function main() {\n    // Basic error logging\n    error simpleError = error(\"Something went wrong\");\n    log:printError(\"Application encountered an error\", simpleError);\n\n    // Error logging with additional context\n    error? processOrderRes = processOrder(-1);\n    if processOrderRes is error {\n        log:printError(\"Order processing failed\", processOrderRes,\n                operation = \"processOrder\",\n                timestamp = \"2025-08-25T10:30:00Z\");\n    }\n\n    // Error with causes and stack trace\n    error? databaseConnectionRes = connectToDatabase();\n    if databaseConnectionRes is error {\n        log:printError(\"Database operation failed\", databaseConnectionRes,\n                serviceName = \"OrderService\",\n                severity = \"HIGH\");\n    }\n\n    // Custom error with detailed information\n    error customError = error(\"Validation failed\",\n                            'field = \"email\",\n                            value = \"invalid-email\",\n                            expectedFormat = \"user@domain.com\");\n    log:printError(\"User input validation error\", customError,\n            userId = \"user123\",\n            action = \"registration\");\n}\n"
  },
  {
    "path": "examples/error-logging/error_logging.md",
    "content": "# Error logging\n\nThis example demonstrates how to log errors with detailed information including error messages, causes, stack traces, and additional context in Ballerina.\n\n::: code error_logging.bal :::\n\nError logging in Ballerina automatically includes the error message, stack trace, and any error details. You can also add additional contextual information to help with debugging and monitoring.\n\n::: out error_logging.out :::\n\nThe logged errors include comprehensive information such as the error message, causes (for nested errors), stack trace showing the call hierarchy, and any additional context provided through key-value pairs.\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#2-logging)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/error-logging/error_logging.metatags",
    "content": "description: BBE on how to log error messages with detailed error information and context in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, log, error, exception, stack trace\n"
  },
  {
    "path": "examples/error-logging/error_logging.out",
    "content": "$ bal run error-logging.bal\ntime=2025-08-25T10:35:20.456+05:30 level=ERROR module=\"\" message=\"Application encountered an error\" error={\"causes\":[],\"message\":\"Something went wrong\",\"detail\":{},\"stackTrace\":[{\"callableName\":\"main\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":18}]}\ntime=2025-08-25T10:35:20.458+05:30 level=ERROR module=\"\" message=\"Order processing failed\" error={\"causes\":[],\"message\":\"Invalid order ID\",\"detail\":{\"orderId\":-1},\"stackTrace\":[{\"callableName\":\"processOrder\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":5},{\"callableName\":\"main\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":21}]} operation=\"processOrder\" timestamp=\"2025-08-25T10:30:00Z\"\ntime=2025-08-25T10:35:20.460+05:30 level=ERROR module=\"\" message=\"Database operation failed\" error={\"causes\":[{\"message\":\"Connection timeout\",\"detail\":{},\"stackTrace\":[{\"callableName\":\"connectToDatabase\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":12}]}],\"message\":\"Failed to connect to database\",\"detail\":{\"retryCount\":3},\"stackTrace\":[{\"callableName\":\"connectToDatabase\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":13},{\"callableName\":\"main\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":28}]} serviceName=\"OrderService\" severity=\"HIGH\"\ntime=2025-08-25T10:35:20.462+05:30 level=ERROR module=\"\" message=\"User input validation error\" error={\"causes\":[],\"message\":\"Validation failed\",\"detail\":{\"field\":\"email\",\"value\":\"invalid-email\",\"expectedFormat\":\"user@domain.com\"},\"stackTrace\":[{\"callableName\":\"main\",\"moduleName\":(),\"fileName\":\"error-logging.bal\",\"lineNumber\":36}]} userId=\"user123\" action=\"registration\"\n"
  },
  {
    "path": "examples/error-reporting/error_reporting.bal",
    "content": "import ballerina/io;\n\ntype Person record {\n    string name;\n    int age;\n};\n\nfunction validatePeople(Person[] people) returns error? {\n    if people.length() == 0 {\n        // Create an error value specifying only the error message.\n        return error(\"Expected a non-empty array\");\n    }\n\n    foreach Person p in people {\n        io:println(\"Validating \", p.name);\n        error? err = validatePerson(p);\n        if err is error {\n            // Create a new error value with the validation error as the cause\n            // and the `Person` value for which validation failed in the detail mapping.\n            return error(\"Validation failed for a person\", err, person = p);\n        }\n    }\n}\n\nfunction validatePerson(Person person) returns error? {\n    int age = person.age;\n    if age < 0 {\n        // If validation fails for age, create a new error value specifying\n        // an error message and the age value for which validation failed.\n        return error(\"Age cannot be negative\", age = age);\n    }\n}\n\npublic function main() {\n    Person[] people = [\n        {name: \"Alice\", age: 25},\n        {name: \"Bob\", age: -1},\n        {name: \"Charlie\", age: 30}\n    ];\n    // Note how the `Person` value after the value for which validation fails is\n    // not processed.\n    error? err = validatePeople(people);\n    if err is error {\n        printError(err);\n    }\n}\n\n// Helper function to print internals of error value.\nfunction printError(error err) {\n    io:println(\"Message: \", err.message());\n    io:println(\"Detail: \", err.detail());\n    io:println(\"Stack trace: \", err.stackTrace());\n\n    error? cause = err.cause();\n    if cause is error {\n        io:println(\"Cause:\");\n        printError(cause);\n    }\n}\n"
  },
  {
    "path": "examples/error-reporting/error_reporting.md",
    "content": "# Errors\n\nBallerina does not have exceptions. Instead functions report invalid states by returning error values. Each error value has,\n1. Message, a human-readable `string` value describing the error.\n2. Cause, which is an `error` value if this error was caused due to another error, which needs to be propagated, otherwise nil.\n3. Detail, a mapping value consisting of additional information about the error.\n4. Stack trace, a snapshot of the state of the execution stack when the error value was created.\n\nError values are immutable.\n\nYou can create a new error value using an error constructor. As the first argument to the error constructor, it expects the message string. As the second argument, you can optionally pass in an `error?` value for cause. Subsequent named arguments, if specified, will be used to create the detail mapping. The stack trace is provided by the runtime.\n\n::: code error_reporting.bal :::\n\n::: out error_reporting.out :::\n\n## Related links\n- [Error subtyping](https://ballerina.io/learn/by-example/error-subtyping/)\n- [Error cause](https://ballerina.io/learn/by-example/error-cause/)\n- [Error detail](https://ballerina.io/learn/by-example/error-detail/)\n"
  },
  {
    "path": "examples/error-reporting/error_reporting.metatags",
    "content": "description: This BBE demonstrates how errors are reported in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, error, error reporting\n"
  },
  {
    "path": "examples/error-reporting/error_reporting.out",
    "content": "$ bal run error_reporting.bal\nValidating Alice\nValidating Bob\nMessage: Validation failed for a person\nDetail: {\"person\":{\"name\":\"Bob\",\"age\":-1}}\nStack trace: [callableName: validatePeople  fileName: error_reporting.bal lineNumber: 20,callableName: main  fileName: error_reporting.bal lineNumber: 42]\nCause:\nMessage: Age cannot be negative\nDetail: {\"age\":-1}\nStack trace: [callableName: validatePerson  fileName: error_reporting.bal lineNumber: 30,callableName: validatePeople  fileName: error_reporting.bal lineNumber: 16,callableName: main  fileName: error_reporting.bal lineNumber: 42]\n"
  },
  {
    "path": "examples/error-subtyping/error_subtyping.bal",
    "content": "import ballerina/io;\n\ntype InvalidIntDetail record {|\n    int value;\n|};\n\n// Subtype of `InvalidIntDetail`.\ntype InvalidI32Detail record {|\n    int:Signed32 value;\n|};\n\n// Error with the `InvalidIntDetail` type as the detail type.\ntype InvalidIntError error<InvalidIntDetail>;\n\n// Error with `InvalidI32Detail` as the detail type. Thus it is a subtype of `InvalidIntError`.\ntype InvalidI32Error error<InvalidI32Detail>;\n\n// Distinct error with the `InvalidIntDetail` type as the detail type and a unique type ID.\n// Therefore, this is a proper subtype of `InvalidIntError`, but doesn't have a subtype relationship \n// with `AnotherDistinctIntError` because they have different type IDs.\ntype DistinctIntError distinct error<InvalidIntDetail>;\n\n// Another distinct error with `InvalidIntDetail` as the detail type, but a different type ID to `DistinctIntError`\n// This is also a proper subtype of `InvalidIntError`, but doesn't have a subtype relationship with `DistinctIntError`\ntype AnotherDistinctIntError distinct error<InvalidIntDetail>;\n\npublic function main() {\n    InvalidI32Error e1 = createInvalidI32Error(5);\n    io:println(e1 is InvalidIntError);\n\n    InvalidIntError e2 = createInvalidIntError(5);\n    io:println(e2 is DistinctIntError);\n\n    DistinctIntError e3 = createDistinctInvalidIntError(5);\n    // This is true because `InvalidInt` is not a distinct type, thus it ignores the type id of `e3`.\n    io:println(e3 is InvalidIntError);\n\n    // This is false because `DistinctIntError` and `AnotherDistinctIntError` have different type ids.\n    io:println(e3 is AnotherDistinctIntError);\n}\n\n// Helper functions to create errors.\nfunction createInvalidIntError(int value) returns InvalidIntError {\n    return error(\"Invalid int\", value = value);\n}\n\nfunction createDistinctInvalidIntError(int value) returns DistinctIntError {\n    return error(\"Invalid int\", value = value);\n}\n\nfunction createInvalidI32Error(int:Signed32 value) returns InvalidI32Error {\n    return error(\"Invalid i32\", value = value);\n}\n"
  },
  {
    "path": "examples/error-subtyping/error_subtyping.md",
    "content": "# Error subtyping\n\nIf we want to identify if a given `error` type (say `ESub`) is a subtype of another error type (say `ESuper`), first we need to check if `ESuper` is a distinct error type. If it is not, then `ESub` is a subtype if and only if the detail type of `ESub` is a subtype of the detail type of `ESuper`.\n\nIf more explicit control over error type relations is desired you can use `distinct` error types. Each declaration of a distinct error type has a unique type ID. If `ESuper` is a distinct error type there is the additional requirement that the type ID set of `ESub` must contain all the type IDs of `ESuper`. In other words, with distinct error types, typing relationships can be made more like nominal typing.\n\nNote that you can create subtypes of distinct error types by intersecting them with other error types.\n\n::: code error_subtyping.bal :::\n\n::: out error_subtyping.out :::\n\n## Related links\n- [Type intersection for error types](https://ballerina.io/learn/by-example/error-type-intersection/)\n"
  },
  {
    "path": "examples/error-subtyping/error_subtyping.metatags",
    "content": "description: This BBE demonstrates how subtypes of errors are defined in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, error, error subtypes\n"
  },
  {
    "path": "examples/error-subtyping/error_subtyping.out",
    "content": "$ bal run error_subtyping.bal\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "examples/error-type-intersection/error_type_intersection.bal",
    "content": "import ballerina/io;\n\ntype InputErrorDetail record {|\n    int|string value;\n|};\n\ntype NumericErrorDetail record {|\n    int|float value;\n|};\n\ntype InputError error<InputErrorDetail>;\n\ntype NumericError error<NumericErrorDetail>;\n\n// `NumericInputError` has detail type, `record {| int value |}`.\ntype NumericInputError InputError & NumericError;\n\ntype DistinctInputError distinct error<InputErrorDetail>;\n\ntype DistinctNumericError distinct error<NumericErrorDetail>;\n\n// `DistinctNumericInputError` has type IDs of both `DistinctInputError` and `DistinctNumericError`.\ntype DistinctNumericInputError DistinctInputError & DistinctNumericError;\n\npublic function main() {\n    NumericInputError e1 = error(\"Numeric input error\", value = 5);\n    // `e1` belongs to `InputError` since its detail type is a subtype of `InputErrorDetail`.\n    io:println(e1 is InputError);\n\n    // `e1` doesn't belong to `DistinctInputError` since it doesn't have the type ID of `DistinctInputError`.\n    io:println(e1 is DistinctInputError);\n\n    DistinctNumericInputError e2 = error(\"Distinct numeric input error\", value = 5);\n    // `e2` belongs to `InputError` since its detail type is a subtype of `InputErrorDetail`.\n    io:println(e2 is InputError);\n\n    // `e2` belongs to `DistinctInputError` since its type ID set includes the type id of `DistinctInputError`.\n    io:println(e2 is DistinctInputError);\n}\n"
  },
  {
    "path": "examples/error-type-intersection/error_type_intersection.md",
    "content": "# Type intersection for error types\n\nIf you intersect two `error` types, the resulting type's detail type is the intersection of the detail types of both types. Furthermore, if any of the types being intersected is a distinct type, then the resultant type's type ID set includes all the type IDs of that type. Thus it is a subtype of both types. This way, you can create an error type that is a subtype of multiple distinct types and also use a more specific detail type.\n\n::: code error_type_intersection.bal :::\n\n::: out error_type_intersection.out :::\n\n+ [Error subtyping](https://ballerina.io/learn/by-example/error-subtyping/)\n"
  },
  {
    "path": "examples/error-type-intersection/error_type_intersection.metatags",
    "content": "description: This BBE demonstrates type intersection for error types.\nkeywords: ballerina, ballerina by example, bbe, error, intersection, distinct\n"
  },
  {
    "path": "examples/error-type-intersection/error_type_intersection.out",
    "content": "$ bal run error_type_intersection.bal\ntrue\nfalse\ntrue\ntrue\n"
  },
  {
    "path": "examples/expression-equality/expression_equality.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    map<string> student = {\"name\": \"John\", \"age\": \"25\"};\n    map<anydata> student2 = {\"name\": \"John\", \"age\": \"25\"};\n\n    // The `==` check evaluates to `true` since the values are considered equal based on the\n    // equality of members.\n    io:println(student == student2);\n\n    // The `!=` check evaluates to `false` since the values are considered equal based on the\n    // equality of members.\n    io:println(student != student2);\n    \n    // The `===` check evaluates to `false` since references are different.\n    io:println(student === student2);\n\n    // Assign the value assigned to the `student` variable to the `student3` variable.\n    map<string> student3 = student;\n\n    // The `===` check evaluates to `true` since references are same.\n    io:println(student3 === student);\n\n    // The `!==` check evaluates to `false` since references are same.\n    io:println(student3 !== student);\n\n    // Since values of simple types do not have storage identity \n    // `===` and `==` return the same result, except for floating point values.\n    int a = 1;\n    anydata b = 1;\n\n    // The `==` and `===` checks evaluates to `true` since the values are equal.\n    io:println(a == b);\n    io:println(a === b);\n\n    decimal c = 1.0;\n    decimal d = 1.00;\n\n    // The `==` check evaluates to `true` since the values are equal.\n    io:println(c == d);\n    // The `===` check evaluates to `false` since `c` and `d` are distinct values with different precision.\n    io:println(c === d);\n\n    string s1 = \"Hello\";\n    string s2 = \"Hello\";\n\n    // String values also do not have storage identity, and `===` checks are\n    // the same as `==` checks for string values also.\n    io:println(s1 == s2);\n    io:println(s1 === s2);\n}\n"
  },
  {
    "path": "examples/expression-equality/expression_equality.md",
    "content": "# Expression equality\n\nExpression equality is determined using two operators: `==` for value equality and `===` for reference equality. The `==` operator checks for deep equality between two values by comparing the actual data. In contrast, the `===` operator checks whether two values share the same storage identity, meaning it checks if the values reference the same memory location. \n\nValues with storage identity, such as structured types like maps and arrays, have an identity that comes from the location where the value is stored. For such values, the `===` check determines if two references point to the same location. For simple types such as integers and booleans, which do not have storage identity, `===` behaves the same as `==` except for floating point values.\n\n::: code expression_equality.bal :::\n\n::: out expression_equality.out :::\n\n## Related links\n- [Maps](/learn/by-example/maps)\n"
  },
  {
    "path": "examples/expression-equality/expression_equality.metatags",
    "content": "description: This BBE demonstrates expression equality checks in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, ==, !=, ===, !==, equality\n"
  },
  {
    "path": "examples/expression-equality/expression_equality.out",
    "content": "$ bal run expression_equality.bal\ntrue\nfalse\nfalse\ntrue\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\ntrue\n"
  },
  {
    "path": "examples/expression-oriented-style/expression_oriented_style.bal",
    "content": "import ballerina/io;\n\n// You can define the body of a function using the `=>` notation followed by the return value expression\n// instead of using curly braces to define the function body block, when the function body is just\n// a return statement with an expression.\nfunction inc1(int x) returns int => x + 1;\n\n// `inc2` is effectively the same as` inc1`.\nfunction inc2(int x) returns int {\n    return x + 1;\n}\n\nvar obj = object {\n    private int x = 1;\n    // This can also be used to define the body of a method.\n    function getX() returns int => self.x;\n};\n\n// Let expressions allow you to do more with an expression.\n// Here, the let expression defines a variable that can be used in the function call.\nfunction hypot(float x) returns float =>\n    let float x2 = x * x in float:sqrt(x2 + x2);\n\npublic function main() {\n    int x = 2;\n    io:println(inc1(x));\n    io:println(inc2(x));\n    \n    io:println(obj.getX());\n\n    io:println(hypot(1.5));\n}\n"
  },
  {
    "path": "examples/expression-oriented-style/expression_oriented_style.md",
    "content": "# Expression-oriented style\n\nBallerina supports statements for familiarity but also tries to enable an expression-oriented style to be more intuitive.\nFor example instead of using an if statement Ballerina allows `return x > 0 ? 1 : 0;`.\n\n::: code expression_oriented_style.bal :::\n\n::: out expression_oriented_style.out :::\n"
  },
  {
    "path": "examples/expression-oriented-style/expression_oriented_style.metatags",
    "content": "description: This BBE demonstrates the expression-oriented style in ballerina.\nkeywords: ballerina, ballerina by example, bbe, expression, expression-bodied\n"
  },
  {
    "path": "examples/expression-oriented-style/expression_oriented_style.out",
    "content": "$ bal run expression_oriented_style.bal\n3\n3\n1\n2.1213203435596424\n"
  },
  {
    "path": "examples/filepaths/filepaths.bal",
    "content": "import ballerina/file;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Gets the absolute representation of the path.\n    string absValue = check file:getAbsolutePath(\"test.txt\");\n    io:println(\"Absolute path: \", absValue);\n\n    // Checks whether the path is absolute.\n    boolean isAbs = check file:isAbsolutePath(\"/A/B/C\");\n    io:println(\"/A/B/C is absolute: \", isAbs);\n\n    // Gets the base name of the path.\n    string name = check file:basename(\"/A/B/C\");\n    io:println(\"Filename of /A/B/C: \", name);\n\n    // Gets the enclosing parent directory.\n    string parentPath = check file:parentPath(\"/A/B/C\");\n    io:println(\"Parent of /A/B/C: \", parentPath);\n\n    // Gets the shortest path name equivalent to the path by purely lexical processing.\n    string normalizedPath = check file:normalizePath(\"foo/../bar\", file:CLEAN);\n    io:println(\"Normalized path of foo/../bar: \", normalizedPath);\n\n    // Gets the list of path elements joined by the OS-specific path separator.\n    string[] parts = check file:splitPath(\"/A/B/C\");\n    io:println(string `Path elements of /A/B/C: ${parts.toString()}`);\n\n    // Joins any number of path elements into a single path.\n    string path = check file:joinPath(\"/\", \"foo\", \"bar\");\n    io:println(\"Built path of '/', 'foo', 'bar': \", path);\n\n    // Returns a relative path that is logically equivalent to the target path when joined to the base path.\n    string relPath = check file:relativePath(\"a/b/c\", \"a/c/d\");\n    io:println(\"Relative path between 'a/b/c' and 'a/c/d': \", relPath);\n}\n"
  },
  {
    "path": "examples/filepaths/filepaths.md",
    "content": "# File paths\n\nThe `file` library also provides APIs to manipulate file paths in a way that is compatible with the target operating system.\n\nFor more information on the underlying module, see the [`file` module](https://lib.ballerina.io/ballerina/file/latest/).\n\n::: code filepaths.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out filepaths.out :::\n"
  },
  {
    "path": "examples/filepaths/filepaths.metatags",
    "content": "description: This BBE shows how to manipulate file paths in a way that is compatible with the target Operating System in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, file, directory, path, filepath\n"
  },
  {
    "path": "examples/filepaths/filepaths.out",
    "content": "$ bal run filepaths.bal\nOn Unix:\nAbsolute path of test.txt: /A/test.txt\n/A/B/C is absolute: true\nFilename of /A/B/C: C\nParent of /A/B/C: /A/B\nNormalized path of foo/../bar: bar\nPath elements of /A/B/C: [\"A\",\"B\",\"C\"]\nBuilt path of '/', 'foo', 'bar': /foo/bar\nRelative path between 'a/b/c' and 'a/c/d': ../../c/d\n\nOn Windows:\nAbsolute path of test.txt: \\A\\test.txt\n/A/B/C is absolute: false\nFilename of /A/B/C: C\nParent of /A/B/C: \\A\\B\nNormalized path of foo/../bar: bar\nPath elements of /A/B/C: [\"A\",\"B\",\"C\"]\nBuilt path of '/', 'foo', 'bar': \\foo\\bar\nRelative path between 'a/b/c' and 'a/c/d': ..\\..\\c\\d\n"
  },
  {
    "path": "examples/filepaths/tests/filepath_test.bal",
    "content": "import ballerina/test;\nimport ballerina/os;\n\nstring[] outputs = [];\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any... val) {\n    outputs.push(val.reduce(function (any a, any b) returns string => a.toString() + b.toString(), \"\").toString());\n}\n\nboolean isWindows = os:getEnv(\"OS\") != \"\";\n\n@test:Config {}\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n    // Invoking the main function.\n    check main();\n\n    string absolutePath;\n    string filename;\n    string parent;\n    string normalized;\n    string elements;\n    string buildPath;\n    string relative;\n\n    if (isWindows) {\n        absolutePath =\"/A/B/C is absolute: false\";\n        filename =\"Filename of /A/B/C: C\";\n        parent =\"Parent of /A/B/C: \\\\A\\\\B\";\n        normalized =\"Normalized path of foo/../bar: bar\";\n        elements =\"Path elements of /A/B/C: [\\\"A\\\",\\\"B\\\",\\\"C\\\"]\";\n        buildPath =\"Built path of '/', 'foo', 'bar': \\\\foo\\\\bar\";\n        relative =\"Relative path between 'a/b/c' and 'a/c/d': ..\\\\..\\\\c\\\\d\";\n    } else {\n        absolutePath =\"/A/B/C is absolute: true\";\n        filename =\"Filename of /A/B/C: C\";\n        parent =\"Parent of /A/B/C: /A/B\";\n        normalized =\"Normalized path of foo/../bar: bar\";\n        elements =\"Path elements of /A/B/C: [\\\"A\\\",\\\"B\\\",\\\"C\\\"]\";\n        buildPath =\"Built path of '/', 'foo', 'bar': /foo/bar\";\n        relative =\"Relative path between 'a/b/c' and 'a/c/d': ../../c/d\";\n    }\n    test:assertEquals(outputs[1], absolutePath);\n    test:assertEquals(outputs[2], filename);\n    test:assertEquals(outputs[3], parent);\n    test:assertEquals(outputs[4], normalized);\n    test:assertEquals(outputs[5], elements);\n    test:assertEquals(outputs[6], buildPath);\n    test:assertEquals(outputs[7], relative);\n}\n"
  },
  {
    "path": "examples/files/files.bal",
    "content": "import ballerina/file;\nimport ballerina/io;\n\npublic function main() returns error? {\n\n    // Creates a file in the given file path.\n    check file:create(\"bar.txt\");\n    io:println(\"The bar.txt file created successfully.\");\n\n    // Checks whether the file exists on the provided path.\n    boolean fileExists = check file:test(\"bar.txt\", file:EXISTS);\n    io:println(\"Does the bar.txt file exist: \", fileExists.toString());\n\n    // Checks whether the file is readable or not.\n    fileExists = check file:test(\"bar.txt\", file:READABLE);\n    io:println(\"Is the bar.txt file readable: \", fileExists.toString());\n\n    // Checks whether the file is writable or not.\n    fileExists = check file:test(\"bar.txt\", file:WRITABLE);\n    io:println(\"Is the bar.txt file writeable: \", fileExists.toString());\n\n    // Copies the file or directory to the new path.\n    check file:copy(\"bar.txt\",  \"bar1.txt\", file:REPLACE_EXISTING);\n    io:println(\"The bar.txt file copied successfully.\");\n\n    check file:rename(\"bar.txt\", \"bar2.txt\");\n    io:println(\"The bar.txt file renamed successfully.\");\n\n    // Gets the metadata information of the file.\n    file:MetaData fileMetadata = check file:getMetaData(\"bar1.txt\");\n    io:println(\"File path: \", fileMetadata.absPath);\n    io:println(\"File size: \", fileMetadata.size.toString());\n    io:println(\"Is directory: \", fileMetadata.dir.toString());\n    io:println(\"Modified at \", fileMetadata.modifiedTime.toString());\n\n    // Removes the file in the specified file path.\n    check file:remove(\"bar1.txt\");\n    check file:remove(\"bar2.txt\");\n    io:println(\"Files removed successfully.\");\n}\n"
  },
  {
    "path": "examples/files/files.md",
    "content": "# Files\n\nThe `file` library provides APIs to perform file-system operations.\n\nFor more information on the underlying module, see the [`file` module](https://lib.ballerina.io/ballerina/file/latest/).\n\n::: code files.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out files.out :::"
  },
  {
    "path": "examples/files/files.metatags",
    "content": "description: This BBE shows how to perform file-system operations in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, file, path\n"
  },
  {
    "path": "examples/files/files.out",
    "content": "$ bal run files.bal\nThe bar.txt file created successfully.\nDoes the bar.txt file exist: true\nIs the bar.txt file readable: true\nIs the bar.txt file writeable: true\nThe bar.txt file copied successfully.\nThe bar.txt file renamed successfully.\nFile path: /A/B/bar1.txt\nFile size: 0\nIs directory: false\nModified at [1643011228,0.178000000]\nFiles removed successfully.\n"
  },
  {
    "path": "examples/filler-values-of-a-list/filler_values_of_a_list.bal",
    "content": "import ballerina/io;\n \npublic function main() {\n    // Since the filler value for int is `0`,\n    // the `severity` array will be initialized as [0, 0, 0].\n    int[3] severity = [];\n    io:println(severity);\n \n    // Since the filler value for `boolean` is `false` and the rest type can contain no members,\n    // the `scores` will be initialized as `[false]`.\n    [boolean, int...] scores = [];\n    io:println(scores);\n \n    // As the filler value for string is `\"\"`,\n    // the `names` array will be initialized as [\"John\", \"Mike\", \"\"].\n    string[3] names = [\"John\", \"Mike\"];\n    io:println(names);\n \n    // As the filler value for the list is an empty list,\n    // the `orderItems` tuple will be initialized as `[[\"carrot\", \"apple\"], [\"avacado\", \"egg\"], [\"\", \"\"]]``.\n    string[3][2] orderItems = [[\"carrot\", \"apple\"], [\"avocado\", \"egg\"]];\n    io:println(orderItems);\n}\n"
  },
  {
    "path": "examples/filler-values-of-a-list/filler_values_of_a_list.md",
    "content": "# Filler values of a list\n\nLists can be initialized with the help of filler values. These are the default values that a list member will be initialized with if you do not provide a value in the list constructor. This gives you the flexibility to assign the actual values later for lists.\n\n::: code filler_values_of_a_list.bal :::\n\n::: out filler_values_of_a_list.out :::\n\n## Related links\n- [Tuples](/learn/by-example/tuples)\n- [Arrays](/learn/by-example/arrays)\n- [Nested arrays](/learn/by-example/nested-arrays)\n"
  },
  {
    "path": "examples/filler-values-of-a-list/filler_values_of_a_list.metatags",
    "content": "description: Initialize an array and a collection with default values.\nkeywords: ballerina, ballerina by example, bbe, filler, default, initialize, array, collection, tuple\n\n"
  },
  {
    "path": "examples/filler-values-of-a-list/filler_values_of_a_list.out",
    "content": "$ bal run filler_values_of_a_list.bal\n[0,0,0]\n[false]\n[\"John\",\"Mike\",\"\"]\n[[\"carrot\",\"apple\"],[\"avocado\",\"egg\"],[\"\",\"\"]]\n"
  },
  {
    "path": "examples/floating-point-numbers/floating_point_numbers.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    float x = 1.0;\n\n    int n = 5;\n\n    // Numeric literals can use `f` or `F` suffix for them to be interpreted as `float` values.\n    // (Similarly, the `d` or `D` suffix can be used for `decimal`).\n    var f = 12345f;\n    io:println(f is float);\n\n    // No implicit conversions between integers and floating point values are allowed.\n    // You can use `<T>` for explicit conversions.\n    float y = x + <float>n;\n\n    io:println(y);\n}\n"
  },
  {
    "path": "examples/floating-point-numbers/floating_point_numbers.md",
    "content": "# Floating point numbers\n\nThe `float` type is IEEE 64-bit binary floating point and supports the same arithmetic operators as `int`.\n\n::: code floating_point_numbers.bal :::\n\n::: out floating_point_numbers.out :::"
  },
  {
    "path": "examples/floating-point-numbers/floating_point_numbers.metatags",
    "content": "description: This BBE introduces the float type in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, floating point numbers, float, NaN\n"
  },
  {
    "path": "examples/floating-point-numbers/floating_point_numbers.out",
    "content": "$ bal run floating_point_numbers.bal \ntrue\n6.0\n"
  },
  {
    "path": "examples/flush/flush.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    worker A {\n        10 -> B;\n\n        // This transmission will not happen.\n        \"Hello\" -> B;\n        \n        // Flush all messages sent to worker 'B'. \n        // Worker 'A' will stop here until all messages are sent or until a failure occurs in 'B'.\n        error? result = trap flush B;\n        \n        // This will return the `panic` error.\n        io:println(\"Result from worker B : \", result ?: \"nil\");\n    }\n\n    worker B {\n        int value = <- A;\n        io:println(string `Received integer ${value} from worker A`);\n\n        if value == 10 {\n            panic error(\"Error in worker B\");\n        }\n\n        string text = <- A;\n        io:println(string `Received string \"${text}\" from worker A`);\n    }\n}\n"
  },
  {
    "path": "examples/flush/flush.md",
    "content": "# Flush\n\nThe `flush` action is used by the workers to check whether all the messages sent to a given worker are successfully recovered or not. If the transmission fails with an `error` or a `panic`, then, the error will be propagated to the waiting strand. Otherwise, it will return `nil`.\n\n::: code flush.bal :::\n\n::: out flush.out :::"
  },
  {
    "path": "examples/flush/flush.metatags",
    "content": "description: This BBE demonstrates how the `flush` action can be used for concurrency.\nkeywords: ballerina, ballerina by example, bbe, flush, concurrency\n"
  },
  {
    "path": "examples/flush/flush.out",
    "content": "$ bal run flush.bal\nReceived integer 10 from worker A\nResult from worker B : error(\"Error in worker B\")\n"
  },
  {
    "path": "examples/foreach-statement/foreach_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n\n    string[] names = [\"Bob\", \"Jo\", \"Ann\", \"Tom\"];\n    // Loop through a list.\n    foreach string name in names {\n        io:println(name);\n    }\n\n    // Iterate a structure.\n    map<int> grades = { Bob : 65, Jo : 70, Ann : 75, Tom : 60};\n    int sum = 0;\n    foreach int grade in grades {\n      sum += grade;\n    }\n\n    io:println(\"Average :\", sum/grades.length());\n\n    // Binding patterns can be used with the `foreach` statement.\n    // Values in `resultList` are assigned to `name`, `grade` variables in the binding pattern.\n    [string, int][] resultList = [[\"Bob\", 65], [\"Jo\", 70], [\"Ann\", 75], [\"Tom\", 60]];\n    // Binding patterns (e.g., `[string, int]` and `[name, grade]`) are used with the `foreach` statement.\n    foreach [string, int] [name, grade] in resultList {\n        io:println(\"Name:\", name, \" \", \"Grade:\", grade);\n    }\n\n}\n"
  },
  {
    "path": "examples/foreach-statement/foreach_statement.md",
    "content": "# Foreach statement\n\nThe `foreach` statement iterates over an `iterable` value such as arrays, tuples, maps, records, string, and tables etc. by executing a block of statements for each value in the iteration order. For a string value, it will iterate over each code point of the string.\n\nThe syntax contains a variable and an `in` keyword followed by an expression and a block of statements. The variable can also be in the form of a type binding pattern and the expression can be an action invocation, which should evaluate to an iterable value.\n\n::: code foreach_statement.bal :::\n\n::: out foreach_statement.out :::\n\n## Related links\n- [Break statement](/learn/by-example/break-statement/)\n- [Continue statement](/learn/by-example/continue-statement/)\n- [While statement](/learn/by-example/while-statement/)\n"
  },
  {
    "path": "examples/foreach-statement/foreach_statement.metatags",
    "content": "description: This BBE demonstrates how to use the `foreach` statement to loop a list, iterate a structure, and use `foreach` statement with binding patterns in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, foreach, loops, iterate, iterable, collections\n"
  },
  {
    "path": "examples/foreach-statement/foreach_statement.out",
    "content": "$ bal run foreach_statement.bal\nBob\nJo\nAnn\nTom\nAverage :67\nName:Bob Grade:65\nName:Jo Grade:70\nName:Ann Grade:75\nName:Tom Grade:60\n"
  },
  {
    "path": "examples/fork/fork.bal",
    "content": "import ballerina/io;\n\npublic function main(int? userInput) {\n    if userInput is int {\n        int num = userInput;\n        fork {\n            worker A {\n                num -> B;\n                string value = <- B;\n                io:println(string `Received string '${value}' from worker B`);\n            }\n\n            worker B {\n                int value = <- A;\n                io:println(string `Received int '${value}' from worker A`);\n                \"a\" -> A;\n            }\n        }\n    } else {\n        io:println(\"Not forked\");\n    }\n}\n"
  },
  {
    "path": "examples/fork/fork.md",
    "content": "# Fork\n\nThe fork statement starts one or more named workers, which run in parallel with each other, each in its own new strand. Variables and parameters in scope for the fork statement remain in scope within the workers. Message passing can be done only between the workers created within the fork statement and cannot be done with the enclosing function's default worker and its named workers. Unlike named workers outside a fork statement, with a fork statement, workers can be defined anywhere within the function body (e.g., within a conditional block).\n\n::: code fork.bal :::\n\n::: out fork.out :::\n"
  },
  {
    "path": "examples/fork/fork.metatags",
    "content": "description: This BBE demonstrates how the `fork` statement can be used for concurrency.\nkeywords: ballerina, ballerina by example, bbe, fork, concurrency, named workers\n"
  },
  {
    "path": "examples/fork/fork.out",
    "content": "$ bal run fork.bal -- 5\nReceived int '5' from worker A\nReceived string 'a' from worker B\n"
  },
  {
    "path": "examples/ftp-client-receive-file/ftp_client_receive_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates the client with the connection parameters, host, username, and\n    // password. An error is returned in a failure. The default port number\n    // `21` is used with these configurations.\n    ftp:Client fileClient = check new ({\n        host: \"ftp.example.com\",\n        auth: {\n            credentials: {\n                username: \"user1\",\n                password: \"pass456\"\n            }\n        }\n    });\n\n    // Reads a file from an FTP server for a given file path. In error cases,\n    // an error is returned.\n    stream<byte[] & readonly, io:Error?> fileStream = check fileClient->get(\"/server/logFile.txt\");\n\n    // Write the content to a file.\n    check io:fileWriteBlocksFromStream(\"./local/newLogFile.txt\", fileStream);\n    // Closes the file stream to finish the `get` operation.\n    check fileStream.close();\n}\n"
  },
  {
    "path": "examples/ftp-client-receive-file/ftp_client_receive_file.md",
    "content": "# FTP client - Receive file\n\nThe `ftp:Client` connects to a given FTP server, and then sends and receives files as byte streams. An `ftp:Client` is created by giving the host-name and required credentials. Once connected, `get` method is used to read files as byte streams from the FTP server. Use this to transfer files from a remote file system to a local file system.\n\n::: code ftp_client_receive_file.bal :::\n\n## Prerequisites\n- Start a [FTP server](https://hub.docker.com/r/stilliard/pure-ftpd/) instance.\n- Run the FTP client given in the [FTP client - Send file](/learn/by-example/ftp-client-send-file) example to put a file in the FTP server.\n\nRun the program by executing the following command. The newly-added file will appear in the local directory.\n\n::: out ftp_client_receive_file.out :::\n\n## Related links\n- [`ftp:Client->get` method - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Client#get)\n- [FTP client - Specification](/spec/ftp/#321-insecure-client)\n"
  },
  {
    "path": "examples/ftp-client-receive-file/ftp_client_receive_file.metatags",
    "content": "description: This example demonstrates getting file content from a remote FTP server.\nkeywords: ballerina, ballerina by example, bbe, FTP\n"
  },
  {
    "path": "examples/ftp-client-receive-file/ftp_client_receive_file.out",
    "content": "$ bal run ftp_client_read.bal\n"
  },
  {
    "path": "examples/ftp-client-send-file/ftp_client_send_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates the client with the connection parameters, host, username, and\n    // password. An error is returned in a failure. The default port number\n    // `21` is used with these configurations.\n    ftp:Client fileClient = check new ({\n        host: \"ftp.example.com\",\n        auth: {\n            credentials: {\n                username: \"user1\",\n                password: \"pass456\"\n            }\n        }\n    });\n\n    // Add a new file to the given file location. In error cases,\n    // an error is returned. The local file is provided as a stream of\n    // `io:Block` in which 1024 is the block size.\n    stream<io:Block, io:Error?> fileStream\n        = check io:fileReadBlocksAsStream(\"./local/logFile.txt\", 1024);\n    check fileClient->put(\"/server/logFile.txt\", fileStream);\n    check fileStream.close();\n}\n"
  },
  {
    "path": "examples/ftp-client-send-file/ftp_client_send_file.md",
    "content": "# FTP client - Send file\n\nThe `ftp:Client` connects to a given FTP server, and then sends and receives files as byte streams. An `ftp:Client` is created by giving the host-name and required credentials. Once connected, `put` method is used to write files as byte streams to the FTP server. Use this to transfer files from a local file system to a remote file system.\n\n::: code ftp_client_send_file.bal :::\n\n## Prerequisites\n- Start a [FTP server](https://hub.docker.com/r/stilliard/pure-ftpd/) instance.\n\nRun the program by executing the following command. The newly-added file will appear in the FTP server.\n\n::: out ftp_client_send_file.out :::\n\n## Related links\n- [`ftp:Client->put` method - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Client#put)\n- [FTP client - Specification](/spec/ftp/#321-insecure-client)\n"
  },
  {
    "path": "examples/ftp-client-send-file/ftp_client_send_file.metatags",
    "content": "description: This example demonstrates adding file content on a remote FTP server.\nkeywords: ballerina, ballerina by example, bbe, FTP\n"
  },
  {
    "path": "examples/ftp-client-send-file/ftp_client_send_file.out",
    "content": "$ bal run ftp_client_write.bal\n"
  },
  {
    "path": "examples/ftp-service-receive-file/ftp_service_receive_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\n// Creates the listener with the connection parameters and the protocol-related\n// configuration. The listener listens to the files\n// with the given file name pattern located in the specified path.\nlistener ftp:Listener fileListener = new ({\n    host: \"ftp.example.com\",\n    auth: {\n        credentials: {\n            username: \"user1\",\n            password: \"pass456\"\n        }\n    },\n    path: \"/home/in\",\n    fileNamePattern: \"(.*).txt\"\n});\n\n// One or many services can listen to the FTP listener for the periodically-polled\n// file related events.\nservice on fileListener {\n\n    // When a file event is successfully received, the `onFileChange` method is called.\n    remote function onFileChange(ftp:WatchEvent & readonly event, ftp:Caller caller) returns error? {\n        // `addedFiles` contains the paths of the newly-added files/directories\n        // after the last polling was called.\n        foreach ftp:FileInfo addedFile in event.addedFiles {\n            // Get the newly added file from the FTP server as a `byte[]` stream.\n            stream<byte[] & readonly, io:Error?> fileStream = check caller->get(addedFile.pathDecoded);\n\n            // Write the content to a file.\n            check io:fileWriteBlocksFromStream(string `./local/${addedFile.name}`, fileStream);\n            check fileStream.close();\n        }\n    }\n}\n"
  },
  {
    "path": "examples/ftp-service-receive-file/ftp_service_receive_file.md",
    "content": "# FTP service - Receive file\n\nThe `ftp:Service` connects to a given FTP server via the `ftp:Listener`. A `ftp:Listener` is created by providing the host-name and required credentials. Once connected, the service starts receiving events every time a file is deleted or added to the server. To take action for these events `ftp:Caller` is used. The `ftp:Caller` can be specified as a parameter of `onFileChange` remote method. The `ftp:Caller` allows interacting with the server via `get`, `append`, `delete`, etc remote methods. Use this to listen to file changes occurring in a remote file system and take action for those changes.\n\n::: code ftp_service_receive_file.bal :::\n\n## Prerequisites\n- Start a [FTP server](https://hub.docker.com/r/stilliard/pure-ftpd/) instance.\n\nRun the program by executing the following command. Each newly added file in the SFTP server will be saved in the local file system.\n\n::: out ftp_service_receive_file.out :::\n\n>**Tip:** Run the FTP client given in the [FTP client - Send file](/learn/by-example/ftp-client-send-file) example to put a file in the FTP server.\n\n## Related links\n- [`ftp:Listener` client object  - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Listener)\n- [FTP service - Specification](/spec/ftp/#422-secure-listener)\n"
  },
  {
    "path": "examples/ftp-service-receive-file/ftp_service_receive_file.metatags",
    "content": "description: This example demonstrates receiving file/directory changes that occur in a remote FTP server and using an ftp:Caller to read the contents of the newly added files.\nkeywords: ballerina, ballerina by example, bbe, FTP, remote file, listener\n"
  },
  {
    "path": "examples/ftp-service-receive-file/ftp_service_receive_file.out",
    "content": "$ bal run ftp_service_read.bal\n"
  },
  {
    "path": "examples/ftp-service-send-file/ftp_service_send_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\n// Creates the listener with the connection parameters and the protocol-related\n// configuration. The listener listens to the files\n// with the given file name pattern located in the specified path.\nlistener ftp:Listener fileListener = check new ({\n    host: \"ftp.example.com\",\n    auth: {\n        credentials: {\n            username: \"user1\",\n            password: \"pass456\"\n        }\n    },\n    path: \"/home/in\",\n    fileNamePattern: \"(.*).txt\"\n});\n\n// One or many services can listen to the FTP listener for the periodically-polled\n// file related events.\nservice on fileListener {\n\n    // When a file event is successfully received, the `onFileChange` method is called.\n    remote function onFileChange(ftp:WatchEvent & readonly event, ftp:Caller caller) returns error? {\n        foreach ftp:FileInfo addedFile in event.addedFiles {\n            // The `ftp:Caller` can be used to append another file to the added files in the server.\n            stream<io:Block, io:Error?> fileStream = check io:fileReadBlocksAsStream(\"./local/appendFile.txt\", 7);\n            check caller->append(addedFile.pathDecoded, fileStream);\n            check fileStream.close();\n        }\n    }\n}\n"
  },
  {
    "path": "examples/ftp-service-send-file/ftp_service_send_file.md",
    "content": "# FTP service - Send file\n\nThe `ftp:Service` connects to a given FTP server via the `ftp:Listener`. Once connected, the service starts receiving events every time a file is deleted or added to the server. To take action for these events `ftp:Caller` is used. The `ftp:Caller` can be specified as a parameter of `onFileChange` remote method. The `ftp:Caller` allows interacting with the server via `get`, `append`, `delete`, etc remote methods. Use this to listen to file changes occurring in a remote file system and take action for those changes.\n\n::: code ftp_service_send_file.bal :::\n\n## Prerequisites\n- Start a [FTP server](https://hub.docker.com/r/stilliard/pure-ftpd/) instance.\n\nRun the program by executing the following command. Each newly added file in the FTP server will be appended with the content in the appending file.\n\n::: out ftp_service_send_file.out :::\n\n>**Tip:** Run the FTP client given in the [FTP client - Send file](/learn/by-example/ftp-client-send-file) example to put a file in the FTP server.\n\n## Related links\n- [`ftp:Caller` client object  - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Caller)\n- [`ftp:Caller` functions - Specification](/spec/ftp/#52-functions)\n"
  },
  {
    "path": "examples/ftp-service-send-file/ftp_service_send_file.metatags",
    "content": "description: This example demonstrates receiving file/directory changes that occur in a remote FTP server and using an ftp:Caller to append a file to the newly added files.\nkeywords: ballerina, ballerina by example, bbe, FTP, remote file, listener\n"
  },
  {
    "path": "examples/ftp-service-send-file/ftp_service_send_file.out",
    "content": "$ bal run ftp_service_read_write.bal\n"
  },
  {
    "path": "examples/function-closure/function_closure.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    string[] names = [\"Ana\", \"Alice\", \"Bob\"];\n\n    // Define a function to modify and return the variable 'names' that are declared outside the scope.\n    var addName = function(string value) returns string[] {\n        // Access the variable `names` as closure within the `addName` inner function.\n        names.push(value);\n        return names;\n    };\n\n    io:println(addName(\"James\"));\n    io:println(names);\n}\n"
  },
  {
    "path": "examples/function-closure/function_closure.md",
    "content": "# Function closure\n\nThe object constructor and function can work as a closure, that can access variables outside of its own scope. It is a compile-time error to have parameter names similar to the outer-scope variable names.\n\n::: code function_closure.bal :::\n\n::: out function_closure.out :::\n\n## Related links\n- [Function values](/learn/by-example/function-values/)\n- [Anonymous function](/learn/by-example/anonymous-function/)\n"
  },
  {
    "path": "examples/function-closure/function_closure.metatags",
    "content": "description: This BBE demonstrates handling closures in a function by creating an anonymous function in Ballerina.\nkeywords: anonymous function, ballerina, ballerina by example, bbe, closures, functions, function value\n"
  },
  {
    "path": "examples/function-closure/function_closure.out",
    "content": "$ bal run function_closure.bal\n[\"Ana\",\"Alice\",\"Bob\",\"James\"]\n[\"Ana\",\"Alice\",\"Bob\",\"James\"]\n"
  },
  {
    "path": "examples/function-pointers/function_pointers.bal",
    "content": "import ballerina/io;\n\nfunction add(int v1, int v2) returns int {\n    return v1 + v2;\n}\n\nint num1 = 10;\nint num2 = 100;\n\n// In this example, the function pointer with default values for function pointer parameters is used \n// as a parameter. \nfunction executeWithDefaultValues(function (int a = num1, int b = num2) returns int func) returns int {\n    return func();\n}\n\n//  In this example, the function pointer without default values for the function pointer parameters is used \n// as a parameter. \nfunction execute(function (int, int) returns int func, int v1, int v2) returns int {\n    return func(v1, v2);\n}\n\npublic function main() {\n    // The `add` function names serve as a function pointer argument in the\n    // call to the `executeWithDefaultValues` and `execute` functions.\n    io:println(\"Add num1 & num2: \", executeWithDefaultValues(add));\n    io:println(\"Add 1 & 2: \", execute(add, 1, 2));\n}\n"
  },
  {
    "path": "examples/function-pointers/function_pointers.md",
    "content": "# Function pointers\n\nBallerina allows you to define variables (function pointers) of function types. The name of the function variable serves as a reference to that function when it is used in an expression context. A function pointer can be invoked similarly to how a normal function is invoked.\n\n::: code function_pointers.bal :::\n\n::: out function_pointers.out :::\n\n## Related links\n- [Functions values](/learn/by-example/function-values/)\n- [Default values for function parameters](/learn/by-example/default-values-for-function-parameters/)\n- [Function types](/learn/by-example/function-types/)\n"
  },
  {
    "path": "examples/function-pointers/function_pointers.metatags",
    "content": "description: This BBE demonstrates using function pointers in function parameters, passing the default value to the parameters of the function pointers, and creating a function in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, function definition, function pointers, defaultable parameters\n"
  },
  {
    "path": "examples/function-pointers/function_pointers.out",
    "content": "$ bal run function_pointers.bal\nAdd num1 & num2: 110\nAdd 1 & 2: 3\n"
  },
  {
    "path": "examples/function-types/function_types.bal",
    "content": "import ballerina/io;\n\n// Function type syntax.\ntype IntFilter function (int num) returns boolean;\n\n// Module-level function definition.\nfunction isEven(int n) returns boolean {\n    return n % 2 == 0;\n}\n\npublic function main() {\n    // Type of the `evenFunc1` variable is the `IntFilter` function type.\n    IntFilter evenFunc1 = isEven;\n    io:println(evenFunc1(5));\n    io:println(evenFunc1(6));\n\n    // Type of the `evenFunc2` variable is the `function (int num = 5) returns boolean` function type.\n    function (int num = 5) returns boolean evenFunc2 = isEven;\n\n    // Invoke the function with the default value defined in the function type.\n    io:println(evenFunc2());\n    // Invoke the function with the passed argument.\n    io:println(evenFunc2(6));\n\n    function (int num = 6) returns boolean evenFunc3 = isolated function(int n = 5) returns boolean {\n        return n % 2 == 0;\n    };\n\n    // Invoke the function with `6` as the default value for the parameter `num`.\n    io:println(evenFunc3());\n}\n"
  },
  {
    "path": "examples/function-types/function_types.md",
    "content": "# Function types\nIn Ballerina, the function type is a separate basic type. The syntax for a function type looks like a function definition without a function name. \n\nWhen assigning a function value to a variable of the function type, the function signatures must be equal. However, parameters may have default values in either the function value or the function type or both. If a default value is provided in both the function value and function type, the default value in the function type will be used when the function is invoked.\n\n::: code function_types.bal :::\n\n::: out function_types.out :::\n\n## Related links\n- [Function values](/learn/by-example/function-values/)\n- [Anonymous function](/learn/by-example/anonymous-function/)\n- [Default values for function parameters](/learn/by-example/default-values-for-function-parameters/)\n- [Function pointers](/learn/by-example/function-pointers/)\n"
  },
  {
    "path": "examples/function-types/function_types.metatags",
    "content": "description: This BBE demonstrates defining function types, creating the function definition, and assigning the function value to the function variable in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, functions, function types, function defintion, default parameters\n"
  },
  {
    "path": "examples/function-types/function_types.out",
    "content": "$ bal run function_types.bal\nfalse\ntrue\nfalse\ntrue\ntrue\n"
  },
  {
    "path": "examples/function-values/function_values.bal",
    "content": "import ballerina/io;\n \n// Module-level function definition.\nfunction isEven(int n) returns boolean {\n   return n % 2 == 0;\n}\n \npublic function main() {\n   // The `isEven` function is referred as a value.\n   function (int n) returns boolean f = isEven;\n\n   // The function values can be executed like regular function calls.\n   io:println(f(5));\n   io:println(f(6));\n}\n"
  },
  {
    "path": "examples/function-values/function_values.md",
    "content": "# Function values\n\nIn Ballerina, a function is also a value implying that it can be stored in variables and passed to or returned from the functions.  A function value can be executed by calling it. A function value cannot be assigned to a defined function name.\n\n::: code function_values.bal :::\n\n::: out function_values.out :::\n\n## Related links\n- [Functions](/learn/by-example/functions/)\n- [Function pointers](/learn/by-example/function-pointers/)\n- [Function types](/learn/by-example/function-types/)\n"
  },
  {
    "path": "examples/function-values/function_values.metatags",
    "content": "description: This BBE demonstrates creating a variable with the function type and creating a function. \nkeywords:  ballerina, ballerina by example, bbe, functions, function type, function defintion, function value\n"
  },
  {
    "path": "examples/function-values/function_values.out",
    "content": "$ bal run function_values.bal\nfalse\ntrue\n"
  },
  {
    "path": "examples/functions/functions.bal",
    "content": "import ballerina/io;\n\n// This function definition has two parameters of type `int`.\n// The `returns` clause specifies the type of the return value.\nfunction add(int x, int y) returns int {\n    int sum = x + y;\n    // The `return` statement returns a value.\n    return sum;\n}\n\n// The function parameters can have default values.\nfunction calculateWeight(decimal mass, decimal gForce = 9.8) returns decimal {\n    return mass * gForce;\n}\n\n// The function returns `nil`.\nfunction print(anydata data) {\n    io:println(data);\n}\n\npublic function main() {\n    // Invoke the function `add` by passing the arguments.\n    int sum = add(5, 11);\n    // A function with no return type does not need a variable assignment.\n    print(sum);\n\n    // Invoke the `calculateWeight` function with the default arguments.\n    print(calculateWeight(5));\n\n    // Invoke the `add` function with the named arguments.\n    print(add(x = 5, y = 6));\n\n    // The return value of the function can be ignored by assigning it to `_`.\n    _ = calculateWeight(mass = 5, gForce = 10);\n}\n"
  },
  {
    "path": "examples/functions/functions.md",
    "content": "# Functions\n\nFunctions are declared using the `function` keyword. It accepts zero or more arguments and returns a single value. The `returns` keyword is used to indicate the return type of the function.\n\nFunction parameters are final variables and cannot be modified within the function.\n\n::: code functions.bal :::\n\n::: out functions.out :::\n\n## Related links\n- [Included record parameters](/learn/by-example/included-record-parameters/)\n- [Rest Parameters](/learn/by-example/rest-parameters/)\n- [Default values for function parameters](/learn/by-example/default-values-for-function-parameters/)\n- [Provide function arguments by name](/learn/by-example/provide-function-arguments-by-name/)\n- [Rest arguments](/learn/by-example/rest-arguments/)\n- [Function pointers](/learn/by-example/function-pointers/)\n- [Function values](/learn/by-example/function-values/)\n- [Function types](/learn/by-example/function-types/)\n- [Anonymous function](/learn/by-example/anonymous-function/)\n- [Function closure](/learn/by-example/function-closure/)\n"
  },
  {
    "path": "examples/functions/functions.metatags",
    "content": "description: This BBE demonstrates creating functions with defaultable parameters and passing named arguments to the function in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, functions, function defintion, parameters, default parameters, returns\n"
  },
  {
    "path": "examples/functions/functions.out",
    "content": "$ bal run functions.bal\n16\n49.0\n11\n"
  },
  {
    "path": "examples/gauge-metrics/gauge_metrics.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/log;\nimport ballerina/observe;\nimport ballerinax/prometheus as _;\n\n//Create a gauge as a global variable in the service with the optional field description,\n//default statistics configurations = { timeWindow: 600000, buckets: 5,\n// and percentiles: [0.33, 0.5, 0.66, 0.99] }.\nobserve:Gauge globalGauge = new (\"global_gauge\", \"Global gauge defined\");\n\nservice /onlineStoreService on new http:Listener(9090) {\n\n    resource function get makeOrder(http:Caller caller, http:Request req) {\n        io:println(\"------------------------------------------\");\n        //Incrementing the global gauge defined by 15.0.\n        globalGauge.increment(15.0);\n        //Log the current state of global gauge.\n        printGauge(globalGauge);\n\n\n        //Create a gauge with simply a name, and default statistics configurations.\n        observe:Gauge localGauge = new (\"local_operations\");\n        //Increment the local gauge by default value 1.0.\n        localGauge.increment();\n        //Increment the value of the gauge by 20.\n        localGauge.increment(20.0);\n        //Decrement the local gauge by default value 1.0.\n        localGauge.decrement();\n        //Decrement the value of the gauge by 20.\n        localGauge.decrement(10.0);\n        //Log the current state of local gauge.\n        printGauge(localGauge);\n\n\n        //Create a gauge with optional fields description, and tags defined.\n        observe:Gauge registeredGaugeWithTags =\n                  new (\"registered_gauge_with_tags\", \"RegisteredGauge\",\n                       {property: \"gaugeProperty\", gaugeType: \"RegisterType\"});\n\n        //Register the gauge instance, therefore it is stored in the global registry and can be reported to the\n        //metrics server such as Prometheus. Additionally, this operation will register to the global registry for the\n        //first invocation and will throw an error if there is already a registration of different metrics instance\n        //or type. And subsequent invocations of register() will simply retrieve the stored metrics instance\n        //for the provided name and tags fields, and use that instance for the subsequent operations on the\n        //Counter instance.\n        error? result = registeredGaugeWithTags.register();\n        if (result is error) {\n            log:printError(\"Error in registering gauge\", 'error = result);\n        }\n\n        //Set the value of the gauge with the new value.\n        registeredGaugeWithTags.increment();\n        float value = registeredGaugeWithTags.getValue();\n        float newValue = value * 12.0;\n        registeredGaugeWithTags.setValue(newValue);\n        //Log the current state of registered gauge with tags.\n        printGauge(registeredGaugeWithTags);\n\n\n        //Create a gauge with statistics disabled by passing empty statistics config array.\n        observe:StatisticConfig[] statsConfigs = [];\n        observe:Gauge gaugeWithNoStats = new (\"gauge_with_no_stats\",\n                                        \"Some description\", (), statsConfigs);\n        gaugeWithNoStats.setValue(100);\n        printGauge(gaugeWithNoStats);\n\n\n        //Create gauge with custom statistics config.\n        observe:StatisticConfig config = {\n            timeWindow: 30000,\n            percentiles: [0.33, 0.5, 0.9, 0.99],\n            buckets: 3\n        };\n        statsConfigs[0] = config;\n        observe:Gauge gaugeWithCustomStats = new (\"gauge_with_custom_stats\",\n                                        \"Some description\", (), statsConfigs);\n        int i = 1;\n        while (i < 6) {\n            gaugeWithCustomStats.setValue(<float>(100 * i));\n            i = i + 1;\n        }\n        //Log the current state of registered gauge with tags.\n        printGauge(gaugeWithCustomStats);\n\n        io:println(\"------------------------------------------\");\n\n        //Send response to the client.\n        http:Response res = new;\n        // Use a util method to set a string payload.\n        res.setPayload(\"Order Processed!\");\n\n        // Send the response back to the caller.\n        result = caller->respond(res);\n\n        if (result is error) {\n            log:printError(\"Error sending response\", 'error = result);\n        }\n    }\n}\n\nfunction printGauge(observe:Gauge gauge) {\n    //Get the statistics snapshot of the gauge.\n    io:print(\"Gauge - \" + gauge.name + \" Snapshot: \");\n    observe:Snapshot[]? snapshots = gauge.getSnapshot();\n    json|error snapshotAsAJson = snapshots.cloneWithType(json);\n    if snapshotAsAJson is json {\n        io:println(snapshotAsAJson.toJsonString());\n    }\n    //Get the current value of the gauge.\n    io:println(\"Gauge - \", gauge.name, \" Current Value: \"\n        , gauge.getValue());\n}\n"
  },
  {
    "path": "examples/gauge-metrics/gauge_metrics.client.out",
    "content": "$ curl http://localhost:9090/onlineStoreService/makeOrder\nOrder Processed!\n"
  },
  {
    "path": "examples/gauge-metrics/gauge_metrics.md",
    "content": "# Gauge-based metrics\n\nBallerina supports observability out of the box and metrics is one of the three key components of observability. To observe Ballerina code, the build time flag `--observability-included` should be given along with the `Config.toml` file when starting the service. The `Config.toml` file should contain the required runtime configurations related to observability.\n\nThe developers can define and use metrics to measure their own logic. A gauge is one type of the metrics that is supported by default in Ballerina, and it represents a single numerical value that can arbitrarily go up and down, and also based on the statistics configurations provided to the Gauge, it can also report the statistics such as max, min, mean, percentiles, etc.\n\nFor more information about configs and observing applications, see [Observe Ballerina programs](/learn/observe-ballerina-programs/).\n\n::: code gauge_metrics.bal :::\n\nInvoke the service using the cURL command below.\n\n::: out gauge_metrics.client.out :::\n\nTo start the service, navigate to the directory that contains the\n`.bal` file, and execute the `bal run` command below with the `--observability-included` build time flag and the `Config.toml` runtime configuration file.\n\n::: out gauge_metrics.server.out :::\n"
  },
  {
    "path": "examples/gauge-metrics/gauge_metrics.metatags",
    "content": "description: BBE on how to use the default Gauge Metrics Observability feature in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, observability, tracing, opentracing, gauge\n"
  },
  {
    "path": "examples/gauge-metrics/gauge_metrics.server.out",
    "content": "$ BAL_CONFIG_FILES=Config.toml bal run --observability-included gauge_metrics.bal\nballerina: started Prometheus HTTP listener 0.0.0.0:9797\n------------------------------------------\nGauge - global_gauge Snapshot: [{\"timeWindow\":600000, \"mean\":15.0, \"max\":15.0, \"min\":15.0, \"stdDev\":0.0, \"percentileValues\":[{\"percentile\":0.33, \"value\":15.0}, {\"percentile\":0.5, \"value\":15.0}, {\"percentile\":0.66, \"value\":15.0}, {\"percentile\":0.75, \"value\":15.0}, {\"percentile\":0.95, \"value\":15.0}, {\"percentile\":0.99, \"value\":15.0}, {\"percentile\":0.999, \"value\":15.0}]}]\nGauge - global_gauge Current Value: 15.0\nGauge - local_operations Snapshot: [{\"timeWindow\":600000, \"mean\":13.0390625, \"max\":21.1171875, \"min\":1.0, \"stdDev\":8.180620171277893, \"percentileValues\":[{\"percentile\":0.33, \"value\":10.0546875}, {\"percentile\":0.5, \"value\":10.0546875}, {\"percentile\":0.66, \"value\":20.1171875}, {\"percentile\":0.75, \"value\":20.1171875}, {\"percentile\":0.95, \"value\":21.1171875}, {\"percentile\":0.99, \"value\":21.1171875}, {\"percentile\":0.999, \"value\":21.1171875}]}]\nGauge - local_operations Current Value: 10.0\nGauge - registered_gauge_with_tags Snapshot: [{\"timeWindow\":600000, \"mean\":6.515625, \"max\":12.0546875, \"min\":1.0, \"stdDev\":5.515625, \"percentileValues\":[{\"percentile\":0.33, \"value\":1.0}, {\"percentile\":0.5, \"value\":1.0}, {\"percentile\":0.66, \"value\":12.0546875}, {\"percentile\":0.75, \"value\":12.0546875}, {\"percentile\":0.95, \"value\":12.0546875}, {\"percentile\":0.99, \"value\":12.0546875}, {\"percentile\":0.999, \"value\":12.0546875}]}]\nGauge - registered_gauge_with_tags Current Value: 12.0\nGauge - gauge_with_no_stats Snapshot: null\nGauge - gauge_with_no_stats Current Value: 100.0\nGauge - gauge_with_custom_stats Snapshot: [{\"timeWindow\":30000, \"mean\":300.7, \"max\":501.5, \"min\":100.0, \"stdDev\":141.775033062948, \"percentileValues\":[{\"percentile\":0.33, \"value\":200.5}, {\"percentile\":0.5, \"value\":301.5}, {\"percentile\":0.9, \"value\":501.5}, {\"percentile\":0.99, \"value\":501.5}]}]\nGauge - gauge_with_custom_stats Current Value: 500.0\n------------------------------------------\n------------------------------------------\nGauge - global_gauge Snapshot: [{\"timeWindow\":600000, \"mean\":22.53125, \"max\":30.0625, \"min\":15.0, \"stdDev\":7.53125, \"percentileValues\":[{\"percentile\":0.33, \"value\":15.0}, {\"percentile\":0.5, \"value\":15.0}, {\"percentile\":0.66, \"value\":30.0625}, {\"percentile\":0.75, \"value\":30.0625}, {\"percentile\":0.95, \"value\":30.0625}, {\"percentile\":0.99, \"value\":30.0625}, {\"percentile\":0.999, \"value\":30.0625}]}]\nGauge - global_gauge Current Value: 30.0\nGauge - local_operations Snapshot: [{\"timeWindow\":600000, \"mean\":13.0390625, \"max\":21.1171875, \"min\":1.0, \"stdDev\":8.180620171277893, \"percentileValues\":[{\"percentile\":0.33, \"value\":10.0546875}, {\"percentile\":0.5, \"value\":10.0546875}, {\"percentile\":0.66, \"value\":20.1171875}, {\"percentile\":0.75, \"value\":20.1171875}, {\"percentile\":0.95, \"value\":21.1171875}, {\"percentile\":0.99, \"value\":21.1171875}, {\"percentile\":0.999, \"value\":21.1171875}]}]\nGauge - local_operations Current Value: 10.0\nGauge - registered_gauge_with_tags Snapshot: [{\"timeWindow\":600000, \"mean\":55.4140625, \"max\":156.9921875, \"min\":1.0, \"stdDev\":61.38432884406833, \"percentileValues\":[{\"percentile\":0.33, \"value\":12.0546875}, {\"percentile\":0.5, \"value\":12.0546875}, {\"percentile\":0.66, \"value\":52.2421875}, {\"percentile\":0.75, \"value\":52.2421875}, {\"percentile\":0.95, \"value\":156.9921875}, {\"percentile\":0.99, \"value\":156.9921875}, {\"percentile\":0.999, \"value\":156.9921875}]}]\nGauge - registered_gauge_with_tags Current Value: 156.0\nGauge - gauge_with_no_stats Snapshot: null\nGauge - gauge_with_no_stats Current Value: 100.0\nGauge - gauge_with_custom_stats Snapshot: [{\"timeWindow\":30000, \"mean\":300.7, \"max\":501.5, \"min\":100.0, \"stdDev\":141.775033062948, \"percentileValues\":[{\"percentile\":0.33, \"value\":200.5}, {\"percentile\":0.5, \"value\":301.5}, {\"percentile\":0.9, \"value\":501.5}, {\"percentile\":0.99, \"value\":501.5}]}]\nGauge - gauge_with_custom_stats Current Value: 500.0\n------------------------------------------\n------------------------------------------\nGauge - global_gauge Snapshot: [{\"timeWindow\":600000, \"mean\":30.0625, \"max\":45.1875, \"min\":15.0, \"stdDev\":12.298479750223873, \"percentileValues\":[{\"percentile\":0.33, \"value\":15.0}, {\"percentile\":0.5, \"value\":30.0625}, {\"percentile\":0.66, \"value\":30.0625}, {\"percentile\":0.75, \"value\":45.1875}, {\"percentile\":0.95, \"value\":45.1875}, {\"percentile\":0.99, \"value\":45.1875}, {\"percentile\":0.999, \"value\":45.1875}]}]\nGauge - global_gauge Current Value: 45.0\nGauge - local_operations Snapshot: [{\"timeWindow\":600000, \"mean\":13.0390625, \"max\":21.1171875, \"min\":1.0, \"stdDev\":8.180620171277893, \"percentileValues\":[{\"percentile\":0.33, \"value\":10.0546875}, {\"percentile\":0.5, \"value\":10.0546875}, {\"percentile\":0.66, \"value\":20.1171875}, {\"percentile\":0.75, \"value\":20.1171875}, {\"percentile\":0.95, \"value\":21.1171875}, {\"percentile\":0.99, \"value\":21.1171875}, {\"percentile\":0.999, \"value\":21.1171875}]}]\nGauge - local_operations Current Value: 10.0\nGauge - registered_gauge_with_tags Snapshot: [{\"timeWindow\":600000, \"mean\":377.1927083333333, \"max\":1887.9921875, \"min\":1.0, \"stdDev\":676.7534301455432, \"percentileValues\":[{\"percentile\":0.33, \"value\":12.0546875}, {\"percentile\":0.5, \"value\":52.2421875}, {\"percentile\":0.66, \"value\":156.9921875}, {\"percentile\":0.75, \"value\":157.9921875}, {\"percentile\":0.95, \"value\":1887.9921875}, {\"percentile\":0.99, \"value\":1887.9921875}, {\"percentile\":0.999, \"value\":1887.9921875}]}]\nGauge - registered_gauge_with_tags Current Value: 1884.0\nGauge - gauge_with_no_stats Snapshot: null\nGauge - gauge_with_no_stats Current Value: 100.0\nGauge - gauge_with_custom_stats Snapshot: [{\"timeWindow\":30000, \"mean\":300.7, \"max\":501.5, \"min\":100.0, \"stdDev\":141.775033062948, \"percentileValues\":[{\"percentile\":0.33, \"value\":200.5}, {\"percentile\":0.5, \"value\":301.5}, {\"percentile\":0.9, \"value\":501.5}, {\"percentile\":0.99, \"value\":501.5}]}]\nGauge - gauge_with_custom_stats Current Value: 500.0\n------------------------------------------\n"
  },
  {
    "path": "examples/gauge-metrics/tests/gauge_metrics_test.bal",
    "content": "import ballerina/test;\nimport ballerina/io;\nimport ballerina/http;\n\n@test:Config { }\nfunction testFunc() {\n    // Invoking the main function\n    http:Client httpEndpoint = new (\"http://localhost:9090\");\n\n    string response1 = \"Order Processed!\";\n\n    // Send a GET request to the specified endpoint.\n    http:Response|error response = httpEndpoint->get(\"/onlineStoreService/makeOrder\");\n    if response is http:Response {\n        var res = response.getTextPayload();\n        if res is error {\n            test:assertFail(msg = \"Failed to call the endpoint:\");\n        } else {\n            test:assertEquals(res, response1);\n        }\n    } else {\n        test:assertFail(msg = \"Failed to call the endpoint:\");\n    }\n}\n\nfunction stopService() {\n    test:stopServices(\"gauge-metrics\");\n}\n"
  },
  {
    "path": "examples/graphql-client-error-handling/graphql_client_error_handling.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    do {\n        graphql:Client graphqlClient = check new (\"localhost:9090/graphql\");\n        // This is a malformed GraphQL document.\n        string document = \"mutation { updateName(name: 1) { name, age } }\";\n        ProfileResponse response = check graphqlClient->execute(document);\n        io:println(response);\n    } on fail graphql:ClientError err {\n        handleErrors(err);\n    }\n}\n\nfunction handleErrors(graphql:ClientError clientError) {\n    if clientError is graphql:PayloadBindingError {\n        // This error represents a client-side data binding error. This error occurs due to the\n        // assigned variable type and the value obtained from the wire having a mismatching \n        // shape.\n        io:println(\"PayloadBindingError: \", clientError.message());\n    } else if clientError is graphql:InvalidDocumentError {\n        // This error represents GraphQL errors due to GraphQL server-side document \n        // validation. The GraphQL errors returned from the server-side can be obtained by \n        // calling the `detail` method on the `graphql:InvalidDocumentError`.\n        graphql:ErrorDetail[]? errorDetails = clientError.detail().errors;\n        io:println(\"InvalidDocumentError: \", errorDetails);\n    } else if clientError is graphql:HttpError {\n        // This error represents network-level errors. If the response from the server contains \n        // a body then, it can be obtained by calling the `detail` method on the `graphql:HttpError`.\n        anydata body = clientError.detail().body;\n        io:println(\"HttpError: \", body, clientError.message());\n    }\n}\n"
  },
  {
    "path": "examples/graphql-client-error-handling/graphql_client_error_handling.md",
    "content": "# GraphQL client - Handle error response\n\nThe `graphql:Client` allows handling different errors occurred when executing the `execute` method. It returns a `graphql:ClientError` error, which has different subtypes that can be handled differently based on the use case. Use the subtypes of the `graphql:ClientError` to handle different types of errors based on the use case.\n\n::: code graphql_client_error_handling.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [Mutations](https://ballerina.io/learn/by-example/graphql-mutations/) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_error_handling.out :::\n\n## Related links\n- [`graphql:ClientError` error - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ClientError)\n- [GraphQL client error handling - Specification](/spec/graphql/#63-client-error-handling)\n"
  },
  {
    "path": "examples/graphql-client-error-handling/graphql_client_error_handling.metatags",
    "content": "description: This example demonstrates handling the errors of a GraphQL client.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, error handling, graphql client errors\n"
  },
  {
    "path": "examples/graphql-client-error-handling/graphql_client_error_handling.out",
    "content": "$ bal run graphql_client_error_handling.bal\nInvalidDocumentError: [{\"message\":\"String cannot represent non String value: 1\",\"locations\":[{\"line\":1,\"column\":29}]},{\"message\":\"Field \"updateName\" argument \"id\" of type \"Int!\" is required, but it was not provided.\",\"locations\":[{\"line\":1,\"column\":12}]}]\n"
  },
  {
    "path": "examples/graphql-client-handle-partial-response/graphql_client_handle_partial_response.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// The `ProfileResponse` is a sub-type of `graphql:GenericResponseWithErrors`.\n// The `graphql:GenericResponseWithErrors` record represents the generic shape of the GraphQL\n// response. The `graphql:GenericResponseWithErrors` record contains `data`, `errors`,\n// and `extensions` fields of which `data` represents the requested data from the GraphQL server,\n// `errors` represents the field errors raised during the execution, and `extensions` represents\n// the meta information on the protocol extensions from the GraphQL server.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\n// The following record type defines the shape of the response from a GraphQL service, which allows\n// the `age` field to have a `null` value.\ntype Profile record {|\n    string name;\n    int? age;\n|};\n\npublic function main() returns error? {\n    // Creates a new client with the backend URL.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\");\n\n    string document = \"{ profile(id: 1) { name, age } }\";\n    ProfileResponse response = check graphqlClient->execute(document);\n\n    // Access the data from the response.\n    io:println(response.data);\n\n    if response.errors !is () {\n        // Access the field errors from the response.\n        io:println(response.errors);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-client-handle-partial-response/graphql_client_handle_partial_response.md",
    "content": "# GraphQL client - Handle partial response\n\nThe `graphql:Client` allows handling cases where a GraphQL service responds with partial data along with errors. To retrieve the partial data, define the fields as nilable types in the expected response type where applicable. Use this approach when the response with partial data is considered to be valid or the partial data needs to be retrieved.\n\n>**Hint:** When defining field types as nilable, check the corresponding GraphQL schema to check the nilable fields.\n\n::: code graphql_client_handle_partial_response.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [Error handling](https://ballerina.io/learn/by-example/graphql-service-error-handling) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_handle_partial_response.out :::\n\n## Related links\n- [`graphql:Client` client object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Client)\n- [`graphql:GenericResponseWithErrors` record - API documentation](https://lib.ballerina.io/ballerina/graphql/1.4.4#GenericResponseWithErrors)\n- [`graphql:PayloadBindingError` error - API documentation](https://lib.ballerina.io/ballerina/graphql/1.5.0#PayloadBindingError)\n- [GraphQL client - Specification](/spec/graphql/#25-client)\n"
  },
  {
    "path": "examples/graphql-client-handle-partial-response/graphql_client_handle_partial_response.metatags",
    "content": "description: This example demonstrates handling partial data returned along with errors, by a GraphQL client.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, query, partial response\n"
  },
  {
    "path": "examples/graphql-client-handle-partial-response/graphql_client_handle_partial_response.out",
    "content": "$ bal run graphql_client_handle_partial_response.bal\n{\"profile\":{\"name\":\"Walter White\",\"age\":null}}\n[{\"message\":\"Error occurred while retrieving age\",\"locations\":[{\"line\":1,\"column\":26}],\"path\":[\"profile\",\"age\"]}]\n"
  },
  {
    "path": "examples/graphql-client-query-endpoint/graphql_client_query_endpoint.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// User defined data types to perform client side data-binding.\ntype ProfileResponse record {|\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    // Creates a new client with the backend URL.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\");\n\n    string document = \"{ profile { name, age } }\";\n\n    // The `execute` remote method of the `graphql:Client` takes a GraphQL document as the\n    // required argument and sends a request to the specified backend URL seeking a response. On the\n    // retrieval of a successful response, the client tries to perform data binding for the\n    // user-defined data type. On failure to retrieve a successful response or when the client fails\n    // to perform data binding, a `graphql:ClientError` will be returned.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-query-endpoint/graphql_client_query_endpoint.md",
    "content": "# GraphQL client - Query GraphQL endpoint\n\nThe `graphql:Client` allows connecting and interacting with a GraphQL server.  A `graphql:Client` is created by passing the URL of a GraphQL service endpoint. The `execute` method is used to execute a GraphQL operation. This method requires the GraphQL `document` as a required argument and takes a map of `variables` and an `operationName` as arguments optionally, in case the document contains any variables or contains more than one operation. Use the GraphQL client to execute the `Query` and `Mutation` operations on a GraphQL service.\n\n::: code graphql_client_query_endpoint.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [Record as output object](https://ballerina.io/learn/by-example/graphql-returning-record-values) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_query_endpoint.out :::\n\n## Related links\n- [`graphql:Client` client object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Client)\n- [GraphQL client - Specification](/spec/graphql/#25-client)\n"
  },
  {
    "path": "examples/graphql-client-query-endpoint/graphql_client_query_endpoint.metatags",
    "content": "description: This example demonstrates connecting and interacting with a GraphQL server via the Ballerina GraphQL client.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, query, mutation\n"
  },
  {
    "path": "examples/graphql-client-query-endpoint/graphql_client_query_endpoint.out",
    "content": "$ bal run graphql_client_query_endpoint.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-client-security-basic-auth/graphql_client_security_basic_auth.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// User-defined data types to retrieve data from the service.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    // Defines the GraphQL client to call the APIs secured with basic authentication.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\",\n        auth = {\n            username: \"ldclakmal\",\n            password: \"ldclakmal@123\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    // Defines the GraphQL document to be sent to the GraphQL service.\n    string document = \"{ profile { name, age } }\";\n\n    // Execute the document and retrieve the response from the GraphQL service.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-security-basic-auth/graphql_client_security_basic_auth.md",
    "content": "# GraphQL client - Basic authentication\n\nThe `graphql:Client` can connect to a service that is secured with basic authentication by adding the `Authorization: Basic <token>` header to each request. The username and password for basic authentication can be specified in the `auth` field of the `graphql:ClientConfiguration`. Use this to communicate with the service, which is secured with basic authentication.\n\n::: code graphql_client_security_basic_auth.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [Basic authentication file user store](/learn/by-example/graphql-service-basic-auth-file-user-store) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_security_basic_auth.out :::\n\n## Related links\n- [`graphql:CredentialsConfig` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#CredentialsConfig)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [GraphQL client basic authentication - Specification](/spec/graphql/#821-basic-authentication)\n"
  },
  {
    "path": "examples/graphql-client-security-basic-auth/graphql_client_security_basic_auth.metatags",
    "content": "description: This example demonstrates securing a GraphQL client with basic authentication.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, security, basic auth, security\n"
  },
  {
    "path": "examples/graphql-client-security-basic-auth/graphql_client_security_basic_auth.out",
    "content": "$ bal run graphql_client_security_basic_auth.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-client-security-jwt-authentication/graphql_client_security_jwt_authentication.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// User-defined data types to retrive data from the service.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\n\npublic function main() returns error? {\n    // Defines the GraphQL client to call the JWT Auth secured APIs.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\",\n        auth = {\n            username: \"ballerina\",\n            issuer: \"wso2\",\n            audience: [\"ballerina\", \"ballerina.org\", \"ballerina.io\"],\n            keyId: \"5a0b754-895f-4279-8843-b745e11a57e9\",\n            jwtId: \"JlbmMiOiJBMTI4Q0JDLUhTMjU2In\",\n            customClaims: { \"scp\": \"admin\" },\n            expTime: 3600,\n            signatureConfig: {\n                config: {\n                    keyFile: \"../resource/path/to/private.key\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    // Defines the GraphQL document to be sent to the GraphQL service.\n    string document = \"{ profile { name, age } }\";\n\n    // Execute the document and retrieve the response from the GraphQL service.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-security-jwt-authentication/graphql_client_security_jwt_authentication.md",
    "content": "# GraphQL client - JWT authentication\n\nThe `graphql:Client` can connect to a service that is secured with self-signed JWT by adding the `Authorization: Bearer <token>` header by passing the `graphql:JwtIssuerConfig` to the `auth` configuration of the client. A self-signed JWT is issued before the request is sent.\n\n::: code graphql_client_security_jwt_authentication.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [JWT Auth service](/learn/by-example/graphql-service-jwt-auth/) example.\n\nRun the client program by executing the command below.\n\n::: out graphql_client_security_jwt_authentication.out :::\n\n## Related links\n- [`graphql:JwtIssuerConfig` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#JwtIssuerConfig)\n- [`jwt` module - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n- [GraphQL client self signed JWT authentication - Specification](/spec/graphql/#823-self-signed-jwt-authentication)\n"
  },
  {
    "path": "examples/graphql-client-security-jwt-authentication/graphql_client_security_jwt_authentication.metatags",
    "content": "description: This example demonstrates securing a GraphQL client with self-signed JWT Auth.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, security, auth, jwt auth\n"
  },
  {
    "path": "examples/graphql-client-security-jwt-authentication/graphql_client_security_jwt_authentication.out",
    "content": "$ bal run graphql_client_security_self_signed_jwt_authentication.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-client-security-mutual-ssl/graphql_client_security_mutual_ssl.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// User-defined data types to retrive data from the service.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    // The GraphQL client can be configured to initiate new connections that are secured via mutual SSL.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\",\n        secureSocket = {\n            key: {\n                certFile: \"../resource/path/to/public.crt\",\n                keyFile: \"../resource/path/to/private.key\"\n            },\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    // Defines the GraphQL document to be sent to the GraphQL service.\n    string document = \"{ profile { name, age } }\";\n\n    // Execute the document and retrieve the response from the GraphQL service.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-security-mutual-ssl/graphql_client_security_mutual_ssl.md",
    "content": "# GraphQL client - Mutual SSL\n\nThe `graphql:Client` allows opening up a connection secured with mutual SSL (mTLS), which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `graphql:Client` secured with mutual SSL is created by providing the `secureSocket` configurations, which require the client's public certificate as the `certFile`, the client's private key as the `keyFile`, and the server's certificate as the `cert`. Use this to interact with mTLS-encrypted GraphQL servers.\n\n::: code graphql_client_security_mutual_ssl.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [Mutual SSL](https://ballerina.io/learn/by-example/graphql-service-mutual-ssl) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_security_mutual_ssl.out :::\n\n## Related links\n- [`graphql:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ClientSecureSocket)\n- [GraphQL client mutual SSL - Specification](/spec/graphql/#8322-mutual-ssl)\n"
  },
  {
    "path": "examples/graphql-client-security-mutual-ssl/graphql_client_security_mutual_ssl.metatags",
    "content": "description: This example demonstrates securing a GraphQL client with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, security, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/graphql-client-security-mutual-ssl/graphql_client_security_mutual_ssl.out",
    "content": "$ bal run graphql_client_security_mutual_ssl.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-client-security-oauth2-password-grant-type/graphql_client_security_oauth2_password_grant_type.bal",
    "content": "import ballerina/graphql;\nimport ballerina/oauth2;\nimport ballerina/io;\n\n// User-defined data types to retrive data from the service.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    // Defines the GraphQL client to call the OAuth2-secured APIs.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            username: \"admin\",\n            password: \"admin\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            refreshConfig: oauth2:INFER_REFRESH_CONFIG,\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    // Defines the GraphQL document to be sent to the GraphQL service.\n    string document = \"{ profile { name, age } }\";\n\n    // Execute the document and retrieve the response from the GraphQL service.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-security-oauth2-password-grant-type/graphql_client_security_oauth2_password_grant_type.md",
    "content": "# GraphQL client - OAuth2 password grant type\n\nThe `graphQL:Client` can connect to a service that is secured with the OAuth2 password grant type by adding the `Authorization: Bearer <token>` header to each request. The required configurations for this grant type can be specified in the `auth` field of the `graphql:ClientConfiguration`. Use this grant type when you need to exchange the user's credentials for an access token.\n\n::: code graphql_client_security_oauth2_password_grant_type.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [OAuth2 service](/learn/by-example/graphql-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out graphql_client_security_oauth2_password_grant_type.out :::\n\n## Related links\n- [`graphql:OAuth2PasswordGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#OAuth2PasswordGrantConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [GraphQL client OAuth2 password grant type - Specification](/spec/graphql/#8242-password-grant-type)\n"
  },
  {
    "path": "examples/graphql-client-security-oauth2-password-grant-type/graphql_client_security_oauth2_password_grant_type.metatags",
    "content": "description: This example demonstrates securing a GraphQL client with the OAuth2 password grant type.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, security, auth, oauth2, password grant type\n"
  },
  {
    "path": "examples/graphql-client-security-oauth2-password-grant-type/graphql_client_security_oauth2_password_grant_type.out",
    "content": "$ bal run graphql_client_security_oauth2_password_grant_type.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-client-security-ssl-tls/graphql_client_security_ssl_tls.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\n// User-defined data types to retrive data from the service.\ntype ProfileResponse record {|\n    *graphql:GenericResponseWithErrors;\n    record {|Profile profile;|} data;\n|};\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\npublic function main() returns error? {\n    // Defines the GraphQL client with secure socket configurations.\n    graphql:Client graphqlClient = check new (\"localhost:9090/graphql\",\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    // Defines the GraphQL document to be sent to the GraphQL service.\n    string document = \"{ profile { name, age } }\";\n\n    // Execute the document and retrieve the response from the GraphQL service.\n    ProfileResponse response = check graphqlClient->execute(document);\n    io:println(response.data.profile);\n}\n"
  },
  {
    "path": "examples/graphql-client-security-ssl-tls/graphql_client_security_ssl_tls.md",
    "content": "# GraphQL client - SSL/TLS\n\nThe `graphql:Client` can be configured to communicate through HTTPS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the `graphql:ClientConfiguration`. Use this to secure the communication between the client and the server.\n\n::: code graphql_client_security_ssl_tls.bal :::\n\n## Prerequisites\n- Run the GraphQL service given in the [SSL/TLS](https://ballerina.io/learn/by-example/graphql-returning-record-values) example.\n\nRun the client program by executing the following command.\n\n::: out graphql_client_security_ssl_tls.out :::\n\n## Related links\n- [`graphql:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ClientSecureSocket)\n- [GraphQL client SSL/TLS - Specification](/spec/graphql/#8311-ssltls)\n"
  },
  {
    "path": "examples/graphql-client-security-ssl-tls/graphql_client_security_ssl_tls.metatags",
    "content": "description: This example demonstrates securing a GraphQL client with SSL.\nkeywords: ballerina, ballerina by example, bbe, graphql, client, security, ssl, tls\n"
  },
  {
    "path": "examples/graphql-client-security-ssl-tls/graphql_client_security_ssl_tls.out",
    "content": "$ bal run graphql_client_security_ssl_tls.bal\n{\"name\":\"Walter White\",\"age\":51}\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.1.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -H \"scope: admin\" -d '{ \"query\": \"{ profile { name salary } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"salary\":737000.0}}}\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.2.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -H \"scope: unknown\" -d '{ \"query\": \"{ profile { name salary } }\" }' 'http://localhost:9090/graphql'\n{\"errors\":[{\"message\":\"Permission denied\", \"locations\":[{\"line\":1, \"column\":3}], \"path\":[\"profile\"]}], \"data\":null}\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.bal",
    "content": "import ballerina/graphql;\nimport ballerina/http;\n\n@graphql:ServiceConfig {\n    // Initialization of the `graphqlContext` should be provided to the `contextInit` field.\n    contextInit\n}\nservice /graphql on new graphql:Listener(9090) {\n    // Defines a `Profile` field inside the service.\n    private final Profile profile;\n\n    function init() {\n        // Initializes the `profile` value.\n        self.profile = new (\"Walter White\", 51, 737000.00);\n    }\n\n    // If the context is needed, it should be defined as a parameter of the resolver function.\n    resource function get profile(graphql:Context context) returns Profile|error {\n        // The profile information will be returned only if the scope is `admin` or `user`.\n        check validateScope(context, [\"admin\", \"user\"]);\n        return self.profile;\n    }\n}\n\n// Defines a service class to use as an object in the GraphQL service.\nservice class Profile {\n    private final string name;\n    private final int age;\n    private final float salary;\n\n    function init(string name, int age, float salary) {\n        self.name = name;\n        self.age = age;\n        self.salary = salary;\n    }\n\n    resource function get name() returns string => self.name;\n\n    resource function get age() returns int => self.age;\n\n    // If the context is needed, it should just be specified as a parameter of the resolver method.\n    // Ballerina handles propagating the context, and therefore, it is not required to be passed \n    // as an argument to the `init` method from the parent resolver.\n    resource function get salary(graphql:Context context) returns float|error {\n        // The salary information will be returned only if the scope is `admin`.\n        check validateScope(context, [\"admin\"]);\n        return self.salary;\n    }\n}\n\nisolated function validateScope(graphql:Context context, string[] allowedScopes) returns error? {\n    // Retrieves the `scope` attribute from the context. This will return a `graphql:Error` if\n    // the `scope` is not found in the context.\n    final string scope = check context.get(\"scope\").ensureType();\n    // If the scope doesn't matches any of the allowed scopes return an `error`.\n    if !allowedScopes.some(allowedScope => scope == allowedScope) {\n        // Returns an `error` if the required scope is not found.\n        return error(\"Permission denied\");\n    }\n}\n\nisolated function contextInit(http:RequestContext requestContext, http:Request request) returns graphql:Context|error {\n    // Initialize the `graphql:Context` object.\n    graphql:Context context = new;\n\n    // Retrieves the header named `scope` from the `http:request` and set it to the context with\n    // the `scope` key. If the header does not exist, this will return an `error`, and thereby,\n    // the request will not be processed.\n    context.set(\"scope\", check request.getHeader(\"scope\"));\n\n    // Finally, the context object should be returned.\n    return context;\n}\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.graphql",
    "content": "{\n    profile {\n        name\n        salary\n    }\n}\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.md",
    "content": "# GraphQL service - Context object\n\nThe Ballerina `graphql` module allows defining and using a `graphql:Context` object. The `contextInit` field in the `graphql:ServiceConfig` annotation can be used to pass the context initialization function. If it is not provided, a default, empty `context` object will be created per request. When the `graphql:Context` is needed to be accessed, define it as a parameter of the `resource`/`remote` method. Use the `graphql:Context` to pass meta information between the `resource`/`remote` methods used as GraphQL object fields.\n\n>**Hint:** The `graphql:Context` is defined before the other parameters of a function as a convention.\n\n>**Note:** If the `graphql:Context` is defined as a parameter of a resolver function, it will be accessible inside the resolver. Passing it down is not necessary.\n\n::: code graphql_context.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_context.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_context.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal. First, send the request with the `scope` header value set to `admin`.\n::: out graphql_context.1.client.out :::\n\nNow, send the same document with the `scope` header value set to `unknown`. This will return an error in the `profile` field.\n\n::: out graphql_context.2.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql:Context` object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Context)\n- [GraphQL context - Specification](/spec/graphql/#101-context-object)\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.metatags",
    "content": "description: This example demonstrates defining and using a GraphQL context object. \nkeywords: ballerina, ballerina by example, bbe, graphql, context object\n"
  },
  {
    "path": "examples/graphql-context/graphql_context.server.out",
    "content": "$ bal run graphql_context.bal\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.bal",
    "content": "import ballerina/graphql;\nimport ballerina/graphql.dataloader;\nimport ballerina/http;\nimport ballerina/log;\n\npublic type Book record {|\n    int id;\n    string title;\n|};\n\ntype BookRow record {|\n    readonly int id;\n    string title;\n    int author;\n|};\n\ntype AuthorRow record {|\n    readonly int id;\n    string name;\n|};\n\nfinal readonly & table<AuthorRow> key(id) authorTable = table [\n    {id: 1, name: \"J.K. Rowling\"},\n    {id: 2, name: \"Stephen King\"}\n];\n\nfinal readonly & table<BookRow> key(id) bookTable = table [\n    {id: 1, title: \"Harry Potter and the Sorcerer's Stone\", author: 1},\n    {id: 2, title: \"The Shining\", author: 2},\n    {id: 3, title: \"Harry Potter and the Chamber of Secrets\", author: 1},\n    {id: 4, title: \"It\", author: 2},\n    {id: 5, title: \"Harry Potter and the Prisoner of Azkaban\", author: 1},\n    {id: 6, title: \"The Stand\", author: 2}\n];\n\n// Implement the `batch load` function for the data loader. \n// This function handles fetching data in batches. The primary keys of the data to be loaded\n// will be provided as the values of the `ids` parameter to the batch load function. The expected output\n// of this function is an array of results in which each element in the result array corresponds\n// to a primary key from the `ids` array.\nisolated function bookLoaderFunction(readonly & anydata[] ids) returns BookRow[][]|error {\n    final int[] keys = check ids.ensureType();\n    log:printInfo(\"executing bookLoaderFunction\", keys = keys);\n    // Implement the batching logic.\n    return keys.'map(isolated function(readonly & int key) returns BookRow[] {\n        return bookTable.'filter(book => book.author == key).toArray();\n    });\n}\n\n@graphql:ServiceConfig {\n    contextInit\n}\nservice /graphql on new graphql:Listener(9090) {\n    resource function get authors() returns Author[] {\n        return from AuthorRow authorRow in authorTable\n            select new (authorRow);\n    }\n}\n\npublic isolated distinct service class Author {\n    private final readonly & AuthorRow author;\n\n    isolated function init(readonly & AuthorRow author) {\n        self.author = author;\n    }\n\n    isolated resource function get name() returns string {\n        return self.author.name;\n    }\n\n    // Define a prefetch function.\n    isolated function preBooks(graphql:Context ctx) {\n        // Obtain the dataloader from the context using the unique name.\n        // Providing an invalid name here will lead to a panic.\n        dataloader:DataLoader bookLoader = ctx.getDataLoader(\"bookLoader\");\n        // Add the primary key of the data to be fetched to the dataloader.\n        bookLoader.add(self.author.id);\n    }\n\n    isolated resource function get books(graphql:Context ctx) returns Book[]|error {\n        // Obtain the dataloader from the context using the unique name.\n        dataloader:DataLoader bookLoader = ctx.getDataLoader(\"bookLoader\");\n        // Obtain the data from the dataloader using the primary key of the data.\n        BookRow[] bookrows = check bookLoader.get(self.author.id);\n        return from BookRow bookRow in bookrows\n            select {id: bookRow.id, title: bookRow.title};\n    }\n}\n\nisolated function contextInit(http:RequestContext requestContext, http:Request request) returns graphql:Context {\n    graphql:Context ctx = new;\n    // Register the dataloader with the context using a unique name.\n    // A defult implementation of the dataloader is used here.\n    ctx.registerDataLoader(\"bookLoader\", new dataloader:DefaultDataLoader(bookLoaderFunction));\n    return ctx;\n}\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.client.out",
    "content": "$ curl 'http://localhost:9090/graphql' -H 'Content-Type: application/json' -d '{\"query\": \"{ authors { name books { title } } }\"}'\n{\"data\":{\"authors\":[{\"name\":\"J.K. Rowling\", \"books\":[{\"title\":\"Harry Potter and the Sorcerer's Stone\"}, {\"title\":\"Harry Potter and the Chamber of Secrets\"}, {\"title\":\"Harry Potter and the Prisoner of Azkaban\"}]}, {\"name\":\"Stephen King\", \"books\":[{\"title\":\"The Shining\"}, {\"title\":\"It\"}, {\"title\":\"The Stand\"}]}]}}\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.graphql",
    "content": "{\n  authors {\n    name\n    books {\n      title\n    }\n  }\n}\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.md",
    "content": "# GraphQL service - Dataloader\n\nThe Ballerina GraphQL module provides the capability to batch and cache data fetching from data sources using the `graphql.dataloader` submodule. To leverage this functionality in a GraphQL service, you must register data loaders through the `graphql:Context` object and implement the corresponding prefetch method logic and resolver method logic. \n\nA prefetch method, in the context of Ballerina GraphQL, is a method that is invoked before the actual resolver method. By default, the prefetch method name follows the convention of having the prefix `pre`, followed by the resolver method name. The use of `graphql.dataloader` avoids excessive data fetching, effectively addressing the GraphQL N+1 problem.\n\n::: code graphql_dataloader.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_dataloader.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_dataloader.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_dataloader.client.out :::\n\n## Related links\n- [`garaphql.dataloader` module - API documentation](https://lib.ballerina.io/ballerina/graphql.dataloader/latest)\n- [DataLoader - Specification](/spec/graphql/#106-dataloader)\n- [Utilizing multiple dataloaders in a graphql service](/spec/graphql/#example-utilizing-multiple-dataloaders-in-a-graphql-service)\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.metatags",
    "content": "description: This example demonstrates engaging data loaders with a GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, dataloader, batching, caching\n"
  },
  {
    "path": "examples/graphql-dataloader/graphql_dataloader.server.out",
    "content": "$ bal run graphql_dataloader.bal\ntime = 2023-08-08T13:58:40.479+05:30 level = INFO module = \"\" message = \"executing bookLoaderFunction\" keys = [1,2]\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.1.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name, gender @skip(if: true) } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\"}}}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.1.graphql",
    "content": "{\n    profile {\n        name\n        gender @skip(if: true)\n    }\n}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.2.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name, gender @include(if: true) } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"gender\":\"MALE\"}}}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.2.graphql",
    "content": "{\n    profile {\n        name\n        gender @include(if: true) {\n    }\n}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.3.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ __type(name: \\\"Gender\\\") { name, enumValues(includeDeprecated: true) { name, isDeprecated, deprecationReason } } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"__type\":{\"name\":\"Gender\", \"enumValues\":[{\"name\":\"OTHER\", \"isDeprecated\":false, \"deprecationReason\":null}, {\"name\":\"NON_BINARY\", \"isDeprecated\":true, \"deprecationReason\":\"The `NON_BINARY` is deprecated. Use `OTHER` instead.\"}, {\"name\":\"FEMALE\", \"isDeprecated\":false, \"deprecationReason\":null}, {\"name\":\"MALE\", \"isDeprecated\":false, \"deprecationReason\":null}]}}}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.3.graphql",
    "content": "{\n    __type(name: \"Gender\") {\n        name\n        enumValues {\n            name\n            isDeprecated\n            deprecationReason\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {\n    string name;\n    int age;\n    Gender gender;\n};\n\n// Marks enum value as deprecated.\nenum Gender {\n    MALE,\n    FEMALE,\n    # # Deprecated\n    # The `NON_BINARY` is deprecated. Use `OTHER` instead.\n    @deprecated\n    NON_BINARY,\n    OTHER\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Marks a field as deprecated.\n    # # Deprecated\n    # The `profileInfo` field is deprecated. Use `profile` instead.\n    @deprecated\n    resource function get profileInfo() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 51,\n            gender: MALE\n        };\n    }\n\n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 51,\n            gender: MALE\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.md",
    "content": "# GraphQL service - Directives\n\nThe Ballerina `graphql` module allows using the following set of pre-defined directives.\n\n- `@deprecated` - The `@deprecated` annotation can be used as the `deprecated` directive on the `resource`/`remote` methods and `enum` values. Use this to mark a field or an enum value as deprecated.\n- `@skip(if: Boolean!)` - The `@skip` directive can be used on fields or fragments in GraphQL documents. Use this to skip a field execution based on the given condition.\n- `@include(if: Boolean!)` - The `@include` directive can be used on fields or fragments in GraphQL documents. Use this to include a field execution based on the given condition.\n\n::: code graphql_directives.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_directives.server.out :::\n\nThe requests below demonstrate the usage of the `@skip` and `@include` directives. Invoke the service using the following cURL command to inspect the result.\n\nSend the following document containing the `@skip` directive to test it.\n\n::: code graphql_directives.1.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_directives.1.client.out :::\n\nThen, send the following document containing the `@include` directive.\n\n::: code graphql_directives.2.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_directives.2.client.out :::\n\nFinally, send the following document with an introspection query to check the deprecated enum values.\n\n::: code graphql_directives.3.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_directives.3.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL directives - Specification](/spec/graphql/#5-directives)\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.metatags",
    "content": "description: This example demonstrates using GraphQL directives in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, graphql, directives\n"
  },
  {
    "path": "examples/graphql-directives/graphql_directives.server.out",
    "content": "$ bal run graphql_directives.bal\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.bal",
    "content": "import ballerina/graphql;\n\n// All the types that are used in the GraphQL service can have documentation.\n# Represents a profile.\n# + name - The name of the profile\n# + age - The age of the profile\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Add documentation to reflect them in the generated GraphQL schema.\n    # Returns a profile using the provided ID.\n    # + id - The ID of the profile\n    # + return - The profile with the requested ID\n    resource function get profile(int id) returns Profile? {\n        if id == 1 {\n            return {name: \"Walter White\", age: 52};\n        } else if id == 2 {\n            return {name: \"Jesse Pinkman\", age: 25};\n        }\n        return;\n    }\n}\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ __schema { queryType { fields { name description type { name description fields { name description } } args { name description } } } } }\" }' 'http://localhost:9090/graphql'\n{ \"data\": { \"__schema\": { \"queryType\": { \"fields\": [ { \"name\": \"profile\", \"description\": \"Returns a profile using the provided id.\", \"type\": { \"name\": \"Profile\", \"description\": \"Represents a Profile.\", \"fields\": [ { \"name\": \"name\", \"description\": \"The name of the profile\" }, { \"name\": \"age\", \"description\": \"The age of the profile\" } ] }, \"args\": [ { \"name\": \"id\", \"description\": \"The ID of the profile\" } ] } ] } } } }\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.graphql",
    "content": " {\n    __schema {\n        queryType {\n            fields {\n                name\n                description\n                type {\n                    name\n                    description\n                    fields {\n                        name\n                        description\n                    }\n                }\n                args {\n                    name\n                    description\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.md",
    "content": "# GraphQL service - Documentation\n\nThe Ballerina `graphql` module allows adding documentation to the generated GraphQL schema and its subsequent types. To add documentation, use Ballerina documentation for the `graphql:Service`, `resource`/`remote` methods, types, and `enum`s. The Ballerina documentation will be automatically added as the documentation in the generated GraphQL schema.\n\n::: code graphql_documentation.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_documentation.server.out :::\n\nSend the following document with an introspection query to test how the documentation is added to the schema.\n\n::: code graphql_documentation.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_documentation.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL documentation - Specification](/spec/graphql/#35-documentation)\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.metatags",
    "content": "description: This example demonstrates adding documentation to a GraphQL service and its subsequent types.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, documentation\n"
  },
  {
    "path": "examples/graphql-documentation/graphql_documentation.server.out",
    "content": "$ bal run graphql_documentation.bal\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.bal",
    "content": "import ballerina/graphql;\nimport ballerina/log;\n\n// Defines an interceptor named `LogInterceptor` using a service class. It cannot have any\n// `resource`/`remote` methods except the `execute()` remote method. Other methods are allowed.\nreadonly service class LogInterceptor {\n    // Includes the `graphql:Interceptor` service object from the GraphQL package.\n    *graphql:Interceptor;\n\n    // Implement the `execute()` remote method provided by the `graphql:Interceptor` object.\n    isolated remote function execute(graphql:Context context, graphql:Field 'field)\n    returns anydata|error {\n        // Access the current execution field name using the `graphql:Field` object.\n        string fieldName = 'field.getName();\n\n        // This log statement executes before the resolver execution.\n        log:printInfo(string `Field \"${fieldName}\" execution started!`);\n\n        // The `context.resolve()` function can be used to invoke the next interceptor.\n        var data = context.resolve('field);\n\n        // This log statement executes after the resolver execution.\n        log:printInfo(string `Field \"${fieldName}\" execution completed!`);\n\n        // Returns the execution result of the next interceptor or the resolver.\n        return data;\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n    @graphql:ResourceConfig {\n        // Interceptor instances should be inserted using the `interceptors` field. A single\n        // interceptor or an array of interceptors can be provided. The execution order of the\n        // interceptor will be the order of the interceptors.\n        interceptors: new LogInterceptor()\n    }\n    isolated resource function get name() returns string {\n        log:printInfo(\"Executing the field \\\"name\\\"\");\n        return \"GraphQL Interceptors\";\n    }\n}\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ name }\"}' 'http://localhost:9090/graphql'\n{\"data\":{\"name\":\"GraphQL Interceptors\"}}\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.graphql",
    "content": "{\n    name\n}\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.md",
    "content": "# GraphQL service - Field interceptors\n\nThe GraphQL resolver functions allow adding interceptors for GraphQL requests to execute custom logic. An interceptor can be defined using a `readonly` class that includes the `graphql:Interceptor` type. The interceptor class must implement the `execute` remote method, which is defined in the `graphql:Interceptor` service object type. It can be passed as a single interceptor or an array of interceptors using the `interceptors` field in the `graphql:ResourceConfig` annotation. The provided interceptors will be executed using the _onion principle_. Use the field interceptors to execute custom logic before and after executing a `resource` or a `remote` method that needs to be separated from the business logic.\n\n>**Note:** A resolver can have zero or more interceptors.\n\n::: code graphql_field_interceptors.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_field_interceptors.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_field_interceptors.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_field_interceptors.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql:Interceptor` object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Interceptor)\n- [GraphQL field interceptors - Specification](/spec/graphql/#10332-field-interceptors)\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.metatags",
    "content": "description: This example demonstrates using interceptors on GraphQL remote and resource methods to execute custom logic.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, interceptors, resolver functions\n"
  },
  {
    "path": "examples/graphql-field-interceptors/graphql_field_interceptors.server.out",
    "content": "$ bal run graphql_field_interceptors.bal\n# when executing the query, following statements are logged in the terminal.\ntime = 2023-04-04T10:26:10.795+05:30 level = INFO module = \"\" message = \"Field \\\"name\\\" execution started!\"\ntime = 2023-04-04T10:26:10.813+05:30 level = INFO module = \"\" message = \"Executing the field \\\"name\\\"\"\ntime = 2023-04-04T10:26:10.824+05:30 level = INFO module = \"\" message = \"Field \\\"name\\\" execution completed!\"\n"
  },
  {
    "path": "examples/graphql-file-upload/graphql_file_upload.bal",
    "content": "import ballerina/graphql;\nimport ballerina/io;\n\nservice /fileUpload on new graphql:Listener(9090) {\n\n    // Remote methods can use the `graphql:Upload` type as an input parameter type.\n    remote function fileUpload(graphql:Upload file) returns string|error {\n        // The uploaded file information can be accessed using the `graphql:Upload` type.\n        string fileName = file.fileName;\n        string path = string `./uploads/${fileName}`;\n\n        // Accesses the byte stream of the file from the `graphql:Upload` type. The type of the\n        // `byteStream` field is `stream<byte[], io:Error?>`.\n        stream<byte[], io:Error?> byteStream = file.byteStream;\n\n        // Stores the received file using the ballerina `io` package. If any `error` occurred during\n        // the file write, it can be returned as the resolver function output.\n        check io:fileWriteBlocksFromStream(path, byteStream);\n\n        // Returns the message if the uploading process is successful.\n        return string `File ${fileName} successfully uploaded`;\n    }\n\n    resource function get getUploadedFileNames() returns string[] {\n        return [\"image1.png\", \"image2.png\"];\n    }\n}\n"
  },
  {
    "path": "examples/graphql-file-upload/graphql_file_upload.client.out",
    "content": "$ curl localhost:9090/fileUpload -F operations='{ \"query\": \"mutation($file: Upload!) { fileUpload(file: $file) }\", \"variables\": { \"file\": null } }' -F map='{ \"0\": [\"variables.file\"] }' -F 0=@file1.png\n{\"data\":{\"fileUpload\":\"File file1.png successfully uploaded\"}}\n"
  },
  {
    "path": "examples/graphql-file-upload/graphql_file_upload.md",
    "content": "# GraphQL service - File upload\n\nThe Ballerina `graphql` module allows uploading files to a GraphQL schema. To enable file uploading in a GraphQL service, add the `graphql:Upload` record as an input parameter of a `remote` method inside a `graphql:Service`. The `graphql:Upload` record includes the details of the file that is being uploaded. The GraphQL file upload follows the [_Graphql Multipart Request Spec_](https://github.com/jaydenseric/graphql-multipart-request-spec/tree/master) to upload the files. Use this to create a GraphQL API where users can upload files.\n\n::: code graphql_file_upload.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_file_upload.server.out :::\n\nTo upload a file, send an HTTP multipart request to the GraphQL endpoint using the following cURL command.\n\nThe first part of the request is `operations` field that includes a `JSON-encoded` map. This field is similar to a standard HTTP POST request that being sent to a GraphQL endpoint, except where the variable values related to the file upload should be `null`.\n\nThe second part of the request is the `map` field, which is a `JSON-encoded` map. It contains a mapping between the variables defined in the first part of the request and the files that are mentioned in the next part. The `key` is used to map a file using the key provided in the next part of the request, and the value is mapped to the variable name defined in the previous part. Multiple variables can have the same file, so the value is an array.\n\nNext part contains the unique key for each file and the path for each file. The `key` in this part should be the same key used in the previous part.\n\nFollowing is a complete cURL request to send a multipart request to upload files to the GraphQL service.\n\n::: out graphql_file_upload.client.out :::\n\nThis will create a directory `uploads` where the service is running, and then saves the `file1.png` inside it.\n\n## Related links\n- [`graphql:Upload` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Upload)\n- [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec)\n- [GraphQL file upload - Specification](/spec/graphql/#104-file-upload)\n"
  },
  {
    "path": "examples/graphql-file-upload/graphql_file_upload.metatags",
    "content": "description: This example demonstrates implementing a GraphQL service with the file uploading capability.\nkeywords: ballerina, ballerina by example, bbe, graphql, file upload\n"
  },
  {
    "path": "examples/graphql-file-upload/graphql_file_upload.server.out",
    "content": "$ bal run graphql_file_upload.bal\n"
  },
  {
    "path": "examples/graphql-graphiql/graphql_graphiql.bal",
    "content": "import ballerina/graphql;\n\n// Enables the GraphiQL client with the provided path.\n@graphql:ServiceConfig {\n    graphiql: {\n        enabled: true,\n        // Path is optional, if not provided, it will be dafulted to `/graphiql`.\n        path: \"/testing\"\n    }\n}\nservice /graphql on new graphql:Listener(9090) {\n    \n    resource function get greeting() returns string {\n        return \"Hello, World\";\n    }\n}\n"
  },
  {
    "path": "examples/graphql-graphiql/graphql_graphiql.md",
    "content": "# GraphQL service - GraphiQL client\n\nThe Ballerina `graphql` module includes a built-in GraphiQL client. To enable the GraphiQL client, use the `graphiql` field in the `graphql:ServiceConfig` annotation on a `graphql:Service`. The GraphiQL client can be used to test the GraphQL APIs using the GraphiQL IDE.\n\nThis example shows how to enable the GraphiQL client for a Ballerina GraphQL service.\n\n::: code graphql_graphiql.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_graphiql.out :::\n\nTo access the GraphiQL client, open a browser and access `http://localhost:9090/testing`. Following is a sample screenshot of the GraphiQL client.\n\n![GraphiQL client](/learn/by-example/images/graphiql-client.png \"GraphiQL Client\")\n\n## Related links\n- [`graphql:ServiceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [`graphql:GraphiQL` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Graphiql)\n- [GraphQL GraphiQL client - Specification](/spec/graphql/#91-graphiql-client)\n- [GraphQL GraphiQL client configuration - Specification](/spec/graphql/#715-graphiql-configurations)\n"
  },
  {
    "path": "examples/graphql-graphiql/graphql_graphiql.metatags",
    "content": "description: This example demonstrates enabling the built-in GraphiQL client for a GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, graphiql\n"
  },
  {
    "path": "examples/graphql-graphiql/graphql_graphiql.out",
    "content": "$ bal run graphql_graphiql.bal\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.bal",
    "content": "import ballerina/graphql;\n\n// Service attached to a GraphQL listener exposes a GraphQL service on the provided port.\nservice /graphql on new graphql:Listener(9090) {\n\n    // A resource method with `get` accessor inside a `graphql:Service` represents a field in the\n    // root `Query` type.\n    resource function get greeting() returns string {\n        return \"Hello, World\";\n    }\n}\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ greeting }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"greeting\":\"Hello, World\"}}\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.graphql",
    "content": "{\n    greeting\n}\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.md",
    "content": "# GraphQL service - Hello world\n\nA `graphql:Service` in Ballerina represents a GraphQL schema. Each resource method of the `graphql:Service` with the `get` accessor represents a resolver function in the root `Query` type. The return type of the `resource` method will be the type of field represented by that resource method.\n\n>**Note:** GraphQL queries are expected to be read-only operations that are usually executed against entities such as `Person`, `Profile`, `Address`, etc. Ballerina uses `resource` methods to handle such cases. Therefore, these `resource` methods are usually named using nouns with `get` accessor.\n\n::: code graphql_hello_world.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_hello_world.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_hello_world.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_hello_world.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL `Query` type - Specification](/spec/graphql/#311-the-query-type)\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.metatags",
    "content": "description: This example demonstrates a GraphQL service endpoint written in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, graphql, service endpoint\n"
  },
  {
    "path": "examples/graphql-hello-world/graphql_hello_world.server.out",
    "content": "$ bal run graphql_hello_world.bal\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.bal",
    "content": "import ballerina/graphql;\n\n// This service has multiple resources with hierarchical resource paths. Since all the resource\n// paths starts with `profile`, the root `Query` operation will have a single field named `profile`.\n// The type of this field is `profile!`. (For hierarchical paths, the field name and the\n// type name will be the same). The `profile` type has two fields: `quote` and `name`. The type of\n// the `quote` field is `String!` and the type of the `name` field is `name!`. The `name` type has\n// two fields: `first` and the `last`. Both of the fields are of type `String!`.\nservice /graphql on new graphql:Listener(9090) {\n\n    // This resource method represents the `quote` field under the `profile` object.\n    resource function get profile/quote() returns string {\n        return \"I am the one who knocks!\";\n    }\n\n    // This resource method represents the `first` field under the `name` object type. The `name`\n    // field in the `profile` object is of type `name!`.\n    resource function get profile/name/first() returns string {\n        return \"Walter\";\n    }\n\n    // This resource method represents the `last` field under the `name` object type. The `name`\n    // field in the `profile` object is of type `name!`.\n    resource function get profile/name/last() returns string {\n        return \"White\";\n    }\n}\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { quote name { first } } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"quote\":\"I am the one who knocks!\", \"name\":{\"first\":\"Walter\"}}}}\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.graphql",
    "content": "{\n    profile {\n        quote\n        name {\n            first\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.md",
    "content": "# GraphQL service - Hierarchical resource paths\n\nThe Ballerina `graphql` module allows using hierarchical resource paths in the GraphQL resources. When hierarchical resource paths are used, a GraphQL output object type is created for each intermediate path segment with the same name. Every sub-path under a path segment is added as a field of the created type. Hierarchical paths can be used when there is no need to define the GraphQL output object types explicitly.\n\n::: code graphql_hierarchical_resource_paths.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_hierarchical_resource_paths.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_hierarchical_resource_paths.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_hierarchical_resource_paths.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL hierarchical resource paths - Specification](/spec/graphql/#333-hierarchical-resource-path)\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.metatags",
    "content": "description: This example demonstrates using hierarchical resource paths in GraphQL services.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, hierarchical resource paths\n"
  },
  {
    "path": "examples/graphql-hierarchical-resource-paths/graphql_hierarchical_resource_paths.server.out",
    "content": "$ bal run graphql_hierarchical_resource_paths.bal\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.bal",
    "content": "import ballerina/graphql;\n\n// Defines a `record` type to use as an object in the GraphQL service.\npublic type User readonly & record {|\n    @graphql:ID int id;\n    string name;\n    int age;\n|};\n\n// Defines an in-memory table to store the users.\ntable<User> key(id) users = table [\n    {id: 1, name: \"Walter White\", age: 50},\n    {id: 2, name: \"Jesse Pinkman\", age: 25}\n];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Returns the user for the given `id`.\n    resource function get user(@graphql:ID int id) returns User|error {\n        if users.hasKey(id) {\n            return users.get(id);\n        }\n        return error(string `User with the ${id} not found`);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ user(id: 1){ id name } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"user\":{\"id\":1, \"name\":\"Walter White\"}}}\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.graphql",
    "content": "{\n    user(id: 1) { \n        id\n        name\n    }\n}\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.md",
    "content": "# GraphQL service - ID scalar type\n\nThe Ballerina `graphql` module provides support for the `ID` scalar type in GraphQL. The `ID` type is used to represent unique identifiers within a GraphQL schema. It is a built-in scalar type that can be utilized to define input parameters for GraphQL fields. Applying the `@graphql:ID` annotation to specific fields indicates that they correspond to the GraphQL `ID` scalar type. Consequently, the generated schema will display the field type as `ID` regardless of the actual type of the field.\n\n::: code graphql_id_scalar_type.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_id_scalar_type.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_id_scalar_type.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_id_scalar_type.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL ID scalar type - Specification](/spec/graphql/#415-id)\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.metatags",
    "content": "description: This example demonstrates using the GraphQL ID scalar type as a unique identifier.\nkeywords: ballerina, ballerina by example, bbe, graphql, scalar, id\n"
  },
  {
    "path": "examples/graphql-id-scalar-type/graphql_id_scalar_type.server.out",
    "content": "$ bal run graphql_id_scalar.bal\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerina/graphql;\n\npublic type Profile record {|\n    // Define constraints for the fields\n    @constraint:String {\n        maxLength: 5\n    }\n    string name;\n\n    @constraint:Int {\n        minValue: 0\n    }\n    int age;\n\n    @constraint:Float {\n        maxValue: 3.0\n    }\n    float height;\n|};\n\nservice /graphql on new graphql:Listener(9090) {\n\n    resource function get name(Profile profile) returns string {\n        return profile.name;\n    }\n}\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.client.out",
    "content": "curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"query{ name(profile:{name:\\\"Harry Potter\\\", age: -4, height:6})}\" }' 'http://localhost:9090/graphql'\n{\"errors\":[{\"message\":\"Input validation failed in the field \\\"name\\\": Validation failed for '$.age:minValue','$.height:maxValue','$.name:maxLength' constraint(s).\", \"locations\":[{\"line\":1, \"column\":8}], \"path\":[\"name\"]}], \"data\":null}\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.graphql",
    "content": "{\n  name(profile: {name: \"Harry Potter\", age: -4, height: 6})\n}\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.md",
    "content": "# GraphQL service - Input constraint validation\n\nGraphQL input constraint validation allows you to define and enforce constraints on input arguments. These constraints ensure that the provided input values meet certain criteria before they are processed. The input constraints can be configured using the `@constraint` annotation provided by the Ballerina constraint package. The constraint validation can be enabled or disabled using the `validation` field in the `graphql:ServiceConfig`. By default, the validation field is set to `true`.\n\n::: code graphql_input_constraint_validation.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_input_constraint_validation.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_input_constraint_validation.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_input_constraint_validation.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [Constraint annotation - API documentation](https://lib.ballerina.io/ballerina/constraint/latest#Annotations)\n- [GraphQL constraint config - Specification](/spec/graphql/#718-constraint-configurations)\n- [`constraint` module - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.metatags",
    "content": "description: This example demonstrates defining and enforcing constraints on the input arguments of a GraphQL service. \nkeywords: ballerina, ballerina by example, bbe, graphql, graphql input constraint validation, graphql constraint validation\n"
  },
  {
    "path": "examples/graphql-input-constraint-validation/graphql_input_constraint_validation.server.out",
    "content": "$ bal run graphql_input_constraint_validation.bal\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.bal",
    "content": "import ballerina/graphql;\n\n// Defines the `NewProfile` record type to use as an input object.\ntype NewProfile record {|\n    string name;\n    int age;\n|};\n\n// Defines the `Profile` record type to use as an output object.\ntype Profile readonly & record {|\n    *NewProfile;\n    int id;\n|};\n\n// Defines an in-memory table to store the Profiles.\ntable<Profile> key(id) profiles = table [];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // This remote method (`addProfile`) has an input argument `newProfile` of type `NewProfile!`.\n    // This `NewProfile` record type will be mapped to an `INPUT_OBJECT` type in the generated\n    // GraphQL schema. This method will take the next ID from the table and adds it to the `Profile`\n    // record.\n    remote function addProfile(NewProfile newProfile) returns Profile {\n        Profile profile = {id: profiles.nextKey(), ...newProfile};\n        profiles.add(profile);\n        return profile;\n    }\n\n    // Query resolver to retrive all the profiles. A Ballerina GraphQL resolver can return a table\n    // directly.\n    resource function get profiles() returns table<Profile> {\n        return profiles;\n    }\n}\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"mutation { addProfile(newProfile: { name: \\\"Walter White\\\", age: 50 }) { id } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"addProfile\":{\"id\":0}}}\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.graphql",
    "content": "mutation {\n    addProfile(newProfile: { name: \"Walter White\", age: 50 }) {\n        id\n    }\n}\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.md",
    "content": "# GraphQL service - Input objects\n\nThe Ballerina `graphql` module allows defining GraphQL input objects in a `graphql:Service` using Ballerina records. To define a GraphQL input object, define a record type in Ballerina and use it as an input type in a `resource` or a `remote` method inside a `graphql:Service`. Use GraphQL input objects to define non-primitive, structured input arguments in a GraphQL API.\n\n::: code graphql_input_objects.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_input_objects.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_input_objects.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_input_objects.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL input objects - Specification](/spec/graphql/#452-input-objects)\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.metatags",
    "content": "description: This example demonstrates defining input objects in a GraphQL service using Ballerina records.\nkeywords: ballerina, ballerina by example, bbe, graphql, input objects\n"
  },
  {
    "path": "examples/graphql-input-objects/graphql_input_objects.server.out",
    "content": "$ bal run graphql_input_objects.bal\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.bal",
    "content": "import ballerina/graphql;\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // In the generated schema of this GraphQL service, the `greeting` field of the `Query` type has\n    // an input value `name`, which is of the type `String!`.\n    resource function get greeting(string name) returns string {\n        return string `Hello, ${name}`;\n    }\n}\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ greeting(name: \\\"Walter\\\") }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"greeting\":\"Hello, Walter\"}}\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.graphql",
    "content": "{\n    greeting(name: \"Walter\")\n}\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.md",
    "content": "# GraphQL service - Input types\n\nThe Ballerina `graphql` module allows defining input parameters for the GraphQL fields. To define input parameters, add the desired input parameters in the `resource` and `remote` methods in a `graphql:Service` and the subsequent service types.\n\n::: code graphql_input_types.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_input_types.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_input_types.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_input_types.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL input types - Specification](/spec/graphql/#45-input-types)\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.metatags",
    "content": "description: This example demonstrates defining input parameters for the fields of a GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, input types\n"
  },
  {
    "path": "examples/graphql-input-types/graphql_input_types.server.out",
    "content": "$ bal run graphql_input_types.bal\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.bal",
    "content": "import ballerina/graphql;\nimport ballerina/log;\nimport ballerina/time;\n\n// Configure the behavior of the interceptor.\n@graphql:InterceptorConfig {\n    // Change the scope of the interceptor.\n    global: false\n}\nreadonly service class LogExecutionTime {\n    *graphql:Interceptor;\n\n    isolated remote function execute(graphql:Context context, graphql:Field 'field)\n    returns anydata|error {\n        // Access the current execution field name using the `graphql:Field` object.\n        string fieldName = 'field.getName();\n\n        // Get execution start time.\n        time:Utc startUtc = time:utcNow();\n\n        // Invoke the next interceptor or resolver.\n        var data = context.resolve('field);\n\n        // Get execution end time.\n        time:Utc endUtc = time:utcNow();\n\n        // Calculate the execution time.\n        time:Seconds executionTime = time:utcDiffSeconds(endUtc, startUtc);\n\n        // Log the execution time.\n        log:printInfo(string `execution time of the \"${fieldName}\" field: ${executionTime}s`);\n\n        // Returns the execution result of the next interceptor or the resolver.\n        return data;\n    }\n}\n\n// Define the type Name.\npublic type Name record {|\n    string first;\n    string last;\n|};\n\n@graphql:ServiceConfig {\n    // Insert the service interceptor.\n    interceptors: new LogExecutionTime()\n}\nservice /graphql on new graphql:Listener(9090) {\n\n    isolated resource function get name() returns Name {\n        return {\n            first: \"GraphQL\",\n            last: \"Interceptors\"\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ name { first last } }\"}' 'http://localhost:9090/graphql'\n{\"data\":{\"name\": { \"first\":\"GraphQL\", \"last\":\"Interceptors\"}}\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.graphql",
    "content": "{\n    name {\n        first\n        last\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.md",
    "content": "# GraphQL service - Interceptor configurations\n\nA GraphQL interceptor can be configured to change the behavior of an interceptor. It can be configured via the `graphql:InterceptorConfig` annotation. The `graphql:InterceptorConfig` includes the `global` field, which accepts a boolean value to define the scope of the interceptor.\n\n- If the `global` field is set to `true`, the interceptor will be applied to each field and subfield of the service.\n- If the `global` field is set to `false`, the interceptor will be applied only to the fields of the service, but not to the subfields of the service.\n\n>**Info:** By default, the `global` flag is set to `true`. Use `global: false` to apply the interceptor functionality only to an entry point of the GraphQL service. The scope configuration is applied only to the GraphQL `service interceptors`.\n\n::: code graphql_interceptor_configurations.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_interceptor_configurations.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_interceptor_configurations.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_interceptor_configurations.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql:InterceptorConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#InterceptorConfig)\n- [GraphQL interceptor configuration - Specification](/spec/graphql/#73-interceptor-configuration)\n- [GraphQL interceptors - Specification](/spec/graphql/#103-interceptors)\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.metatags",
    "content": "description: This example demonstrates configuring the behavior of a GraphQL interceptor.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, interceptor\n"
  },
  {
    "path": "examples/graphql-interceptor-configurations/graphql_interceptor_configurations.server.out",
    "content": "$ bal run graphql_interceptor_configurations.bal\n# when executing the query, following statements are logged in the terminal.\ntime = 2023-04-10T12:11:01.263+05:30 level = INFO module = \"\" message = \"execution time of the \\\"name\\\" field: 0.022773s\"\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.bal",
    "content": "import ballerina/graphql;\n\n// Defines the interface `Profile` using a `distinct` `service` object.\ntype Profile distinct service object {\n\n    // Defines the field `name` as a resource method definition.\n    resource function get name() returns string;\n};\n\n// Defines the `Teacher` class implementing the `Profile` interface.\ndistinct service class Teacher {\n    // This denotes that this object implements the `Profile` interface.\n    *Profile;\n\n    private final string name;\n    private final string subject;\n\n    function init(string name, string subject) {\n        self.name = name;\n        self.subject = subject;\n    }\n\n    // Since this object implements the `Profile` interface, this object must implement the fields\n    // of the `Profile` interface.\n    resource function get name() returns string {\n        return self.name;\n    }\n\n    // Adds an additional field `subject` to the `Teacher` class.\n    resource function get subject() returns string {\n        return self.subject;\n    }\n}\n\n// Defines another class implementing the `Profile` interface.\ndistinct service class Student {\n    *Profile;\n\n    private final string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n\n    resource function get name() returns string {\n        return \"Jesse Pinkman\";\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Returns the `Profile[]` type from a GraphQL resolver. The `Profile` type is identified as an\n    // interface.\n    resource function get profiles() returns Profile[] {\n        return [new Teacher(\"Walter White\", \"Chemistry\"), new Student(\"Jesse Pinkman\")];\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profiles { name  ...on Teacher { subject }}}\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profiles\":[{\"name\":\"Walter White\", \"subject\":\"Chemistry\"}, {\"name\":\"Jesse Pinkman\"}]}}\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.graphql",
    "content": "{\n    profiles {\n        name\n        ... on Teacher {\n            subject\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.md",
    "content": "# GraphQL service - Interfaces\n\nThe Ballerina `graphql` module allows defining GraphQL interface types. An interface specifies a set of fields that multiple object types can include. In Ballerina, interfaces are defined using `distinct` `service` objects and the fields of the interfaces are defined as resource method definitions. Objects that are implementing the interfaces must implement the `resource` methods defined in the `service` objects. The Ballerina type inclusion includes the interface type to an object type. Use an interface to return a type that consists of a set of possible types with common fields.\n\n::: code graphql_interfaces.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_interfaces.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_interfaces.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_interfaces.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL interfaces - Specification](/spec/graphql/#46-interfaces)\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.metatags",
    "content": "description: This example demonstrates defining GraphQL interface types.\nkeywords: ballerina, ballerina by example, bbe, graphql, interfaces\n"
  },
  {
    "path": "examples/graphql-interfaces/graphql_interfaces.server.out",
    "content": "$ bal run graphql_interfaces.bal\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.bal",
    "content": "import ballerina/graphql;\n\n// Defines the `Profile` interface using a `distinct` `service` object.\ntype Profile distinct service object {\n\n    // Defines the `name` field as a resource method definition.\n    resource function get name() returns string;\n};\n\n// Defines another `Teacher` interface, which implements the `Profile` interface.\ntype Teacher distinct service object {\n\n    // Denotes that this interface implements the `Profile` interface.\n    *Profile;\n\n    // Adds an additional field to the `Teacher` interface.\n    resource function get school() returns string;\n};\n\n// Defines the `HighSchoolTeacher` class implementing the `Teacher` interface.\ndistinct service class HighSchoolTeacher {\n    // Denotes that this object implements the `Teacher` interface. Since this object implements\n    // the `Teacher` interface and the `Teacher` interface implements the `Profile` interface, this\n    // object must implement the fields from both interfaces.\n    *Teacher;\n\n    private final string name;\n    private final string school;\n    private final string subject;\n\n    function init(string name, string school, string subject) {\n        self.name = name;\n        self.school = school;\n        self.subject = subject;\n    }\n\n    // Implements the `name` field from the `Profile` interface.\n    resource function get name() returns string {\n        return self.name;\n    }\n\n    // Implements the `school` field from the `Teacher` interface.\n    resource function get school() returns string {\n        return self.school;\n    }\n\n    // Adds an additional `subject` field to the `HighSchoolTeacher` class.\n    resource function get subject() returns string {\n        return self.subject;\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Returns the `Profile` type from a GraphQL resolver. The `Profile` type is identified as an\n    // interface.\n    resource function get profile() returns Profile {\n        return new HighSchoolTeacher(\"Walter White\", \"J. P. Wynne\", \"Chemistry\");\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name ...on Teacher { school ...on HighSchoolTeacher { subject }}}}\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"school\":\"J. P. Wynne\", \"subject\":\"Chemistry\"}}}\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.graphql",
    "content": "{\n    profile {\n        name\n        ... on Teacher {\n            school\n            ... on HighSchoolTeacher {\n                subject\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.md",
    "content": "# GraphQL service - Interfaces implementing interfaces\n\nThe Ballerina `graphql` module allows defining GraphQL interface types that can implement other interfaces. A `distinct` `service` object must be used to define an interface. The Ballerina type-inclusion is used to define interfaces that implement other interfaces. This can be used in GraphQL schemas to define higher-order interfaces that share common functionalities in the application logic.\n\n::: code graphql_interfaces_implementing_interfaces.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_interfaces_implementing_interfaces.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_interfaces_implementing_interfaces.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_interfaces_implementing_interfaces.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL interfaces implementing interfaces - Specification](/spec/graphql/#461-interfaces-implementing-interfaces)\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.metatags",
    "content": "description: This example demonstrates defining GraphQL interface types that can implement other interfaces.\nkeywords: ballerina, ballerina by example, bbe, graphql, interfaces, interfaces implementing interfaces\n"
  },
  {
    "path": "examples/graphql-interfaces-implementing-interfaces/graphql_interfaces_implementing_interfaces.server.out",
    "content": "$ bal run graphql_interfaces_implementing_interfaces.bal\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.bal",
    "content": "import ballerina/graphql;\n\n// Defines a `record` type to use as an object in the GraphQL service.\ntype Profile readonly & record {|\n    int id;\n    string name;\n    int age;\n|};\n\n// Defines an in-memory table to store the profiles.\ntable<Profile> key(id) profiles = table [\n        {id: 1, name: \"Walter White\", age: 50},\n        {id: 2, name: \"Jesse Pinkman\", age: 25}\n    ];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // A resource method represents a field in the root `Query` operation.\n    resource function get profile(int id) returns Profile {\n        return profiles.get(id);\n    }\n\n    // A `remote` method represents a field in the root `Mutation` operation. This `remote` method\n    // is used to update the name for the given profile ID and returns the updated `Profile` value.\n    // If the ID is not found, this will return an error.\n    remote function updateName(int id, string name) returns Profile|error {\n        if profiles.hasKey(id) {\n            Profile profile = profiles.remove(id);\n            Profile updatedProfile = {\n                id: profile.id,\n                name: name,\n                age: profile.age\n            };\n            profiles.put(updatedProfile);\n            return updatedProfile;\n        }\n        return error(string `Profile with ID \"${id}\" not found`);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"mutation { updateName(id: 1, name: \\\"Mr. Lambert\\\") { id name } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"updateName\":{\"id\":1, \"name\":\"Mr. Lambert\"}}}\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.graphql",
    "content": "mutation {\n    updateName(id: 1, name: \"Mr. Lambert\") {\n        id\n        name\n    }\n}\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.md",
    "content": "# GraphQL service - Mutations\n\nThe Ballerina `graphql` module allows defining GraphQL `Mutation` operations. A `remote` method inside a `graphql:Service` represents a field in the root `Mutation` object type. Therefore, if a `remote` method is present inside the `graphql:Service`, the auto-generated schema will have the `Mutation` type. Each `remote` method in the service will be added as a field of the `Mutation` type. The field name will be the `remote` method name and the field type will be the return type of the `remote` method. Use the `Mutation` operation when performing any side-effects on the underlying data system.\n\n>**Note:** GraphQL mutations are actions that are expected to mutate the state of the server. Ballerina uses `remote` methods to handle such cases. Therefore, these `remote` methods are usually named using verbs.\n\n::: code graphql_mutations.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_mutations.server.out :::\n\nThen, send the following document to update the name.\n\n::: code graphql_mutations.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_mutations.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL `Mutation` type - Specification](/spec/graphql/#312-the-mutation-type)\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.metatags",
    "content": "description: This example demonstrates defining a GraphQL mutation operation.\nkeywords: ballerina, ballerina by example, bbe, graphql, mutation\n"
  },
  {
    "path": "examples/graphql-mutations/graphql_mutations.server.out",
    "content": "$ bal run graphql_mutations.bal\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.bal",
    "content": "import ballerina/graphql;\n\n// Define the custom record types for the returning data.\npublic type Profile record {|\n    string name;\n    int age;\n    Address address;\n|};\n\npublic type Address record {|\n    string number;\n    string street;\n    string city;\n|};\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // Ballerina GraphQL resolvers can return `record` values. The record will be mapped to a\n    // GraphQL output object type in the generated GraphQL schema with the same name and fields.\n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 51,\n            address: {\n                number: \"308\",\n                street: \"Negra Arroyo Lane\",\n                city: \"Albuquerque\"\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name, address { city } } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"address\":{\"city\":\"Albuquerque\"}}}}\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.graphql",
    "content": "{\n    profile {\n        name,\n        address {\n            city\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.md",
    "content": "# GraphQL service - Record as output object\n\nThe Ballerina `graphql` module allows returning `record` types from the `resource` or `remote` methods of the `graphql:Service`. These `record` types are mapped to GraphQL output object types in the GraphQL schema in which the type name and the field names are mapped one-to-one from Ballerina to GraphQL. Use a `record` type to represent a GraphQL output object type only when all fields of that object type do not have any input arguments or the field resolution does not require any complex logic execution. The `record` type is preferred over the `service` object type in this case as it makes the code more concise.\n\n::: code graphql_returning_record_values.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_returning_record_values.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_returning_record_values.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_returning_record_values.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL record type as object - Specification](/spec/graphql/#421-record-type-as-object)\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.metatags",
    "content": "description: This example demonstrates returning record types from the resource or remote methods of a GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, record types\n"
  },
  {
    "path": "examples/graphql-returning-record-values/graphql_returning_record_values.server.out",
    "content": "$ bal run graphql_returning_record_values.bal\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.bal",
    "content": "import ballerina/graphql;\n\n// Defines a service class to use as an object in the GraphQL service.\nservice class Profile {\n    private final string name;\n    private final int age;\n\n    function init(string name, int age) {\n        self.name = name;\n        self.age = age;\n    }\n\n    // Each resource method becomes a field of the `Profile` type.\n    resource function get name() returns string {\n        return self.name;\n    }\n    resource function get age() returns int {\n        return self.age;\n    }\n    resource function get isAdult() returns boolean {\n        return self.age > 21;\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // This resolver returns a service type, which will be mapped to a GraphQL output object type\n    // named `Profile`. Each resource method in the service type is mapped to a field in the GraphQL\n    // output object type.\n    resource function get profile() returns Profile {\n        return new (\"Walter White\", 51);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name isAdult } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"isAdult\":true}}}\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.graphql",
    "content": "{\n    profile {\n        name\n        isAdult\n    }\n}\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.md",
    "content": "# GraphQL service - Service as output object\n\nThe Ballerina `graphql` module allows returning `service` objects from the `resource` or `remote` methods of the `graphql:Service`. These `service` objects are mapped to GraphQL output object types in the GraphQL schema. Each `resource` method in the returned `service` object becomes a field in the created GraphQL output object type. The `resource` methods in these `service` types can have input parameters. These input parameters are mapped to arguments in the corresponding field. Use a `service` type to represent a GraphQL output object type when a field of that GraphQL output object type has any input arguments. Further, using a `service` type to represent a GraphQL output object type offers the flexibility of organizing complex logic.\n\n::: code graphql_returning_service_objects.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_returning_service_objects.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_returning_service_objects.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_returning_service_objects.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL service type as object - Specification](/spec/graphql/#422-service-type-as-object)\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.metatags",
    "content": "description: This example demonstrates returning service objects from the resource or remote methods of a GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, service objects\n"
  },
  {
    "path": "examples/graphql-returning-service-objects/graphql_returning_service_objects.server.out",
    "content": "$ bal run graphql_returning_service_objects.bal\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-file-user-store/graphql_service_basic_auth_file_user_store.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the file user store can be enabled by setting\n// the `graphql:FileUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@graphql:ServiceConfig {\n    auth: [\n        {\n            fileUserStoreConfig: {},\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-file-user-store/graphql_service_basic_auth_file_user_store.md",
    "content": "# GraphQL service - Basic authentication file user store\n\nThe `graphql:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header against the provided configurations in the `Config.toml` file. The file stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication set the default values to the `fileUserStoreConfig` field and add the `Config.toml` file next to the service file. To enable authorization, set the scopes to the `scopes` field. Both configurations must be given as part of the `@graphql:ServiceConfig` annotation.\n\nA `graphql:Error` response is sent to the client when the authentication or authorization fails. Use this to authenticate and authorize requests based on user stores.\n\n::: code graphql_service_basic_auth_file_user_store.bal :::\n\n>**Info:** As a prerequisite to running the service, populate the `Config.toml` file correctly with the user information as shown below.\n\n::: code Config.toml :::\n\nRun the service by executing the command below.\n\n::: out graphql_service_basic_auth_file_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - Basic authentication](/learn/by-example/graphql-client-security-basic-auth/) example.\n\n## Related links\n- [`graphql:ServiceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [`graphql:FileUserStoreConfigWithScopes` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#FileUserStoreConfigWithScopes)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [GraphQL service basic authentication - file user store - Specification](/spec/graphql/#8111-basic-authentication---file-user-store)\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-file-user-store/graphql_service_basic_auth_file_user_store.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with basic authentication by validating via a file user store.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, auth, basic auth\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-file-user-store/graphql_service_basic_auth_file_user_store.server.out",
    "content": "$ bal run graphql_service_basic_auth_file_user_store.bal\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-ldap-user-store/graphql_service_basic_auth_ldap_user_store.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the LDAP user store can be enabled by setting\n// the `graphql:LdapUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@graphql:ServiceConfig {\n    auth: [\n        {\n            ldapUserStoreConfig: {\n                domainName: \"avix.lk\",\n                connectionUrl: \"ldap://localhost:389\",\n                connectionName: \"cn=admin,dc=avix,dc=lk\",\n                connectionPassword: \"avix123\",\n                userSearchBase: \"ou=Users,dc=avix,dc=lk\",\n                userEntryObjectClass: \"inetOrgPerson\",\n                userNameAttribute: \"uid\",\n                userNameSearchFilter: \"(&(objectClass=inetOrgPerson)(uid=?))\",\n                userNameListFilter: \"(objectClass=inetOrgPerson)\",\n                groupSearchBase: [\"ou=Groups,dc=avix,dc=lk\"],\n                groupEntryObjectClass: \"groupOfNames\",\n                groupNameAttribute: \"cn\",\n                groupNameSearchFilter: \"(&(objectClass=groupOfNames)(cn=?))\",\n                groupNameListFilter: \"(objectClass=groupOfNames)\",\n                membershipAttribute: \"member\",\n                userRolesCacheEnabled: true,\n                connectionPoolingEnabled: false,\n                connectionTimeout: 5,\n                readTimeout: 60\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-ldap-user-store/graphql_service_basic_auth_ldap_user_store.md",
    "content": "# GraphQL service - Basic authentication LDAP user store\n\nThe `graphql:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header with the LDAP server. This server stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the LDAP server configurations to the `ldapUserStoreConfig` field. To enable authorization, set the scopes to the `scopes` field. Both configurations must be given as part of the `@graphql:ServiceConfig` annotation.\n\nA `graphql:Error` response is sent to the client when the authentication or authorization fails. Use this to authenticate and authorize requests based on LDAP user stores.\n\n::: code graphql_service_basic_auth_ldap_user_store.bal :::\n\n## Prerequisites\n- LDAP server should be up and running.\n\nRun the service by executing the command below.\n\n::: out graphql_service_basic_auth_ldap_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - Basic authentication](/learn/by-example/graphql-client-security-basic-auth/) example.\n\n## Related links\n- [`graphql:ServiceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [`graphql:LdapUserStoreConfigWithScopes` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#LdapUserStoreConfigWithScopes)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [GraphQL service basic authentication - LDAP user store - Specification](/spec/graphql/#8112-basic-authentication---ldap-user-store)\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-ldap-user-store/graphql_service_basic_auth_ldap_user_store.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with basic authentication by validating via an LDAP user store.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, auth, basic auth, ldap\n"
  },
  {
    "path": "examples/graphql-service-basic-auth-ldap-user-store/graphql_service_basic_auth_ldap_user_store.server.out",
    "content": "$ bal run graphql_service_basic_auth_ldap_user_store.bal\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.bal",
    "content": "import ballerina/graphql;\n\n// Defines a `record` type to use as an object in the GraphQL service.\ntype User readonly & record {|\n    int id;\n    string name;\n    int age;\n|};\n\n// Defines an in-memory table to store the profiles.\ntable<User> key(id) users = table [\n    {id: 1, name: \"Walter White\", age: 50},\n    {id: 2, name: \"Jesse Pinkman\", age: 25}\n];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    @graphql:ResourceConfig {\n        cacheConfig: {}\n    }\n    resource function get user(int id) returns User|error {\n        if users.hasKey(id) {\n            return users.get(id);\n        }\n        return error(string `User with the ${id} not found`);\n    }\n\n    @graphql:ResourceConfig {\n        cacheConfig: {}\n    }\n    resource function get users() returns User[] {\n        return users.toArray();\n    }\n\n    // Updates a user.\n    remote function updateUser(graphql:Context context, int id, string name,\n                               int age) returns User|error {\n        // `invalidate()` is used to invalidate the cache for the given field.\n        check context.invalidate(\"user\");\n        if users.hasKey(id) {\n            _ = users.remove(id);\n            User user = {id: id, name: name, age: age};\n            users.add(user);\n            return user;\n        }\n        return error(string `User with the ${id} not found`);\n    }\n\n    // Deletes a user.\n    remote function deleteUser(graphql:Context context, int id) returns User|error {\n        // `invalidateAll()` is used to invalidate all the caches in the service.\n        check context.invalidateAll();\n        if users.hasKey(id) {\n            User user = users.remove(id);\n            return user;\n        }\n        return error(string `User with the ${id} not found`);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"mutation updateUser { updateUser(id: 1, name: \\\"Heisenberg\\\", age: 52){id name age} }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"updateUser\":{\"id\":1, \"name\":\"Heisenberg\", \"age\":52}}}\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.graphql",
    "content": "mutation updateUser {\n    updateUser(id: 1, name: \"Heisenberg\" age: 52) {\n        id\n        name\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.md",
    "content": "# GraphQL service - Cache invalidation\n\nThe Ballerina `graphql` module provides functionality for cache invalidation. The `invalidate()` and `invalidateAll()` APIs in the `graphql:Context` can be used to invalidate caches in a `graphql:Service`. The `invalidate()` API supports the cache invalidation of a specific field by providing the full path of the field separated by a full stop(`.`). For example, `invalidate(\"field.subfield.anotherSubfield\")`. Conversely, the `invalidateAll()` API invalidates all caches within the `graphql:Service`.\n\n::: code graphql_service_cache_invalidation.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_cache_invalidation.server.out :::\n\nThen, send the following document to update the user.\n\n::: code graphql_service_cache_invalidation.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_service_cache_invalidation.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL Cache invalidation - Specification](/spec/graphql/#10713-cache-invalidation)\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.metatags",
    "content": "description: This example demonstrates the cache invalidation of a GraphQL service.\nkeywords: ballerina, ballerina by example, graphql, cache, invalidation, server-side caching\n"
  },
  {
    "path": "examples/graphql-service-cache-invalidation/graphql_service_cache_invalidation.server.out",
    "content": "$ bal run graphql_service_cache_invalidation.bal\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.1.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile(id: 1) { name age } }\" }' 'http://localhost:9090/graphql'\n{\"errors\":[{\"message\":\"Error occurred while retrieving age\", \"locations\":[{\"line\":1, \"column\":25}], \"path\":[\"profile\", \"age\"]}], \"data\":{\"profile\":{\"name\":\"Walter White\", \"age\":null}}}\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.1.graphql",
    "content": "{\n    profile(id: 1) {\n        name\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.2.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile(id: 2) { name age } }\" }' 'http://localhost:9090/graphql'\n{\"errors\":[{\"message\":\"Error occurred while retrieving name\", \"locations\":[{\"line\":1, \"column\":20}], \"path\":[\"profile\", \"name\"]}], \"data\":null}\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.2.graphql",
    "content": "{\n    profile(id: 2) {\n        name\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.bal",
    "content": "import ballerina/graphql;\n\nservice class Profile {\n    private final int id;\n    private final string name;\n    private final int age;\n\n    function init(int id, string name, int age) {\n        self.id = id;\n        self.name = name;\n        self.age = age;\n    }\n\n    // This resource method does not have `nil` as a possible return type, which means the\n    // corresponding GraphQL field type is wrapped by the GraphQL `NON_NULL` type. Therefore, if this\n    // method returns an `error`, the `name` value will become `null` and since it is a `NON_NULL`\n    // field, the value will be propagated to the upper level. This means the corresponding\n    // `profile` field value will become `null`.\n    resource function get name() returns string|error {\n        if self.id == 2 {\n            // Returns a mock error.\n            return error(\"Error occurred while retrieving name\");\n        }\n        return self.name;\n    }\n\n    // This resource method has `nil` as a possible return type, which means the corresponding\n    // GraphQL field type is nullable. Therefore, if this field returns an error, the field value\n    // can be `null`.\n    resource function get age() returns int|error? {\n        if self.id == 1 {\n            // Returns a mock error.\n            return error(\"Error occurred while retrieving age\");\n        }\n        return self.age;\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // This resource method returns only the `Profile` type, which means the field type is wrapped\n    // by GraphQL `NON_NULL` type. Therefore, if the `null` value is propagated to the `profile`\n    // field (by returning an `error` from the `name` field in the `Profile` object), it will be\n    // propagated further making the `data` field of the response `null`.\n    resource function get profile(int id) returns Profile {\n        return new (id, \"Walter White\", 50);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.md",
    "content": "# GraphQL service - Error handling\n\nThe Ballerina `graphql` module allows returning `error`s from the `resource` and `remote` methods. When the method returns an `error`, it is added to the GraphQL response under the `errors` field whereas the field value is set to `null` under the `data` field. However, if the return type of the `resource` or the `remote` does not also include `nil`, the GraphQL field type becomes  `NON_NULL`. Therefore, the `null` value is propagated to the upper levels until a `null` value is allowed as the field value. This might cause the whole `data` field in the GraphQL response to be `null` in some cases. To avoid this cascading behavior, the return type should include nil as appropriate.\n\n::: code graphql_service_error_handling.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_error_handling.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_error_handling.1.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_error_handling.1.client.out :::\n\nCheck the response to see how both the `errors` and the `data` fields are present in the response.\n\nNow, send the following document to the GraphQL endpoint.\n\n::: code graphql_service_error_handling.2.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_error_handling.2.client.out :::\n\nCheck the response to see how the `data` field is set to null due to propagating the `null` value because the `name` field and the `profile` field are of `NON_NULL` type.\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL error handling - Specification](/spec/graphql/#62-service-error-handling)\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.metatags",
    "content": "description: This example demonstrates handling errors in a Ballerina GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, error handling\n"
  },
  {
    "path": "examples/graphql-service-error-handling/graphql_service_error_handling.server.out",
    "content": "$ bal run graphql_service_error_handling.bal\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.bal",
    "content": "import ballerina/graphql;\n\n// Defines a `record` type to use as an object in the GraphQL service.\ntype User readonly & record {|\n    int id;\n    string name;\n    int age;\n|};\n\n// Defines an in-memory table to store the users.\ntable<User> key(id) users = table [\n    {id: 1, name: \"Walter White\", age: 50},\n    {id: 2, name: \"Jesse Pinkman\", age: 25}\n];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // The `cacheConfig` in the `graphql:ResourceConfig` annotation is used to\n    // configure the cache for a specific field in the GraphQL service.\n    // (default: {enabled: true, maxAge: 60, maxSize: 120})\n    @graphql:ResourceConfig {\n        cacheConfig: {}\n    }\n    resource function get name(int id) returns string|error {\n        if users.hasKey(id) {\n            return users.get(id).name;\n        }\n        return error(string `User with the ${id} not found`);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ name(id: 1) }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"name\":\"Walter White\"}}\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.graphql",
    "content": "{\n    name(id: 1)\n}\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.md",
    "content": "# GraphQL service - Field-level caching\n\nThe Ballerina `graphql` module provides the capability to enable GraphQL caching, which can be applied at either the field or operation level. To enable caching at the field level, the `cacheConfig` field in the `graphql:ResourceConfig` annotation can be used on a resource method within a `graphql:Service`. By setting this configuration, caching is enabled for the specified GraphQL field, and it can override the cache configurations set at the operation level.\n\n::: code graphql_service_field_level_caching.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_field_level_caching.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_field_level_caching.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_service_field_level_caching.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL Field-level caching - Specification](/spec/graphql/#10712-field-level-caching)\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.metatags",
    "content": "description: This example demonstrates the field-level caching functionality within a GraphQL service.\nkeywords: ballerina, ballerina by example, graphql, cache, server-side caching\n"
  },
  {
    "path": "examples/graphql-service-field-level-caching/graphql_service_field_level_caching.server.out",
    "content": "$ bal run graphql_service_field_level_caching.bal\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.1.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -H \"scope: admin\" -d '{ \"query\": \"{ profile { name age } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":[{\"name\":\"Walter White\", \"age\":50}, {\"name\":\"Jesse Pinkman\", \"age\":25}]}}\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.1.graphql",
    "content": "{\n    profile {\n        name\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.2.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ profile { name address { city } } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":[{\"name\":\"Walter White\", \"address\":{\"city\":\"Albuquerque\"}}, {\"name\":\"Jesse Pinkman\", \"address\":{\"city\":\"Albuquerque\"}}]}}\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.2.graphql",
    "content": "{\n    profile {\n        name\n        address {\n            city\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.bal",
    "content": "import ballerina/graphql;\nimport ballerina/log;\n\n// Define the record types to use as an object in the GraphQL service.\n// The `address` field is optional and can be removed from the result if it is not needed.\ntype Profile readonly & record {|\n    string name;\n    int age;\n    Address address?;\n|};\n\ntype Address record {|\n    int number;\n    string street;\n    string city;\n|};\n\n// Define an in-memory table to store the data.\ntable<Profile> key(name) profileTable = table [\n    {\n        name: \"Walter White\",\n        age: 50,\n        address: {number: 308, street: \"Negra Arroyo Lane\", city: \"Albuquerque\"}\n    },\n    {\n        name: \"Jesse Pinkman\",\n        age: 25,\n        address: {number: 9809, street: \"Margo Street\", city: \"Albuquerque\"}\n    }\n];\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // If the field is needed, it should be defined as the first parameter of the resolver function.\n    resource function get profile(graphql:Field 'field) returns Profile[]|error {\n        // Check whether the `address` field is included in the subfields.\n        if 'field.getSubfieldNames().indexOf(\"address\") !is int {\n            // Add a log message to check the behavior.\n            log:printInfo(\"Address field is not queried\");\n            // If the `address` field is not needed, remove the `address` field from the query.\n            return from Profile profile in profileTable\n                select {\n                    name: profile.name,\n                    age: profile.age\n                };\n        }\n        // Add a log message to check the behavior.\n        log:printInfo(\"Querying all the fields\");\n        return from Profile profile in profileTable\n            select {\n                name: profile.name,\n                age: profile.age,\n                address: profile.address\n            };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.md",
    "content": "# GraphQL service - Field object\n\nThe Ballerina `graphql` module exposes information about a GraphQL field in a document using the `graphql:Field` object. When the `graphql:field` is needed to be accessed, define it as a parameter of the `resource`/`remote` method that represents a GraphQL field. Use the `graphql:Field` object in scenarios where the information about the fields such as subfield names and field type are needed for optimizing the business logic such as query optimizations.\n\n>**Hint:** The `graphql:Field` is defined before the other parameters of a function as a convention.\n\n>**Note:** If the `graphql:Field` is defined as a parameter of a resolver function, it will be accessible inside the resolver. Passing it down is not necessary.\n\n::: code graphql_service_field_object.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_field_object.server.1.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_field_object.1.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_field_object.1.client.out :::\n\nThis will print a log message in the server terminal similar to the following log verifying that the `address` field is not queried.\n\n::: out graphql_service_field_object.server.2.out :::\n\nNow, send the following document of which the `address` field is queried.\n\n::: code graphql_service_field_object.2.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_field_object.2.client.out :::\n\nThis will print a log message in the server terminal similar to the following log verifying that the `address` field is queried.\n\n::: out graphql_service_field_object.server.3.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n\n- [`graphql:Field` object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Field)\n- [GraphQL field - Specification](/spec/graphql/#102-field-object)\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.metatags",
    "content": "description: This example demonstrates accessing information of a GraphQL field in a document.\nkeywords: ballerina, ballerina by example, bbe, graphql, field\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.server.1.out",
    "content": "$ bal run graphql_service_field_object.bal\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.server.2.out",
    "content": "time = 2023-01-27T14:32:47.888+05:30 level = INFO module = \"\" message = \"Address field is not queried\"\n"
  },
  {
    "path": "examples/graphql-service-field-object/graphql_service_field_object.server.3.out",
    "content": "time = 2023-01-27T14:33:47.057+05:30 level = INFO module = \"\" message = \"Querying all the fields\"\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.bal",
    "content": "import ballerina/graphql;\nimport ballerina/log;\n\n// Defines an interceptor named `LogInterceptor` using a service class. It cannot have any\n// `resource`/`remote` methods except the `execute()` remote method. Other methods are allowed.\nreadonly service class LogInterceptor {\n    // Includes the `graphql:Interceptor` service object from the GraphQL package.\n    *graphql:Interceptor;\n\n    // Implement the `execute()` remote method provided by the `graphql:Interceptor` object.\n    // Within the function, the `graphql:Context` and the `graphql:Field` object can be accessed to\n    // get the request and field-related information.\n    isolated remote function execute(graphql:Context context, graphql:Field 'field)\n        returns anydata|error {\n        // Access the current execution field name using the `graphql:Field` object.\n        string fieldName = 'field.getName();\n\n        // This log statement executes before the resolver execution.\n        log:printInfo(string `Field \"${fieldName}\" execution started!`);\n\n        // The `context.resolve()` function can be used to invoke the next interceptor. If all the\n        // interceptors were executed, then it invokes the actual resolver function. The function\n        // returns an `anydata` type value that includes the execution result of the next\n        // interceptor or the actual resolver. To call the `context.resolve()` function, the\n        // `graphql:Field` value should be provided as the argument.\n        var data = context.resolve('field);\n\n        // This log statement executes after the resolver execution.\n        log:printInfo(string `Field \"${fieldName}\" execution completed!`);\n\n        // Returns the execution result of the next interceptor or the resolver.\n        return data;\n    }\n}\n\n@graphql:ServiceConfig {\n    // Interceptor instances should be inserted into the `interceptors` array according to the\n    // desired execution order.\n    interceptors: [new LogInterceptor()]\n}\nservice /graphql on new graphql:Listener(9090) {\n\n    isolated resource function get name() returns string {\n        log:printInfo(\"Executing the field \\\"name\\\"\");\n        return \"GraphQL Interceptors\";\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ name }\"}' 'http://localhost:9090/graphql'\n{\"data\":{\"name\":\"GraphQL Interceptors\"}}\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.graphql",
    "content": "{\n    name\n}\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.md",
    "content": "# GraphQL service - Service interceptors\n\nThe `graphql:Service` allows adding interceptors for GraphQL requests to execute custom logic. An interceptor can be defined using a `readonly` class that includes the `graphql:Interceptor` type. The interceptor class must implement the `execute` remote method, which is defined in the `graphql:Interceptor` service object type. They can be passed as an array using the `interceptors` field in the `graphql:ServiceConfig` annotation. The provided interceptors will be executed using the _onion principle_. Use the interceptors to execute custom logic before and after executing the `resource` and `remote` methods that need to be separated from the business logic.\n\n>**Note:** A service can have zero or more interceptors.\n\n::: code graphql_service_interceptors.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_interceptors.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_interceptors.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_interceptors.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql:Interceptor` object - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#Interceptor)\n- [GraphQL service interceptors - Specification](/spec/graphql/#10331-service-interceptors)\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.metatags",
    "content": "description: This example demonstrates using interceptors on GraphQL services to execute custom logic.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, interceptors\n"
  },
  {
    "path": "examples/graphql-service-interceptors/graphql_service_interceptors.server.out",
    "content": "$ bal run graphql_interceptors.bal\n# when executing the query, following statements are logged in the terminal.\ntime = 2022-11-16T17:09:59.234+05:30 level = INFO module = \"\" message = \"Field \\\"name\\\" execution started!\"\ntime = 2022-11-16T17:09:59.243+05:30 level = INFO module = \"\" message = \"Executing the field \\\"name\\\"\"\ntime = 2022-11-16T17:09:59.247+05:30 level = INFO module = \"\" message = \"Field \\\"name\\\" execution completed!\"\n"
  },
  {
    "path": "examples/graphql-service-jwt-auth/graphql_service_jwt_auth.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with JWT authentication and can be authorized optionally.\n// JWT authentication can be enabled by setting the `graphql:JwtValidatorConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups. Authorization can be\n// enabled by setting the `string|string[]` type configurations for the `scopes` field.\n@graphql:ServiceConfig {\n    auth: [\n        {\n            jwtValidatorConfig: {\n                issuer: \"wso2\",\n                audience: \"ballerina\",\n                signatureConfig: {\n                    certFile: \"../resource/path/to/public.crt\"\n                },\n                scopeKey: \"scp\"\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-jwt-auth/graphql_service_jwt_auth.md",
    "content": "# GraphQL service - JWT authentication\n\nThe `graphql:Service` can be secured with JWT and additionally, scopes can be added to enforce authorization. It validates the JWT sent in the `Authorization` header against the provided configurations. Ballerina uses the concept of scopes for authorization. A resource declared in a service can be bound to one/more scope(s). The scope can be included in the JWT using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service are compared against the scope included in the JWT for at least one match between the two sets.\n\n::: code graphql_service_jwt_auth.bal :::\n\nRun the service by executing the command below.\n\n::: out graphql_service_jwt_auth.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - JWT authentication](/learn/by-example/graphql-client-security-jwt-authentication/) example.\n\n## Related links\n- [`graphql:ServiceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [`graphql:JwtValidatorConfigWithScopes` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#JwtValidatorConfigWithScopes)\n- [`jwt` module - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n- [GraphQL service JWT authentication - Specification](/spec/graphql/#8113-jwt-authentication)\n"
  },
  {
    "path": "examples/graphql-service-jwt-auth/graphql_service_jwt_auth.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with JWT Auth.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, auth, jwt auth\n"
  },
  {
    "path": "examples/graphql-service-jwt-auth/graphql_service_jwt_auth.server.out",
    "content": "$ bal run graphql_service_jwt_auth.bal\n"
  },
  {
    "path": "examples/graphql-service-mutual-ssl/graphql_service_mutual_ssl.bal",
    "content": "import ballerina/graphql;\nimport ballerina/http;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\n// A GraphQL listener can be configured to accept new connections that are secured via mutual SSL.\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        },\n        // Enables mutual SSL.\n        mutualSsl: {\n            verifyClient: http:REQUIRE,\n            cert: \"../resource/path/to/public.crt\"\n        }\n    }\n);\n\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-mutual-ssl/graphql_service_mutual_ssl.md",
    "content": "# GraphQL service - Mutual SSL\n\nThe `graphql:Listener` with mutual SSL (mTLS) enabled in it allows exposing a connection secured with mutual SSL, which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `graphql:Listener` secured with mutual SSL is created by providing the `secureSocket` configurations, which require the word `require` as the `verifyClient`, the server's public certificate as the `certFile`, the server's private key as the `keyFile`, and the client's certificate as the `cert`. Use this to secure the GraphQL connection over mutual SSL.\n\n::: code graphql_service_mutual_ssl.bal :::\n\nRun the service by executing the command below.\n\n::: out graphql_service_mutual_ssl.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - Mutual SSL](/learn/by-example/graphql-client-security-mutual-ssl/) example.\n\n## Related links\n- [`graphql:ListenerConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ListenerConfiguration)\n- [`graphql:ListenerSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ListenerSecureSocket)\n- [GraphQL service mutual SSL - Specification](/spec/graphql/#8312-mutual-ssl)\n"
  },
  {
    "path": "examples/graphql-service-mutual-ssl/graphql_service_mutual_ssl.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/graphql-service-mutual-ssl/graphql_service_mutual_ssl.server.out",
    "content": "$ bal run graphql_service_mutual_ssl.bal\n"
  },
  {
    "path": "examples/graphql-service-oauth2/graphql_service_oauth2.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with OAuth2 and by enforcing authorization optionally.\n// It can be enabled by setting the `graphql:OAuth2IntrospectionConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups. Authorization can be\n// enabled by setting the `string|string[]` type configurations for the `scopes` field.\n@graphql:ServiceConfig {\n    auth: [\n        {\n            oauth2IntrospectionConfig: {\n                url: \"https://localhost:9445/oauth2/introspect\",\n                tokenTypeHint: \"access_token\",\n                scopeKey: \"scp\",\n                clientConfig: {\n                    customHeaders: {\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"},\n                    secureSocket: {\n                        cert: \"../resource/path/to/public.crt\"\n                    }\n                }\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-oauth2/graphql_service_oauth2.md",
    "content": "# GraphQL service - OAuth2\n\nThe `graphql:Service` can be secured with OAuth2 and additionally, scopes can be added to enforce fine-grained authorization. It validates the OAuth2 token sent in the `Authorization` header against the provided configurations. This calls the configured introspection endpoint for validation. Ballerina uses the concept of scopes for authorization. A resource declared in a service can be bound to one/more scope(s). The scope can be included in the introspection response using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service are compared against the scope included in the introspection response for at least one match between the two sets.\n\n::: code graphql_service_oauth2.bal :::\n\n## Prerequisites\n- An STS endpoint should be up and running.\n\nRun the service by executing the command below.\n\n::: out graphql_service_oauth2.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - OAuth2 password grant type](/learn/by-example/graphql-client-security-oauth2-password-grant-type/) example.\n\n## Related links\n- [`graphql:ServiceConfig` annotation - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [`graphql:OAuth2IntrospectionConfigWithScopes` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#OAuth2IntrospectionConfigWithScopes)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [GraphQL service OAuth2 - Specification](/spec/graphql/#8114-oauth2)\n"
  },
  {
    "path": "examples/graphql-service-oauth2/graphql_service_oauth2.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with OAuth2.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, auth, oauth2, introspection\n"
  },
  {
    "path": "examples/graphql-service-oauth2/graphql_service_oauth2.server.out",
    "content": "$ bal run graphql_service_oauth2.bal\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.bal",
    "content": "import ballerina/graphql;\n\n// Defines a `record` type to use as an object in the GraphQL service.\ntype User readonly & record {|\n    int id;\n    string name;\n    int age;\n|};\n\n// Defines an in-memory table to store the users.\ntable<User> key(id) users = table [\n    {id: 1, name: \"Walter White\", age: 50},\n    {id: 2, name: \"Jesse Pinkman\", age: 25}\n];\n\n// The `cacheConfig` in the `graphql:ServiceConfig` annotation is used to \n// configure the cache for the GraphQL service.\n// (default: {enabled: true, maxAge: 60, maxSize: 120})\n@graphql:ServiceConfig {\n    cacheConfig: {}\n}\nservice /graphql on new graphql:Listener(9090) {\n\n    resource function get name(int id) returns string|error {\n        if users.hasKey(id) {\n            return users.get(id).name;\n        }\n        return error(string `User with the ${id} not found`);\n    }\n\n    // The `enabled` field enables/disables the cache for the field. (default: true)\n    @graphql:ResourceConfig {\n        cacheConfig: {\n            enabled: false\n        }\n    }\n    resource function get user(int id) returns User|error {\n        if users.hasKey(id) {\n            return users.get(id);\n        }\n        return error(string `User with the ${id} not found`);\n    }\n\n    // The `maxAge` field sets the maximum age of the cache in seconds. (default: 60)\n    // The `maxSize` field indicates the maximum capacity of the cache table by entries. \n    // (default: 120)\n    @graphql:ResourceConfig {\n        cacheConfig: {\n            maxAge: 600,\n            maxSize: 100\n        }\n    }\n    resource function get age(int id) returns int|error {\n        if users.hasKey(id) {\n            return users.get(id).age;\n        }\n        return error(string `User with the ${id} not found`);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ name(id: 1) }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"name\":\"Walter White\"}}\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.graphql",
    "content": "{\n    name(id: 1)\n}\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.md",
    "content": "# GraphQL service - Operation-level caching\n\nThe Ballerina `graphql` module provides the capability to enable GraphQL caching. GraphQL caching can be enabled at either the field level or the operation level. To enable caching at the operation level, the `cacheConfig` field in the `graphql:ServiceConfig` annotation can be applied to a service. This configuration will enable caching for all resource paths within the `graphql:Service`.\n\n::: code graphql_service_operation_level_caching.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_operation_level_caching.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_operation_level_caching.graphql :::\n\nTo send the document, execute the following cURL command.\n\n::: out graphql_service_operation_level_caching.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL Operation-level caching - Specification](/spec/graphql/#10711-operation-level-caching)\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.metatags",
    "content": "description: This example demonstrates the caching of a GraphQL service at the operation level.\nkeywords: ballerina, ballerina by example, graphql, cache, server-side caching\n"
  },
  {
    "path": "examples/graphql-service-operation-level-caching/graphql_service_operation_level_caching.server.out",
    "content": "$ bal run graphql_service_operation_level_caching.bal\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.1.graphql",
    "content": "query {\n    profile(id: 1) {\n        name\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.2.graphql",
    "content": "query {\n    profile1: profile(id: 1) {\n        name\n        age\n    }\n    profile2: profile(id: 2) {\n        age\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.bal",
    "content": "import ballerina/graphql;\n\n// Defines a service class to use as an object in the GraphQL service.\nservice class Profile {\n    private final string name;\n    private final int age;\n\n    function init(string name, int age) {\n        self.name = name;\n        self.age = age;\n    }\n\n    @graphql:ResourceConfig {\n        complexity: 1\n    }\n    resource function get name() returns string {\n        return self.name;\n    }\n\n    @graphql:ResourceConfig {\n        complexity: 10\n    }\n    resource function get age() returns int {\n        return self.age;\n    }\n\n    // Default complexity will be applied\n    resource function get isAdult() returns boolean {\n        return self.age > 21;\n    }\n}\n\n@graphql:ServiceConfig {\n    // The queryComplexityConfig is used to define the values for the maximum query complexity,\n    // default field complexity, and whether to return an error or warning when the maximum\n    // complexity is exceeded.\n    queryComplexityConfig: {\n        maxComplexity: 50, // Maximum complexity allowed for a query\n        defaultFieldComplexity: 2 // Default complexity for a field\n    }\n}\nservice graphql:Service /graphql on new graphql:Listener(9090) {\n\n    @graphql:ResourceConfig {\n        complexity: 20 // Assigning a complexity value to the `profile` field\n    }\n    resource function get profile(@graphql:ID int id) returns Profile {\n        // Return a dummy profile object\n        return new (\"Walter White\", 50);\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.client.1.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -H \"scope: admin\" -d '{ \"query\": \"{ profile(id: 1) { name age } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"profile\":{\"name\":\"Walter White\", \"age\":50}}}\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.client.2.out",
    "content": "curl -X POST -H \"Content-type: application/json\" -H \"scope: admin\" -d '{ \"query\": \"{ profile1: profile(id: 1) { name age } profile2: profile(id: 2) { name age } }\" }' 'http://localhost:9090/graphql'\n{\"errors\":[{\"message\":\"The operation exceeds the maximum query complexity threshold. Maximum allowed complexity: 50, actual complexity: 62\", \"locations\":[{\"line\":1, \"column\":1}]}]}\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.md",
    "content": "# GraphQL service - Query Complexity\n\nA `graphql:Service` can be secured by limiting the complexity of the operations that can be executed. This can be done by setting a maximum complexity threshold for a given service. The query complexity is calculated by assigning a complexity value to each field in the GraphQL schema. The complexity of an operation is the sum of the complexity values of the fields in the operation.\n\n::: code graphql_service_query_complexity.bal :::\n\nRun the service by executing the command below.\n\n::: out graphql_service_query_complexity.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_query_complexity.1.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_query_complexity.client.1.out :::\n\nAs shown in the output above, the query is executed without any issues. Now, send the following document to the GraphQL endpoint.\n\n::: code graphql_service_query_complexity.2.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_query_complexity.client.2.out :::\n\nThis will result in an error as the query complexity exceeds the maximum complexity threshold set for the service.\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n\n- [`graphql:ServiceConfig` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig)\n- [GraphQL `queryComplexityConfiguration` - Specification](/spec/graphql/#7110-query-complexity-configurations)\n- [GraphQL query complexity validation - Specification](/spec/graphql/#1091-query-complexity-validation)\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.metatags",
    "content": "description: This example demonstrates securing a GraphQL service query complexity analysis.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, query complexity\n"
  },
  {
    "path": "examples/graphql-service-query-complexity/graphql_service_query_complexity.server.out",
    "content": "$ bal run graphql_service_query_complexity.bal\n"
  },
  {
    "path": "examples/graphql-service-ssl-tls/graphql_service_ssl_tls.bal",
    "content": "import ballerina/graphql;\n\ntype Profile record {|\n    string name;\n    int age;\n|};\n\nlistener graphql:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\nservice /graphql on securedEP {\n    \n    resource function get profile() returns Profile {\n        return {\n            name: \"Walter White\",\n            age: 50\n        };\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-ssl-tls/graphql_service_ssl_tls.md",
    "content": "# GraphQL service - SSL/TLS\n\nThe `graphql:Listener` can be configured to communicate through HTTPS by providing a certificate file and a private key file. The certificate and the key can be provided through the `secureSocket` field of the `graphql:ListenerConfiguration`. Use this to secure the communication and data transfer between the server and the client.\n\n::: code graphql_service_ssl_tls.bal :::\n\nRun the service by executing the command below.\n\n::: out graphql_service_ssl_tls.server.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client - SSL/TLS](/learn/by-example/graphql-client-security-ssl-tls/) example.\n\n## Related links\n- [`graphql:ListenerConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ListenerConfiguration)\n- [`graphql:ListenerSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ListenerSecureSocket)\n- [GraphQL service SSL/TLS - Specification](/spec/graphql/#8311-ssltls)\n"
  },
  {
    "path": "examples/graphql-service-ssl-tls/graphql_service_ssl_tls.metatags",
    "content": "description: This example demonstrates securing a GraphQL service with SSL.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, security, ssl, tls\n"
  },
  {
    "path": "examples/graphql-service-ssl-tls/graphql_service_ssl_tls.server.out",
    "content": "$ bal run graphql_service_ssl_tls.bal\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.bal",
    "content": "import ballerina/graphql;\n\n// Defines the `SearchResult` union type that includes the `Profile` and the `Address` types.\ntype SearchResult Profile|Address;\n\n// Defines the `Profile` class to represent the `Profile` object.\ndistinct service class Profile {\n    private final string name;\n    private final int age;\n\n    function init(string name, int age) {\n        self.name = name;\n        self.age = age;\n    }\n\n    // Defines the fields of the `Profile` object.\n    resource function get name() returns string {\n        return self.name;\n    }\n\n    resource function get age() returns int {\n        return self.age;\n    }\n}\n\n// Defines the `Address` class to represent the `Address` object.\ndistinct service class Address {\n    private final int number;\n    private final string street;\n    private final string city;\n\n    function init(int number, string street, string city) {\n        self.number = number;\n        self.street = street;\n        self.city = city;\n    }\n\n    resource function get number() returns int {\n        return self.number;\n    }\n\n    resource function get street() returns string {\n        return self.street;\n    }\n\n    resource function get city() returns string {\n        return self.city;\n    }\n}\n\nservice /graphql on new graphql:Listener(9090) {\n\n    // The return type `SearchResult[]` will allow to return an array consisting both `Profile` and\n    // `Address` values.\n    resource function get search(string keyword) returns SearchResult[] {\n        return [new (\"Walter White\", 50), new (308, \"Negra Arroyo Lane\", \"Albuquerque\")];\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.client.out",
    "content": "$ curl -X POST -H \"Content-type: application/json\" -d '{ \"query\": \"{ search(keyword: \\\"Walter\\\") { ... on Profile { name age } ... on Address { number city } } }\" }' 'http://localhost:9090/graphql'\n{\"data\":{\"search\":[{\"name\":\"Walter White\", \"age\":50}, {\"number\":308, \"city\":\"Albuquerque\"}]}}\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.graphql",
    "content": "{\n    search(keyword: \"Walter\") {\n        ... on Profile {\n            name\n            age\n        }\n        ... on Address {\n            number\n            city\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.md",
    "content": "# GraphQL service - Union Types\n\nThe Ballerina `graphql` module allows defining union types as defined in the GraphQL specification. However, the Ballerina union type that represents a GraphQL union type can only consist of `distinct` `service` classes. This is because the Ballerina type system is structurally-typed, whereas, the GraphQL type system is nominally-typed. The `distinct` types are the only types of Ballerina, which have the similar behavior to nominal types. Use union types when an API requires a type that consists of more than one type.\n\n::: code graphql_service_union_types.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_service_union_types.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service.\n\n::: code graphql_service_union_types.graphql :::\n\nTo send the document, execute the following cURL command in a separate terminal.\n\n::: out graphql_service_union_types.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/).\n\n## Related links\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL union types - Specification](/spec/graphql/#43-unions)\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.metatags",
    "content": "description: This example demonstrates defining union types in a Ballerina GraphQL service.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, union type\n"
  },
  {
    "path": "examples/graphql-service-union-types/graphql_service_union_types.server.out",
    "content": "$ bal run graphql_service_union_types.bal\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.bal",
    "content": "import ballerina/graphql;\nimport ballerina/lang.runtime;\nimport ballerina/random;\n\n@graphql:ServiceConfig {\n    graphiql: {\n        enabled: true\n    }\n}\nservice /graphql on new graphql:Listener(9090) {\n\n    private final readonly & string[] names = [\"Walter White\", \"Jesse Pinkman\", \"Saul Goodman\"];\n\n    resource function get names() returns string[] {\n        return self.names;\n    }\n\n    // A resource method with the `subscribe` accessor represents a field in the root\n    // `Subscription` operation. It must always return a stream. Since the stream is of type\n    // `string`, the resulting field in the generated GraphQL schema will be of type `String!`.\n    resource function subscribe names() returns stream<string, error?> {\n        // Create a `NameGenerator` object.\n        NameGenerator nameGenerator = new (self.names);\n        // Create a stream using the `NameGenerator` object.\n        stream<string, error?> names = new (nameGenerator);\n        return names;\n    }\n}\n\n// Defines a stream implementor that can be used to create a stream of strings. This will pick a random name from\n// the list of names and return it with a delay to demonstrate a stream of values.\nclass NameGenerator {\n    private final string[] names;\n\n    isolated function init(string[] names) {\n        self.names = names;\n    }\n\n    // The `next` method picks a random name from the list and returns it.\n    public isolated function next() returns record {|string value;|}|error? {\n        // Sleep for 1 second to simulate a delay.\n        runtime:sleep(1);\n        int index = check random:createIntInRange(0, self.names.length());\n        return {value: self.names[index]};\n    }\n}\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.client.out",
    "content": "{ \"data\": { \"names\": \"Walter White\" } }\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.graphql",
    "content": "subscription {\n    names\n}\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.md",
    "content": "# GraphQL service - Subscriptions\n\nThe Ballerina `graphql` module allows defining GraphQL `Subscription` operations. A resource method with the `subscribe` accessor inside a GraphQL service represents a field in the root `Subscription` type. Therefore, If a resource method with the `subscribe` accessor is present inside the Ballerina GraphQL service, the auto-generated schema will have a `Subscription` type. Each resource method with a `subscribe` accessor in the service is added as a field of the `Subscription` type. The field name will be the resource method name and the field type will be the constraint type of the `stream` returned from the resource method. Not returning a `stream` type from a resource method having a `subscribe` accessor results in a compilation error. Use a subscription operation to monitor small, incremental changes to large objects or to obtain low-latency, real-time updates.\n\n>**Note:** GraphQL subscriptions are read-only operations that are used to continuously fetch data from a GraphQL server. They are usually executed against information such as `PersonStatus`, `CurrentLocation`, `TotalDonations`, etc. Ballerina uses `resource` methods to handle such cases. Therefore, these `resource` methods are usually named using nouns with `subscription` accessor.\n\n::: code graphql_subscriptions.bal :::\n\nRun the service by executing the following command.\n\n::: out graphql_subscriptions.server.out :::\n\nSend the following document to the GraphQL endpoint to test the service using a GraphQL client that supports subscriptions to test the service.\n\n::: code graphql_subscriptions.graphql :::\n\nIt should result in a response similar to the following.\n\n>**Note:** The response will get updated in real-time and can be different due to the random name generation.\n\n::: out graphql_subscriptions.client.out :::\n\n>**Tip:** You can invoke the above service via the [GraphiQL client](/learn/by-example/graphql-graphiql/).\n\n## Related links\n\n- [`graphql` module - API documentation](https://lib.ballerina.io/ballerina/graphql/latest)\n- [GraphQL `Subscription` type - Specification](/spec/graphql/#313-the-subscription-type)\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.metatags",
    "content": "description: This example demonstrates defining a GraphQL subscription operation.\nkeywords: ballerina, ballerina by example, bbe, graphql, service, subscription\n"
  },
  {
    "path": "examples/graphql-subscriptions/graphql_subscriptions.server.out",
    "content": "$ bal run graphql_subscriptions.bal\n"
  },
  {
    "path": "examples/grpc-client-basic-auth/grpc_client_basic_auth.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the APIs secured with basic authentication.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            username: \"ldclakmal\",\n            password: \"ldclakmal@123\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-basic-auth/grpc_client_basic_auth.md",
    "content": "# gRPC client - Basic authentication\n\nThe `grpc:Client` can connect to a service that is secured with basic authentication by enriching the client metadata with the `Authorization: Basic <token>` header. The username and password for basic authentication can be specified in the `auth` field of the client configuration.\n\n   ::: code grpc_client_basic_auth.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Basic authentication file user store](/learn/by-example/grpc-service-basic-auth-file-user-store/) or [gRPC service - Basic authentication LDAP user store](/learn/by-example/grpc-service-basic-auth-ldap-user-store/) examples.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_basic_auth.out :::\n\n## Related links\n- [`grpc:ClientAuthConfig` type - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ClientAuthConfig)\n- [gRPC client basic authentication - Specification](/spec/grpc/#5115-client---basic-auth)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n"
  },
  {
    "path": "examples/grpc-client-basic-auth/grpc_client_basic_auth.metatags",
    "content": "description: BBE on how to secure gRPC client with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, basic auth\n"
  },
  {
    "path": "examples/grpc-client-basic-auth/grpc_client_basic_auth.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-basic-auth/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-bearer-token-auth/grpc_client_bearer_token_auth.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the APIs secured with bearer token authentication.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            token: \"56ede317-4511-44b4-8579-a08f094ee8c5\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-bearer-token-auth/grpc_client_bearer_token_auth.md",
    "content": "# gRPC client - Bearer token authentication\n\nThe `grpc:Client` can connect to a service that is secured with bearer token authentication by enriching the client metadata with the `Authorization: Bearer <token>` header. The bearer token can be specified in the `auth` field of the client configuration.\n\n   ::: code grpc_client_bearer_token_auth.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run a sample secured service with bearer token authentication.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_bearer_token_auth.out :::\n\n## Related links\n- [`grpc:BearerTokenConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#BearerTokenConfig)\n- [gRPC client bearer token authentication - Specification](/spec/grpc/#5116-client---bearer-token-auth)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n"
  },
  {
    "path": "examples/grpc-client-bearer-token-auth/grpc_client_bearer_token_auth.metatags",
    "content": "description: BBE on how to secure gRPC client with Bearer token auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, jwt auth\n"
  },
  {
    "path": "examples/grpc-client-bearer-token-auth/grpc_client_bearer_token_auth.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-bearer-token-auth/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming.md",
    "content": "# gRPC client - Bidirectional streaming RPC\n\nA `grpc:Client` is created by providing the endpoint URL of a gRPC server. In the bidirectional streaming scenario, once connected, the client and the service send message streams to each other. In this scenario, the two streams operate independently, and therefore, clients and servers can read and write in any order. Use this to send multiple request messages to a server and get multiple response messages back.\n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file `grpc_bidirectional_streaming.proto` and add the service definition below.\n\n   ::: code grpc_bidirectional_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n   ::: code grpc_bidirectional_streaming.out :::\n\nOnce you run the command, the `grpc_bidirectional_streaming_pb.bal` file gets generated inside the `stubs` directory.\n\n## Prerequisites\n- Run the gRPC service given in the [bidirectional streaming RPC service](/learn/by-example/grpc-service-bidirectional-streaming/) example.\n\n## Implement and run the client\n\n1. Create a Ballerina package (e.g., `client`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_bidirectional_streaming_pb.bal` file from the `stubs` directory to the  `client` package.\n\n3. Create a new `grpc_bidirectional_streaming_client.bal` file inside the `client` package and add the client implementation below.\n\n    ::: code grpc_bidirectional_streaming_service_client.bal :::\n\n4. Run the client by executing the command below.\n\n    ::: out grpc_bidirectional_streaming_service_client.out :::\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC client bidirectional streaming - Specification](/spec/grpc/#44-bidirectional-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC streaming client for bidirectional streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, bidirectional streaming, client\n"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming.out",
    "content": "$ bal grpc --input grpc_bidirectional_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming.proto",
    "content": "// This is the service definition for the bidirectional streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice Chat {\n\trpc chat (stream ChatMessage) returns (stream google.protobuf.StringValue);\n}\n\nmessage ChatMessage {\n\tstring name = 1;\n\tstring message = 2;\n}\n"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming_service_client.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Creates a gRPC client to interact with the remote server.\n    ChatClient ep = check new (\"http://localhost:9090\");\n\n    // Executes the RPC call and receives the customized streaming client.\n    ChatStreamingClient streamingClient = check ep->chat();\n    // Reads the server responses in another strand.\n    future<error?> f1 = start readResponse(streamingClient);\n    // Sends multiple messages to the server.\n    ChatMessage[] messages = [\n        {name: \"Sam\", message: \"Hi\"},\n        {name: \"Ann\", message: \"Hey\"},\n        {name: \"John\", message: \"Hello\"}\n    ];\n    foreach ChatMessage msg in messages {\n        check streamingClient->sendChatMessage(msg);\n    }\n    // Once all the messages are sent, the client sends the message to notify the\n    // server about the completion.\n    check streamingClient->complete();\n    // Waits until all server messages are received.\n    check wait f1;\n}\n\nfunction readResponse(ChatStreamingClient streamingClient) returns error? {\n    // Receives the server stream response iteratively.\n    string? result = check streamingClient->receiveString();\n    while !(result is ()) {\n        io:println(result);\n        result = check streamingClient->receiveString();\n    }\n}\n"
  },
  {
    "path": "examples/grpc-client-bidirectional-streaming/grpc_bidirectional_streaming_service_client.out",
    "content": "$ bal run grpc_chat_client\nSam: Hi\nAnn: Hey\nJohn: Hello\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming.md",
    "content": "# gRPC client - Client-side streaming RPC\n\nA `grpc:Client` is created by providing the endpoint URL of a gRPC server. In the client streaming scenario, once connected, the client sends a sequence of messages to the remote service and waits for the server to read them and returns a single response message. Use this to send multiple request messages and get a single response message back.\n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file `grpc_client_streaming.proto` and add service definition below.\n\n   ::: code grpc_client_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_client_streaming.out :::\n\nOnce you run the command, the `grpc_client_streaming_pb.bal` file gets generated inside the stubs directory.\n\n## Prerequisites\n- Run the gRPC service given in the [client streaming RPC service](/learn/by-example/grpc-service-client-streaming/) example.\n\n## Implement and run the client\n\n1. Create a Ballerina package (e.g., `client`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_client_streaming_pb.bal` file from the `stubs` directory to the  `client` package.\n\n3. Create a new `grpc_client_streaming_client.bal` file inside the `client` package and add the client implementation below.\n\n   ::: code grpc_client_streaming_service_client.bal :::\n\n4. Run the client by executing the command below.\n\n   ::: out grpc_client_streaming_service_client.out :::\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC client client-side streaming - Specification](/spec/grpc/#43-client-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC streaming client for client streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, client streaming, client\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming.out",
    "content": "$ bal grpc --input grpc_client_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming.proto",
    "content": "// This is the service definition for the client streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n\trpc lotsOfGreetings (stream google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming_service_client.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Creates a gRPC client to interact with the remote server.\n    HelloWorldClient ep = check new (\"http://localhost:9090\");\n\n    // Executes the client-streaming RPC call and receives the streaming client.\n    LotsOfGreetingsStreamingClient streamingClient = check\n    ep->lotsOfGreetings();\n\n    // Sends multiple messages to the server.\n    string[] requests = [\"Hi Sam\", \"Hey Sam\", \"GM Sam\"];\n    foreach var greet in requests {\n        check streamingClient->sendString(greet);\n    }\n\n    // Once all the messages are sent, the server notifies the caller with a `complete` message.\n    check streamingClient->complete();\n\n    // Receives the server response.\n    string? response = check streamingClient->receiveString();\n    io:println(response);\n}\n"
  },
  {
    "path": "examples/grpc-client-client-streaming/grpc_client_streaming_service_client.out",
    "content": "$ bal run client\nAck\n"
  },
  {
    "path": "examples/grpc-client-headers/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-headers/grpc_simple_with_headers.md",
    "content": "# gRPC client - Send/Receive headers\n\nThe `grpc:Client` allows sending headers and receiving headers to/from a gRPC server. The gRPC - Protobuf CLI tool generates a `Context` record for each Protobuf message type, which contains the Protobuf message and the header map. The header map supports `string`and `string[]` types. A Context record value is created with the required headers and sent using the `context` method of the client (`helloContext()`). The `Contex type of the required record is provided as the target type of the response to receive headers. The `getHeader` and `getHeaders` methods are also available to manipulate the header values.\n\n   ::: code grpc_simple_with_headers_service_client.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with input and output parameter change. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Send/Receive headers](/learn/by-example/grpc-service-headers/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_simple_with_headers_service_client.out :::\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [`grpc` module - Specification](/spec/grpc/)\n"
  },
  {
    "path": "examples/grpc-client-headers/grpc_simple_with_headers.metatags",
    "content": "description: This Ballerina by Example has a gRPC simple client sends and receives messages and headers through a remote call.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, simple, client, headers, metadata\n"
  },
  {
    "path": "examples/grpc-client-headers/grpc_simple_with_headers_service_client.bal",
    "content": "import ballerina/grpc;\nimport ballerina/io;\nimport ballerina/protobuf.types.wrappers;\n\npublic function main() returns error? {\n    // Creates a gRPC client to interact with the remote server.\n    HelloWorldClient ep = check new (\"http://localhost:9090\");\n\n    // Creates the request message with the header value.\n    wrappers:ContextString requestMessage =\n    {content: \"WSO2\", headers: {client_header_key: \"0987654321\"}};\n\n    // Executes a simple remote call.\n    wrappers:ContextString result = check ep->helloContext(requestMessage);\n\n    // Prints the received result.\n    io:println(result.content);\n\n    // Reads the header value in the response message and prints it.\n    io:println(check grpc:getHeader(result.headers, \"server_header_key\"));\n}\n"
  },
  {
    "path": "examples/grpc-client-headers/grpc_simple_with_headers_service_client.out",
    "content": "$ bal run client\nHello WSO2\nResponse Header value\n"
  },
  {
    "path": "examples/grpc-client-mutual-ssl/grpc_client_mutual_ssl.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // The gRPC client can be configured to initiate new connections that are secured via mutual SSL.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        secureSocket = {\n            key: {\n                certFile: \"../resource/path/to/public.crt\",\n                keyFile: \"../resource/path/to/private.key\"\n            },\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-mutual-ssl/grpc_client_mutual_ssl.md",
    "content": "# gRPC client - Mutual SSL\n\nThe `grpc:Client` allows opening up a connection secured with mutual SSL (mTLS), which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `grpc:Client` secured with mutual SSL is created by providing the `secureSocket` configurations, which require the client's public certificate as the `certFile`, the client's private key as the `keyFile`, and the server's certificate as the `cert`. Use this to interact with mTLS-encrypted gRPC servers.\n\n   ::: code grpc_client_mutual_ssl.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Mutual SSL](/learn/by-example/grpc-service-mutual-ssl/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_mutual_ssl.out :::\n\n## Related links\n- [`grpc:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ClientSecureSocket)\n- [gRPC client mutual SSL - Specification](/spec/grpc/#52-ssltls-and-mutual-ssl)\n"
  },
  {
    "path": "examples/grpc-client-mutual-ssl/grpc_client_mutual_ssl.metatags",
    "content": "description: BBE on how to secure gRPC client with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, grpc, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/grpc-client-mutual-ssl/grpc_client_mutual_ssl.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-mutual-ssl/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-client-credentials-grant-type/grpc_client_oauth2_client_credentials_grant_type.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the OAuth2-secured APIs.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-client-credentials-grant-type/grpc_client_oauth2_client_credentials_grant_type.md",
    "content": "# gRPC client - OAuth2 client credentials grant type \n\nThe `grpc:Client` can connect to a service that is secured with the OAuth2 client credentials grant type by enriching client metadata with the `Authorization: Bearer <token>` header. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n   ::: code grpc_client_oauth2_client_credentials_grant_type.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - OAuth2](/learn/by-example/grpc-service-oauth2/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_oauth2_client_credentials_grant_type.out :::\n\n## Related links\n- [`grpc:OAuth2ClientCredentialsGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#OAuth2ClientCredentialsGrantConfig)\n- [gRPC client OAuth2 authentication and authorization - Specification](/spec/grpc/#5118-client---oauth2)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-client-oauth2-client-credentials-grant-type/grpc_client_oauth2_client_credentials_grant_type.metatags",
    "content": "description: BBE on how to secure gRPC client with OAuth2 client credentials grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, oauth2, client credentials grant type\n"
  },
  {
    "path": "examples/grpc-client-oauth2-client-credentials-grant-type/grpc_client_oauth2_client_credentials_grant_type.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-oauth2-client-credentials-grant-type/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-jwt-bearer-grant-type/grpc_client_oauth2_jwt_bearer_grant_type.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the OAuth2-secured APIs.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            assertion: \"eyJhbGciOiJFUzI1NiIsImtpZCI6Ij[...omitted for brevity...]\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-jwt-bearer-grant-type/grpc_client_oauth2_jwt_bearer_grant_type.md",
    "content": "# gRPC client - OAuth2 JWT bearer grant type \n\nThe `grpc:Client` can connect to a service that is secured with the OAuth2 JWT bearer grant type by enriching the client metadata with the `Authorization: Bearer <token>` header. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n   ::: code grpc_client_oauth2_jwt_bearer_grant_type.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - OAuth2](/learn/by-example/grpc-service-oauth2/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_oauth2_jwt_bearer_grant_type.out :::\n\n## Related links\n- [`grpc:OAuth2JwtBearerGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#OAuth2JwtBearerGrantConfig)\n- [gRPC client OAuth2 authentication and authorization - Specification](/spec/grpc/#5118-client---oauth2)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-client-oauth2-jwt-bearer-grant-type/grpc_client_oauth2_jwt_bearer_grant_type.metatags",
    "content": "description: BBE on how to secure gRPC client with OAuth2 JWT bearer grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, oauth2, jwt bearer grant type\n"
  },
  {
    "path": "examples/grpc-client-oauth2-jwt-bearer-grant-type/grpc_client_oauth2_jwt_bearer_grant_type.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-oauth2-jwt-bearer-grant-type/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-password-grant-type/grpc_client_oauth2_password_grant_type.bal",
    "content": "import ballerina/io;\nimport ballerina/oauth2;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the OAuth2-secured APIs.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            username: \"admin\",\n            password: \"admin\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            refreshConfig: oauth2:INFER_REFRESH_CONFIG,\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-password-grant-type/grpc_client_oauth2_password_grant_type.md",
    "content": "# gRPC client - OAuth2 password grant type \n\nThe `grpc:Client` can connect to a service that is secured with the OAuth2 password grant type by enriching the client metadata with the `Authorization: Bearer <token>` header. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this grant type when you need to exchange the user's credentials for an access token.\n\n   ::: code grpc_client_oauth2_password_grant_type.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - OAuth2](/learn/by-example/grpc-service-oauth2/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_oauth2_password_grant_type.out :::\n\n## Related links\n- [`grpc:OAuth2PasswordGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#OAuth2PasswordGrantConfig)\n- [gRPC client OAuth2 authentication and authorization - Specification](/spec/grpc/#5118-client---oauth2)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-client-oauth2-password-grant-type/grpc_client_oauth2_password_grant_type.metatags",
    "content": "description: BBE on how to secure gRPC client with OAuth2 password grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, oauth2, password grant type\n"
  },
  {
    "path": "examples/grpc-client-oauth2-password-grant-type/grpc_client_oauth2_password_grant_type.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-oauth2-password-grant-type/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-refresh-token-grant-type/grpc_client_oauth2_refresh_token_grant_type.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the OAuth2-secured APIs.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            refreshUrl: \"https://localhost:9445/oauth2/token\",\n            refreshToken: \"24f19603-8565-4b5f-a036-88a945e1f272\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-oauth2-refresh-token-grant-type/grpc_client_oauth2_refresh_token_grant_type.md",
    "content": "# gRPC client - OAuth2 refresh token grant type \n\nThe `grpc:Client` can connect to a service that is secured with the OAuth2 refresh token grant type by enriching the client metadata with the `Authorization: Bearer <token>` header. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this to retrieve an access token automatically when it is expired.\n\n   ::: code grpc_client_oauth2_refresh_token_grant_type.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - OAuth2](/learn/by-example/grpc-service-oauth2/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_oauth2_refresh_token_grant_type.out :::\n\n## Related links\n- [`grpc:OAuth2RefreshTokenGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#OAuth2RefreshTokenGrantConfig)\n- [gRPC client OAuth2 authentication and authorization - Specification](/spec/grpc/#5118-client---oauth2)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-client-oauth2-refresh-token-grant-type/grpc_client_oauth2_refresh_token_grant_type.metatags",
    "content": "description: BBE on how to secure gRPC client with OAuth2 refresh token grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, oauth2, refresh token grant type\n"
  },
  {
    "path": "examples/grpc-client-oauth2-refresh-token-grant-type/grpc_client_oauth2_refresh_token_grant_type.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-oauth2-refresh-token-grant-type/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-self-signed-jwt-auth/grpc_client_self_signed_jwt_auth.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Defines the gRPC client to call the JWT-secured APIs.\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        auth = {\n            username: \"ballerina\",\n            issuer: \"wso2\",\n            audience: [\"ballerina\", \"ballerina.org\", \"ballerina.io\"],\n            keyId: \"5a0b754-895f-4279-8843-b745e11a57e9\",\n            jwtId: \"JlbmMiOiJBMTI4Q0JDLUhTMjU2In\",\n            customClaims: { \"scp\": \"admin\" },\n            expTime: 3600,\n            signatureConfig: {\n                config: {\n                    keyFile: \"../resource/path/to/private.key\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-self-signed-jwt-auth/grpc_client_self_signed_jwt_auth.md",
    "content": "# gRPC client - Self signed JWT authentication\n\nThe `grpc:Client` can connect to a service that is secured with self-signed JWT by enriching the client metadata with the `Authorization: Bearer <token>` header by passing the `grpc:JwtIssuerConfig` to the auth configuration of the client. A self-signed JWT is issued before the request is sent.\n\n   ::: code grpc_client_self_signed_jwt_auth.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - JWT authentication](/learn/by-example/grpc-service-jwt-auth/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_self_signed_jwt_auth.out :::\n\n## Related links\n- [`grpc:JwtIssuerConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#JwtIssuerConfig)\n- [gRPC client self signed JWT authentication - Specification](/spec/grpc/#5117-client---self-signed-jwt-auth)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-client-self-signed-jwt-auth/grpc_client_self_signed_jwt_auth.metatags",
    "content": "description: BBE on how to secure gRPC client with self-signed JWT Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, jwt auth\n"
  },
  {
    "path": "examples/grpc-client-self-signed-jwt-auth/grpc_client_self_signed_jwt_auth.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-self-signed-jwt-auth/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming.md",
    "content": "# gRPC client - Server-side streaming RPC\n\nA `grpc:Client` is created by providing the endpoint URL of a gRPC server. In the server streaming scenario, once connected, the client sends a request message to the remote service and gets a message stream as the response, which contains multiple messages. Use this to send a single request message and get multiple response messages back.\n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file `grpc_server_streaming.proto` and add service definition below.\n\n    ::: code grpc_server_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_server_streaming.out :::\n\nOnce you run the command, the `grpc_server_streaming_pb.bal` file gets generated inside the stubs directory.\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Server-side streaming RPC](/learn/by-example/grpc-service-server-streaming/) example.\n\n## Implement and run the client\n\n1. Create a Ballerina package (e.g., `client`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_server_streaming_pb.bal` file from the `stubs` directory to the  `client` package.\n\n3. Create a new `grpc_server_streaming_client.bal` file inside the `client` package and add the client implementation below.\n\n   ::: code grpc_server_streaming_service_client.bal :::\n\n4. Run the client by executing the command below.\n\n   ::: out grpc_server_streaming_service_client.out :::\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC client server-side streaming - Specification](/spec/grpc/#42-server-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC client for server streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, server streaming\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming.out",
    "content": "$ bal grpc --input grpc_server_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming.proto",
    "content": "// This is the service definition for the server streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n\trpc lotsOfReplies (google.protobuf.StringValue) returns (stream google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming_service_client.bal",
    "content": "import ballerina/grpc;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates a gRPC client to interact with the remote server.\n    HelloWorldClient ep = check new (\"http://localhost:9090\");\n\n    // Executes the streaming RPC call and gets the response as a stream.\n    stream<string, grpc:Error?> result = check ep->lotsOfReplies(\"WSO2\");\n    // Iterates through the stream and prints the content.\n    check result.forEach(function(string str) {\n        io:println(str);\n    });\n}\n"
  },
  {
    "path": "examples/grpc-client-server-streaming/grpc_server_streaming_service_client.out",
    "content": "$ bal run client\nHi WSO2\nHey WSO2\nGM WSO2\n"
  },
  {
    "path": "examples/grpc-client-set-deadline/grpc_client_set_deadline.bal",
    "content": "import ballerina/grpc;\nimport ballerina/io;\nimport ballerina/protobuf.types.wrappers;\nimport ballerina/time;\n\npublic function main() returns error? {\n    HelloWorldClient ep = check new (\"http://localhost:9090\");\n    // Get a deadline time by adding 5 seconds to the current time.\n    time:Utc current = time:utcNow();\n    time:Utc deadline = time:utcAddSeconds(current, 5);\n    // Set the deadline time as a header.\n    map<string|string[]> headers = grpc:setDeadline(deadline);\n    wrappers:ContextString|grpc:Error response = ep->helloContext({content: \"WSO2\", headers: headers});\n    if response is grpc:Error {\n        io:println(\"An error has occured : \" + response.message());\n    } else {\n        io:println(response.content);\n    }\n}\n"
  },
  {
    "path": "examples/grpc-client-set-deadline/grpc_client_set_deadline.md",
    "content": "# gRPC client - Set deadline\n\nThe `grpc:Client` allows setting deadlines to specify how long they are willing to wait for an RPC to complete before the RPC is terminated with an error. The deadline is set as a header using the `setDeadline` method. Use this to set an upper limit on how long a call can run.\n\n::: code grpc_client_set_deadline.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Check deadline](/learn/by-example/grpc-service-check-deadline/) example.\n\nRun the client by executing the command below.\n\n::: out grpc_client_set_deadline.out :::\n\n## Related links\n- [`grpc:setDeadline` function - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#setDeadline)\n- [gRPC client set deadline - Specification](/spec/grpc/#61-grpc-deadline)\n"
  },
  {
    "path": "examples/grpc-client-set-deadline/grpc_client_set_deadline.metatags",
    "content": "description: This Ballerina by Example has a gRPC client with a configured deadline.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, client, deadline\n"
  },
  {
    "path": "examples/grpc-client-set-deadline/grpc_client_set_deadline.out",
    "content": "$ bal run client\nAn error has occured : Exceeded the configured deadline\n"
  },
  {
    "path": "examples/grpc-client-set-deadline/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-simple/grpc_client_simple.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Creates a gRPC client to interact with the remote server.\n    HelloWorldClient ep = check new (\"http://localhost:9090\");\n\n    // Executes a simple remote call.\n    string result = check ep->hello(\"WSO2\");\n    // Prints the received result.\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-simple/grpc_client_simple.md",
    "content": "# gRPC client - Simple RPC\n\nA `grpc:Client` is created by providing the endpoint URL of a gRPC server. In the simple RPC scenario, once connected, the client sends a request message to the remote service and waits for the response message. Use this to send a single request message and get a single response message back. \n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file named `grpc_simple.proto` and add the service definition below.\n\n    ::: code grpc_client_simple.proto :::\n\n2. Run the command below from the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_simple.out :::\n\nOnce you run the command, the `grpc_simple_pb.bal` file gets generated inside the `stubs` directory.\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/) example.\n\n## Implement and run the client\n\n1. Create a Ballerina package (e.g., `client`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_simple_pb.bal` file from the `stubs` directory to the  `client` package.\n\n3. Create a new `grpc_simple_client.bal` file inside the `client` package and add the client implementation below.\n\n   ::: code grpc_client_simple.bal :::\n\n4. Run the client by executing the command below.\n\n   ::: out grpc_client_simple.out :::\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC client simple RPC - Specification](/spec/grpc/#41-simple-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-client-simple/grpc_client_simple.metatags",
    "content": "description: This Ballerina by Example has a gRPC client for Simple RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, simple, client\n"
  },
  {
    "path": "examples/grpc-client-simple/grpc_client_simple.out",
    "content": "$ bal run client\nHello WSO2"
  },
  {
    "path": "examples/grpc-client-simple/grpc_client_simple.proto",
    "content": "syntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-client-simple/grpc_simple.out",
    "content": "$ bal grpc --input grpc_simple.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-client-ssl-tls/grpc_client_ssl_tls.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    HelloWorldClient securedEP = check new(\"https://localhost:9090\",\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n\n    string result = check securedEP->hello(\"WSO2\");\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/grpc-client-ssl-tls/grpc_client_ssl_tls.md",
    "content": "# gRPC client - SSL/TLS\n\nThe `grpc:Client` can be configured to communicate through HTTPS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the client configuration. Use this to secure the communication between the client and the server.\n\n   ::: code grpc_client_ssl_tls.bal :::\n\nSetting up the client is the same as setting up the simple RPC client with additional configurations. For information on implementing the client, see [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Prerequisites\n- Run the gRPC service given in the [gRPC service - SSL/TLS](/learn/by-example/grpc-service-ssl-tls/) example.\n\nRun the client by executing the command below.\n\n   ::: out grpc_client_ssl_tls.out :::\n\n## Related links\n- [`grpc:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ClientSecureSocket)\n- [gRPC client SSL/TLS - Specification](/spec/grpc/#52-ssltls-and-mutual-ssl)\n"
  },
  {
    "path": "examples/grpc-client-ssl-tls/grpc_client_ssl_tls.metatags",
    "content": "description: BBE on how to secure gRPC client with SSL.\nkeywords: ballerina, ballerina by example, bbe, grpc, ssl, tls\n"
  },
  {
    "path": "examples/grpc-client-ssl-tls/grpc_client_ssl_tls.out",
    "content": "$ bal run client\nHello WSO2\n"
  },
  {
    "path": "examples/grpc-client-ssl-tls/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_server_reflection.bal",
    "content": "import ballerina/grpc;\n\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090, {reflectionEnabled: true}) {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_server_reflection.md",
    "content": "# gRPC service - Server reflection\n\nThe `grpc:Listener` provides the server reflection capability, which allows dynamic clients such as command-line tools for debugging to discover the protocol used by a gRPC server at run time. Server reflection is enabled by providing the `reflectionEnabled` configuration in the `grpc:ListenerConfiguration`.\n\n   ::: code grpc_server_reflection.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_server_reflection.out :::\n\nAfter running the service, you can use a tool like [`gRPCurl`](https://github.com/fullstorydev/grpcurl), [`Postman`](https://www.postman.com/), [`evans CLI`](https://github.com/ktr0731/evans) to inspect the service.\n\n   ::: out grpc_server_reflection_grpcurl.out :::\n\n## Related links\n- [`grpc:ListenerConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ListenerConfiguration)\n- [gRPC service server reflection - Specification](/spec/grpc/#7-grpc-server-reflection)\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_server_reflection.metatags",
    "content": "description: This Ballerina by Example show how to enabled server reflection for a gRPC service.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, simple, service, reflection\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_server_reflection.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_server_reflection_grpcurl.out",
    "content": "$ ./grpcurl -use-reflection -plaintext localhost:9090 describe\nHelloWorld is a service:\nservice HelloWorld {\n  rpc hello ( .google.protobuf.StringValue ) returns ( .google.protobuf.StringValue );\n}\ngrpc.reflection.v1alpha.ServerReflection is a service:\nservice ServerReflection {\n  rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse );\n}\n"
  },
  {
    "path": "examples/grpc-server-reflection/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-file-user-store/grpc_service_basic_auth_file_user_store.bal",
    "content": "import ballerina/grpc;\n\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the file user store can be enabled by setting\n// the `grpc:FileUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@grpc:ServiceConfig {\n    auth: [\n        {\n            fileUserStoreConfig: {},\n            scopes: [\"admin\"]\n        }\n    ]\n}\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-file-user-store/grpc_service_basic_auth_file_user_store.md",
    "content": "# gRPC service - Basic authentication file user store\n\nThe `grpc:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` metadata against the provided configurations provided in the `Config.toml` file. The file stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the default values for the `fileUserStoreConfig` field and add the `Config.toml` file next to the service file. To engage authorization, set the scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `grpc:UnauthenticatedError` is sent to the client when the authentication fails, and a `grpc:PermissionDeniedError` is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on user stores.\n\n   ::: code grpc_service_basic_auth_file_user_store.bal :::\n\n## Prerequisites\n- Populate the `Config.toml` file correctly with the user information as shown below.\n\n    ::: code Config.toml :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_basic_auth_file_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Basic authentication](/learn/by-example/grpc-client-basic-auth).\n\n## Related links\n- [`grpc:FileUserStoreConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#FileUserStoreConfig)\n- [gRPC service basic authentication file user store - Specification](/spec/grpc/#5111-service---basic-auth---file-user-store)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-file-user-store/grpc_service_basic_auth_file_user_store.metatags",
    "content": "description: BBE on how to secure gRPC service with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, basic auth\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-file-user-store/grpc_service_basic_auth_file_user_store.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-file-user-store/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-ldap-user-store/grpc_service_basic_auth_ldap_user_store.bal",
    "content": "import ballerina/grpc;\n\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the LDAP user store can be enabled by setting\n// the `grpc:LdapUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@grpc:ServiceConfig {\n    auth: [\n        {\n            ldapUserStoreConfig: {\n                domainName: \"avix.lk\",\n                connectionUrl: \"ldap://localhost:389\",\n                connectionName: \"cn=admin,dc=avix,dc=lk\",\n                connectionPassword: \"avix123\",\n                userSearchBase: \"ou=Users,dc=avix,dc=lk\",\n                userEntryObjectClass: \"inetOrgPerson\",\n                userNameAttribute: \"uid\",\n                userNameSearchFilter: \"(&(objectClass=inetOrgPerson)(uid=?))\",\n                userNameListFilter: \"(objectClass=inetOrgPerson)\",\n                groupSearchBase: [\"ou=Groups,dc=avix,dc=lk\"],\n                groupEntryObjectClass: \"groupOfNames\",\n                groupNameAttribute: \"cn\",\n                groupNameSearchFilter: \"(&(objectClass=groupOfNames)(cn=?))\",\n                groupNameListFilter: \"(objectClass=groupOfNames)\",\n                membershipAttribute: \"member\",\n                userRolesCacheEnabled: true,\n                connectionPoolingEnabled: false,\n                connectionTimeout: 5,\n                readTimeout: 60\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-ldap-user-store/grpc_service_basic_auth_ldap_user_store.md",
    "content": "# gRPC service - Basic authentication LDAP user store\n\nThe `grpc:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` metadata with the LDAP server. This server stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the LDAP-related configurations to the `ldapUserStoreConfig` field. To engage authorization, set the scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `grpc:UnauthenticatedError` is sent to the client when the authentication fails, and a `grpc:PermissionDeniedError` is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on LDAP user stores.\n\n   ::: code grpc_service_basic_auth_ldap_user_store.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\n## Prerequisites\n- Run the LDAP server.\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_basic_auth_ldap_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Basic authentication](/learn/by-example/grpc-client-basic-auth).\n\n## Related links\n- [`grpc:LdapUserStoreConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#LdapUserStoreConfig)\n- [gRPC service basic authentication LDAP user store - Specification](/spec/grpc/#5112-service---basic-auth---ldap-user-store)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-ldap-user-store/grpc_service_basic_auth_ldap_user_store.metatags",
    "content": "description: BBE on how to secure gRPC service with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, basic auth\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-ldap-user-store/grpc_service_basic_auth_ldap_user_store.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-basic-auth-ldap-user-store/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming.md",
    "content": "# gRPC service - Bidirectional streaming RPC\n\nA `grpc:Listener` is created by providing the port and a `grpc:Service` is attached to it. In the bidirectional streaming scenario, once a client is connected to the service, the client and the service send message streams to each other. In this scenario, the two streams operate independently, and therefore, the clients and servers can read and write in any order. Use this to receive multiple request messages from a client and send multiple response messages back.\n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file `grpc_bidirectional_streaming.proto` and add the service definition below.\n\n    ::: code grpc_bidirectional_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n    ::: code grpc_bidirectional_streaming.out :::\n\nOnce you run the command, the `grpc_bidirectional_streaming_pb.bal` file gets generated inside the `stubs` directory. \n\n## Implement and run the service\n\n1. Create a Ballerina package (e.g., `service`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_bidirectional_streaming_pb.bal` file from the `stubs` directory to the  `service` package.\n\n3. Create a new `grpc_bidirectional_streaming_service.bal` file inside the `service` package and add the service implementation below.\n\n    ::: code grpc_bidirectional_streaming_service.bal :::\n\n4. Run the service by executing the command below.\n\n    ::: out grpc_bidirectional_streaming_service.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Bidirectional streaming RPC](/learn/by-example/grpc-client-bidirectional-streaming/).\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC service bidirectional streaming - Specification](/spec/grpc/#44-bidirectional-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC streaming service for bidirectional streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, bidirectional streaming, service\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming.out",
    "content": "$ bal grpc --input grpc_bidirectional_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming.proto",
    "content": "// This is the service definition for the bidirectional streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice Chat {\n\trpc chat (stream ChatMessage) returns (stream google.protobuf.StringValue);\n}\n\nmessage ChatMessage {\n\tstring name = 1;\n\tstring message = 2;\n}\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming_service.bal",
    "content": "import ballerina/grpc;\nimport ballerina/log;\n\n@grpc:Descriptor {\n    value: GRPC_BIDIRECTIONAL_STREAMING_DESC\n}\nservice \"Chat\" on new grpc:Listener(9090) {\n\n    // The generated code of the Ballerina gRPC command does not contain ChatStringCaller.\n    // To show the usage of a caller, this RPC call uses a caller to send messages to the client.\n    remote function chat(ChatStringCaller caller,\n                    stream<ChatMessage, error?> clientStream) {\n        // Reads and processes each message in the client stream.\n        do {\n            _ = check from ChatMessage chatMsg in clientStream\n                do {\n                    checkpanic caller->sendString(string `${chatMsg.name}: ${chatMsg.message}`);\n                };\n            // Once the client sends a notification to indicate the end of the stream,\n            // '()' is returned by the stream.\n            check caller->complete();\n        } on fail error err {\n            log:printError(\"The connection is closed with an error.\", 'error = err);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/grpc_bidirectional_streaming_service.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-bidirectional-streaming/tests/grpc_bidirectional_streaming_test.bal",
    "content": "// This is the Ballerina test for bidirectional streaming scenario.\nimport ballerina/test;\n//Client endpoint configuration.\nChatClient chatEp = check new(\"http://localhost:9090\");\n@test:Config\nfunction testBidiStreamingService() returns error? {\n        // Executes the RPC call and receives the customized streaming client.\n        ChatStreamingClient streamingClient = check chatEp->chat();\n        // Reads the server responses in another strand.\n        future<error?> f1 = start readResponseTest(streamingClient);\n        // Sends multiple messages to the server.\n        ChatMessage[] messages = [\n            {name: \"Sam\", message: \"Hi\"},\n            {name: \"Ann\", message: \"Hey\"},\n            {name: \"John\", message: \"Hello\"}\n        ];\n        foreach ChatMessage msg in messages {\n            check streamingClient->sendChatMessage(msg);\n        }\n        // Once all the messages are sent, the client sends the message to notify the server about the completion.\n        check streamingClient->complete();\n        // Waits until all server messages are received.\n        check wait f1;\n}\n\nfunction readResponseTest(ChatStreamingClient streamingClient) returns error? {\n    string expectedMsg1 = \"Sam: Hi\";\n    string expectedMsg2 = \"Ann: Hey\";\n    string expectedMsg3 = \"John: Hello\";\n    // Receives the server stream response iteratively.\n    string? result = check streamingClient->receiveString();\n    while !(result is ()) {\n        test:assertTrue(result == expectedMsg1 || result == expectedMsg2 || result == expectedMsg3);\n        result = check streamingClient->receiveString();\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-check-deadline/grpc_service_check_deadline.bal",
    "content": "import ballerina/grpc;\nimport ballerina/protobuf.types.wrappers;\n\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090) {\n\n    remote function hello(wrappers:ContextString request) returns string|error {\n        // Check if the deadline has been exceeded and response accordingly.\n        boolean isCancelled = check grpc:isCancelled(request.headers);\n        if isCancelled {\n            return error grpc:DeadlineExceededError(\"Exceeded the configured deadline\");\n        }\n        return \"Hello\";\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-check-deadline/grpc_service_check_deadline.md",
    "content": "# gRPC service - Check deadline\n\nThe `grpc:Service` allows to check whether a deadline has been exceeded in a client connection. Deadlines allow gRPC clients to specify how long they are willing to wait for an RPC to complete. The deadline is checked in the service using the `isCancelled` method  and a `grpc:DeadlineExceededError` is returned if it is exceeded. Use this to check the upper limit on how long a call can run.\n\n::: code grpc_service_check_deadline.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n::: out grpc_service_check_deadline.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Set deadline](/learn/by-example/grpc-client-set-deadline/).\n\n## Related links\n- [`grpc:isCancelled` function - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#isCancelled)\n- [gRPC service check deadline - Specification](/spec/grpc/#61-grpc-deadline)\n"
  },
  {
    "path": "examples/grpc-service-check-deadline/grpc_service_check_deadline.metatags",
    "content": "description: This Ballerina by Example has a gRPC service with a deadline check.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, service, deadline\n"
  },
  {
    "path": "examples/grpc-service-check-deadline/grpc_service_check_deadline.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-check-deadline/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming.md",
    "content": "# gRPC service - Client-side streaming RPC\n\nA `grpc:Listener` is created by providing the port and a `grpc:Service` is attached to it. In the client streaming scenario, once a client is connected to the service, the client sends a message stream to the server. Once the client completes the request message, the server sends the response message to complete the call. Use this to receive multiple request messages from a client and send a single response message back.\n\n## Generate the service definition\n\n1. Create new Protocol Buffers definition file `grpc_client_streaming.proto` and add service definition below.\n\n   ::: code grpc_client_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_client_streaming.out :::\n\nOnce you run the command, the `grpc_client_streaming_pb.bal` file gets generated inside the stubs directory.\n\n## Implement and run the service\n\n1. Create a Ballerina package (e.g., `service`).\n   \n2. Copy the generated `grpc_client_streaming_pb.bal` file from the `stubs` directory to the  `service` package.\n\n3. Create a new `grpc_client_streaming.bal` file inside the `service` package and add the service implementation below.\n\n   ::: code grpc_client_streaming_service.bal :::\n   \n4. Run the service by executing the command below.\n\n   ::: out grpc_client_streaming_service.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Client-side streaming RPC](/learn/by-example/grpc-client-client-streaming/).\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC service client-side streaming - Specification](/spec/grpc/#43-client-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC service for client streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, client streaming, service\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming.out",
    "content": "$ bal grpc --input grpc_client_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming.proto",
    "content": "// This is the service definition for the client streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n\trpc lotsOfGreetings (stream google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming_service.bal",
    "content": "import ballerina/grpc;\nimport ballerina/log;\n\n@grpc:Descriptor {\n    value: GRPC_CLIENT_STREAMING_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090) {\n\n    remote function lotsOfGreetings(stream<string, error?> clientStream)\n                        returns string {\n        // Reads and processes each message in the client stream.\n        error? result = from string name in clientStream\n            do {\n                log:printInfo(string `Greet received: ${name}`);\n            };\n\n        if (result is error) {\n            // Client closes the connection with an error.\n            log:printError(\"The connection is closed with an error.\", 'error = result);\n        }\n        // Once the client sends a notification to indicate the end of the stream,\n        // '()' is returned by the stream.\n        return \"Ack\";\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/grpc_client_streaming_service.out",
    "content": "$ bal run service\ntime = 2022-11-17T17:10:14.503+05:30 level = INFO module = foo/test message = \"Greet received: Hi Sam\"\ntime = 2022-11-17T17:10:14.512+05:30 level = INFO module = foo/test message = \"Greet received: Hey Sam\"\ntime = 2022-11-17T17:10:14.513+05:30 level = INFO module = foo/test message = \"Greet received: GM Sam\"\n"
  },
  {
    "path": "examples/grpc-service-client-streaming/tests/grpc_client_streaming_test.bal",
    "content": "// This is the Ballerina test for the client streaming scenario.\nimport ballerina/test;\n\n// Client endpoint configuration.\nHelloWorldClient helloWorldEp = check new(\"http://localhost:9090\");\n\n@test:Config\nfunction testClientStreamingService() returns error? {\n    // Executes the client-streaming RPC call and receives the streaming client.\n    LotsOfGreetingsStreamingClient streamingClient = check helloWorldEp->lotsOfGreetings();\n    string[] requests = [\"Hi Sam\", \"Hey Sam\", \"GM Sam\"];\n\n    // Sends multiple messages to the server.\n    string[] greets = [\"Hi\", \"Hey\", \"GM\"];\n    foreach var greet in requests {\n        check streamingClient->sendString(greet);\n    }\n\n    // Once all the messages are sent, the server notifies the caller with a `complete` message.\n    check streamingClient->complete();\n\n    string? response = check streamingClient->receiveString();\n    string expected = \"Ack\";\n    test:assertEquals(response is () ? \"\" : response, expected);\n}\n"
  },
  {
    "path": "examples/grpc-service-headers/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-headers/grpc_simple_with_headers.md",
    "content": "# gRPC service - Send/Receive headers\n\nThe `grpc:Service` allows receiving headers and sending headers from/to a gRPC server. The gRPC - Protobuf CLI tool generates a `Context` record for each Protobuf message type, which contains the Protobuf message and the header map. The header map supports `string`and `string[]` types. The `Context` type of the required record is provided as the target type of the remote method to receive the headers. A `Context` record value is created with the required headers and is returned to the client. The `getHeader` and `getHeaders` methods are also available to manipulate the header values.\n\n   ::: code grpc_simple_with_headers_service.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with input and output parameter change. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_simple_with_headers_service.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Send/Receive headers](/learn/by-example/grpc-client-headers/).\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [`grpc` module - Specification](/spec/grpc/)\n"
  },
  {
    "path": "examples/grpc-service-headers/grpc_simple_with_headers.metatags",
    "content": "description: This Ballerina by Example has a gRPC simple service sends and receives messages and headers through a remote call.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, simple, service, headers, metadata\n"
  },
  {
    "path": "examples/grpc-service-headers/grpc_simple_with_headers_service.bal",
    "content": "import ballerina/grpc;\nimport ballerina/log;\nimport ballerina/protobuf.types.wrappers;\n\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090) {\n\n    remote function hello(wrappers:ContextString request) returns wrappers:ContextString|error {\n        // Reads the request message and creates a response.\n        string message = \"Hello \" + request.content;\n\n        // Reads the header value in the request message by passing the request header\n        // map and header key.\n        string reqHeader = check grpc:getHeader(request.headers, \"client_header_key\");\n        log:printInfo(\"Server received header value: \" + reqHeader);\n\n        // Sends the response with the header.\n        return {content: message, headers: {server_header_key: \"Response Header value\"}};\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-headers/grpc_simple_with_headers_service.out",
    "content": "$ bal run service\ntime = 2022-11-17T11:55:59.543+05:30 level = INFO module = foo/test message = \"Server received header value: 0987654321\"\n"
  },
  {
    "path": "examples/grpc-service-headers/tests/grpc_simple_with_headers_test.bal",
    "content": "// This is the Ballerina test for simple RPC with headers scenario.\nimport ballerina/grpc;\nimport ballerina/test;\nimport ballerina/protobuf.types.wrappers;\n\n// Client endpoint configuration.\nHelloWorldClient clientEp = check new(\"http://localhost:9090\");\n\n@test:Config\nfunction testSimpleServiceWithHeaders() returns error? {\n    // Creates the request message with the header value.\n    wrappers:ContextString requestMessage =\n    {content: \"WSO2\", headers: {client_header_key: \"0987654321\"}};\n\n    // Executes a simple remote call.\n    wrappers:ContextString result = check clientEp->helloContext(requestMessage);\n\n    // Reads the content in the response message.\n    string expected = \"Hello WSO2\";\n    test:assertEquals(result.content, expected);\n\n    // Reads the header value in the response message.\n    string headerValue = check grpc:getHeader(result.headers, \"server_header_key\");\n    string expectedHeaderValue = \"Response Header value\";\n    test:assertEquals(headerValue, expectedHeaderValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-jwt-auth/grpc_service_jwt_auth.bal",
    "content": "import ballerina/grpc;\n\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n@grpc:ServiceConfig {\n    auth: [\n        {\n            jwtValidatorConfig: {\n                issuer: \"wso2\",\n                audience: \"ballerina\",\n                signatureConfig: {\n                    certFile: \"../resource/path/to/public.crt\"\n                },\n                scopeKey: \"scp\"\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-jwt-auth/grpc_service_jwt_auth.md",
    "content": "# gRPC service - JWT authentication\n\nThe `grpc:Service` can be secured with JWT and additionally, scopes can be added to enforce authorization. It validates the JWT sent in the `Authorization` metadata against the provided configurations. Ballerina uses the concept of scopes for authorization. The scope can be included in the JWT using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service are compared against the scope included in the JWT for at least one match between the two sets.\n\n   ::: code grpc_service_jwt_auth.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_jwt_auth.server.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Self signed JWT authentication](/learn/by-example/grpc-client-self-signed-jwt-auth).\n\n## Related links\n- [`grpc:JwtValidatorConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#JwtValidatorConfig)\n- [gRPC service JWT authentication - Specification](/spec/grpc/#5113-service---jwt-auth)\n- [`jwt` package - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n"
  },
  {
    "path": "examples/grpc-service-jwt-auth/grpc_service_jwt_auth.metatags",
    "content": "description: BBE on how to secure gRPC service with JWT Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, jwt auth\n"
  },
  {
    "path": "examples/grpc-service-jwt-auth/grpc_service_jwt_auth.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-jwt-auth/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-mutual-ssl/grpc_service_mutual_ssl.bal",
    "content": "import ballerina/grpc;\n\n// The gRPC listener can be configured to accept new connections that are secured via mutual SSL.\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        },\n        // Enables mutual SSL.\n        mutualSsl: {\n            verifyClient: grpc:REQUIRE,\n            cert: \"../resource/path/to/public.crt\"\n        }\n    }\n);\n\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-mutual-ssl/grpc_service_mutual_ssl.md",
    "content": "# gRPC service - Mutual SSL\n\nThe `grpc:Listener` with mutual SSL (mTLS) enabled in it allows exposing a connection secured with mutual SSL, which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `grpc:Listener` secured with mutual SSL is created by providing the `secureSocket` configurations, which require `grpc:REQUIRE` as the `verifyClient`, the server's public certificate as the `certFile`, the server's private key as the `keyFile`, and the client's certificate as the `cert`. Use this to secure the gRPC connection with mutual SSL.\n\n   ::: code grpc_service_mutual_ssl.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_mutual_ssl.server.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Mutual SSL](/learn/by-example/grpc-client-mutual-ssl/).\n\n## Related links\n- [`grpc:ListenerSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ListenerSecureSocket)\n- [gRPC service mutual SSL - Specification](/spec/grpc/#52-ssltls-and-mutual-ssl)\n"
  },
  {
    "path": "examples/grpc-service-mutual-ssl/grpc_service_mutual_ssl.metatags",
    "content": "description: BBE on how to secure gRPC listener with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, grpc, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/grpc-service-mutual-ssl/grpc_service_mutual_ssl.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-mutual-ssl/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-oauth2/grpc_service_oauth2.bal",
    "content": "import ballerina/grpc;\n\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n@grpc:ServiceConfig {\n    auth: [\n        {\n            oauth2IntrospectionConfig: {\n                url: \"https://localhost:9445/oauth2/introspect\",\n                tokenTypeHint: \"access_token\",\n                scopeKey: \"scp\",\n                clientConfig: {\n                    customHeaders: {\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"},\n                    secureSocket: {\n                        cert: \"../resource/path/to/public.crt\"\n                    }\n                }\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-oauth2/grpc_service_oauth2.md",
    "content": "# gRPC service - OAuth2\n\nA gRPC service can be secured with OAuth2 and additionally, scopes can be added to enforce fine-grained authorization. It validates the OAuth2 token sent in the `Authorization` metadata against the provided configurations. This calls the configured introspection endpoint to validate.\n\nBallerina uses the concept of scopes for authorization. The scope can be included in the introspection response using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service are compared against the scope included in the introspection response for at least one match between the two sets.\n\n   ::: code grpc_service_oauth2.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_oauth2.server.out :::\n\n>**Tip:** You can invoke the above service via the clients below.\n - [gRPC client - OAuth2 client credentials grant type](/learn/by-example/grpc-client-oauth2-client-credentials-grant-type)\n - [gRPC client - OAuth2 password grant type](/learn/by-example/grpc-client-oauth2-password-grant-type)\n - [gRPC client - OAuth2 refresh token grant type](/learn/by-example/grpc-client-oauth2-refresh-token-grant-type)\n - [gRPC client - OAuth2 JWT bearer grant type](/learn/by-example/grpc-client-oauth2-jwt-bearer-grant-type)\n\n## Related links\n- [`grpc:OAuth2IntrospectionConfig` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#OAuth2IntrospectionConfig)\n- [gRPC service OAuth2 - Specification](/spec/grpc/#5114-service---oauth2)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n"
  },
  {
    "path": "examples/grpc-service-oauth2/grpc_service_oauth2.metatags",
    "content": "description: BBE on how to secure gRPC service with OAuth2 in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, grpc, auth, oauth2, introspection\n"
  },
  {
    "path": "examples/grpc-service-oauth2/grpc_service_oauth2.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-oauth2/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming.md",
    "content": "# gRPC service - Server-side streaming RPC\n\nA `grpc:Listener` is created by providing the port and a `grpc:Service` is attached to it. In the server streaming scenario, once a client is connected to the service and sends a request message, the service sends multiple messages to the client. Use this to receive a single request message from a client and send multiple response messages back.\n\n## Generate the service definition\n\n1. Create new Protocol Buffers definition file `grpc_server_streaming.proto` and add service definition below.\n\n    ::: code grpc_server_streaming.proto :::\n\n2. Run the command below in the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_server_streaming.out :::\n\nOnce you run the command, the `grpc_server_streaming_pb.bal` file gets generated inside the stubs directory.\n\n## Implement and run the service\n\n1. Create a Ballerina package (e.g., `service`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_server_streaming_pb.bal` file from the `stubs` directory to the  `service` package.\n\n3. Create a new `grpc_server_streaming.bal` file inside the `service` package and add the service implementation below.\n\n   ::: code grpc_server_streaming_service.bal :::\n\n4. Run the service by executing the command below.\n\n   ::: out grpc_server_streaming_service.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Server-side streaming RPC](/learn/by-example/grpc-client-server-streaming/).\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC service server-side streaming - Specification](/spec/grpc/#42-server-streaming-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming.metatags",
    "content": "description: This Ballerina by Example has a gRPC streaming service for server streaming RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, server streaming, service\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming.out",
    "content": "$ bal grpc --input grpc_server_streaming.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming.proto",
    "content": "// This is the service definition for the server streaming scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n\trpc lotsOfReplies (google.protobuf.StringValue) returns (stream google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming_service.bal",
    "content": "import ballerina/grpc;\n\n@grpc:Descriptor {\n    value: GRPC_SERVER_STREAMING_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090) {\n\n    remote function lotsOfReplies(string name) returns stream<string, error?> {\n        string[] greets = [\"Hi\", \"Hey\", \"GM\"];\n        // Creates the array of responses by appending the received name.\n        int i = 0;\n        foreach string greet in greets {\n            greets[i] = greet + \" \" + name;\n            i += 1;\n        }\n        // Returns the stream of messages back to the client.\n        return greets.toStream();\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/grpc_server_streaming_service.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-server-streaming/tests/grpc_server_streaming_test.bal",
    "content": "// This is the Ballerina test for the server streaming scenario.\nimport ballerina/grpc;\nimport ballerina/test;\n\n// Client endpoint configuration.\nHelloWorldClient streamingEp = check new(\"http://localhost:9090\");\n\n@test:Config\nfunction testServerStreamingService() returns error? {\n    // Executes the streaming RPC call and gets the response as a stream.\n    stream<string, grpc:Error?> result = check streamingEp->lotsOfReplies(\"Sam\");\n\n    string expectedMsg1 = \"Hi Sam\";\n    string expectedMsg2 = \"Hey Sam\";\n    string expectedMsg3 = \"GM Sam\";\n    // Iterates through the stream and prints the content.\n    check result.forEach(function(string msg) {\n        test:assertTrue(msg == expectedMsg1 || msg == expectedMsg2 || msg == expectedMsg3);\n    });\n}\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_service_simple.bal",
    "content": "import ballerina/grpc;\n\n@grpc:Descriptor {\n    value: GRPC_SERVICE_SIMPLE_DESC\n}\nservice \"HelloWorld\" on new grpc:Listener(9090) {\n\n    remote function hello(string request) returns string {\n        // Reads the request message and sends a response.\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_service_simple.md",
    "content": "# gRPC service - Simple RPC\n\nA `grpc:Listener` is created by providing the port and a `grpc:Service` is attached to it. In the simple RPC scenario, once a client is connected to the service and sends a request message, the service sends a single response message to the client. Use this to receive a single request message from a client and send a single response message back.\n\n## Generate the service definition\n\n1. Create a new Protocol Buffers definition file named `grpc_simple.proto` and add the service definition below.\n\n    ::: code grpc_service_simple.proto :::\n\n2. Run the command below from the Ballerina tools distribution for stub generation.\n\n   ::: out grpc_simple.out :::\n\nOnce you run the command, the `grpc_simple_pb.bal` file gets generated inside the `stubs` directory.\n\n## Implement and run the service\n\n1. Create a Ballerina package (e.g., `service`). Delete the `main.bal` file created by default as it is not required for this example.\n\n2. Copy the generated `grpc_simple_pb.bal` stub file from the `stubs` directory to the  `service` package.\n\n3. Create a new `grpc_simple_service.bal` file inside the `service` package and add the service implementation below.\n\n   ::: code grpc_service_simple.bal :::\n\n4. Execute the commands below to run the service.\n\n   ::: out grpc_service_simple.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - Simple RPC](/learn/by-example/grpc-client-simple/).\n\n## Related links\n- [`grpc` module - API documentation](https://lib.ballerina.io/ballerina/grpc/latest)\n- [gRPC service simple RPC - Specification](/spec/grpc/#41-simple-rpc)\n- [gRPC tool](/learn/grpc-tool/)\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_service_simple.metatags",
    "content": "description: This Ballerina by Example has a gRPC service for simple RPC.\nkeywords: ballerina, ballerina by example, bbe, grpc, unary, simple, service\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_service_simple.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_service_simple.proto",
    "content": "syntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/grpc-service-simple/grpc_simple.out",
    "content": "$ bal grpc --input grpc_simple.proto  --output stubs\n"
  },
  {
    "path": "examples/grpc-service-simple/tests/grpc_simple_test.bal",
    "content": "// This is the Ballerina test for the simple GRPC scenario.\nimport ballerina/test;\n\n// Client endpoint configuration.\nHelloWorldClient clientEp = check new(\"http://localhost:9090\");\n\n@test:Config\nfunction testSimpleService() returns error? {\n    // Executes a simple remote call.\n    string result = check clientEp->hello(\"WSO2\");\n    string expected = \"Hello WSO2\";\n    test:assertEquals(result, expected);\n}\n"
  },
  {
    "path": "examples/grpc-service-ssl-tls/grpc_service_ssl_tls.bal",
    "content": "import ballerina/grpc;\n\nlistener grpc:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"./resources/public.crt\",\n            keyFile: \"./resources/private.key\"\n        }\n    }\n);\n\n@grpc:Descriptor {\n    value: GRPC_SIMPLE_DESC\n}\nservice \"HelloWorld\" on securedEP {\n\n    remote function hello(string request) returns string {\n        return \"Hello \" + request;\n    }\n}\n"
  },
  {
    "path": "examples/grpc-service-ssl-tls/grpc_service_ssl_tls.md",
    "content": "# gRPC service - SSL/TLS\n\nThe `grpc:Listener` can be configured to communicate with a gRPC client via SSL/TLS by providing a certificate file and a private key file. The certificate and the key can be provided through the `secureSocket` field of the listener configuration. Use this to secure the communication and data transfer between the server and the client.\n\n   ::: code grpc_service_ssl_tls.bal :::\n\nSetting up the service is the same as setting up the simple RPC service with additional configurations. For information on implementing the service, see [gRPC service - Simple RPC](/learn/by-example/grpc-service-simple/).\n\nRun the service by executing the command below.\n\n   ::: out grpc_service_ssl_tls.server.out :::\n\n>**Tip:** You can invoke the above service via the [gRPC client - SSL/TLS](/learn/by-example/grpc-client-ssl-tls/).\n\n## Related links\n- [`grpc:ListenerSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/grpc/latest#ListenerSecureSocket)\n- [gRPC service SSL/TLS - Specification](/spec/grpc/#52-ssltls-and-mutual-ssl)\n"
  },
  {
    "path": "examples/grpc-service-ssl-tls/grpc_service_ssl_tls.metatags",
    "content": "description: BBE on how to secure gRPC listener with SSL.\nkeywords: ballerina, ballerina by example, bbe, grpc, ssl, tls\n"
  },
  {
    "path": "examples/grpc-service-ssl-tls/grpc_service_ssl_tls.server.out",
    "content": "$ bal run service\n"
  },
  {
    "path": "examples/grpc-service-ssl-tls/grpc_simple.proto",
    "content": "// This is the service definition of the simple scenario.\nsyntax = \"proto3\";\n\nimport \"google/protobuf/wrappers.proto\";\n\nservice HelloWorld {\n    rpc hello (google.protobuf.StringValue) returns (google.protobuf.StringValue);\n}\n"
  },
  {
    "path": "examples/hello-world/hello_world.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    io:println(\"Hello, World!\");\n}\n"
  },
  {
    "path": "examples/hello-world/hello_world.md",
    "content": "# Hello world main\n\nLet's write the `Hello World` program in Ballerina.\n\n::: code hello_world.bal :::\n\nTo run this sample, place the source code in a file named `hello_world.bal` and use the `bal run` command.\n\n::: out hello_world.out :::"
  },
  {
    "path": "examples/hello-world/hello_world.metatags",
    "content": "description: The classic \"Hello, World\" program in Ballerina\nkeywords:  ballerina, ballerina by example, bbe,\n"
  },
  {
    "path": "examples/hello-world/hello_world.out",
    "content": "$ bal run hello_world.bal\nHello, World!\n"
  },
  {
    "path": "examples/hello-world-service/hello_world_service.bal",
    "content": "import ballerina/http;\n\nservice / on new http:Listener(9090) {\n\n    // This function responds with `string` value `Hello, World!` to HTTP GET requests.\n    resource function get greeting() returns string {\n        return \"Hello, World!\";\n    }\n}\n"
  },
  {
    "path": "examples/hello-world-service/hello_world_service.client.out",
    "content": "$ curl http://localhost:9090/greeting\nHello, World!\n"
  },
  {
    "path": "examples/hello-world-service/hello_world_service.md",
    "content": "# Hello world service\n\nLet's write a simple HTTP service in Ballerina. This example demonstrates the network primitives in the language that make it simpler to develop services.\n\n::: code hello_world_service.bal :::\n\nRun the service as follows.\n\n::: out hello_world_service.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out hello_world_service.client.out :::\n"
  },
  {
    "path": "examples/hello-world-service/hello_world_service.metatags",
    "content": "description: The Hello World HTTP service in Ballerina\nkeywords:  ballerina, ballerina by example, bbe,\n"
  },
  {
    "path": "examples/hello-world-service/hello_world_service.server.out",
    "content": "$ bal run hello_world_service.bal\n"
  },
  {
    "path": "examples/hierarchical-resources/hierarchical_resources.bal",
    "content": "import ballerina/http;\n\n// Base path of this service is `/demo`.\nservice /demo on new http:Listener(8080) {\n    // You can combine the base path and the relative path to get the path of the resource (i.e., `/demo/greeting/hello`).\n    resource function get greeting/hello(string name) returns string {\n        return \"Hello, \" + name;\n    }\n}\n"
  },
  {
    "path": "examples/hierarchical-resources/hierarchical_resources.client.out",
    "content": "$ curl \"localhost:8080/demo/greeting/hello?name=Ballerina\"\nHello, Ballerina\n"
  },
  {
    "path": "examples/hierarchical-resources/hierarchical_resources.md",
    "content": "# Hierarchical resources\n\nResource name is relative path, which can have multiple path segments. Base path is absolute path. A listener can have multiple services each with different base paths.\n\n::: code hierarchical_resources.bal :::\n\nRun the service using the `bal run` command.\n\n::: out hierarchical_resources.server.out :::\n\nRun this cURL command to invoke the resource.\n\n::: out hierarchical_resources.client.out :::"
  },
  {
    "path": "examples/hierarchical-resources/hierarchical_resources.metatags",
    "content": "description: This BBE introduces hierarchical resources concept.\nkeywords:  ballerina, ballerina by example, bbe, resources, hierarchical resources, services\n"
  },
  {
    "path": "examples/hierarchical-resources/hierarchical_resources.server.out",
    "content": "$ bal run hierarchical_resources.bal\n"
  },
  {
    "path": "examples/http-1-1-to-2-0-protocol-switch/http_1_1_to_2_0_protocol_switch.md",
    "content": ""
  },
  {
    "path": "examples/http-100-continue/http_100_continue.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\n\nservice / on new http:Listener(9090) {\n\n    resource function post greeting(http:Caller caller, http:Request request)\n            returns error? {\n        // Check if the client expects a 100-continue response.\n        if request.expects100Continue() {\n            string mediaType = request.getContentType();\n            if mediaType.toLowerAscii() == \"text/plain\" {\n                // Send a `100-continue` response to the client.\n                check caller->continue();\n            } else {\n                // Send a `417` response to ignore the payload as the content type is mismatched\n                // with the expected content type.\n                http:ExpectationFailed resp = {body: \"Unprocessable Entity\"};\n                return caller->respond(resp);\n            }\n        }\n\n        // The client starts sending the payload once it receives the\n        // `100-continue` response. The payload that is sent by the client is retrieved.\n        var payload = request.getTextPayload();\n        if payload is string {\n            log:printInfo(payload);\n            check caller->respond(\"Hello World!\\n\");\n        } else {\n            http:InternalServerError resp = {body: payload.message()};\n            check caller->respond(resp);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/http-100-continue/http_100_continue.client.out",
    "content": "$ curl -v -d \"TEST 100 CONTINUE\" http://localhost:9090/greeting -H 'Expect:100-continue' -H 'Content-Type: text/plain'\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> POST /greeting HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n> Expect:100-continue\n> Content-Type: text/plain\n> Content-Length: 17\n>\n< HTTP/1.1 100 Continue\n< server: ballerina\n< date: Tue, 20 Dec 2022 17:01:05 +0530\n* We are completely uploaded and fine\n< HTTP/1.1 201 Created\n< content-type: text/plain\n< content-length: 13\n< server: ballerina\n< date: Tue, 20 Dec 2022 17:01:05 +0530\n<\nHello World!\n* Connection #0 to host localhost left intact\n\n# Use the following client to invoke the service using an unsupported media type. The service is supposed to ignore\n# the payload if the content type does not match.\n$ curl -v -d '{\"TEST\":\"100 CONTINUE\"}' http://localhost:9090/greeting -H 'Expect:100-continue' -H 'Content-Type: application/json'\n* Connected to localhost (::1) port 9090 (#0)\n> POST /greeting HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n> Expect:100-continue\n> Content-Type: application/json\n> Content-Length: 23\n>\n< HTTP/1.1 417 Expectation Failed\n< content-type: text/plain\n< content-length: 20\n< server: ballerina\n< date: Tue, 20 Dec 2022 17:01:59 +0530\n* HTTP error before end of send, stop sending\n<\n* Closing connection 0\nUnprocessable Entity\n"
  },
  {
    "path": "examples/http-100-continue/http_100_continue.md",
    "content": "# HTTP service - 100 continue\n\nConvenience functions are provided in the `http` module for ease of use when handling `100-continue` scenarios. The `100-continue` indicates that the server has received the request headers and the client can proceed with sending the request. It is done by invoking the `continue` method of the `http:Caller` which results in an interim response containing the `100 Continue` status code if allowed. This is useful when handling multipart or large request payloads.\n\n::: code http_100_continue.bal :::\n\nRun the service as follows.\n\n::: out http_100_continue.server.out :::\n\nInvoke the service by executing the following cURL commands in a new terminal.\n\n::: out http_100_continue.client.out :::\n\n## Related links\n- [`expects100Continue()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Request#expects100Continue)\n"
  },
  {
    "path": "examples/http-100-continue/http_100_continue.metatags",
    "content": "description: This example is on how HTTP 100-continue can be handled by the Ballerina server and the HTTP client connector.\nkeywords: ballerina, ballerina by example, bbe, http, 100-continue\n"
  },
  {
    "path": "examples/http-100-continue/http_100_continue.server.out",
    "content": "$ bal run http_expect_header.bal\ntime = 2021-01-21 20:31:28,347 level = INFO  module = \"\" message = \"TEST 100 CONTINUE\"\n"
  },
  {
    "path": "examples/http-100-continue/tests/http_100_continue_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    // Invoking the main function\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    string response1 = \"Hello World!\\n\";\n\n    // Send a GET request to the specified endpoint\n    string response = check httpEndpoint->post(\"/greeting\", \"Hello from client\");\n    test:assertEquals(response, response1);\n}\n\n"
  },
  {
    "path": "examples/http-2-0-client-server-push/http_2_0_client_server_push.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\n\n// Create an HTTP client that can send HTTP/2 messages.\nhttp:Client clientEP = check new (\"localhost:9090\");\n\npublic function main() returns error? {\n\n    http:Request serviceReq = new;\n    // Submit a request.\n    http:HttpFuture httpFuture = check clientEP->submit(\"GET\", \"/http2Service\", serviceReq);\n\n    http:PushPromise?[] promises = [];\n    int promiseCount = 0;\n    // Check if promises exists.\n    boolean hasPromise = clientEP->hasPromise(httpFuture);\n\n    while hasPromise {\n        // Get the next promise.\n        http:PushPromise pushPromise = check clientEP->getNextPromise(httpFuture);\n        log:printInfo(\"Received a promise for \" + pushPromise.path);\n\n        if pushPromise.path == \"/resource2\" {\n            // The client is not interested in receiving `/resource2`.\n            // Therefore, reject the promise.\n            clientEP->rejectPromise(pushPromise);\n            log:printInfo(\"Push promise for resource2 rejected\");\n        } else {\n            // Store the required promises.\n            promises[promiseCount] = pushPromise;\n            promiseCount = promiseCount + 1;\n        }\n        hasPromise = clientEP->hasPromise(httpFuture);\n    }\n\n    // Get the requested resource.\n    http:Response response = check clientEP->getResponse(httpFuture);\n    json responsePayload = check response.getJsonPayload();\n    log:printInfo(\"Response : \" + responsePayload.toJsonString());\n\n    // Fetch required promise responses.\n    foreach var p in promises {\n        http:PushPromise promise = <http:PushPromise>p;\n        http:Response promisedResponse = check clientEP->getPromisedResponse(promise);\n        json promisedPayload = check promisedResponse.getJsonPayload();\n        log:printInfo(\"Promised resource : \" + promisedPayload.toJsonString());\n    }\n}\n"
  },
  {
    "path": "examples/http-2-0-client-server-push/http_2_0_client_server_push.md",
    "content": "# HTTP client - HTTP/2 Server push\n\nHTTP/2 server push messages can be received using the Ballerina `http:Client`. HTTP/2 Server Push messages allow the server to send resources to the client before the client requests them.\n\n::: code http_2_0_client_server_push.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [HTTP/2 server push](/learn/by-example/http-2-0-server-push/) example.\n\nRun the client program by executing the following command.\n\n::: out http_2_0_client_server_push.out :::\n\n## Related links\n- [`hasPromise()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Client#hasPromise)\n- [`getNextPromise()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Client#getNextPromise)\n- [`rejectPromise()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Client#rejectPromise)\n- [Push promise and promise response - Specification](/spec/http/#1011-push-promise-and-promise-response)\n"
  },
  {
    "path": "examples/http-2-0-client-server-push/http_2_0_client_server_push.metatags",
    "content": "description: This example demonstrates sending and receiving HTTP/2 server push messages by using the Ballerina HTTP package.\nkeywords: ballerina, ballerina by examples, bbe, http, http/2.0, http/2\n"
  },
  {
    "path": "examples/http-2-0-client-server-push/http_2_0_client_server_push.out",
    "content": "$ bal run http_2_0_client_server_push.bal\ntime = 2021-01-21 18:54:45,237 level = INFO  module = \"\" message = \"Received a promise for /resource1\"\ntime = 2021-01-21 18:54:45,278 level = INFO  module = \"\" message = \"Received a promise for /resource2\"\ntime = 2021-01-21 18:54:45,281 level = INFO  module = \"\" message = \"Push promise for resource2 rejected\"\ntime = 2021-01-21 18:54:45,283 level = INFO  module = \"\" message = \"Received a promise for /resource3\"\ntime = 2021-01-21 18:54:45,306 level = INFO  module = \"\" message = \"Response : {\"response\":{\"name\":\"main resource\"}}\"\ntime = 2021-01-21 18:54:45,314 level = INFO  module = \"\" message = \"Promised resource : {\"push\":{\"name\":\"resource1\"}}\"\ntime = 2021-01-21 18:54:45,468 level = INFO  module = \"\" message = \"Promised resource : {\"push\":{\"name\":\"resource3\"}}\"\n"
  },
  {
    "path": "examples/http-2-0-server-push/http_2_0_server_push.bal",
    "content": "import ballerina/http;\n\n// Create an endpoint with port 9090 to accept HTTP requests.\nlistener http:Listener http2ServiceEP = new (9090);\n\nservice /http2service on http2ServiceEP {\n\n    resource function 'default .(http:Caller caller) returns error? {\n\n        // Send a push promise.\n        http:PushPromise promise1 = new (path = \"/resource1\", method = \"GET\");\n        check caller->promise(promise1);\n\n        // Send another push promise.\n        http:PushPromise promise2 = new (path = \"/resource2\", method = \"GET\");\n        check caller->promise(promise2);\n\n        // Send one more push promise.\n        http:PushPromise promise3 = new (path = \"/resource3\", method = \"GET\");\n        check caller->promise(promise3);\n\n        // Construct the requested resource.\n        http:Response res = new;\n        json msg = {\"response\": {\"name\": \"main resource\"}};\n        res.setPayload(msg);\n\n        // Send the requested resource.\n        check caller->respond(res);\n\n        // Construct promised resource1.\n        http:Response push1 = new;\n        msg = {\"push\": {\"name\": \"resource1\"}};\n        push1.setPayload(msg);\n\n        // Push promised `resource1`.\n        check caller->pushPromisedResponse(promise1, push1);\n\n        // Construct promised `resource2`.\n        http:Response push2 = new;\n        msg = {\"push\": {\"name\": \"resource2\"}};\n        push2.setPayload(msg);\n\n        // Push promised `resource2`.\n        check caller->pushPromisedResponse(promise2, push2);\n\n        // Construct promised `resource3`.\n        http:Response push3 = new;\n        msg = {\"push\": {\"name\": \"resource3\"}};\n        push3.setPayload(msg);\n\n        // Push promised `resource3`.\n        check caller->pushPromisedResponse(promise3, push3);\n    }\n}\n"
  },
  {
    "path": "examples/http-2-0-server-push/http_2_0_server_push.md",
    "content": "# HTTP service - HTTP/2 Server push\n\nHTTP/2 server push messages can be sent using the Ballerina `http` service. HTTP/2 server push messages allow the server to send resources to the client before the client requests them.\n\n::: code http_2_0_server_push.bal :::\n\nRun the service by executing the following command.\n\n::: out http_2_0_server_push.out :::\n\n>**Tip:** You can invoke the above service via the [Server push client](/learn/by-example/http-2-0-client-server-push/) example.\n\n## Related links\n- [`promise()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Caller#promise)\n- [`pushPromisedResponse()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Caller#pushPromisedResponse)\n- [HTTP service Server push - Specification](/spec/http/#1011-push-promise-and-promise-response)\n"
  },
  {
    "path": "examples/http-2-0-server-push/http_2_0_server_push.metatags",
    "content": "description: This example demonstrates sending and receiving HTTP/2 server push messages by using the Ballerina HTTP package.\nkeywords: ballerina, ballerina by examples, bbe, http, http/2.0, http/2\n"
  },
  {
    "path": "examples/http-2-0-server-push/http_2_0_server_push.out",
    "content": "$ bal run http_2_0_server_push.bal\n"
  },
  {
    "path": "examples/http-2-prior-knowledge-client/http_2_prior_knowledge_client.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Enable HTTP/2 prior knowledge.\n    http:Client albumClient = check new (\"localhost:9090\",\n        http2Settings = {\n            http2PriorKnowledge: true\n        }\n    );\n    Album[] albums = check albumClient->/albums;\n    io:println(\"GET request:\" + albums.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-2-prior-knowledge-client/http_2_prior_knowledge_client.md",
    "content": "# HTTP client - HTTP/2 prior knowledge\n\nThe HTTP client is configured to enable HTTP/2 prior knowledge. So the client will directly send requests using HTTP/2 without an HTTP/2 upgrade request.\n\n::: code http_2_prior_knowledge_client.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_2_prior_knowledge_client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [http client - Specification](https://ballerina.io/spec/http/#24-client)\n"
  },
  {
    "path": "examples/http-2-prior-knowledge-client/http_2_prior_knowledge_client.metatags",
    "content": "description: This example shows how the Ballerina HTTP client can be configured to enable HTTP/2 prior knowledge.\nkeywords: ballerina, ballerina by examples, bbe, http, http/2, prior knowledge\n"
  },
  {
    "path": "examples/http-2-prior-knowledge-client/http_2_prior_knowledge_client.out",
    "content": "$ bal run http_2_prior_knowledge_client.bal\nGET request:[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-client/http_2_to_1_1_downgrade_client.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Since the default HTTP version is 2.0, HTTP version is set to 1.1.\n    http:Client albumClient = check new (\"localhost:9090\", httpVersion = http:HTTP_1_1);\n    Album[] albums = check albumClient->/albums;\n    io:println(\"GET request:\" + albums.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-client/http_2_to_1_1_downgrade_client.md",
    "content": "# HTTP client - HTTP/2 to HTTP/1.1 downgrade\n\nThe HTTP client is configured to run over the HTTP/1.1 protocol. This client only sends requests over the HTTP/1.1 protocol. When you send a request to an HTTP2-supported service using this client, the connection gets downgraded to HTTP/1.1. If the client is configured to communicate over HTTPS, the ALPN negotiation of choosing which protocol to be used over the secure connection is handled internally. This avoids additional round trips and is independent of the application-layer protocols.  \n\n::: code http_2_to_1_1_downgrade_client.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_2_to_1_1_downgrade_client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [http client - Specification](https://ballerina.io/spec/http/#24-client)\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-client/http_2_to_1_1_downgrade_client.metatags",
    "content": "description: This example shows how the Ballerina HTTP client can be configured to communicate over the HTTP/1.1 protocol.\nkeywords: ballerina, ballerina by examples, bbe, http, http/1.1, http/2\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-client/http_2_to_1_1_downgrade_client.out",
    "content": "$ bal run http_2_to_1_1_downgrade_client.bal\nGET request:[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/http_2_to_1_1_downgrade_service.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n// Since the default HTTP version is 2.0, HTTP version is set to 1.1.\nservice / on new http:Listener(9090, httpVersion = http:HTTP_1_1) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/http_2_to_1_1_downgrade_service.client.out",
    "content": "$ curl http://localhost:9090/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/http_2_to_1_1_downgrade_service.md",
    "content": "# HTTP service - HTTP/2 to HTTP/1.1 downgrade\n\nThe HTTP service is configured to run over the HTTP/1.1 protocol. Therefore this service only accepts requests received over the HTTP/1.1 protocol. If an HTTP2-enabled client sends a request to this service, the client gets downgraded to use HTTP/1.1. If the listener is configured to communicate over HTTPS, the ALPN negotiation of choosing which protocol to be used over the secure connection is handled internally. This avoids additional round trips and is independent of the application-layer protocols.\n\n::: code http_2_to_1_1_downgrade_service.bal :::\n\nRun the service as follows.\n\n::: out http_2_to_1_1_downgrade_service.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_2_to_1_1_downgrade_service.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP resource - Specification](https://ballerina.io/spec/http/#23-resource)\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/http_2_to_1_1_downgrade_service.metatags",
    "content": "description: This example shows how a Ballerina HTTP service can be configured to accept messages only over the HTTP/1.1 protocol.\nkeywords: ballerina, ballerina by examples, bbe, http, http/1.1, http/2\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/http_2_to_1_1_downgrade_service.server.out",
    "content": "$ bal run http_2_to_1_1_downgrade_service.bal\n"
  },
  {
    "path": "examples/http-2-to-1-1-downgrade-service/tests/http_2_0_to_1_1_downgrade_service_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new (\"localhost:9090\", httpVersion = http:HTTP_1_1);\n    json[] payload = check httpEndpoint->get(\"/albums\");\n    test:assertEquals(payload, [{title: \"Blue Train\", artist: \"John Coltrane\"}, {title: \"Jeru\", artist: \"Gerry Mulligan\"}]);\n}\n"
  },
  {
    "path": "examples/http-access-logs/http_access_logs.bal",
    "content": "import ballerina/http;\n\npublic type Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-access-logs/http_access_logs.client.out",
    "content": "$ curl http://localhost:9090/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-access-logs/http_access_logs.md",
    "content": "# HTTP service - Access logs\n\nBallerina allows enabling HTTP access logs to record the HTTP requests handled by an application. HTTP access logs are disabled by default. To enable them, set `console=true` under `ballerina.http.accessLogConfig` in the `Config.toml` file.\nIn addition to logging to the console, logs can be written to a file using the `file` configuration. This configuration allows specifying the log file location and related settings, including log rotation.\n\nThe log format can be specified as either `flat` or `json` using the optional `format` field (defaults to `flat`). Furthermore, you can customize the logged attributes using the optional `attributes` field.\n\n::: code http_access_logs.bal :::\n\n## Prerequisites\n- Populate the `Config.toml` file with the access log configurations.\n\n::: code Config.toml :::\n\nRun the service as follows.\n\n::: out http_access_logs.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_access_logs.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http:AccessLogConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#AccessLogConfiguration)\n- [HTTP service access log - Specification](/spec/http/#824-access-log)\n"
  },
  {
    "path": "examples/http-access-logs/http_access_logs.metatags",
    "content": "description: This example demonstrates the access logs for HTTP services in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, access log, service\n"
  },
  {
    "path": "examples/http-access-logs/http_access_logs.server.out",
    "content": "$ bal run http_access_logs.bal\nballerina: HTTP access log enabled\n127.0.0.1 [11/Jul/2024:13:21:01.620 +0530] \"GET /albums HTTP/1.1\" 200 95 \"-\" \"curl/8.4.0\"\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.client.1.out",
    "content": "$ curl http://localhost:9090/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.client.2.out",
    "content": "$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Sarah Vaughan and Clifford Brown\\\", \\\"artist\\\": \\\"Sarah Vaughan\\\"}\"\n{\"title\":\"Sarah Vaughan and Clifford Brown\", \"artist\":\"Sarah Vaughan\"}\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.md",
    "content": "# REST service - Basic\n\nBallerina language has first-class abstractions for service and resource concepts in the form of `service` and `resource methods`. A resource method consists of an accessor and path. A service can have a collection of resource methods. These abstractions allow mapping REST concepts such as operations, resource paths and resource representations cleanly into your program. `http:Service` can be used to write RESTful services. A service is defined with a base path, the path common to all resource paths. Each resource method is defined with the required operation such as `get`, `put`, `post`, etc and the path. Similar to regular functions resource methods have input parameters and return types that are mapped to the HTTP request and response.\n\n::: code http_basic_rest_service.bal :::\n\nRun the service as follows.\n\n::: out http_basic_rest_service.server.out :::\n\nInvoke the HTTP GET resource by executing the following cURL command in a new terminal.\n\n::: out http_basic_rest_service.client.1.out :::\n\nInvoke the HTTP POST resource by executing the following cURL command in a new terminal.\n\n::: out http_basic_rest_service.client.2.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service resource - Specification](/spec/http/#23-resource)\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.metatags",
    "content": "description: This example demonstrates creating a basic REST service in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http service, path, verb, rest\n"
  },
  {
    "path": "examples/http-basic-rest-service/http_basic_rest_service.server.out",
    "content": "$ bal run http_basic_rest_service.bal\n"
  },
  {
    "path": "examples/http-basic-rest-service/tests/http_basic_rest_service_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    Album[] payload = check httpEndpoint->get(\"/albums\");\n    test:assertEquals(payload, [{title:\"Blue Train\",artist:\"John Coltrane\"},{title:\"Jeru\",artist:\"Gerry Mulligan\"}]);\n\n\n    Album lastAlbum = check httpEndpoint->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    test:assertEquals(lastAlbum, {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n}\n"
  },
  {
    "path": "examples/http-caching-client/http_caching_client.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // In this example, the `isShared` field of the `cacheConfig` is set\n    // to true, as the cache will be a public cache in this particular scenario.\n    http:Client albumClient = check new (\"localhost:9090\",\n        cache = {\n            isShared: true\n        }\n    );\n\n    Album album = check albumClient->/albums/Jeru;\n    io:println(\"Received album: \" + album.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-caching-client/http_caching_client.md",
    "content": "# HTTP client - Enable Caching\n\nHTTP caching is enabled by default in the `http:Client`. The cache configurations can be set by the `cache` field in the `http:ClientConfiguration`. The default behavior is to allow caching only when the `Cache-Control` header and either the `ETag` or `Last-Modified` headers are present. Use the `policy` field of the `http:CacheConfig` if you want to change this default behavior. The `http` module currently supports the following policies: `http:CACHE_CONTROL_AND_VALIDATORS` (the default policy) and `http:RFC_7234`.\n\n::: code http_caching_client.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Sending cache response service](/learn/by-example/http-service-cache-response/) example.\n\nRun the client program by executing the following command.\n\n::: out http_caching_client.out :::\n\n>**Tip:** You can enable the [trace logs](/learn/by-example/http-trace-logs/) for both service and client to observe the in and out traffic.\n\n## Related links\n- [`http:CacheConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#CacheConfig)\n- [HTTP client caching - Specification](/spec/http/#2412-caching)\n"
  },
  {
    "path": "examples/http-caching-client/http_caching_client.metatags",
    "content": "description: This example is on how HTTP caching is configured and performed in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, client, caching\n"
  },
  {
    "path": "examples/http-caching-client/http_caching_client.out",
    "content": "$ bal run http_caching_client.bal\nReceived album: {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}\n"
  },
  {
    "path": "examples/http-caching-client/tests/http_caching_client_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpClient = check new (\"localhost:9090\",\n        cache = {\n            enabled: true,\n            isShared: true\n        }\n    );\n    http:Response response = check httpClient->get(\"/greeting\");\n    test:assertEquals(response.getHeader(\"etag\"), \"ec4ac3d0\");\n    test:assertEquals(response.getHeader(\"cache-control\"), \"must-revalidate,public,max-age=15\");\n    test:assertFalse(response.hasHeader(\"age\"));\n    test:assertEquals(response.getTextPayload(), \"Hello, World!\");\n\n    response = check httpClient->get(\"/greeting\");\n    test:assertEquals(response.getHeader(\"etag\"), \"ec4ac3d0\");\n    test:assertEquals(response.getHeader(\"cache-control\"), \"must-revalidate,public,max-age=15\");\n    test:assertTrue(response.hasHeader(\"age\"));\n    test:assertEquals(response.getTextPayload(), \"Hello, World!\");\n}\n\nservice / on new http:Listener(9090) {\n\n    resource function get greeting() returns http:Response {\n        http:Response res = new;\n        // The `http:ResponseCacheControl` object in the `http:Response` object can be\n        // used for setting the cache control directives associated with the response.\n        // In this example, `max-age` directive is set to 15 seconds indicating that the response\n        // will be fresh for 15 seconds. The `must-revalidate` directive instructs that\n        // the cache should not serve a stale response without validating it with the origin server\n        // first. The `public` directive is set by setting `isPrivate=false`. This indicates that\n        // the response can be cached even by intermediary caches which serve multiple users.\n        http:ResponseCacheControl resCC = new;\n\n        resCC.maxAge = 15;\n        resCC.mustRevalidate = true;\n        resCC.isPrivate = false;\n        res.cacheControl = resCC;\n        string payload = \"Hello, World!\";\n\n        // The `setETag()` function can be used for generating ETags for\n        // `string`, `json`, and `xml` types. This uses the `getCRC32()`\n        // function from the `ballerina/crypto` module for generating the ETag.\n        res.setETag(payload);\n\n        // The `setLastModified()` function sets the current time as the `last-modified` header.\n        res.setLastModified();\n\n        res.setPayload(payload);\n        // When sending the response, if the `cacheControl` field of the response is set,\n        // and the user has not already set a `cache-control` header, a `cache-control` header\n        // will be set using the directives set in the `cacheControl` object.\n        return res;\n\n    }\n}\n"
  },
  {
    "path": "examples/http-caller/http_caller.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // Caller is defined in the signature parameter.\n    resource function get albums(http:Caller caller) returns error? {\n        http:Response response = new;\n        response.setPayload(albums.toArray());\n        response.setHeader(\"x-music-genre\", \"Jazz\");\n\n        // Sending the response using the caller functions.\n        check caller->respond(response);\n    }\n}\n"
  },
  {
    "path": "examples/http-caller/http_caller.client.out",
    "content": "$ curl -v localhost:9090/albums\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n> \n< HTTP/1.1 200 OK\n< content-type: application/json\n< x-music-genre: Jazz\n< content-length: 92\n< server: ballerina\n< date: Tue, 10 Jan 2023 15:52:25 +0530\n< \n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-caller/http_caller.md",
    "content": "# HTTP service - Caller object\n\nThe `http:Caller` represents the endpoint that initiated the call toward a service. It is used to send responses back to the caller. In addition, it also contains meta information such as remote/local addresses. When the `http:Caller` is defined, the resource method return type is constrained to `error?`. `http:Caller` is useful to handle scenarios such as sending status code `100 Continue` or doing some work after sending the response to the caller. In most cases, `http:Caller` is not required as returning from the resource method sends the response back to the caller.\n\n::: code http_caller.bal :::\n\nRun the service as follows.\n\n::: out http_caller.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_caller.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP caller - Specification](/spec/http/#2341-httpcaller)\n"
  },
  {
    "path": "examples/http-caller/http_caller.metatags",
    "content": "description: This example demonstrates the HTTP caller and its usage with an HTTP service in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http caller, service\n"
  },
  {
    "path": "examples/http-caller/http_caller.server.out",
    "content": "$ bal run http_caller.bal\n"
  },
  {
    "path": "examples/http-caller/tests/http_caller_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\");\n    http:Response response = check albumClient->/albums();\n    test:assertEquals(response.getHeader(\"x-music-genre\"), \"Jazz\");\n}\n"
  },
  {
    "path": "examples/http-circuit-breaker/http_circuit_breaker.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\",\n        circuitBreaker = {\n            // The failure calculation window measures how long the circuit breaker keeps the\n            // statistics for the operations.\n            rollingWindow: {\n\n                // The period is in seconds for which the failure threshold is calculated.\n                timeWindow: 10,\n\n                // The granularity (in seconds) at which the time window slides.\n                // The rolling window is divided into buckets and slides by these increments.\n                bucketSize: 2,\n\n                // The minimum number of requests in the rolling window that trips the circuit.\n                requestVolumeThreshold: 0\n\n            },\n            // The threshold for request failures. When this threshold exceeds, the circuit trips.\n            // This is the ratio between failures and total requests. The ratio is calculated using\n            // the requests received within the given rolling window.\n            failureThreshold: 0.2,\n\n            // The period (in seconds) to wait before attempting to make another request to the upstream service.\n            resetTime: 10,\n\n            // HTTP response status codes that are considered as failures\n            statusCodes: [400, 404, 500]\n\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-circuit-breaker/http_circuit_breaker.md",
    "content": "# HTTP client - Circuit breaker\n\nThe circuit breaker is used to gracefully handle errors that could occur due to network and backend failures. This is configured in the `circuitBreaker` field of the client configuration. The circuit breaker looks for errors across a rolling time window. After the circuit is broken, it does not send requests to the backend until the `resetTime`.\n\n::: code http_circuit_breaker.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the program by executing the following command.\n\n::: out http_circuit_breaker.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client circuit breaker - Specification](/spec/http/#2415-circuit-breaker)\n"
  },
  {
    "path": "examples/http-circuit-breaker/http_circuit_breaker.metatags",
    "content": "description: This example is on how to use an HTTP circuit breaker to handle requests when a backend is failing.\nkeywords: ballerina, ballerina by examples, bbe, http, resiliency, circuit breaker, circuit break\n"
  },
  {
    "path": "examples/http-circuit-breaker/http_circuit_breaker.out",
    "content": "$ bal run http_circuit_breaker.bal\n\n"
  },
  {
    "path": "examples/http-circuit-breaker/tests/http_circuit_breaker_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpClient = check new (\"localhost:8080\",\n        // Configuration options that control the behavior of the circuit\n        // breaker.\n        circuitBreaker = {\n            // Failure calculation window. This is how long the circuit\n            // breaker keeps the statistics for the operations.\n            rollingWindow: {\n\n                // Time period in seconds for which the failure\n                // threshold is calculated.\n                timeWindow: 10,\n\n                // The granularity (in seconds) at which the time\n                // window slides. The `RollingWindow` is divided into\n                // buckets and slides by these increments.\n                bucketSize: 2,\n\n                // Minimum number of requests in the `RollingWindow` that\n                // will trip the circuit.\n                requestVolumeThreshold: 0\n\n            },\n            // The threshold for request failures.\n            // When this threshold exceeds, the circuit trips. This is the\n            // ratio between failures and total requests. The ratio is\n            // calculated using the requests received within the given\n            // rolling window.\n            failureThreshold: 0.2,\n\n            // The time period (in seconds) to wait before attempting to\n            // make another request to the upstream service.\n            resetTime: 10,\n\n            // HTTP response status codes that are considered as failures\n            statusCodes: [400, 404, 500]\n\n        },\n        timeout = 2\n    );\n    string responseString = \"Hello World!!!\";\n    // Send 1st GET request to the specified endpoint.\n    string payload = check httpClient->/greeting;\n    test:assertEquals(payload, responseString);\n\n    // Send 2nd GET request to the specified endpoint\n    payload = check httpClient->/greeting;\n    test:assertEquals(payload, responseString);\n\n    // Send 3rd GET request to the specified endpoint\n    string|error result = httpClient->/greeting;\n    if result is http:RemoteServerError {\n        test:assertEquals(result.detail().body, \"Error occurred while processing the request.\");\n    }\n\n    // Send 4th GET request to the specified endpoint\n    result = httpClient->/greeting;\n    test:assertTrue(result is error, \"Invalid type\");\n\n    // Send 5th GET request to the specified endpoint\n    result = httpClient->/greeting;\n    test:assertTrue(result is error, \"Invalid type\");\n\n    // Send 6th GET request to the specified endpoint\n    result = httpClient->/greeting;\n    test:assertTrue(result is error , \"Invalid type\");\n}\n\nservice / on new http:Listener(8080) {\n    private int counter = 1;\n    resource function get greeting() returns string|http:InternalServerError {\n        if self.counter % 5 == 3 {\n            self.counter += 1;\n            return {body:\"Error occurred while processing the request.\"};\n        } else {\n            self.counter += 1;\n            return \"Hello World!!!\";\n        }\n    }\n}\n"
  },
  {
    "path": "examples/http-client-basic-authentication/http_client_basic_authentication.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the APIs secured with basic authentication.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            username: \"ldclakmal\",\n            password: \"ldclakmal@123\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-basic-authentication/http_client_basic_authentication.md",
    "content": "# HTTP client - Basic authentication\n\nThe `http:Client` can connect to a service that is secured with basic authentication by adding the `Authorization: Basic <token>` header to each request. The username and password for basic authentication can be specified in the `auth` field of the client configuration.\n\n::: code http_client_basic_authentication.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic authentication file user store service](/learn/by-example/http-service-basic-authentication-file-user-store) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_basic_authentication.out :::\n\n## Related links\n- [`http:CredentialsConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#CredentialsConfig)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [HTTP client basic authentication - Specification](/spec/http/#9115-client---basic-auth)\n"
  },
  {
    "path": "examples/http-client-basic-authentication/http_client_basic_authentication.metatags",
    "content": "description: This example is on how to secure an HTTP client with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, basic auth\n"
  },
  {
    "path": "examples/http-client-basic-authentication/http_client_basic_authentication.out",
    "content": "$ bal run http_client_basic_auth.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-bearer-token-authentication/http_client_bearer_token_authentication.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the APIs secured with bearer token authentication.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            token: \"56ede317-4511-44b4-8579-a08f094ee8c5\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-bearer-token-authentication/http_client_bearer_token_authentication.md",
    "content": "# HTTP client - Bearer token authentication\n\nThe `http:Client` can connect to a service that is secured with bearer token authentication by adding the `Authorization: Bearer <token>` header to each request. The bearer token can be specified in the `auth` field of the client configuration.\n\n::: code http_client_bearer_token_authentication.bal :::\n\n## Prerequisites\n- Run a sample secured service with bearer token authentication.\n\nRun the client program by executing the command below.\n\n::: out http_client_bearer_token_authentication.out :::\n\n## Related links\n- [`http:BearerTokenConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#BearerTokenConfig)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [HTTP client bearer token authentication - Specification](/spec/http/#9116-client---bearer-token-auth)\n"
  },
  {
    "path": "examples/http-client-bearer-token-authentication/http_client_bearer_token_authentication.metatags",
    "content": "description: This example is on how to secure an HTTP client with Bearer token auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, jwt auth\n"
  },
  {
    "path": "examples/http-client-bearer-token-authentication/http_client_bearer_token_authentication.out",
    "content": "$ bal run http_client_bearer_token_auth.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-chunking/http_client_chunking.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\",\n        httpVersion = http:HTTP_1_1,\n        http1Settings = {\n            chunking: http:CHUNKING_NEVER\n        }\n    );\n    Album payload = check albumClient->/albums.post({\n        title: \"Sarah Vaughan and Clifford Brown\",\n        artist: \"Sarah Vaughan\"\n    });\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-chunking/http_client_chunking.md",
    "content": "# HTTP client - Chunking\n\nThe HTTP client can be configured for chunking. By default, the HTTP client sends messages with the `content-length` header. If the message size is larger than the buffer size (8K), messages are chunked. Chunking can be disabled using the client configuration. The chunking behavior can be configured as `CHUNKING_AUTO`, `CHUNKING_ALWAYS`, or `CHUNKING_NEVER` only available HTTP/1.1 protocol. When the config is set to `CHUNKING_ALWAYS`, chunking happens irrespective of the response payload size.\n\n::: code http_client_chunking.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_chunking.out :::\n\n## Related links\n- [`http1Settings` - API documentation](https://lib.ballerina.io/ballerina/http/latest#ClientHttp1Settings)\n- [HTTP client - Specification](https://ballerina.io/spec/http/#24-client)\n"
  },
  {
    "path": "examples/http-client-chunking/http_client_chunking.metatags",
    "content": "description: This example is on how to configure the chunking behavior of the HTTP client in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, chunked, transfer-encoding\n"
  },
  {
    "path": "examples/http-client-chunking/http_client_chunking.out",
    "content": "$ bal run http_client_chunking.bal\n"
  },
  {
    "path": "examples/http-client-chunking/tests/http_client_chunking_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client clientEndpoint = check new (\"localhost:9090\", httpVersion = http:HTTP_1_1,\n    http1Settings = {chunking: http:CHUNKING_NEVER});\n    string response = check clientEndpoint->/payload.post({\"name\": \"Ballerina\"});\n    test:assertEquals(response, \"Outbound request content length: 20\");\n}\n\nservice / on new http:Listener(9090) {\n    resource function post payload(@http:Header {name: \"Content-length\"} string cLen) returns string {\n        //Set the response with the content length.\n        return string `Outbound request content length: ${cLen}`;\n    }\n}\n"
  },
  {
    "path": "examples/http-client-data-binding/http_client_data_binding.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Creates a new client with the Basic REST service URL.\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    // Binding the payload to a `record` array type.\n    // The contextually expected type is inferred from the LHS variable type.\n    Album[] albums = check albumClient->/albums;\n    io:println(\"First artist name: \" + albums[0].artist);\n}\n"
  },
  {
    "path": "examples/http-client-data-binding/http_client_data_binding.md",
    "content": "# HTTP client - Payload data binding\n\nThe `http:Client` payload data-binding allows directly binding the response payload to a given subtype of `anydata`. It does this by mapping a given HTTP content-type to one or more Ballerina types. For instance, `text/plain` is mapped to `string`, whereas `application/json` is mapped to `json`, `record`, etc. The client data-binding can be used by simply assigning the resource method’s returned value to the declared variable. If the response is anything other than 2xx, an `error` is returned and no data-binding is performed. If there is no mapping between the given Ballerina type and the response content-type, again an `error` is returned. Use this when the application is only interested in the response payload but not the headers. When the response payload is JSON, the `record` type is preferred to the `json` type as it provides compile-time validations, better readability, and improved tooling support.\n\n::: code http_client_data_binding.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_data_binding.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client return types - Specification](/spec/http/#243-client-action-return-types)\n"
  },
  {
    "path": "examples/http-client-data-binding/http_client_data_binding.metatags",
    "content": "description: This example demonstrates the data-binding capability of an HTTP client.\nkeywords: ballerina, ballerina by example, bbe, http, client, data binding\n"
  },
  {
    "path": "examples/http-client-data-binding/http_client_data_binding.out",
    "content": "$ bal run http_client_data_binding.bal\nFirst artist name: John Coltrane\n"
  },
  {
    "path": "examples/http-client-file-upload/http_client_file_upload.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/mime;\n\npublic function main() returns error? {\n    http:Client httpClient = check new (\"localhost:9090\");\n\n    http:Request request = new;\n\n    // Sets the file as the request payload.\n    request.setFileAsPayload(\"./files/BallerinaLang.pdf\", contentType = mime:APPLICATION_PDF);\n\n    //Sends the request to the receiver service with the file content.\n    string content = check httpClient->/receiver.post(request);\n\n    // forward the received payload to the caller.\n    io:println(content);\n}\n"
  },
  {
    "path": "examples/http-client-file-upload/http_client_file_upload.md",
    "content": "# HTTP client - File upload\n\nThe output streaming is generally handled through the Ballerina `stream` type. Additionally, the `setFileAsPayload` of the `http:Request` is the support function dedicated to file uploads. This is useful when handling continuous payload, file uploads, etc.\n\n::: code http_client_file_upload.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Service file upload](/learn/by-example/http-service-file-upload/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_file_upload.out :::\n\n## Related links\n- [`setFileAsPayload()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Request#setFileAsPayload)\n- [`http` module - Specification](/spec/http/#2423-resource-methods)\n"
  },
  {
    "path": "examples/http-client-file-upload/http_client_file_upload.metatags",
    "content": "description: This example demonstrates the file upload capability through Ballerina streams.\nkeywords: ballerina, ballerina by example, bbe, http, streaming, client, file upload\n"
  },
  {
    "path": "examples/http-client-file-upload/http_client_file_upload.out",
    "content": "$ bal run http_client_file_upload.bal\nFile Received!\n"
  },
  {
    "path": "examples/http-client-header-parameter/http_client_header_parameter.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/mime;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    Album[] albums = check albumClient->/albums({\n        Accept: mime:APPLICATION_JSON\n    });\n    io:println(\"Received albums: \" + albums.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-client-header-parameter/http_client_header_parameter.md",
    "content": "# HTTP client - Header parameter\n\nThe `http:Client` supports sending outbound request headers along with the request payload. These headers can be passed as an argument in the client resource method call. The headers should be provided as a `map`, where the keys represent the header names and the entries represent the header values. The header values can be `string` or `string[]`. Use this when you want to send additional headers as part of the request.\n\n::: code http_client_header_parameter.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [REST service - Header parameter](/learn/by-example/http-header-param/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_header_parameter.out :::\n\nFurthermore, a `post` request with additional headers can be sent as shown below.\n\n::: code http_client_header_parameter_post.bal :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client resource methods - Specification](/spec/http/#2423-resource-methods)\n"
  },
  {
    "path": "examples/http-client-header-parameter/http_client_header_parameter.metatags",
    "content": "description: This example is on how to call a client resource with a header parameter.\nkeywords: ballerina, ballerina by examples, bbe, http, client, header parameter\n"
  },
  {
    "path": "examples/http-client-header-parameter/http_client_header_parameter.out",
    "content": "$ bal run http_client_header_parameter.bal\nReceived albums: [{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-header-parameter/http_client_header_parameter_post.bal",
    "content": "// Sends a `POST` request to the \"/album\" resource.\n// The query parameter can be provided as parameters in the `post` method invocation.\nstring albumId = check albumClient->/album.post({\n        title: \"Blue Train\",\n        artist: \"John Coltrane\"\n    },\n    // Headers can be specified as a `map<string|string[]>`\n    {\n        Accept: mime:APPLICATION_JSON\n    }\n);\nio:println(\"Added album with id: \" + albumId);\n"
  },
  {
    "path": "examples/http-client-mutual-ssl/http_client_mutual_ssl.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // The HTTP client can be configured to initiate new connections that are secured via mutual SSL.\n    http:Client albumClient = check new (\"localhost:9090\",\n        secureSocket = {\n            key: {\n                certFile: \"../resource/path/to/client-public.crt\",\n                keyFile: \"../resource/path/to/client-private.key\"\n            },\n            cert: \"../resource/path/to/server-public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-mutual-ssl/http_client_mutual_ssl.md",
    "content": "# HTTP client - Mutual SSL\n\nThe `http:Client` allows opening up a connection secured with mutual SSL (mTLS), which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `http:Client` secured with mutual SSL is created by providing the `secureSocket` configurations, which require the client's public certificate as the `certFile`, the client's private key as the `keyFile`, and the server's certificate as the `cert`. Use this to interact with mTLS-encrypted HTTP servers.\n\n::: code http_client_mutual_ssl.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Mutual SSL service](/learn/by-example/http-service-mutual-ssl/) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_mutual_ssl.out :::\n\n## Related links\n- [`http:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#ClientSecureSocket)\n- [HTTP client mutual SSL - Specification](/spec/http/#924-client---mutual-ssl)\n"
  },
  {
    "path": "examples/http-client-mutual-ssl/http_client_mutual_ssl.metatags",
    "content": "description: This example is on how to secure an HTTP client with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, http, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/http-client-mutual-ssl/http_client_mutual_ssl.out",
    "content": "$ bal run http_client_mutual_ssl.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-oauth2-client-credentials-grant-type/http_client_oauth2_client_credentials_grant_type.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the OAuth2 secured APIs.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-oauth2-client-credentials-grant-type/http_client_oauth2_client_credentials_grant_type.md",
    "content": "# HTTP client - OAuth2 client credentials grant type\n\nThe `http:Client` can connect to a service that is secured with the OAuth2 client credentials grant type by adding the `Authorization: Bearer <token>` header to each request. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n::: code http_client_oauth2_client_credentials_grant_type.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [OAuth2 service](/learn/by-example/http-service-oauth2/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_oauth2_client_credentials_grant_type.out :::\n\n## Related links\n- [`http:OAuth2ClientCredentialsGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#OAuth2ClientCredentialsGrantConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [HTTP client OAuth2 client credentials grant type - Specification](/spec/http/#9119-client---grant-types-oauth2)\n"
  },
  {
    "path": "examples/http-client-oauth2-client-credentials-grant-type/http_client_oauth2_client_credentials_grant_type.metatags",
    "content": "description: This example is on how to secure an HTTP client with OAuth2 client credentials grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, oauth2, client credentials grant type\n"
  },
  {
    "path": "examples/http-client-oauth2-client-credentials-grant-type/http_client_oauth2_client_credentials_grant_type.out",
    "content": "$ bal run http_client_oauth2_client_credentials_grant_type.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-oauth2-jwt-bearer-grant-type/http_client_oauth2_jwt_bearer_grant_type.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the OAuth2 secured APIs.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            assertion: \"eyJhbGciOiJFUzI1NiIsImtpZCI6Ij[...omitted for brevity...]\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-oauth2-jwt-bearer-grant-type/http_client_oauth2_jwt_bearer_grant_type.md",
    "content": "# HTTP client - OAuth2 JWT bearer grant type\n\nThe `http:Client` can connect to a service that is secured with the OAuth2 JWT bearer grant type by adding the `Authorization: Bearer <token>` header to each request. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n::: code http_client_oauth2_jwt_bearer_grant_type.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [OAuth2 service](/learn/by-example/http-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_oauth2_jwt_bearer_grant_type.out :::\n\n## Related links\n- [`http:OAuth2JwtBearerGrantConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#OAuth2JwtBearerGrantConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [HTTP client grant types - Specification](/spec/http/#9129-client---grant-types-oauth2)\n"
  },
  {
    "path": "examples/http-client-oauth2-jwt-bearer-grant-type/http_client_oauth2_jwt_bearer_grant_type.metatags",
    "content": "description: This example is on how to secure an HTTP client with OAuth2 JWT bearer grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, oauth2, jwt bearer grant type\n"
  },
  {
    "path": "examples/http-client-oauth2-jwt-bearer-grant-type/http_client_oauth2_jwt_bearer_grant_type.out",
    "content": "$ bal run http_client_oauth2_jwt_bearer_grant_type.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-oauth2-password-grant-type/http_client_oauth2_password_grant_type.bal",
    "content": "import ballerina/http;\nimport ballerina/oauth2;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the OAuth2 secured APIs.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            username: \"admin\",\n            password: \"admin\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            refreshConfig: oauth2:INFER_REFRESH_CONFIG,\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-oauth2-password-grant-type/http_client_oauth2_password_grant_type.md",
    "content": "# HTTP client - OAuth2 password grant type\n\nThe `http:Client` can connect to a service that is secured with the OAuth2 password grant type by adding the `Authorization: Bearer <token>` header to each request. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this grant type when you need to exchange the user's credentials for an access token.\n\n::: code http_client_oauth2_password_grant_type.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [OAuth2 service](/learn/by-example/http-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_oauth2_password_grant_type.out :::\n\n## Related links\n- [`http:OAuth2PasswordGrantConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#OAuth2PasswordGrantConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [HTTP client grant types - Specification](/spec/http/#9129-client---grant-types-oauth2)\n"
  },
  {
    "path": "examples/http-client-oauth2-password-grant-type/http_client_oauth2_password_grant_type.metatags",
    "content": "description: This example is on how to secure an HTTP client with the OAuth2 password grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, oauth2, password grant type\n"
  },
  {
    "path": "examples/http-client-oauth2-password-grant-type/http_client_oauth2_password_grant_type.out",
    "content": "$ bal run http_client_oauth2_password_grant_type.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-oauth2-refresh-token-grant-type/http_client_oauth2_refresh_token_grant_type.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the OAuth2 secured APIs.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            refreshUrl: \"https://localhost:9445/oauth2/token\",\n            refreshToken: \"24f19603-8565-4b5f-a036-88a945e1f272\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-oauth2-refresh-token-grant-type/http_client_oauth2_refresh_token_grant_type.md",
    "content": "# HTTP client - OAuth2 refresh token grant type\n\nThe `http:Client` can connect to a service that is secured with the OAuth2 refresh token grant type by adding the `Authorization: Bearer <token>` header to each request. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this to automatically retrieve an access token when it is expired.\n\n::: code http_client_oauth2_refresh_token_grant_type.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [OAuth2 service](/learn/by-example/http-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_oauth2_refresh_token_grant_type.out :::\n\n## Related links\n- [`http:OAuth2RefreshTokenGrantConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#OAuth2RefreshTokenGrantConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [HTTP client grant types - Specification](/spec/http/#9129-client---grant-types-oauth2)\n"
  },
  {
    "path": "examples/http-client-oauth2-refresh-token-grant-type/http_client_oauth2_refresh_token_grant_type.metatags",
    "content": "description: This example is on how to secure an HTTP client with the OAuth2 refresh token grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, oauth2, refresh token grant type\n"
  },
  {
    "path": "examples/http-client-oauth2-refresh-token-grant-type/http_client_oauth2_refresh_token_grant_type.out",
    "content": "$ bal run http_client_oauth2_refresh_token_grant_type.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-path-parameter/http_client_path_parameter.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main(string artist) returns error? {\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    // Sends a `GET` request to the \"/albums\" resource.\n    // The path parameter can be defined inside `[]` after the path followed by a `/`.\n    // This is the same as invoking the get method by `albumClient->get(\"/albums/Blue Train\")`.\n    Album album = check albumClient->/albums/[artist];\n    io:println(\"Received album: \" + album.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-client-path-parameter/http_client_path_parameter.md",
    "content": "# HTTP client - Path parameter\n\nThe `http:Client` supports specifying `path parameters` when invoking a backend resource. Declare the required `path parameter` inside a square bracket along with the resource path (eg: `/albums/[album]`) and invoke the resource method. Use this when invoking backend resources with variable resource paths.\n\n::: code http_client_path_parameter.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [REST service - Path parameter](/learn/by-example/http-path-param/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_path_parameter.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client resource methods - Specification](/spec/http/#2423-resource-methods)\n"
  },
  {
    "path": "examples/http-client-path-parameter/http_client_path_parameter.metatags",
    "content": "description: This example is on how to call a client resource with a path parameter.\nkeywords: ballerina, ballerina by examples, bbe, http, client, path parameter\n"
  },
  {
    "path": "examples/http-client-path-parameter/http_client_path_parameter.out",
    "content": "$ bal run http_client_path_parameter.bal -- \"Blue Train\"\nReceived album: {\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}\n"
  },
  {
    "path": "examples/http-client-payload-constraint-validation/http_client_payload_constraint_validation.bal",
    "content": "import ballerina/http;\nimport ballerina/constraint;\nimport ballerina/io;\n\ntype Album record {\n    // Add a constraint for the maximum length and the minimum length.\n    @constraint:String {\n        maxLength: 5,\n        minLength: 1\n    }\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    // Request the server for the album. If the constraint validation fails,\n    // an `http:PayloadValidationError` will be returned.\n    Album album = check albumClient->/albums.post({\n        // Here, an album which exceeds the constraints are sent to a server\n        // which returns the same record again to the client.\n        title: \"Blue Train\",\n        artist: \"John Coltrane\"\n    });\n    io:println(\"Received album: \" + album.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-client-payload-constraint-validation/http_client_payload_constraint_validation.md",
    "content": "# HTTP client - Payload constraint validation\n\nThe Ballerina `constraint` module allows adding additional constraints to the response payload. The `http:Client` uses the `constraint` module to validate the payload against the given constraints. This validation happens soon after the successful data-binding of the response payload. The constraints can be added to a given data type using different annotations. If the validation fails, an `http:PayloadValidationError` is returned with the validation error message. Use this to validate the response payload as the application program receives it, which protects the client against unnecessary processing and malicious payloads.\n\n::: code http_client_payload_constraint_validation.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [REST service - Payload data binding](/learn/by-example/http-service-data-binding/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_payload_constraint_validation.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [`http` module - Specification](/spec/http/)\n- [Constraint validation example](/learn/by-example/constraint-validations/)\n"
  },
  {
    "path": "examples/http-client-payload-constraint-validation/http_client_payload_constraint_validation.metatags",
    "content": "description: This example demonstrates the constraint validation capability of an HTTP client.\nkeywords: ballerina, ballerina by example, bbe, http, client, data binding, constraint, validation\n"
  },
  {
    "path": "examples/http-client-payload-constraint-validation/http_client_payload_constraint_validation.out",
    "content": "$ bal run http_client_payload_constraint_validation.bal\nerror: payload validation failed: Validation failed for '$.title:maxLength' constraint(s).\n"
  },
  {
    "path": "examples/http-client-query-parameter/http_client_query_parameter.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    // Sends a `GET` request to the \"/albums\" resource.\n    // The query parameter can be provided as parameters in the `get` method invocation.\n    Album[] albums = check albumClient->/albums(artist = \"John Coltrane\");\n    io:println(\"Received albums: \" + albums.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-client-query-parameter/http_client_query_parameter.md",
    "content": "# HTTP client - Query parameter\n\nThe `http:Client` supports specifying query parameters as resource method arguments. Each query parameter can be stated as a key-value pair. When the request is sent, the key-value pairs are appended to the request path (e.g., `?foo=bar`). The supported types are `string`, `int`, `float`, `boolean`, `decimal`, and `array` types of the aforementioned types. Use this when invoking endpoints that expect query parameters.\n\n::: code http_client_query_parameter.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [REST service - Query parameter](/learn/by-example/http-query-parameter/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_query_parameter.out :::\n\nFurthermore, a `post` request with a query parameter can be sent as shown below.\n\n::: code http_client_query_parameter_post.bal :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client resource methods - Specification](/spec/http/#2423-resource-methods)\n"
  },
  {
    "path": "examples/http-client-query-parameter/http_client_query_parameter.metatags",
    "content": "description: This example is on how to call a client resource with a query parameter.\nkeywords: ballerina, ballerina by examples, bbe, http, client, query parameter\n"
  },
  {
    "path": "examples/http-client-query-parameter/http_client_query_parameter.out",
    "content": "$ bal run http_client_query_parameter.bal\nReceived albums: [{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}]\n"
  },
  {
    "path": "examples/http-client-query-parameter/http_client_query_parameter_post.bal",
    "content": "// Sends a `POST` request to the \"/album\" resource.\n// The query parameter can be provided as parameters in the `post` method invocation.\nstring albumId = check albumClient->/album.post({\n        title: \"Sarah Vaughan and Clifford Brown\",\n        artist: \"Sarah Vaughan\"\n    },\n    apiVersion = 2\n);\nio:println(\"Added album with id: \" + albumId);\n"
  },
  {
    "path": "examples/http-client-redirects/http_client_redirects.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\npublic function main() returns error? {\n    // The `followRedirects` record provides configurations associated with HTTP redirects.\n    http:Client albumClient = check new (\"localhost:9092\",\n        followRedirects = {\n            enabled: true,\n            maxCount: 5\n        }\n    );\n    Album[] payload = check albumClient->/redirect;\n    io:println(string `Response received: ${payload.toJsonString()}`);\n}\n"
  },
  {
    "path": "examples/http-client-redirects/http_client_redirects.md",
    "content": "# HTTP client - Redirects\n\nThe `http:Client` supports redirection. If the `http:Response` contains a `redirect` status code with `Location` header, the client internally calls the respective endpoint and returns the successful response. To enable redirection, set `followRedirect` to `true` in the client config.\n\n::: code http_client_redirects.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Redirect service](/learn/by-example/http-service-redirects/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_redirects.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client redirect - Specification](/spec/http/#2413-redirect)\n"
  },
  {
    "path": "examples/http-client-redirects/http_client_redirects.metatags",
    "content": "description: This example is on how to do an HTTP redirect with the Ballerina HTTP client connector.\nkeywords: ballerina, ballerina by example, bbe, http, redirect\n"
  },
  {
    "path": "examples/http-client-redirects/http_client_redirects.out",
    "content": "$ bal run http_client_redirects.bal\nResponse received: [{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-redirects/tests/http_client_redirects_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new (\"localhost:9092\",\n    followRedirects = {enabled: true, maxCount: 5});\n\n    // Send a GET request to the specified endpoint\n    Album[] response = check httpEndpoint->get(\"/redirect\");\n    test:assertEquals(response, [{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]);\n}\n\nservice / on new http:Listener(9092) {\n\n    resource function get redirect() returns http:TemporaryRedirect {\n        // Return a redirect response record with the location header.\n        return {headers: {\"Location\": \"http://localhost:9090/albums\"}};\n    }\n}\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-client-self-signed-jwt-authentication/http_client_self_signed_jwt_authentication.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Defines the HTTP client to call the JWT Auth secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `http:JwtIssuerConfig` for the `auth` configuration of the\n    // client. A self-signed JWT is issued before the request is sent.\n    http:Client albumClient = check new (\"localhost:9090\",\n        auth = {\n            username: \"ballerina\",\n            issuer: \"wso2\",\n            audience: [\"ballerina\", \"ballerina.org\", \"ballerina.io\"],\n            keyId: \"5a0b754-895f-4279-8843-b745e11a57e9\",\n            jwtId: \"JlbmMiOiJBMTI4Q0JDLUhTMjU2In\",\n            customClaims: { \"scp\": \"admin\" },\n            expTime: 3600,\n            signatureConfig: {\n                config: {\n                    keyFile: \"../resource/path/to/private.key\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-self-signed-jwt-authentication/http_client_self_signed_jwt_authentication.md",
    "content": "# HTTP client - Self signed JWT authentication\n\nThe `http:Client` can connect to a service that is secured with self-signed JWT by adding the `Authorization: Bearer <token>` header by passing the `http:JwtIssuerConfig` to the `auth` configuration of the client. A self-signed JWT is issued before the request is sent.\n\n::: code http_client_self_signed_jwt_authentication.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [JWT Auth service](/learn/by-example/http-service-jwt-authentication/) example.\n\nRun the client program by executing the command below.\n\n::: out http_client_self_signed_jwt_authentication.out :::\n\n## Related links\n- [`http:JwtIssuerConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#JwtIssuerConfig)\n- [`jwt` module - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n- [HTTP client self signed JWT authentication - Specification](/spec/http/#9127-client---self-signed-jwt)\n"
  },
  {
    "path": "examples/http-client-self-signed-jwt-authentication/http_client_self_signed_jwt_authentication.metatags",
    "content": "description: This example is on how to secure an HTTP client with self-signed JWT Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, jwt auth\n"
  },
  {
    "path": "examples/http-client-self-signed-jwt-authentication/http_client_self_signed_jwt_authentication.out",
    "content": "$ bal run http_client_self_signed_jwt_authentication.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-client-send-request-receive-response/http_client_send_request_receive_response.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Creates a new client with the Basic REST service URL.\n    http:Client albumClient = check new (\"localhost:9090\");\n\n    // Sends a `GET` request to the \"/albums\" resource.\n    // The verb is not mandatory as it is default to \"GET\".\n    Album[] albums = check albumClient->/albums;\n    io:println(\"GET request:\" + albums.toJsonString());\n\n    // Sends a `POST` request to the \"/albums\" resource.\n    Album album = check albumClient->/albums.post({\n        title: \"Sarah Vaughan and Clifford Brown\",\n        artist: \"Sarah Vaughan\"\n    });\n    io:println(\"\\nPOST request:\" + album.toJsonString());\n}\n"
  },
  {
    "path": "examples/http-client-send-request-receive-response/http_client_send_request_receive_response.md",
    "content": "# HTTP client - Send request/Receive response\n\nThe `http:Client` interacts with an HTTP server. The client is instantiated with the service URL and it uses resource methods to send requests and receive responses from the backend service. The standard HTTP methods `get`, `post`, `put`, `patch`, `delete`, `head`, and `options` are available as resource accessors. A resource method invocation is done by providing the `resource path`, relevant `resource accessor`, and required arguments after the `->`. Since HTTP `get` is the default resource method, the accessor is not mandatory when invoking an HTTP `GET` resource.\n\n::: code http_client_send_request_receive_response.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_client_send_request_receive_response.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client - Specification](/spec/http/#24-client)\n"
  },
  {
    "path": "examples/http-client-send-request-receive-response/http_client_send_request_receive_response.metatags",
    "content": "description: This example is on how to interact with an HTTP server using the Ballerina HTTP client connector.\nkeywords: ballerina, ballerina by examples, bbe, http, client\n"
  },
  {
    "path": "examples/http-client-send-request-receive-response/http_client_send_request_receive_response.out",
    "content": "$ bal run http_client_send_request_receive_response.bal\nGET request:[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n\nPOST request:{\"title\":\"Sarah Vaughan and Clifford Brown\", \"artist\":\"Sarah Vaughan\"}\n"
  },
  {
    "path": "examples/http-client-send-request-receive-response/tests/http_client_send_request_receive_response_test.bal",
    "content": "import ballerina/test;\n\n(anydata|error)[] outputs = [];\nint counter = 0;\n\n// This is the mock function which will replace the real function\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(anydata|error... a) {\n    outputs[counter] = a[0];\n    counter += 1;\n}\n\n@test:Config {}\nfunction testFunc() returns error? {\n     test:when(mock_printLn).call(\"mockPrint\");\n\n    json jsonRes1 = {\n        \"args\": {\n            \"test\": \"123\"\n        },\n        \"url\": \"https://postman-echo.com/get?test=123\"\n    };\n\n    json jsonRes2 = {\n        \"args\": {},\n        \"data\": \"POST: Hello World\",\n        \"files\": {},\n        \"form\": {},\n        \"json\": null,\n        \"url\": \"https://postman-echo.com/post\"\n    };\n\n    json jsonRes5 = {\n        \"args\": {},\n        \"data\": \"DELETE: Hello World\",\n        \"files\": {},\n        \"form\": {},\n        \"json\": null,\n        \"url\": \"https://postman-echo.com/delete\"\n    };\n\n    // Invoking the main function\n    main();\n\n    test:assertEquals(outputs[0], \"GET request:\");\n\n    // Remove the headers since the user-agent will be different\n    // from ballerina version to version.\n    map<json> res = <map<json>> check outputs[1];\n    var result = res.remove(\"headers\");\n    test:assertEquals(res, jsonRes1);\n\n    test:assertEquals(outputs[2], \"\\nPOST request:\");\n\n    res = <map<json>> check outputs[3];\n    result = res.remove(\"headers\");\n    test:assertEquals(res, jsonRes2);\n\n    test:assertEquals(outputs[4], \"\\nDELETE request:\");\n\n    res = <map<json>> check outputs[5];\n    result = res.remove(\"headers\");\n    test:assertEquals(res, jsonRes5);\n\n    test:assertEquals(outputs[6], \"\\nUse custom HTTP verbs:\");\n    test:assertEquals(outputs[7], \"Content-Type: application/json; charset=utf-8\");\n    test:assertEquals(outputs[8], \"Status code: 200\");\n}\n"
  },
  {
    "path": "examples/http-client-ssl-tls/http_client_ssl_tls.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\",\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-client-ssl-tls/http_client_ssl_tls.md",
    "content": "# HTTP client - SSL/TLS\n\nThe `http:Client` can be configured to communicate through HTTPS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the client configuration. Use this to secure the communication between the client and the server.\n\n::: code http_client_ssl_tls.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [SSL/TLS service](/learn/by-example/http-service-ssl-tls/) example.\n\nRun the secure client program by executing the command below.\n\n::: out http_client_ssl_tls.out :::\n\n## Related links\n- [`http:ClientSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#ClientSecureSocket)\n- [HTTP client SSL/TLS - Specification](/spec/http/#923-client---ssltls)\n"
  },
  {
    "path": "examples/http-client-ssl-tls/http_client_ssl_tls.metatags",
    "content": "description: This example is on how to secure an HTTP client with SSL.\nkeywords: ballerina, ballerina by example, bbe, http, ssl, tls\n"
  },
  {
    "path": "examples/http-client-ssl-tls/http_client_ssl_tls.out",
    "content": "$ bal run http_client_ssl_tls.bal\n[{\"title\":\"Blue Train\",\"artist\":\"John Coltrane\"},{\"title\":\"Jeru\",\"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-compression/http_compression.bal",
    "content": "import ballerina/http;\n\n// `COMPRESSION_ALWAYS` guarantees a compressed response entity body. The compression scheme is set to the\n// value indicated in `Accept-Encoding` request header. When a particular header is not present or the header\n// value is `identity`, encoding is done using the \"gzip\" scheme.\n// By default, Ballerina compresses any MIME type unless they are mentioned under `contentTypes`.\n// Compression can be constrained to certain MIME types by specifying them as an array of MIME types.\n// In this example encoding is applied to `text/plain` responses only.\n@http:ServiceConfig {\n    compression: {\n        enable: http:COMPRESSION_ALWAYS,\n        contentTypes: [\"text/plain\"]\n    }\n}\nservice / on new http:Listener(9090) {\n\n    // The response entity body is always compressed since MIME type has matched.\n    resource function 'default compress() returns string {\n        return \"Type : This is a string.\";\n    }\n}\n"
  },
  {
    "path": "examples/http-compression/http_compression.client.out",
    "content": "$ curl -v --output - http://localhost:9090/compress\n> GET /compress HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.58.0\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< content-type: text/plain\n< server: ballerina\n< content-encoding: gzip\n< content-length: 48\n<\n\u001f�\n* Connection #0 to host localhost left intact\n�,HU���,V�D�⒢̼t��\u0003ʴ��\u0017\n\n"
  },
  {
    "path": "examples/http-compression/http_compression.md",
    "content": "# HTTP service - Compression\n\nThe `http:Service` can be configured to change the compression behaviour of the `http:Response` payload. By default, the server compresses the response entity body with the scheme(gzip, deflate) that is specified in the `Accept-Encoding` request header. When the particular header is not present, or the header value is `identity`, the server does not perform any compression. Compression is disabled when the option is set to `COMPRESSION_NEVER` and always enabled when the option is set to `COMPRESSION_ALWAYS`. In the same way `http:Client` can be configured as well.\n\n::: code http_compression.bal :::\n\nRun the service as follows.\n\n::: out http_compression.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\nHere, the `Accept-Encoding` header is not specified.\n\n::: out http_compression.client.out :::\n\n## Related links\n- [`COMPRESSION_ALWAYS` - API documentation](https://lib.ballerina.io/ballerina/http/latest#COMPRESSION_ALWAYS)\n- [HTTP service configuration - Specification](https://ballerina.io/spec/http/#241-client-types)\n"
  },
  {
    "path": "examples/http-compression/http_compression.metatags",
    "content": "description: This example demonstrates how to configure a Ballerina HTTP service to change its compression behavior.\nkeywords: ballerina, ballerina by example, bbe, http, compression, accept-encoding\n"
  },
  {
    "path": "examples/http-compression/http_compression.server.out",
    "content": "$ bal run http_compression.bal\n\n"
  },
  {
    "path": "examples/http-compression/tests/http_compression_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    // Send a GET request to the specified endpoint.\n    string response = check httpEndpoint->get(\"/compress\");\n    // Assert the uncompressed response.\n    test:assertEquals(response, \"Type : This is a string.\");\n}\n"
  },
  {
    "path": "examples/http-cookies-client/http_cookies_client.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\n\n// HTTP client configurations associated with enabling cookies.\nhttp:ClientConfiguration clientEPConfig = {\n    cookieConfig: {\n        enabled: true\n    }\n};\n\npublic function main() returns error? {\n    http:Client httpClient = check new (\"localhost:9095/cookieDemo\", clientEPConfig);\n    // Send an outbound request to the `login` backend resource with username and password.\n    string loginResp = check httpClient->post(\"/login\", {\n        name: \"John\",\n        password: \"p@ssw0rd\"\n    });\n    log:printInfo(loginResp);\n\n    // Make another request to the `/welcome` resource of the backend service.\n    // As cookies are enabled in the HTTP client, it automatically handles cookies received with the\n    // login response and sends the relevant cookies to the `welcome` service resource.\n    string welcomeResp = check httpClient->get(\"/welcome\");\n    log:printInfo(welcomeResp);\n}\n"
  },
  {
    "path": "examples/http-cookies-client/http_cookies_client.md",
    "content": "# HTTP client - Cookies\n\nHTTP cookies can track, personalize, and manage the session between the `http:Client` and service. Cookie client behavior is enabled using the `http:ClientConfiguration`. If the cookie-enabled client receives a response with a cookie, the subsequent requests are sent along with the same cookie. Therefore the same session id is passed back to the service to retrieve the previous state. This is useful to maintain stateful interaction.\n\n::: code http_cookies_client.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Cookies service](/learn/by-example/http-cookies-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_cookies_client.out :::\n\n## Related links\n- [`http:Cookie` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Cookie)\n- [HTTP service cookie - Specification](/spec/http/#2416-cookie)\n"
  },
  {
    "path": "examples/http-cookies-client/http_cookies_client.metatags",
    "content": "description: This example is on how to handle HTTP cookies in a Ballerina client.\nkeywords: ballerina, ballerina by example, bbe, http, cookies, client\n"
  },
  {
    "path": "examples/http-cookies-client/http_cookies_client.out",
    "content": "$ bal run http_client.bal\ntime = 2022-12-05T18:29:26.378+05:30 level = INFO module = \"\" message = \"Login succeeded\"\ntime = 2022-12-05T18:29:26.441+05:30 level = INFO module = \"\" message = \"Welcome back John\"\n"
  },
  {
    "path": "examples/http-cookies-service/http_cookies_service.bal",
    "content": "import ballerina/http;\n\nlistener http:Listener serverEP = new (9095);\n\nservice /cookieDemo on serverEP {\n\n    resource function post login(map<json> details) returns http:Response|http:Unauthorized|error {\n\n        // Retrieve the username and password.\n        json name = check details.name;\n        json password = check details.password;\n\n        // Check the password value.\n        if password == \"p@ssw0rd\" {\n\n            // Create a new cookie by setting `name` as the `username` and `value` as the logged-in user's name.\n            // Set the cookies path as `/` to apply it to all the resources in the service.\n            http:Cookie cookie = new (\"username\", name.toString(), path = \"/\");\n            http:Response response = new;\n\n            // Add the created cookie to the response.\n            response.addCookie(cookie);\n\n            // Set a message payload to inform that the login has\n            // been succeeded.\n            response.setTextPayload(\"Login succeeded\");\n            return response;\n        }\n        return http:UNAUTHORIZED;\n    }\n\n    resource function get welcome(http:Request req) returns string|http:NotFound {\n        // Retrieve cookies from the request.\n        http:Cookie[] cookies = req.getCookies();\n\n        // Get the cookie value of the `username`.\n        http:Cookie[] usernameCookie = cookies.filter(function(http:Cookie cookie) returns boolean {\n            return cookie.name == \"username\";\n        });\n\n        if usernameCookie.length() > 0 {\n            string? user = usernameCookie[0].value;\n            if user is string {\n                // Respond with the username added to the welcome message.\n                return \"Welcome back \" + user;\n            }\n        }\n        return http:NOT_FOUND;\n    }\n}\n"
  },
  {
    "path": "examples/http-cookies-service/http_cookies_service.md",
    "content": "# HTTP service - Cookies\n\nHTTP cookies can track, personalize, and manage the session in the service. The cookies can be accessed from the `getCookies` method of the `http:Request`. Setting cookies back in the response is done by the `addCookie` method of the `http:Response`. This is useful for services to maintain the state.\n\n::: code http_cookies_service.bal :::\n\nRun the service as follows.\n\n::: out http_cookies_service.out :::\n\n>**Tip:** You can invoke the above service via the [Cookies client](/learn/by-example/http-cookies-client/) example.\n\n## Related links\n- [`http:Cookie` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Cookie)\n- [HTTP service cookie - Specification](/spec/http/#2416-cookie)\n"
  },
  {
    "path": "examples/http-cookies-service/http_cookies_service.metatags",
    "content": "description: This example is on how to handle HTTP cookies in a Ballerina service.\nkeywords: ballerina, ballerina by example, bbe, http, cookies, server\n"
  },
  {
    "path": "examples/http-cookies-service/http_cookies_service.out",
    "content": "$ bal run cookie_server.bal\n"
  },
  {
    "path": "examples/http-cors/http_cors.bal",
    "content": "import ballerina/http;\n\n// The service-level CORS config applies globally to each `resource`.\n@http:ServiceConfig {\n    cors: {\n        allowOrigins: [\"http://www.m3.com\", \"http://www.hello.com\"],\n        allowCredentials: false,\n        allowHeaders: [\"CORELATION_ID\"],\n        exposeHeaders: [\"X-CUSTOM-HEADER\"],\n        maxAge: 84900\n    }\n}\nservice /crossOriginService on new http:Listener(9092) {\n\n    // The resource-level CORS config overrides the service-level CORS headers.\n    @http:ResourceConfig {\n        cors: {\n            allowOrigins: [\"http://www.bbc.com\"],\n            allowCredentials: true,\n            allowHeaders: [\"X-Content-Type-Options\", \"X-PINGOTHER\"]\n        }\n    }\n    resource function get company() returns string {\n        return \"middleware\";\n    }\n\n    // Since there are no resource-level CORS configs defined here, the global\n    // service-level CORS configs will be applied to this resource.\n    resource function post lang(@http:Payload string lang) returns string {\n        return lang;\n    }\n}\n"
  },
  {
    "path": "examples/http-cors/http_cors.client.out",
    "content": "# To send a CORS simple request.\n$ curl -v \"http://localhost:9092/crossOriginService/company\" -H \"Origin:http://www.bbc.com\"\n> GET /crossOriginService/company HTTP/1.1\n> Host: localhost:9092\n> User-Agent: curl/7.64.1\n> Accept: */*\n> Origin:http://www.bbc.com\n>\n< HTTP/1.1 200 OK\n< content-type: text/plain\n< access-control-allow-origin: http://www.bbc.com\n< access-control-allow-credentials: true\n< content-length: 10\n< server: ballerina\n< date: Sat, 22 Oct 2022 20:51:49 +0530\n<\n* Connection #0 to host localhost left intact\nmiddleware* Closing connection 0\n\n# To send a CORS preflight request.\n$ curl -v \"http://localhost:9092/crossOriginService/lang\" -X OPTIONS -H \"Origin:http://www.m3.com\" -H \"Access-Control-Request-Method:POST\"\n> OPTIONS /crossOriginService/lang HTTP/1.1\n> Host: localhost:9092\n> User-Agent: curl/7.64.1\n> Accept: */*\n> Origin:http://www.m3.com\n> Access-Control-Request-Method:POST\n>\n< HTTP/1.1 204 No Content\n< access-control-allow-origin: http://www.m3.com\n< access-control-max-age: 84900\n< access-control-allow-methods: POST\n< server: ballerina\n< date: Sat, 22 Oct 2022 20:53:12 +0530\n<\n* Connection #0 to host localhost left intact\n* Closing connection 0\n"
  },
  {
    "path": "examples/http-cors/http_cors.md",
    "content": "# HTTP service - CORS (Cross-Origin Resource Sharing)\n\nCross-Origin Resource Sharing (CORS) is an HTTP-header-based mechanism that allows a server to indicate any origins other than its own from which a browser should permit. The CORS headers can be applied at both the service level and the resource level. Each configuration has the `cors` field to specify the CORS config. Service-level CORS headers apply to all the resources unless there are headers configured at the resource level. Ballerina CORS supports both simple and pre-flight requests.\n\n::: code http_cors.bal :::\n\nRun the service as follows.\n\n::: out http_cors.server.out :::\n\nInvoke the service by executing the following cURL commands in a new terminal.\n\n::: out http_cors.client.out :::\n\n## Related links\n- [`http:CorsConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#CorsConfig)\n- [HTTP service configuration - Specification](/spec/http/#41-service-configuration);"
  },
  {
    "path": "examples/http-cors/http_cors.metatags",
    "content": "description: This example demonstrates the HTTP service-level and resource-level CORS configurations.\nkeywords: ballerina, ballerina by example, bbe, http, cors\n"
  },
  {
    "path": "examples/http-cors/http_cors.server.out",
    "content": "$ bal run http_cors.bal\n"
  },
  {
    "path": "examples/http-cors/tests/http_cors_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9092\");\n    string expected = \"middleware\";\n\n    // Send a `GET` request to the specified endpoint.\n    string companyResponse = check httpEndpoint->get(\"/crossOriginService/company\", {\"Origin\":\"http://www.bbc.com\"});\n    test:assertEquals(companyResponse, expected);\n\n    var headers = {\"Origin\": \"http://www.m3.com\", \"Access-Control-Request-Method\": \"POST\"};\n    // Send a `GET` request to the specified endpoint.\n    http:Response|error langResponse = httpEndpoint->options(\"/crossOriginService/lang\", headers);\n    if langResponse is http:Response {\n        // Asserting the header values.\n        test:assertEquals(langResponse.getHeader(\"Access-Control-Allow-Methods\"), \"POST\");\n        test:assertEquals(langResponse.getHeader(\"Access-Control-Allow-Origin\"), \"http://www.m3.com\");\n    } else {\n        test:assertFail(msg = \"Failed to call the endpoint:\");\n    }\n}\n"
  },
  {
    "path": "examples/http-default-error-handling/http_default_error_handling.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\nservice / on new http:Listener(9090) {\n\n    resource function get artist() returns string|error {\n        // Creates a new client with an invalid endpoint URL.\n        http:Client albumClient = check new (\"localhost:9091\");\n        Album[] albums = check albumClient->/albums;\n        return \"First artist name: \" + albums[0].artist;\n    }\n}\n"
  },
  {
    "path": "examples/http-default-error-handling/http_default_error_handling.client.out",
    "content": "$ curl -v localhost:9090/artist\n*   Trying 127.0.0.1:9090...\n* TCP_NODELAY set\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> GET /artist HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.68.0\n> Accept: */*\n>\n* Mark bundle as not supporting multiuse\n< HTTP/1.1 502 Bad Gateway\n< content-type: application/json\n< content-length: 210\n< server: ballerina\n< date: Fri, 16 Jun 2023 10:40:52 +0530\n<\n* Connection #0 to host localhost left intact\n{\"timestamp\":\"2023-06-16T05:10:52.220224Z\", \"status\":502, \"reason\":\"Bad Gateway\", \"message\":\"Something wrong with the connection: Connection refused: localhost/127.0.0.1:9091\", \"path\":\"/artist\", \"method\":\"GET\"}\n"
  },
  {
    "path": "examples/http-default-error-handling/http_default_error_handling.md",
    "content": "# HTTP service - Error handling\n\nThe Ballerina `http` module allows returning `error`s from the resource method. Therefore, application logic written inside a resource method could propagate errors from the resource method to the `http:Listener`. Though there are many ways to propagate errors, the most common way is to use the `check` keyword. `http:Listener` intercepts these errors and sends a `500 Internal Server Error` response with the error message in the payload. In addition, it logs the error with the stack trace in the console. Users can take control of this behavior by adding a `do/fail` block in the resource method and handling the errors themselves. When there is a repetition of error handling logic in the resource method, the repetition can be avoided by moving the logic to an Error handler interceptor.\n\n>**Note:** Errors originating from the `http:Listener` itself due to resource not found, data-binding, authorization, etc are converted into respective status codes such as `500 Internal Server Error`, `400 Bad Request`, `401 Unauthorized`, etc. Again, users can take control of this behavior by adding an Error handler interceptor.\n\n::: code http_default_error_handling.bal :::\n\nRun the service as follows.\n\n::: out http_default_error_handling.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_default_error_handling.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP error handling - Specification](/spec/http/#82-error-handling)\n"
  },
  {
    "path": "examples/http-default-error-handling/http_default_error_handling.metatags",
    "content": "description: This example demonstrates how HTTP error handling is done by default in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, interceptor, error\n"
  },
  {
    "path": "examples/http-default-error-handling/http_default_error_handling.server.out",
    "content": "$ bal run http_default_error_handling.bal\n\nerror: Something wrong with the connection\ncause: Connection refused: localhost/127.0.0.1:9091\n"
  },
  {
    "path": "examples/http-default-error-handling/tests/http_default_error_handling_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    http:Response response = check httpEndpoint->get(\"/artist\");\n    test:assertEquals(response.statusCode, 502);\n}\n"
  },
  {
    "path": "examples/http-default-resource/http_default_resource.bal",
    "content": "import ballerina/http;\n\nservice on new http:Listener(9090) {\n\n    // The `default` accessor can be used to match with all methods including the standard HTTP methods\n    // and custom methods. The rest param is used to represent the wildcard of the `resource path` in which any path\n    // segment will get dispatched to the resource in the absence of an exact path match.\n    resource function 'default [string... paths](http:Request req) returns string {\n        return string `method: ${req.method}, path: ${paths.toString()}`;\n    }\n}\n"
  },
  {
    "path": "examples/http-default-resource/http_default_resource.client.out",
    "content": "$ curl \"http://localhost:9090/foo/bar\"\nmethod: GET, path: [\"foo\",\"bar\"]\n"
  },
  {
    "path": "examples/http-default-resource/http_default_resource.md",
    "content": "# HTTP service - Default resource\n\nThe default resource slightly varies from the usual resource method as it uses `rest parameters` as the `resource path` and the `default` identifier as the `resource accessor`. The `rest parameters` allow any of the URL paths to be matched, and it supports `string`, `int`, `float`, `boolean`, and `decimal` as types. The `default` identifier also allows any HTTP methods to be dispatched to the resource method. Use it when designing a REST API to handle proxy services or as a default location to get dispatched if none of the other resources are matched.\n\n::: code http_default_resource.bal :::\n\nRun the service as follows.\n\n::: out http_default_resource.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_default_resource.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service default resource - Specification](/spec/http/#233-path-parameter)\n"
  },
  {
    "path": "examples/http-default-resource/http_default_resource.metatags",
    "content": "description: This example is on how to use the `rest-param` and the `default` accessor (HTTP verb) in Ballerina to dispatch and constrain the service in a RESTful manner.\nkeywords: ballerina, ballerina by example, bbe, http service, path, verb\n"
  },
  {
    "path": "examples/http-default-resource/http_default_resource.server.out",
    "content": "$ bal run http_default_resource.bal\n"
  },
  {
    "path": "examples/http-default-resource/tests/http_default_resource_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    string response = check httpEndpoint->get(\"/foo/bar\");\n    test:assertEquals(response, \"method: GET, path: [\\\"foo\\\",\\\"bar\\\"]\");\n}\n"
  },
  {
    "path": "examples/http-error-handling/http_error_handling.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Sarah Vaughan and Clifford Brown\", artist: \"Sarah Vaughan\"}\n];\n\n// A `ResponseErrorInterceptor` service class implementation.\nservice class ResponseErrorInterceptor {\n    *http:ResponseErrorInterceptor;\n\n    // The error occurred in the request-response path can be accessed by the \n    // mandatory argument: `error`. The remote method can return a response,\n    // which will overwrite the existing error response.\n    remote function interceptResponseError(error err) returns http:BadRequest {\n        // In this case, all the errors are sent as `400 BadRequest` responses with a customized\n        // media type and body. Moreover, you can send different status code responses according to\n        // the error type.        \n        return {\n            mediaType: \"application/org+json\",\n            body: {message: err.message()}\n        };\n    }\n}\n\n// Engage interceptors at the service level using an `http:InterceptableService`. The base path of the\n// interceptor services is the same as the target service. Hence, they will be executed only for\n// this particular service.\nservice http:InterceptableService / on new http:Listener(9090) {\n\n    // Service-level error interceptors can handle errors occurred during the service execution.\n    public function createInterceptors() returns ResponseErrorInterceptor {\n        // To handle all of the errors, the `ResponseErrorInterceptor` is added as a first\n        // interceptor as it has to be executed last.\n        return new ResponseErrorInterceptor();\n    }\n\n    // If the request does not have an`x-api-version` header, then an error will be returned\n    // and the execution will jump to the nearest `ResponseErrorInterceptor`.\n    resource function get albums(@http:Header {name: \"x-api-version\"} string xApiVersion)\n            returns Album[]|http:NotImplemented {\n        if xApiVersion != \"v1\" {\n            return http:NOT_IMPLEMENTED;\n        }\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-error-handling/http_error_handling.client.out",
    "content": "$ curl -v http://localhost:9090/albums\n*   Trying 127.0.0.1:9090...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 400 Bad Request\n< content-type: application/org+json\n< content-length: 55\n< server: ballerina\n< date: Wed, 14 Dec 2022 15:33:27 +0530\n< \n{\"message\":\"no header value found for 'x-api-version'\"}\n"
  },
  {
    "path": "examples/http-error-handling/http_error_handling.md",
    "content": "# HTTP service - Error handling\n\nError handling is an integral part of any network program. Errors can be returned by many components such as an interceptor, dispatcher, data binder, security handler, etc. These errors are often handled by a default handler and sent back as `500 InternalSeverError` responses with the error message in the body. This behavior can be changed by adding error interceptors to the interceptor pipeline, which can intercept these errors and handle them as you wish. These error interceptors can be placed anywhere in the interceptor pipeline. When there is an error, execution jumps to the closest error interceptor. Use these error interceptors to handle errors yourself and create appropriate responses for different error types.\n\n::: code http_error_handling.bal :::\n\nRun the service as follows.\n\n::: out http_error_handling.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_error_handling.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service error handling - Specification](/spec/http/#82-error-handling)\n"
  },
  {
    "path": "examples/http-error-handling/http_error_handling.metatags",
    "content": "description: This example demonstrates how to handle HTTP errors manually in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, interceptor, error\n"
  },
  {
    "path": "examples/http-error-handling/http_error_handling.server.out",
    "content": "$ bal run http_error_handling.bal\n"
  },
  {
    "path": "examples/http-error-handling/tests/http_error_handling_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    json expectedBody = {\n        message : \"no header value found for 'x-api-version'\"\n    };\n    http:Client clientEP = check new(\"localhost:9090\");\n    http:Response res = check clientEP->get(\"/albums\");\n    test:assertEquals(res.statusCode, 400);\n    test:assertEquals(res.getContentType(), \"application/org+json\");\n    test:assertEquals(check res.getJsonPayload(), expectedBody);\n}\n"
  },
  {
    "path": "examples/http-failover/http_failover.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Define the failover client endpoint to call the backend services.\n    http:FailoverClient albumClient = check new ({\n\n        timeout: 5,\n        failoverCodes: [501, 502, 503],\n        interval: 5,\n        // Define a set of HTTP Clients that are targeted for failover.\n        targets: [\n            {url: \"http://nonexistentEP\"},\n            {url: \"http://localhost:9090\"}\n        ]\n    });\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-failover/http_failover.md",
    "content": "# HTTP client - Failover\n\nA failover client is used to preserve the continuity of the requests flow even if the endpoint fails. The endpoints are defined in the `targets` field of the failover client configuration. If one of the endpoints fails, the client automatically fails over to another endpoint.\n\n::: code http_failover.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the program by executing the following command.\n\n::: out http_failover.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client failover - Specification](/spec/http/#2418-failover)\n"
  },
  {
    "path": "examples/http-failover/http_failover.metatags",
    "content": "description: This example is on how to use an HTTP failover client to handle network-related issues gracefully in Ballerina. \nkeywords: ballerina, ballerina by examples, bbe, http, resiliency, failover\n"
  },
  {
    "path": "examples/http-failover/http_failover.out",
    "content": "$ bal run http_failover.bal\n"
  },
  {
    "path": "examples/http-failover/tests/http_failover_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\nimport ballerina/lang.runtime;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:FailoverClient httpEndpoint = check new ({\n\n        timeout: 5,\n        failoverCodes: [501, 502, 503],\n        interval: 5,\n        targets: [\n                {url: \"http://nonexistentEP/mock1\"},\n                {url: \"http://localhost:8080/echo\"},\n                {url: \"http://localhost:8080/mock\"}\n            ]\n    });\n\n    string response = check httpEndpoint->/greeting;\n    test:assertEquals(response, \"The mock resource is invoked.\");\n}\n\n// Define the sample service to mock connection timeouts and service outages.\nservice / on new http:Listener(8080) {\n    resource function 'default echo/greeting() returns string {\n\n        // Delay the response for 30 seconds to mimic network level delays.\n        runtime:sleep(30);\n        return \"The echo resource is invoked\";\n    }\n\n    // Define the sample resource to mock a healthy service.\n    resource function 'default mock/greeting() returns string {\n        return \"The mock resource is invoked.\";\n    }\n}\n"
  },
  {
    "path": "examples/http-header-param/http_header_param.bal",
    "content": "import ballerina/http;\nimport ballerina/mime;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The `accept` argument with `@http:Header` annotation takes the value of the `Accept` request header.\n    resource function get albums(@http:Header string accept) returns Album[]|http:NotAcceptable {\n        if !string:equalsIgnoreCaseAscii(accept, mime:APPLICATION_JSON) {\n            return http:NOT_ACCEPTABLE;\n        }\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-header-param/http_header_param.client.out",
    "content": "$ curl \"http://localhost:9090/albums\" -H \"Accept:application/json\"\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-header-param/http_header_param.md",
    "content": "# REST service - Header parameter\n\nThe `@http:header` annotation allows reading header values from the request. The annotation can be used to annotate a given resource parameter. The name of the parameter must match the name of the header. If there is a mismatch, then the header name must be given in the annotation configuration. The resource parameter can be a simple type or an array type (i.e., `string version` or `string[] versions`). If there are many headers to read, a record type can be used as the parameter. Unless the parameter is optional (i.e., `string? version`), a `400 Bad Request` response is sent to the client in the absence of the mapping header.\n\n::: code http_header_param.bal :::\n\nRun the service as follows.\n\n::: out http_header_param.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_header_param.client.out :::\n\n>**Tip:** You can invoke the above service via the client given in the [HTTP client - Header parameter](/learn/by-example/http-client-header-parameter/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service header parameter - Specification](/spec/http/#2345-header-parameter)\n"
  },
  {
    "path": "examples/http-header-param/http_header_param.metatags",
    "content": "description: This example is on how to use the `@http:Header` annotation to retrieve HTTP headers.\nkeywords: ballerina, ballerina by example, bbe, http, http-headers\n"
  },
  {
    "path": "examples/http-header-param/http_header_param.server.out",
    "content": "$ bal run http_headers.bal\n"
  },
  {
    "path": "examples/http-header-param/tests/http_header_param_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    Album[] payload = check testClient->get(\"/albums\", {\"Accept\":\"application/json\"});\n    test:assertEquals(payload, [{title:\"Blue Train\",artist:\"John Coltrane\"},{title:\"Jeru\",artist:\"Gerry Mulligan\"}]);\n\n    Album|error response = testClient->get(\"/albums\", {\"Accept\":\"application/xml\"});\n    if response is http:ClientRequestError {\n        test:assertEquals(response.detail().statusCode, 406);\n    } else {\n        test:assertFail(\"Unexpected status code\");\n    }\n}\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/http_interceptor_error_handling.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Sarah Vaughan and Clifford Brown\", artist: \"Sarah Vaughan\"}\n];\n\nservice class RequestInterceptor {\n    *http:RequestInterceptor;\n\n    // This will return a `HeaderNotFoundError` if you do not set the `x-api-version` header. \n    // Then, the execution will jump to the nearest `RequestErrorInterceptor`.\n    resource function 'default [string... path](\n            http:RequestContext ctx,\n            @http:Header {name: \"x-api-version\"} string xApiVersion)\n        returns http:NotImplemented|http:NextService|error? {\n        // Checks the API version header.    \n        if xApiVersion != \"v1\" {\n            return http:NOT_IMPLEMENTED;\n        }\n        return ctx.next();\n    }\n}\n\n// A `RequestErrorInterceptor` service class implementation. It allows intercepting\n// the error that occurred in the request path and handle it accordingly.\n// A `RequestErrorInterceptor` service class can have only one resource method.\nservice class RequestErrorInterceptor {\n    *http:RequestErrorInterceptor;\n\n    // The resource method inside a `RequestErrorInterceptor` is only allowed\n    // to have the default method and path. The error occurred in the interceptor\n    // execution can be accessed by the mandatory argument: `error`.\n    resource function 'default [string... path](error err) returns http:BadRequest {\n        // In this case, all of the errors are sent as `400 BadRequest` responses with a customized\n        // media type and body. You can also send different status code responses according to\n        // the error type. Furthermore, you can also call `ctx.next()` if you want to continue the \n        // request flow after fixing the error.\n        return {\n            mediaType: \"application/org+json\",\n            body: {message: err.message()}\n        };\n    }\n}\n\nservice http:InterceptableService / on new http:Listener(9090) {\n\n    public function createInterceptors() returns [RequestInterceptor, RequestErrorInterceptor] {\n        // To handle all of the errors in the request path, the `RequestErrorInterceptor`\n        // is added as the last interceptor as it has to be executed last.\n        return [new RequestInterceptor(), new RequestErrorInterceptor()];\n    }\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/http_interceptor_error_handling.client.out",
    "content": "$ curl -v http://localhost:9090/albums\n*   Trying 127.0.0.1:9090...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 400 Bad Request\n< content-type: application/org+json\n< content-length: 55\n< server: ballerina\n< date: Wed, 14 Dec 2022 15:33:27 +0530\n< \n{\"message\":\"no header value found for 'x-api-version'\"}\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/http_interceptor_error_handling.md",
    "content": "# HTTP service - Interceptor error handling\n\nErrors that occurred in the request-response flow can be intercepted and handled by the `ResponseErrorInterceptors`. In addition, the `http:RequestErrorInterceptor` can be used to handle errors that occurred while executing the `RequestInterceptors`. This error interceptor can send a response according to the error similar to a `ResponseErrorInterceptor`. Moreover, it can modify the request and dispatch it to the target service. Use `RequestErrorInterceptors` along with `RequestInterceptors` to validate the request beforehand and handle any errors during this validation.\n\n::: code http_interceptor_error_handling.bal :::\n\nRun the service as follows.\n\n::: out http_interceptor_error_handling.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_interceptor_error_handling.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service error handling - Specification](/spec/http/#82-error-handling)\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/http_interceptor_error_handling.metatags",
    "content": "description: This example demonstrates how HTTP interceptor error handling is done in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, interceptor, error, request, filter\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/http_interceptor_error_handling.server.out",
    "content": "$ bal run http_interceptor_error_handling.bal\n"
  },
  {
    "path": "examples/http-interceptor-error-handling/tests/http_interceptor_error_handling_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    json expectedBody = {\n        message : \"no header value found for 'x-api-version'\"\n    };\n    http:Client clientEP = check new(\"localhost:9090\");\n    http:Response res = check clientEP->get(\"/albums\");\n    test:assertEquals(res.statusCode, 400);\n    test:assertEquals(res.getContentType(), \"application/org+json\");\n    test:assertEquals(check res.getJsonPayload(), expectedBody);\n}\n"
  },
  {
    "path": "examples/http-load-balancer/http_load_balancer.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    // Define the load balance client endpoint to call the backend services.\n    http:LoadBalanceClient albumClient = check new ({\n        // Define the set of HTTP clients that need to be load balanced.\n        targets: [\n            {url: \"http://localhost:9090\"},\n            {url: \"http://localhost:9091\"},\n            {url: \"http://localhost:9092\"}\n        ],\n        timeout: 5\n    });\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-load-balancer/http_load_balancer.md",
    "content": "# HTTP client - Load balancer\n\nA load-balancing client is used when the request load needs to be load balanced across a given set of target endpoints. These endpoints are defined in the `targets` field of the load-balancing client configuration.\n\n::: code http_load_balancer.bal :::\n\n## Prerequisites\n- Run multiple instances of the HTTP service given in [Basic REST services](/learn/by-example/http-basic-rest-service/) example by changing the ports accordingly.\n\nRun the program by executing the following command.\n\n::: out http_load_balancer.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service load balance - Specification](/spec/http/#2417-load-balance)\n"
  },
  {
    "path": "examples/http-load-balancer/http_load_balancer.metatags",
    "content": "description: This example is on how to use an HTTP load balancer in Ballerina to balance the load of an endpoint using a given algorithm.\nkeywords: ballerina, ballerina by examples, bbe, http, resiliency, load balancer, load balance\n"
  },
  {
    "path": "examples/http-load-balancer/http_load_balancer.out",
    "content": "$ bal run http_load_balancer.bal\n"
  },
  {
    "path": "examples/http-load-balancer/tests/http_load_balancer_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:LoadBalanceClient httpEndpoint = check new ({\n        targets: [\n            {url: \"http://localhost:8080/mock1\"},\n            {url: \"http://localhost:8080/mock2\"},\n            {url: \"http://localhost:8080/mock3\"}\n        ],\n        timeout: 5\n    });\n\n    string response = check httpEndpoint->/greeting;\n    test:assertEquals(response, \"Mock1 resource was invoked.\");\n\n    response = check httpEndpoint->/greeting;\n    test:assertEquals(response, \"Mock2 resource was invoked.\");\n\n    response = check httpEndpoint->/greeting;\n    test:assertEquals(response, \"Mock3 resource was invoked.\");\n\n    response = check httpEndpoint->/greeting;\n    test:assertEquals(response, \"Mock1 resource was invoked.\");\n}\n\nservice / on new http:Listener(8080) {\n    resource function get mock1/greeting() returns string {\n        return \"Mock1 resource was invoked.\";\n    }\n\n    resource function get mock2/greeting() returns string {\n        return \"Mock2 resource was invoked.\";\n    }\n\n    resource function get mock3/greeting() returns string {\n        return \"Mock3 resource was invoked.\";\n    }\n}\n"
  },
  {
    "path": "examples/http-matrix-param/http_matrix_param.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue-Train\", artist: \"John-Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry-Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums/[string title](http:Request req) returns Album|http:NotFound|http:BadRequest {\n        Album? album = albums[title];\n        if album is () {\n            return http:NOT_FOUND;\n        }\n\n        // Gets the `MatrixParams` of the path `/albums`.\n        map<any> pathMParams = req.getMatrixParams(\"/albums\");\n        string artist = <string>pathMParams[\"artist\"];\n\n        if album.artist != artist {\n            return http:BAD_REQUEST;\n        }\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-matrix-param/http_matrix_param.client.out",
    "content": "$ curl \"http://localhost:9090/albums;artist=John-Coltrane/Blue-Train\"\n{\"title\":\"Blue-Train\", \"artist\":\"John-Coltrane\"}\n"
  },
  {
    "path": "examples/http-matrix-param/http_matrix_param.md",
    "content": "# HTTP service - Matrix parameter\n\nThe matrix parameter enhances the hierarchical structure of HTTP URIs. The `http:Request` has the `getMatrixParams` method to extract the matrix parameter map from the given path segment.\n\n::: code http_matrix_param.bal :::\n\nRun the service as follows.\n\n::: out http_matrix_param.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_matrix_param.client.out :::\n\n## Related links\n- [`getMatrixParams()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Request#getMatrixParams)\n- [HTTP service matrix parameter - Specification](https://ballerina.io/spec/http/#53-matrix)\n"
  },
  {
    "path": "examples/http-matrix-param/http_matrix_param.metatags",
    "content": "description: This example is on how to extract values using the matrix path parameters in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, matrix param\n"
  },
  {
    "path": "examples/http-matrix-param/http_matrix_param.server.out",
    "content": "$ bal run http_matrix_param.bal\n"
  },
  {
    "path": "examples/http-matrix-param/tests/http_matrix_param_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    json payload = check testClient->get(\"/albums;artist=John-Coltrane/Blue-Train\");\n    test:assertEquals(payload, {title:\"Blue-Train\", artist:\"John-Coltrane\"});\n\n    http:Response res = check testClient->get(\"/albums;artist=John/Blue-Train\");\n    test:assertEquals(res.statusCode, 400);\n}\n"
  },
  {
    "path": "examples/http-passthrough/http_passthrough.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\nhttp:Client clientEP = check new (\"localhost:9090\");\n\nservice / on new http:Listener(9092) {\n\n    resource function 'default [string... path](http:Request req) returns Album[]|error {\n        Album[] payload = check clientEP->forward(\"/albums\", req);\n        return payload;\n    }\n}\n"
  },
  {
    "path": "examples/http-passthrough/http_passthrough.client.out",
    "content": "$ curl http://localhost:9092/passthrough\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]*"
  },
  {
    "path": "examples/http-passthrough/http_passthrough.md",
    "content": "# HTTP service - Passthrough\n\nThe passthrough service forwards the inbound request to the backend and returns the backend response. The passthrough resource is designed to allow all HTTP methods as the accessor is the `default`. Also the rest parameter in the resource path as it allows any request URI to get dispatched. When `forward()` is called on the backend client, it forwards the request that the passthrough resource received to the backend. When forwarding, the request is made using the same HTTP method that was used to invoke the passthrough resource. The `forward()` function returns the response from the backend if there are no errors. This is useful to delegate the functionality to the downstream services.\n\n::: code http_passthrough.bal :::\n\nRun the service as follows.\n\n::: out http_passthrough.server.out :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example as the backend service.\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_passthrough.client.out :::\n\n## Related links\n- [`forward()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Client#forward)\n- [HTTP service forward method - Specification](/spec/http/#2424-forwardexecute-methods)\n"
  },
  {
    "path": "examples/http-passthrough/http_passthrough.metatags",
    "content": "description: This example demonstrates the process of an HTTP passthrough service in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, passthrough, client\n"
  },
  {
    "path": "examples/http-passthrough/http_passthrough.server.out",
    "content": "$ bal run passthrough.bal\n"
  },
  {
    "path": "examples/http-passthrough/tests/http_passthrough_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new (\"localhost:9092\");\n    http:Response response = check httpEndpoint->get(\"/passthrough\");\n    test:assertEquals(response.statusCode, 200);\n}\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-path-param/http_path_param.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The path param is defined as a part of the resource path within brackets\n    // along with the type and it is extracted from the request URI.\n    resource function get albums/[string title]() returns Album|http:NotFound {\n        Album? album = albums[title];\n        if album is () {\n            return http:NOT_FOUND;\n        }\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-path-param/http_path_param.client.out",
    "content": "$ curl \"http://localhost:9090/albums/Jeru\"\n{\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}\n"
  },
  {
    "path": "examples/http-path-param/http_path_param.md",
    "content": "# REST service - Path parameter\n\nThe `path parameter` is a mandatory but variable part of a resource URL. `path parameters` can be added to a resource method by specifying the parameter type and name in the resource path (eg: `albums/[string name]`). The `http` module supports `string`, `int`, `float`, `boolean`, and `decimal` types as path parameter types. Use it when designing REST API endpoints that require dynamic path segments.\n\n::: code http_path_param.bal :::\n\nRun the service as follows.\n\n::: out http_path_param.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_path_param.client.out :::\n\n>**Tip:** You can invoke the above service via the client given in the [HTTP client - Path parameter](/learn/by-example/http-client-path-parameter/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service path parameter - Specification](/spec/http/#233-path-parameter)\n"
  },
  {
    "path": "examples/http-path-param/http_path_param.metatags",
    "content": "description: This example is on how to extract the path parameters in a Ballerina resource function.\nkeywords: ballerina, ballerina by example, bbe, http, path param\n"
  },
  {
    "path": "examples/http-path-param/http_path_param.server.out",
    "content": "$ bal run path_param.bal\n"
  },
  {
    "path": "examples/http-path-param/tests/http_path_param_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    Album payload = check httpEndpoint->get(\"/albums/Blue Train\");\n    test:assertEquals(payload, {title:\"Blue Train\", artist:\"John Coltrane\"});\n\n    Album|error response = httpEndpoint->get(\"/albums/abba\");\n    if response is http:ClientRequestError {\n        test:assertEquals(response.detail().statusCode, 404);\n    } else {\n        test:assertFail(\"Unexpected status code\");\n    }\n}\n"
  },
  {
    "path": "examples/http-query-parameter/http_query_parameter.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The `artist` resource method argument is considered as the query parameter which is extracted from the request URI.\n    resource function get albums(string artist) returns Album[] {\n        return from Album album in albums\n            where album.artist == artist\n            select album;\n    }\n}\n"
  },
  {
    "path": "examples/http-query-parameter/http_query_parameter.client.out",
    "content": "$ curl \"http://localhost:9090/albums?artist=John%20Coltrane\"\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}]\n"
  },
  {
    "path": "examples/http-query-parameter/http_query_parameter.md",
    "content": "# REST service - Query parameter\n\nThe query parameter in the resource argument represents the query segment of the request URL. The argument name should be the key of the query, and its value is mapped during the runtime by extracting it from the URL. The query parameter does not need any additional annotation. The supported types are `string`, `int`, `float`, `boolean`, `decimal`, and `array` types of the aforementioned types. The query parameter type can be nilable (e.g., (`string? bar`)) and defaultable (e.g., (`string bar = \"hello\"`)). When a request contains query segments, retrieving them as resource arguments is much simpler and well-recommended. Alternatively, the `http:Request` also provides related methods to retrieve query parameters.\n\n::: code http_query_parameter.bal :::\n\nRun the service as follows.\n\n::: out http_query_parameter.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_query_parameter.client.out :::\n\n>**Tip:** You can invoke the above service via the client given in the [HTTP client - Query parameter](/learn/by-example/http-client-query-parameter/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service query parameter - Specification](/spec/http/#2343-query-parameter)\n"
  },
  {
    "path": "examples/http-query-parameter/http_query_parameter.metatags",
    "content": "description: This example is on how to extract the query parameters in an HTTP resource function.\nkeywords: ballerina, ballerina by example, bbe, http service, query parameter\n"
  },
  {
    "path": "examples/http-query-parameter/http_query_parameter.server.out",
    "content": "$ bal run http_query_parameter.bal\n"
  },
  {
    "path": "examples/http-query-parameter/tests/http_query_parameter_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new (\"localhost:9090\");\n    json[] payload = check httpEndpoint->/albums(artist = \"John Coltrane\");\n    test:assertEquals(payload, [{title: \"Blue Train\", artist: \"John Coltrane\"}]);\n\n    payload = check httpEndpoint->/albums(artist = \"John\");\n    test:assertEquals(payload, []);\n}\n"
  },
  {
    "path": "examples/http-request-interceptor/http_request_interceptor.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n// A `Requestinterceptorservice` class implementation. It intercepts the request\n// and adds a header before it is dispatched to the target service.\nservice class RequestInterceptor {\n    *http:RequestInterceptor;\n\n    // A default resource method, which will be executed for all the requests.\n    // A `RequestContext` is used to share data between the interceptors.\n    // An accessor and a path can also be specified. In that case, the interceptor will be\n    // executed only for the requests, which match the accessor and path.\n    resource function 'default [string... path](\n            http:RequestContext ctx,\n            @http:Header {name: \"x-api-version\"} string xApiVersion)\n        returns http:NotImplemented|http:NextService|error? {\n        // Checks the API version header.\n        if xApiVersion != \"v1\" {\n            // Returns a `501 NotImplemented` response if the version is not supported.\n            return http:NOT_IMPLEMENTED;\n        }\n        // Returns the next interceptor or the target service in the pipeline. \n        // An error is returned when the call fails.\n        return ctx.next();\n    }\n}\n\n// Engage interceptors at the service level using an `http:InterceptableService`. The interceptors\n// will inherit the basepath of the service.\nservice http:InterceptableService / on new http:Listener(9090) {\n\n    // Creates the interceptor pipeline. The function can return a single interceptor or an array of\n    // interceptors as the interceptor pipeline. If the interceptor pipeline is an array, then, the\n    // request interceptor services will be executed from head to tail.\n    public function createInterceptors() returns RequestInterceptor {\n        return new RequestInterceptor();\n    }\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-request-interceptor/http_request_interceptor.client.out",
    "content": "$ curl -v http://localhost:9090/albums -H \"x-api-version: v2\"\n*   Trying 127.0.0.1:9090...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> x-api-version: v2\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 501 Not Implemented\n< content-length: 0\n< server: ballerina\n< date: Wed, 14 Dec 2022 15:38:41 +0530\n< \n"
  },
  {
    "path": "examples/http-request-interceptor/http_request_interceptor.md",
    "content": "# HTTP service - Request interceptor\n\nThe `http:RequestInterceptor` is used to intercept the request and execute custom logic. A `RequestInterceptor` is a service object with only one resource method, which is executed before dispatching the request to the actual resource in the target service. This resource method can have parameters just like a usual resource method in an `http:Service`. \n\nA `RequestInterceptor` can be created from a service class, which includes the `http:RequestInterceptor` service type. Then, this service object can be engaged at the service level by declaring an `http:InterceptableService` object. \n\nThis accepts an interceptor service object or an array of interceptor service objects as an interceptor pipeline, and the interceptors are executed in the order in which they are placed in the pipeline. Use `RequestInterceptors` to execute common logic such as logging, header manipulation, state publishing, etc., for inbound requests.\n\n::: code http_request_interceptor.bal :::\n\nRun the service as follows.\n\n::: out http_request_interceptor.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_request_interceptor.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example by adding the required header to the request.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service request interceptor - Specification](/spec/http/#811-request-interceptor)\n"
  },
  {
    "path": "examples/http-request-interceptor/http_request_interceptor.metatags",
    "content": "description: This example demonstrates the HTTP request interceptors in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, service, interceptor, request, filter\n"
  },
  {
    "path": "examples/http-request-interceptor/http_request_interceptor.server.out",
    "content": "$ bal run http_request_interceptor.bal\n"
  },
  {
    "path": "examples/http-request-interceptor/tests/http_request_interceptor_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    http:Client clientEP = check new(\"localhost:9090\");\n    http:Response res = check clientEP->get(\"/albums\", {\"x-api-version\": \"v1\"});\n    test:assertEquals(res.statusCode, 200);\n\n    res = check clientEP->get(\"/albums\", {\"x-api-version\": \"v2\"});\n    test:assertEquals(res.statusCode, 501);\n}\n"
  },
  {
    "path": "examples/http-request-response/http_request_response.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The request is defined in the signature parameter.\n    resource function post albums(http:Request request) returns http:Response|error {\n        json payload = check request.getJsonPayload();\n        Album album = check payload.cloneWithType();\n        albums.add(album);\n\n        // Create a response and populate the headers/payload.\n        http:Response response = new;\n        response.setPayload(album);\n        response.setHeader(\"x-music-genre\", \"Jazz\");\n        return response;\n    }\n}\n"
  },
  {
    "path": "examples/http-request-response/http_request_response.client.out",
    "content": "$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Sarah Vaughan and Clifford Brown\\\", \\\"artist\\\": \\\"Sarah Vaughan\\\"}\"\n{\"title\":\"Sarah Vaughan and Clifford Brown\", \"artist\":\"Sarah Vaughan\"}\n"
  },
  {
    "path": "examples/http-request-response/http_request_response.md",
    "content": "# HTTP service - Request/Response object\n\n`http:Request` and `http:Response` objects are Ballerina abstractions for HTTP request and HTTP response respectively. They are considered low-level abstractions which are used to implement high-level abstractions such as data-binding, header mapping, query parameter mapping, etc. They can be used both on the client side and the service side. They are useful when implementing advanced scenarios such as gateways, proxy services, handling multipart requests, etc. In most cases, the `http:Request` and the `http:Response` objects are not needed as higher-level abstractions can do the same thing.\n\n::: code http_request_response.bal :::\n\nRun the service as follows.\n\n::: out http_request_response.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_request_response.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP request and response - Specification](/spec/http/#6-request-and-response)"
  },
  {
    "path": "examples/http-request-response/http_request_response.metatags",
    "content": "description: This example is on the HTTP request and response usage in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, request, response\n"
  },
  {
    "path": "examples/http-request-response/http_request_response.server.out",
    "content": "$ bal run http_request_response.bal\n"
  },
  {
    "path": "examples/http-request-response/tests/http_request_response_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    Album lastAlbum = check httpEndpoint->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    test:assertEquals(lastAlbum, {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n}\n"
  },
  {
    "path": "examples/http-request-with-multiparts/files/test.xml",
    "content": "<ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.1.client.out",
    "content": "$ curl -F \"part1={\\\"name\\\":\\\"ballerina\\\"};type=application/json\" http://localhost:9090/multiparts/decoder -H \"Content-Type: multipart/mixed\" -H 'Expect:'\n--f710b4a02896b88a\ncontent-disposition: attachment;name=\"part1\"\ncontent-type: application/json\ncontent-id: 0\n\n{\"name\":\"ballerina\"}\n--f710b4a02896b88a--\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.2.client.out",
    "content": "$ curl -v http://localhost:9090/multiparts/encoder\n> GET /multiparts/encoder HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< content-type: multipart/form-data; boundary=bd7547c98465dae2\n< date: Wed, 23 Sep 2020 10:20:17 +0530\n< server: ballerina\n< content-length: 398\n<\n--bd7547c98465dae2\ncontent-disposition: form-data;name=\"json part\"\ncontent-type: application/json\ncontent-id: 0\n\n{\"name\":\"wso2\"}\n--bd7547c98465dae2\ncontent-disposition: form-data;name=\"xml file part\"\ncontent-type: application/xml\ncontent-id: 1\n\n<ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\n--bd7547c98465dae2--\n* Connection #0 to host localhost left intact\n* Closing connection 0\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\nimport ballerina/mime;\n\nservice /multiparts on new http:Listener(9090) {\n\n    resource function post decoder(http:Request request)\n            returns http:Response|http:InternalServerError|error {\n        var bodyParts = check request.getBodyParts();\n        foreach var part in bodyParts {\n            handleContent(part);\n        }\n        http:Response response = new;\n        response.setPayload(bodyParts);\n        return response;\n    }\n\n    resource function get encoder(http:Request req)\n            returns http:Response|http:InternalServerError|error {\n        //Create a `json` body part.\n        mime:Entity jsonBodyPart = new;\n        jsonBodyPart.setContentDisposition(getContentDispositionForFormData(\"json part\"));\n        jsonBodyPart.setJson({\"name\": \"wso2\"});\n        //Create an `xml` body part as a file upload.\n        mime:Entity xmlFilePart = new;\n        xmlFilePart.setContentDisposition(getContentDispositionForFormData(\"xml file part\"));\n        // This file path is relative to where Ballerina is running.\n        // If your file is located outside,\n        // give the absolute file path instead.\n        xmlFilePart.setFileAsEntityBody(\"./files/test.xml\", contentType = mime:APPLICATION_XML);\n        // Create an array to hold all the body parts.\n        mime:Entity[] bodyParts = [jsonBodyPart, xmlFilePart];\n        http:Request request = new;\n        // Set the body parts to the request.\n        // Here the content-type is set as multipart form data.\n        // This also works with any other multipart media type.\n        // E.g., `multipart/mixed`, `multipart/related` etc.\n        // You need to pass the content type that suits your requirement.\n        request.setBodyParts(bodyParts, contentType = mime:MULTIPART_FORM_DATA);\n        http:Client httpClient = check new (\"localhost:9090\");\n        http:Response returnResponse = check httpClient->/multiparts/decoder.post(request);\n        return returnResponse;\n    }\n}\n\nfunction handleContent(mime:Entity bodyPart) {\n    // Get the media type from the body part retrieved from the request.\n    var mediaType = mime:getMediaType(bodyPart.getContentType());\n    if mediaType is mime:MediaType {\n        string baseType = mediaType.getBaseType();\n        if mime:APPLICATION_XML == baseType || mime:TEXT_XML == baseType {\n            var payload = bodyPart.getXml();\n            if payload is xml {\n                log:printInfo(payload.toString());\n            } else {\n                log:printError(payload.message());\n            }\n        } else if mime:APPLICATION_JSON == baseType {\n            var payload = bodyPart.getJson();\n            if payload is json {\n                log:printInfo(payload.toJsonString());\n            } else {\n                log:printError(payload.message());\n            }\n        } else if mime:TEXT_PLAIN == baseType {\n            var payload = bodyPart.getText();\n            if payload is string {\n                log:printInfo(payload);\n            } else {\n                log:printError(payload.message());\n            }\n        }\n    }\n}\n\nfunction getContentDispositionForFormData(string partName) returns (mime:ContentDisposition) {\n    mime:ContentDisposition contentDisposition = new;\n    contentDisposition.name = partName;\n    contentDisposition.disposition = \"form-data\";\n    return contentDisposition;\n}\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.md",
    "content": "# HTTP client - Request with multiparts\n\nThe multipart payload is one or more different sets of data combined in a single body. The `http:Client` supports multipart content setting and retrieving in the `http:Request` along with the nested parts through support functions. An array of `mime:Entity` is returned when retrieving parts through `getBodyParts` method of the `http:Request`. If the received parts contain nested parts, you can loop through the parent parts and get the child parts. When sending out multipart content, `setBodyParts` is used to set the array of `mime:Entity`. This is useful to handle different content-typed messages as a single payload and large payloads.\n\n::: code http_request_with_multiparts.bal :::\n\nRun the service as follows.\n\n::: out http_request_with_multiparts.server.out :::\n\n## Prerequisites\nIn the directory, which contains the `.bal` file, create a directory named `files`, and add an XML file named `test.xml` in it.\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_request_with_multiparts.1.client.out :::\n\nExecute the following cURL command to encode the parts of the body and send a multipart request via the Ballerina service.\n\n::: out http_request_with_multiparts.2.client.out :::\n\n## Related links\n- [`setBodyParts()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Request#setBodyParts)\n- [HTTP client supported-multipart-types - Specification](/spec/mime/#3-supported-multipart-types)\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.metatags",
    "content": "description: This example is on how Ballerina supports encoding and decoding multipart content in HTTP requests along with nested parts.\nkeywords: ballerina, ballerina by example, bbe, mime, multiparts, entity\n"
  },
  {
    "path": "examples/http-request-with-multiparts/http_request_with_multiparts.server.out",
    "content": "$ bal run request_with_multiparts.bal\ntime = 2021-01-21 22:00:17,167 level = INFO  module = \"\" message = \"{\"name\":\"ballerina\"}\"\ntime = 2021-01-21 22:01:18,466 level = INFO  module = \"\" message = \"{\"name\":\"wso2\"}\"\ntime = 2021-01-21 22:01:18,682 level = INFO  module = \"\" message = \"<ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\"\n"
  },
  {
    "path": "examples/http-request-with-multiparts/tests/http_request_with_multiparts_test.bal",
    "content": "import ballerina/mime;\nimport ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEP = check new (\"localhost:9090\");\n    mime:Entity jsonBodyPart = new;\n    jsonBodyPart.setJson({\"name\": \"ballerina\"});\n    mime:Entity[] bodyParts = [jsonBodyPart];\n    http:Request request = new;\n    request.setBodyParts(bodyParts, contentType = mime:MULTIPART_FORM_DATA);\n    http:Response response1 = check httpEP->post(\"/multiparts/decoder\", request);\n    mime:Entity[] result = check response1.getBodyParts();\n    json jsonValue = check result[0].getJson();\n    test:assertEquals(jsonValue.toJsonString(), \"{\\\"name\\\":\\\"ballerina\\\"}\");\n\n    http:Response response2 = check httpEP->get(\"/multiparts/encoder\");\n    result = check response2.getBodyParts();\n    jsonValue = check result[0].getJson();\n    test:assertEquals(jsonValue.toString(), \"{\\\"name\\\":\\\"wso2\\\"}\");\n    xml xmlValue = check result[1].getXml();\n    xml element1 = xmlValue.selectDescendants(\"version\");\n    test:assertEquals(element1.data(), \"0.963\");\n    xml element2 = xmlValue.selectDescendants(\"test\");\n    test:assertEquals(element2.data(), \"test xml file to be used as a file part\");\n}\n"
  },
  {
    "path": "examples/http-response-interceptor/http_response_interceptor.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n// A `ResponseInterceptor` service class implementation. It intercepts the response \n// and adds a header before it is dispatched to the client.\nservice class ResponseInterceptor {\n    *http:ResponseInterceptor;\n\n    // The `interceptResponse` remote method will be executed for all the\n    // responses. A `RequestContext` is used to share data between interceptors.\n    remote function interceptResponse(http:RequestContext ctx,\n            http:Response res) returns http:NextService|error? {\n        // Sets a header to the response inside the interceptor service.\n        res.setHeader(\"x-api-version\", \"v2\");\n        // Returns the next interceptor in the pipeline or `nil` if there is no \n        // more interceptors to be returned. In case a `nil` value is returned, then,\n        // the modified response will be returned to the client. In addition to these\n        // return values, an error is returned when the call fails.\n        return ctx.next();\n    }\n}\n\n// Engage interceptors at the service level using an `http:InterceptableService`. The base path of the\n// interceptor services is the same as the target service. Hence, they will be executed only for\n// this particular service.\nservice http:InterceptableService / on new http:Listener(9090) {\n\n    // Creates the interceptor pipeline. The function can return a single interceptor or an array of\n    // interceptors as the interceptor pipeline. If the interceptor pipeline is an array, then, the\n    // request interceptor services will be executed from head to tail.\n    public function createInterceptors() returns ResponseInterceptor {\n        return new ResponseInterceptor();\n    }\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-response-interceptor/http_response_interceptor.client.out",
    "content": "$ curl -v http://localhost:9090/albums\n*   Trying 127.0.0.1:9090...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 200 OK\n< content-type: application/json\n< x-api-version: v2\n< content-length: 95\n< server: ballerina\n< date: Wed, 14 Dec 2022 11:51:35 +0530\n< \n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-response-interceptor/http_response_interceptor.md",
    "content": "# HTTP service - Response interceptor\n\nThe `http:ResponseInterceptor` is used to intercept the response and execute custom logic. A `ResponseInterceptor` is a service object with a remote method called `interceptResponse`, which is executed before dispatching the response to the client. A `ResponseInterceptor` can be created from a service class, which includes the `http:ResponseInterceptor` service type. \n\nThis service object can be engaged at the service level by declaring an `http:InterceptableService` object. This accepts an interceptor service object or an array of interceptor service objects as an interceptor pipeline and the interceptors are executed in the order in which they are placed in the pipeline. \n\nUse `ResponseInterceptors` to execute common logic such as logging, header manipulation, state publishing, etc., for all outbound responses.\n\n::: code http_response_interceptor.bal :::\n\nRun the service as follows.\n\n::: out http_response_interceptor.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_response_interceptor.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/).\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service response interceptor - Specification](/spec/http/#812-response-interceptor)\n"
  },
  {
    "path": "examples/http-response-interceptor/http_response_interceptor.metatags",
    "content": "description: This example demonstrates the HTTP response interceptors in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, service, interceptor, response, filter\n"
  },
  {
    "path": "examples/http-response-interceptor/http_response_interceptor.server.out",
    "content": "$ bal run http_response_interceptor.bal\n"
  },
  {
    "path": "examples/http-response-interceptor/tests/http_response_interceptor_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    http:Client clientEP = check new(\"localhost:9090\");\n    http:Response res = check clientEP->get(\"/albums\");\n    test:assertEquals(res.statusCode, 200);\n    test:assertEquals(check res.getHeader(\"x-api-version\"), \"v2\");\n}\n"
  },
  {
    "path": "examples/http-response-with-multiparts/files/test.xml",
    "content": "<ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.1.client.out",
    "content": "$ curl http://localhost:9092/multiparts/encoder\n--646e483fc8826c55\ncontent-type: multipart/mixed;boundary=e8a931f5e25d263e\n\n--e8a931f5e25d263e\ncontent-type: application/json\n\n{\"name\":\"wso2\"}\n--e8a931f5e25d263e\ncontent-type: text/xml\n\n<ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\n\n--e8a931f5e25d263e--\n\n--646e483fc8826c55--\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.2.client.out",
    "content": "$ curl http://localhost:9090/multiparts/decoder\nBody Parts Received!\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/log;\nimport ballerina/mime;\n\nservice /multiparts on new http:Listener(9092) {\n\n    resource function get encoder() returns http:Response {\n        // Creates an enclosing entity to hold the child parts.\n        mime:Entity parentPart = new;\n        mime:Entity childPart1 = new;\n        childPart1.setJson({\"name\": \"wso2\"});\n        mime:Entity childPart2 = new;\n        // This file path is relative to where the Ballerina is running.\n        // If your file is located outside, give the absolute file path instead.\n        childPart2.setFileAsEntityBody(\"./files/test.xml\", contentType = mime:TEXT_XML);\n        mime:Entity[] childParts = [childPart1, childPart2];\n        parentPart.setBodyParts(childParts, contentType = mime:MULTIPART_MIXED);\n        // Creates an array to hold the parent part and set it to the response.\n        mime:Entity[] immediatePartsToResponse = [parentPart];\n        http:Response outResponse = new;\n        outResponse.setBodyParts(immediatePartsToResponse, contentType = mime:MULTIPART_FORM_DATA);\n        return outResponse;\n    }\n}\n\nservice /multiparts on new http:Listener(9090) {\n\n    // This resource accepts multipart responses.\n    resource function get decoder() returns string|http:InternalServerError|error {\n        http:Client httpClient = check new (\"localhost:9092\");\n        http:Response returnResult = check httpClient->/multiparts/encoder;\n        mime:Entity[] parentParts = check returnResult.getBodyParts();\n        foreach var parentPart in parentParts {\n            handleNestedParts(parentPart);\n        }\n        return \"Body Parts Received!\";\n    }\n}\n\nfunction handleNestedParts(mime:Entity parentPart) {\n    string contentTypeOfParent = parentPart.getContentType();\n    if contentTypeOfParent.startsWith(\"multipart/\") {\n        var childParts = parentPart.getBodyParts();\n        if childParts is mime:Entity[] {\n            log:printInfo(\"Nested Parts Detected!\");\n            foreach var childPart in childParts {\n                handleContent(childPart);\n            }\n        } else {\n            log:printError(\"Error retrieving child parts! \" + childParts.message());\n        }\n    }\n}\n\nfunction handleContent(mime:Entity bodyPart) {\n    string baseType = getBaseType(bodyPart.getContentType());\n    if mime:APPLICATION_XML == baseType || mime:TEXT_XML == baseType {\n        var payload = bodyPart.getXml();\n        if payload is xml {\n            log:printInfo(\"XML data: \" + payload.toString());\n        } else {\n            log:printError(\"Error in parsing XML data\", 'error = payload);\n        }\n    } else if mime:APPLICATION_JSON == baseType {\n        var payload = bodyPart.getJson();\n        if payload is json {\n            log:printInfo(\"JSON data: \" + payload.toJsonString());\n        } else {\n            log:printError(\"Error in parsing JSON data\", 'error = payload);\n        }\n    } else if mime:TEXT_PLAIN == baseType {\n        var payload = bodyPart.getText();\n        if payload is string {\n            log:printInfo(\"Text data: \" + payload);\n        } else {\n            log:printError(\"Error in parsing text data\", 'error = payload);\n        }\n    } else if mime:APPLICATION_PDF == baseType {\n        var payload = bodyPart.getByteStream();\n        if payload is stream<byte[], io:Error?> {\n            // Writes the incoming stream to a file using the `io:fileWriteBlocksFromStream` API by providing the\n            // file location to which the content should be written.\n            io:Error? result = io:fileWriteBlocksFromStream(\"./files/ReceivedFile.pdf\", payload);\n            if result is error {\n                log:printError(\"Error occurred while writing \", 'error = result);\n            }\n            close(payload);\n        } else {\n            log:printError(\"Error in parsing byte channel :\", 'error = payload);\n        }\n    }\n}\n\nfunction getBaseType(string contentType) returns string {\n    var result = mime:getMediaType(contentType);\n    if result is mime:MediaType {\n        return result.getBaseType();\n    }\n    panic result;\n}\n\nfunction close(stream<byte[], io:Error?> byteStream) {\n    var cr = byteStream.close();\n    if cr is error {\n        log:printError(\"Error occurred while closing the stream: \", 'error = cr);\n    }\n}\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.md",
    "content": "# HTTP service - Response with multiparts\n\nThe multipart payload is one or more different sets of data combined in a single body. HTTP service supports multipart content setting and retrieving in the `http:Response` along with the nested parts through support functions. An array of `mime:Entity` is returned when retrieving parts through `getBodyParts` method of the `http:Response`. If the received parts contain nested parts, you can loop through the parent parts and get the child parts. When sending out multipart content, `setBodyParts` is used to set the array of `mime:Entity`. This is useful to handle different content-typed messages as a single payload and large payloads.\n\n::: code http_response_with_multiparts.bal :::\n\nRun the service as follows.\n\n::: out http_response_with_multiparts.server.out :::\n\n## Prerequisites\nIn the directory, which contains the `.bal` file, create a directory named `files`, and add an XML file named `test.xml` in it.\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_response_with_multiparts.1.client.out :::\n\nTo decode the inbound response with multiparts, execute the following cURL command.\n\n::: out http_response_with_multiparts.2.client.out :::\n\n## Related links\n- [`setBodyParts()` - API documentation](https://lib.ballerina.io/ballerina/mime/latest#Entity#setBodyParts)\n- [HTTP service supported-multipart-types - Specification](/spec/mime/#3-supported-multipart-types)\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.metatags",
    "content": "description: This example is on how Ballerina supports encoding and decoding multipart content in HTTP responses along with nested parts.\nkeywords: ballerina, ballerina by example, bbe, mime, multiparts, entity\n"
  },
  {
    "path": "examples/http-response-with-multiparts/http_response_with_multiparts.server.out",
    "content": "$ bal run response_with_multiparts.bal\ntime = 2021-01-21 22:20:38,143 level = INFO  module = \"\" message = \"Nested Parts Detected!\" \ntime = 2021-01-21 22:20:38,185 level = INFO  module = \"\" message = \"JSON data: {\"name\":\"wso2\"}\" \ntime = 2021-01-21 22:20:38,324 level = INFO  module = \"\" message = \"XML data: <ballerinalang>\n    <version>0.963</version>\n    <test>test xml file to be used as a file part</test>\n</ballerinalang>\" \n"
  },
  {
    "path": "examples/http-response-with-multiparts/tests/http_response_with_multiparts_test.bal",
    "content": "import ballerina/mime;\nimport ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEP1 = check new (\"localhost:9090\");\n    http:Client httpEP2 = check new (\"localhost:9092\");\n\n    string response1 = check httpEP1->get(\"/multiparts/decoder\");\n    test:assertEquals(response1, \"Body Parts Received!\");\n\n    http:Response response2 = check httpEP2->get(\"/multiparts/encoder\");\n    mime:Entity[] parentParts = check response2.getBodyParts();\n    mime:Entity[] childParts = check parentParts[0].getBodyParts();\n    json jsonValue = check childParts[0].getJson();\n    test:assertEquals(jsonValue.toString(), \"{\\\"name\\\":\\\"wso2\\\"}\");\n    xml xmlValue = check childParts[1].getXml();\n    xml element1 = xmlValue.selectDescendants(\"version\");\n    test:assertEquals(element1.data(), \"0.963\");\n    xml element2 = xmlValue.selectDescendants(\"test\");\n    test:assertEquals(element2.data(), \"test xml file to be used as a file part\");\n}\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/http_restrict_by_media_type.bal",
    "content": "import ballerina/http;\n\nservice / on new http:Listener(9090) {\n    // The `consumes` and `produces` annotations of the resource configuration contains MIME types as\n    // an array of strings. The resource can only consume/accept `text/plain` media type. Therefore,\n    // the `Content-Type` header of the request must be `text/plain` types. The resource can produce\n    // `application/xml` payloads. Therefore, you need to set the `Accept` header accordingly.\n    @http:ResourceConfig {\n        consumes: [\"text/plain\"],\n        produces: [\"application/xml\"]\n    }\n    resource function post transform(@http:Payload string msg) returns xml|http:InternalServerError {\n        if re `^[a-zA-Z]*$`.isFullMatch(msg) {\n            return xml `<name>${msg}</name>`;\n        }\n        return { body: xml `<name>invalid string</name>`};\n    }\n}\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/http_restrict_by_media_type.client.out",
    "content": "$ curl -v http://localhost:9090/transform -H \"Accept:application/xml\" -H \"Content-Type:text/plain\" -d 'Ballerina'\n*   Trying ::1...\n* TCP_NODELAY set\n* Connected to localhost (::1) port 9090 (#0)\n> POST /transform HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept:application/xml\n> Content-Type:text/plain\n> Content-Length: 9\n>\n* upload completely sent off: 9 out of 9 bytes\n< HTTP/1.1 201 Created\n< content-type: application/xml\n< content-length: 22\n< server: ballerina\n< date: Sat, 22 Oct 2022 17:53:21 +0530\n<\n* Connection #0 to host localhost left intact\n<name>Ballerina</name>* Closing connection 0\n\n# To invoke the service using an unsupported media type, execute the following cURL request. The content type of the\n# request is not listed under the `consumes` resource configuration.\n$ curl -v http://localhost:9090/transform -H \"Accept:application/xml\" -H \"Content-Type:application/json\" -d '{\"name\":\"Ballerina\"}'\n*   Trying ::1...\n* TCP_NODELAY set\n* Connected to localhost (::1) port 9090 (#0)\n> POST /transform HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept:application/xml\n> Content-Type:application/json\n> Content-Length: 20\n>\n* upload completely sent off: 20 out of 20 bytes\n< HTTP/1.1 415 Unsupported Media Type\n< content-type: text/plain\n< content-length: 48\n< server: ballerina\n< date: Sat, 22 Oct 2022 17:56:40 +0530\n<\n* Connection #0 to host localhost left intact\ncontent-type : application/json is not supported* Closing connection 0\n\n# To invoke the service with a media type that is not acceptable, execute the following cURL request. The media type mentioned\n# in the `Accept` header is not listed under the `produces` resource configuration.\n$ curl -v http://localhost:9090/transform -H \"Accept:text/html\" -H \"Content-Type:text/plain\" -d 'Ballerina'\n*   Trying ::1...\n* TCP_NODELAY set\n* Connected to localhost (::1) port 9090 (#0)\n> POST /transform HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept:text/html\n> Content-Type:text/plain\n> Content-Length: 9\n>\n* upload completely sent off: 9 out of 9 bytes\n< HTTP/1.1 406 Not Acceptable\n< content-type: text/plain\n< content-length: 0\n< server: ballerina\n< date: Sat, 22 Oct 2022 17:58:28 +0530\n<\n* Connection #0 to host localhost left intact\n* Closing connection 0\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/http_restrict_by_media_type.md",
    "content": "# HTTP service - Restrict by media type\n\nThe content negotiation for the REST API design is achieved via the `consumes` and `produces` configurations. The resource accepting request content type is defined under the `consumes` and the resource producing response content type is defined under the `produces` in the resource configuration. Each configuration is checked against the `Accept` header and the `Content-type` header of the request. If the negotiation fails, the error response is returned with `406 Not Acceptable` or `415 Unsupported` status codes respectively.\n\n::: code http_restrict_by_media_type.bal :::\n\nRun the service as follows.\n\n::: out http_restrict_by_media_type.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_restrict_by_media_type.client.out :::\n\n## Related links\n- [`http:ResourceConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#HttpResourceConfig)\n- [HTTP service resource configuration - Specification](/spec/http/#42-resource-configuration)\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/http_restrict_by_media_type.metatags",
    "content": "description: This example is on how resources can be configured to restrict the types of media they consume and produce in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, content-type, accept\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/http_restrict_by_media_type.server.out",
    "content": "$ bal run restrict_by_media_type.bal\n"
  },
  {
    "path": "examples/http-restrict-by-media-type/tests/http_restrict_by_media_type_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    xml payload = check testClient->post(\"/transform\", \"Ballerina\");\n    test:assertEquals(payload, xml `<name>Ballerina</name>`);\n\n    xml|error err = testClient->post(\"/transform\", \"WSO2\");\n    if err is http:RemoteServerError {\n        test:assertEquals(err.detail().body, xml `<name>invalid string</name>`);\n    }\n}\n"
  },
  {
    "path": "examples/http-retry/http_retry.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\",\n        retryConfig = {\n            // The initial retry interval in seconds.\n            interval: 3,\n\n            // The number of retry attempts before stopping.\n            count: 3,\n\n            // The multiplier of the retry interval exponentially increases the retry interval.\n            backOffFactor: 2.0,\n\n            // The upper limit of the retry interval is in seconds. If the `interval` into the `backOffFactor`\n            // value exceeded the `maxWaitInterval` interval value, `maxWaitInterval` is considered as the retry interval.\n            maxWaitInterval: 20\n        }\n    );\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-retry/http_retry.md",
    "content": "# HTTP client - Retry\n\nThe HTTP retry client tries sending over the same request to the backend service when there is a network-level failure. The retry is configured in the `retryConfig` field of the client configuration.\n\n::: code http_retry.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the program by executing the following command.\n\n::: out http_retry.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP client retry - Specification](/spec/http/#2414-retry)\n"
  },
  {
    "path": "examples/http-retry/http_retry.metatags",
    "content": "description: This example is on how to use an HTTP retry client in Ballerina to automatically retry when an erroneous response is received.\nkeywords: ballerina, ballerina by examples, bbe, http, resiliency, retry\n"
  },
  {
    "path": "examples/http-retry/http_retry.out",
    "content": "$ bal run http_retry.bal\n"
  },
  {
    "path": "examples/http-retry/tests/http_retry_test.bal",
    "content": "import ballerina/http;\nimport ballerina/lang.runtime;\nimport ballerina/log;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client backendClientEP = check new (\"localhost:8080\",\n        retryConfig = {\n            interval: 3,\n            count: 3,\n            backOffFactor: 2.0,\n            maxWaitInterval: 20\n        },\n        timeout = 2\n    );\n    string payload = check backendClientEP->/greeting;\n    test:assertEquals(payload, \"Hello World!!!\");\n}\n\nservice / on new http:Listener(8080) {\n    private int counter = 0;\n    resource function get greeting() returns string {\n        self.counter += 1;\n        // Delay the response by 5 seconds to mimic network-level delays.\n        if self.counter % 4 != 0 {\n            log:printInfo(\"Request received from the client to delayed service.\");\n            runtime:sleep(5);\n            return \"Hello World!!!\";\n        } else {\n            log:printInfo(\"Request received from the client to healthy service.\");\n            return \"Hello World!!!\";\n        }\n    }\n}\n"
  },
  {
    "path": "examples/http-send-different-status-codes/http_send_different_status_codes.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The resource returns the `409 Conflict` status code as the error response status code using \n    // the `StatusCodeResponse` constants. This constant does not have a body or headers.\n    resource function post albums(Album album) returns Album|http:Conflict {\n        if albums.hasKey(album.title) {\n            return http:CONFLICT;\n        }\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-send-different-status-codes/http_send_different_status_codes.client.out",
    "content": "$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Blue Train\\\", \\\"artist\\\": \\\"John Coltrane\\\"}\" -v\n> POST /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> Content-type:application/json\n> Content-Length: 50\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 409 Conflict\n< content-length: 0\n< server: ballerina\n< date: Mon, 5 Dec 2022 16:23:51 +0530\n< \n"
  },
  {
    "path": "examples/http-send-different-status-codes/http_send_different_status_codes.md",
    "content": "# REST service - Send different status codes\n\nThe subtypes of the `http:StatusCodeResponse` record type represent different HTTP status code responses. Returning them from the resource method results in the relevant HTTP status code response. To send a non-entity body response, use the relevant constant value declared in the `http` module. These constant values can be directly returned from the resource method by specifying the relevant return type in the resource method signature. Use this when different status code responses need to be sent without a body and headers.\n\n::: code http_send_different_status_codes.bal :::\n\nRun the service as follows.\n\n::: out http_send_different_status_codes.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_send_different_status_codes.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service status code response - Specification](/spec/http/#2351-status-code-response)\n"
  },
  {
    "path": "examples/http-send-different-status-codes/http_send_different_status_codes.metatags",
    "content": "description: This example is on how to use status code records in an HTTP resource method.\nkeywords: ballerina, ballerina by example, bbe, http resource, return types, statusCode records\n"
  },
  {
    "path": "examples/http-send-different-status-codes/http_send_different_status_codes.server.out",
    "content": "$ bal run send_different_status_code.bal\n"
  },
  {
    "path": "examples/http-send-different-status-codes/tests/http_send_different_status_codes_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    http:Response response = check testClient->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    test:assertEquals(response.statusCode, 201);\n\n    response = check testClient->post(\"/albums\", {title:\"Blue Train\", artist:\"John Coltrane\"});\n    test:assertEquals(response.statusCode, 409);\n}\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/http_send_different_status_codes_with_payload.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\n// Represents the subtype of http:Conflict status code record.\ntype AlbumConflict record {|\n    *http:Conflict;\n    record {\n        string message;\n    } body;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The resource returns the `409 Conflict` status code as the error response status code using the built-in `StatusCodeResponse`.\n    resource function post albums(Album album) returns Album|AlbumConflict {\n        if albums.hasKey(album.title) {\n            return {body: { message: \"album already exists\" }};\n        }\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/http_send_different_status_codes_with_payload.client.out",
    "content": "$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Blue Train\\\", \\\"artist\\\": \\\"John Coltrane\\\"}\" -v\n> POST /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n> Content-type:application/json\n> Content-Length: 50\n>\n< HTTP/1.1 409 Conflict\n< content-type: application/json\n< content-length: 36\n< server: ballerina\n< date: Thu, 17 Nov 2022 11:13:50 +0530\n<\n{\"message\":\"album already exists\"}\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/http_send_different_status_codes_with_payload.md",
    "content": "# REST service - Send different status codes with payload\n\nThe resource method can return a subtype of the `http:StatusCodeResponse` record type with a body and headers. This type can be created by including a subtype of the `http:StatusCodeResponse` record type. The `body` field represents the response payload, while the `headers` field represents a `map` of the response headers. In addition, the `body` field type can be overridden by a custom record type. Use these custom subtypes if different status code responses need to be sent with custom payload types and headers. Furthermore, defining such records can produce a better representation of the responses in the OpenAPI specification, and using typed records for the `body` field provides compiler validations and better tooling support.\n\n::: code http_send_different_status_codes_with_payload.bal :::\n\nRun the service as follows.\n\n::: out http_send_different_status_codes_with_payload.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_send_different_status_codes_with_payload.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http:StatusCodeResponse` type - API documentation](https://lib.ballerina.io/ballerina/http/latest#StatusCodeResponse)\n- [HTTP service status code response - Specification](/spec/http/#2351-status-code-response)\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/http_send_different_status_codes_with_payload.metatags",
    "content": "description: This example is on how to use the status code records with a payload in an HTTP resource method.\nkeywords: ballerina, ballerina by example, bbe, http resource, return types, statusCode records\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/http_send_different_status_codes_with_payload.server.out",
    "content": "$ bal run send_different_status_code_with_payload.bal\n"
  },
  {
    "path": "examples/http-send-different-status-codes-with-payload/tests/http_send_different_status_codes_with_payload_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    http:Response response = check testClient->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    test:assertEquals(response.statusCode, 201);\n\n    response = check testClient->post(\"/albums\", {title:\"Blue Train\", artist:\"John Coltrane\"});\n    test:assertEquals(response.statusCode, 409);\n}\n"
  },
  {
    "path": "examples/http-send-header/http_send_header.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\ntype AlbumOk record {|\n    *http:Ok;\n    record {|\n        string x\\-music\\-genre;\n    |} headers;\n    Album[] body;\n|};\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns AlbumOk {\n        return {\n            headers: {\n                x\\-music\\-genre: \"Jazz\"\n            },\n            body: albums.toArray()\n        };\n    }\n}\n"
  },
  {
    "path": "examples/http-send-header/http_send_header.client.out",
    "content": "$ curl -v localhost:9090/albums\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< x-music-genre: Jazz\n< content-type: application/json\n< content-length: 95\n< server: ballerina\n< date: Mon, 9 Jan 2023 10:35:56 +0530\n<\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-send-header/http_send_header.md",
    "content": "# HTTP service - Sending header\n\nThe headers are used to send additional details along with the payload. To send custom headers, it is best to create a subtype of the relevant `http:StatusCodeResponse` record by specifying the required header. Creating a subtype helps accurately generate the OpenAPI specification which then can be used to generate the relevant clients. The type of the header can be one of `string`, `int`, `boolean`, `string[]`, `int[]` or `boolean[]`.\n\n::: code http_send_header.bal :::\n\nRun the service as follows.\n\n::: out http_send_header.server.out :::\n\nInvoke the HTTP GET resource by executing the following cURL command in a new terminal.\n\n::: out http_send_header.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service status code response - Specification](/spec/http/#2351-status-code-response)\n"
  },
  {
    "path": "examples/http-send-header/http_send_header.metatags",
    "content": "description: This example demonstrates sending a custom HTTP header from a service in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http service, header, response\n"
  },
  {
    "path": "examples/http-send-header/http_send_header.server.out",
    "content": "$ bal run http_send_header.bal\n"
  },
  {
    "path": "examples/http-send-header/tests/http_send_header_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    http:Response response = check httpEndpoint->get(\"/albums\");\n    test:assertEquals(response.getHeader(\"x-music-genre\"), \"Jazz\");\n}\n"
  },
  {
    "path": "examples/http-send-response/http_send_response.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // The resource returns the `Album` typed array value.\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-send-response/http_send_response.client.out",
    "content": "$ curl http://localhost:9090/albums -v\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< content-type: application/json\n< content-length: 95\n< server: ballerina\n< date: Mon, 14 Nov 2022 15:08:04 +0530\n<\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-send-response/http_send_response.md",
    "content": "# REST service - Send response\n\nReturning an `anydata` type from the resource method results in an HTTP response, where the returned value becomes the body. If the returned type is `nil`, then a `202 Accepted` response is returned to the client without the body. Otherwise, the response contains the returned value as the payload, and the `Content-type` header is inferred from the return type. In addition, the response status code is `201 Created` for `POST` resources and `200 Ok` for other resources. Furthermore, the `@http:Payload` annotation on the return type can be used to override the `Content-type` header. Returning an `anydata` type from the resource method is useful when the desired payload with the default status code and headers needs to be sent as the response.\n\n::: code http_send_response.bal :::\n\nRun the service as follows.\n\n::: out http_send_response.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_send_response.client.out :::\n\n>**Tip:** You can invoke the above service via the [Payload data binding client](/learn/by-example/http-client-data-binding/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service return types - Specification](/spec/http/#235-return-types)\n"
  },
  {
    "path": "examples/http-send-response/http_send_response.metatags",
    "content": "description: This example is on how to return an anydata response from an HTTP resource function.\nkeywords: ballerina, ballerina by example, bbe, http resource, return types, anydata\n"
  },
  {
    "path": "examples/http-send-response/http_send_response.server.out",
    "content": "$ bal run send_response.bal\n"
  },
  {
    "path": "examples/http-send-response/tests/http_send_response_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client testClient = check new(\"localhost:9090\");\n    Album[] payload = check testClient->get(\"/albums\");\n    test:assertEquals(payload, [{title:\"Blue Train\",artist:\"John Coltrane\"},{title:\"Jeru\",artist:\"Gerry Mulligan\"}]);\n}\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/http_service_and_resource_paths.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n// The `service path` represents the absolute path to the service.\n// If the `service path` is omitted, then it defaults to `/`.\n// It can be represented by both identifiers and string literals. E.g., `/music\\-info`, `\"/music-info\"`.\nservice /info on new http:Listener(9090) {\n\n    // The `resource path` represents the relative path to the resource, and the `resource accessor`\n    // represents the HTTP method used to access the resource.\n    // Here, the resource path is `/albums`, and the resource accessor is `get`.\n    // This means the resource is invoked when an HTTP GET request is made to `/info/albums`.\n    // The `resource path` can be set as `.` to represent a resource with the `service path` \n    // that is `/info`.\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/http_service_and_resource_paths.client.out",
    "content": "$ curl http://localhost:9090/info/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/http_service_and_resource_paths.md",
    "content": "# REST service - Service and resource paths\n\nThe `service path` is defined in the service declaration and the `resource path` is defined in the resource method definition. Each resource can be invoked by using the `service path`, `resource path`, and `resource accessor`. In an HTTP resource, the `resource accessor` confines the resource to a specific HTTP method.\n\n::: code http_service_and_resource_paths.bal :::\n\nRun the service as follows.\n\n::: out http_service_and_resource_paths.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_service_and_resource_paths.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service path - Specification](/spec/http/#222-service-base-path)\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/http_service_and_resource_paths.metatags",
    "content": "description: This example is on how to use the `service-path`, `resource-name`, and `accessor-name` (HTTP verb) in Ballerina to dispatch and constrain the service in a RESTful manner.\nkeywords: ballerina, ballerina by example, bbe, http service, path, verb\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/http_service_and_resource_paths.server.out",
    "content": "$ bal run service_path_and_resource_name.bal\n"
  },
  {
    "path": "examples/http-service-and-resource-paths/tests/http_service_and_resource_paths_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    Album[] payload = check httpEndpoint->get(\"/info/albums\");\n    test:assertEquals(payload, [{title:\"Blue Train\",artist:\"John Coltrane\"},{title:\"Jeru\",artist:\"Gerry Mulligan\"}]);\n}\n"
  },
  {
    "path": "examples/http-service-basic-authentication-file-user-store/http_service_basic_authentication_file_user_store.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the file user store can be enabled by setting \n// the `http:FileUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@http:ServiceConfig {\n    auth: [\n        {\n            fileUserStoreConfig: {},\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice / on securedEP {\n\n    // The authentication and authorization configurations can be overwritten at \n    // the resource level. Otherwise, the service-level configurations will be \n    // applied automatically to the resource.\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-basic-authentication-file-user-store/http_service_basic_authentication_file_user_store.md",
    "content": "# HTTP service - Basic authentication file user store\n\nThe `http:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header against the provided configurations in the `Config.toml` file. The file stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the default values for the `fileUserStoreConfig` field and add the `Config.toml` file next to the service file. To engage authorization, set scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `401 Unauthorized` response is sent to the client when the authentication fails, and a `403 Forbidden` response is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on user stores. Furthermore, the authentication and authorization configurations can be overwritten at the resource level using the `@http:ResourceConfig` annotation.\n\n::: code http_service_basic_authentication_file_user_store.bal :::\n\n## Prerequisites\n- Populate the `Config.toml` file correctly with the user information as shown below.\n\n::: code Config.toml :::\n\nRun the service by executing the command below.\n\n::: out http_service_basic_authentication_file_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [Basic authentication client](/learn/by-example/http-client-basic-authentication) example.\n\n## Related links\n- [`http:FileUserStoreConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#FileUserStoreConfig)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [HTTP service listener basic authentication file user store - Specification](/spec/http/#9111-listener---basic-auth---file-user-store)\n"
  },
  {
    "path": "examples/http-service-basic-authentication-file-user-store/http_service_basic_authentication_file_user_store.metatags",
    "content": "description: This example is on how to secure an HTTP service with Basic Authentication in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, basic auth\n"
  },
  {
    "path": "examples/http-service-basic-authentication-file-user-store/http_service_basic_authentication_file_user_store.server.out",
    "content": "$ bal run http_service_basic_auth_file_user_store.bal"
  },
  {
    "path": "examples/http-service-basic-authentication-ldap-user-store/http_service_basic_authentication_ldap_user_store.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// Basic authentication with the LDAP user store can be enabled by setting \n// the `http:LdapUserStoreConfig` configuration.\n// Authorization is based on scopes, which can be specified in the `scopes` field.\n@http:ServiceConfig {\n    auth: [\n        {\n            ldapUserStoreConfig: {\n                domainName: \"avix.lk\",\n                connectionUrl: \"ldap://localhost:389\",\n                connectionName: \"cn=admin,dc=avix,dc=lk\",\n                connectionPassword: \"avix123\",\n                userSearchBase: \"ou=Users,dc=avix,dc=lk\",\n                userEntryObjectClass: \"inetOrgPerson\",\n                userNameAttribute: \"uid\",\n                userNameSearchFilter: \"(&(objectClass=inetOrgPerson)(uid=?))\",\n                userNameListFilter: \"(objectClass=inetOrgPerson)\",\n                groupSearchBase: [\"ou=Groups,dc=avix,dc=lk\"],\n                groupEntryObjectClass: \"groupOfNames\",\n                groupNameAttribute: \"cn\",\n                groupNameSearchFilter: \"(&(objectClass=groupOfNames)(cn=?))\",\n                groupNameListFilter: \"(objectClass=groupOfNames)\",\n                membershipAttribute: \"member\",\n                userRolesCacheEnabled: true,\n                connectionPoolingEnabled: false,\n                connectionTimeout: 5,\n                readTimeout: 60\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice / on securedEP {\n\n    // The authentication and authorization configurations can be overwritten at \n    // the resource level. Otherwise, the service-level configurations will be \n    // applied automatically to the resource.\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-basic-authentication-ldap-user-store/http_service_basic_authentication_ldap_user_store.md",
    "content": "# HTTP service - Basic authentication LDAP user store\n\nThe `http:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header with the LDAP server. This server stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the LDAP related configurations to the `ldapUserStoreConfig` field. To engage authorization, set scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `401 Unauthorized` response is sent to the client when the authentication fails, and a `403 Forbidden` response is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on LDAP user stores. Furthermore, the authentication and authorization configurations can be overwritten at the resource level using the `@http:ResourceConfig` annotation.\n\n::: code http_service_basic_authentication_ldap_user_store.bal :::\n\n## Prerequisites\n- Run the LDAP server.\n\nRun the service by executing the command below.\n\n::: out http_service_basic_authentication_ldap_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [Basic authentication client](/learn/by-example/http-client-basic-authentication) example.\n\n## Related links\n- [`http:LdapUserStoreConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#LdapUserStoreConfig)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [HTTP service listener basic authentication LDAP user store - Specification](/spec/http/#9112-listener---basic-auth---ldap-user-store)\n"
  },
  {
    "path": "examples/http-service-basic-authentication-ldap-user-store/http_service_basic_authentication_ldap_user_store.metatags",
    "content": "description: This example is on how to secure an HTTP service with LDAP Basic Authentication in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, basic auth\n"
  },
  {
    "path": "examples/http-service-basic-authentication-ldap-user-store/http_service_basic_authentication_ldap_user_store.server.out",
    "content": "$ bal run http_service_basic_auth_ldap_user_store.bal\n"
  },
  {
    "path": "examples/http-service-cache-response/http_service_cache_response.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\nservice / on new http:Listener(9090) {\n\n    // In this example, `max-age` directive is set to 15 seconds, indicating that the response\n    // will be fresh for 15 seconds. By default, `must-revalidate` directive is true and instructs that\n    // the cache should not serve a stale response without validating it with the origin server first.\n    resource function get albums/[string title]() returns @http:Cache {maxAge: 15} Album|http:NotFound {\n        return albums[title] ?: http:NOT_FOUND;\n    }\n}\n"
  },
  {
    "path": "examples/http-service-cache-response/http_service_cache_response.md",
    "content": "# REST service - Send cache response\n\nThe `http:Service` can cache a response associated with a request and reuse the cached response for subsequent requests. This can be achieved by adding the `http:Cache` annotation to the return type. By default, this annotation adds the `must-revalidate`, `public`, and `max-age=3600` directives to the `Cache-Control` header of the response, along with the `ETag` and `Last-Modified` headers. These default settings can be changed by adding the configurations to the annotation. Furthermore, the response is only cached when the return type is `anydata` or a subtype of `http:SuccessStatusCodeResponse`.\n\n::: code http_service_cache_response.bal :::\n\nRun the service by executing the following command.\n\n::: out http_service_cache_response.server.out :::\n\n>**Tip:** You can invoke the above service via the [Caching client](/learn/by-example/http-caching-client) example. In addition to that the [trace logs](/learn/by-example/http-trace-logs/) can be enabled to observe the in and out traffic.\n\n## Related links\n- [`http:HttpCacheConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#HttpCacheConfig)\n- [`http:Cache` annotation - Specification](/spec/http/#46-cache-annotation)\n"
  },
  {
    "path": "examples/http-service-cache-response/http_service_cache_response.metatags",
    "content": "description: This example is on how to configure and perform HTTP caching in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, caching\n"
  },
  {
    "path": "examples/http-service-cache-response/http_service_cache_response.server.out",
    "content": "$ bal run http_service_cache_response.bal\n"
  },
  {
    "path": "examples/http-service-cache-response/tests/http_service_cache_response_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n\n    http:Response response = check httpEndpoint->get(\"/albums/Blue Train\");\n    test:assertEquals(response.getHeader(\"etag\"), \"cf55d38\");\n    test:assertEquals(response.getHeader(\"cache-control\"), \"must-revalidate,public,max-age=15\");\n    test:assertFalse(response.hasHeader(\"age\"));\n    test:assertEquals(response.getJsonPayload(), {title:\"Blue Train\", artist:\"John Coltrane\"});\n\n    response = check httpEndpoint->get(\"/albums/Blue Train\");\n    test:assertEquals(response.getHeader(\"etag\"), \"cf55d38\");\n    test:assertEquals(response.getHeader(\"cache-control\"), \"must-revalidate,public,max-age=15\");\n    test:assertTrue(response.hasHeader(\"age\"));\n    test:assertEquals(response.getJsonPayload(), {title:\"Blue Train\", artist:\"John Coltrane\"});\n}\n"
  },
  {
    "path": "examples/http-service-chunking/http_service_chunking.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n@http:ServiceConfig {\n    chunking: http:CHUNKING_ALWAYS\n}\nservice / on new http:Listener(9090, httpVersion = http:HTTP_1_1) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n}\n"
  },
  {
    "path": "examples/http-service-chunking/http_service_chunking.client.out",
    "content": "$ curl -v localhost:9090/albums\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n> \n< HTTP/1.1 200 OK\n< content-type: application/json\n< transfer-encoding: chunked\n< server: ballerina\n< date: Wed, 4 Jan 2023 21:14:48 +0530\n< \n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-service-chunking/http_service_chunking.md",
    "content": "# HTTP service - Chunking\n\nThe HTTP service can be configured for chunked responses. By default, the HTTP service sends messages with the `content-length` header. If the message size is larger than the buffer size (8K), messages are chunked. Chunking can be disabled using the `@http:ServiceConfig`. The chunking behavior can be configured as `CHUNKING_AUTO`, `CHUNKING_ALWAYS`, or `CHUNKING_NEVER` only available HTTP/1.1 protocol. When the config is set to `CHUNKING_ALWAYS`, chunking happens irrespective of the response payload size.\n\n::: code http_service_chunking.bal :::\n\nRun the service as follows.\n\n::: out http_service_chunking.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_service_chunking.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service configuration - Specification](https://ballerina.io/spec/http/#41-service-configuration)\n"
  },
  {
    "path": "examples/http-service-chunking/http_service_chunking.metatags",
    "content": "description: This example is on how to configure the chunking behavior of an HTTP service in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, chunked, transfer-encoding\n"
  },
  {
    "path": "examples/http-service-chunking/http_service_chunking.server.out",
    "content": "$ bal run http_service_chunking.bal\n"
  },
  {
    "path": "examples/http-service-chunking/tests/http_service_chunking_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    http:Response response = check httpEndpoint->get(\"/albums\");\n    test:assertEquals(response.getHeader(\"transfer-encoding\"), \"chunked\");\n}\n"
  },
  {
    "path": "examples/http-service-data-binding/http_service_data_binding.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [];\n\nservice / on new http:Listener(9090) {\n\n    // The `album` parameter in the payload annotation represents the entity body of the inbound request.\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-service-data-binding/http_service_data_binding.client.out",
    "content": "$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Sarah Vaughan and Clifford Brown\\\", \\\"artist\\\": \\\"Sarah Vaughan\\\"}\"\n{\"title\":\"Sarah Vaughan and Clifford Brown\", \"artist\":\"Sarah Vaughan\"}\n"
  },
  {
    "path": "examples/http-service-data-binding/http_service_data_binding.md",
    "content": "# REST service - Payload data binding\n\nHTTP service payload data binding allows accessing the request payload using a resource signature parameter. The resource parameter type should be a sub type of `anydata`. By default, parameters with the `map `, `array`, `tuple`, `table`, `record` and `xml` types are mapped to the payload. For other types, the `@http:Payload` annotation is required and If the signature includes more than one of the aforementioned types, the `@http:Payload` should be used to resolve the ambiguity. This behaviour is limited to the `POST`, `PUT`, `PATCH`, `DELETE`, and `DEFAULT` accessors.  If the data binding process fails, the client receives a `400 Bad Request` response. This feature allows direct access to the request payload from the resource.\n\n::: code http_service_data_binding.bal :::\n\nRun the service as follows.\n\n::: out http_service_data_binding.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_service_data_binding.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http:Payload` annotation - API documentation](https://lib.ballerina.io/ballerina/http/latest#Payload)\n- [HTTP service payload parameter - Specification](/spec/http/#2344-payload-parameter)\n"
  },
  {
    "path": "examples/http-service-data-binding/http_service_data_binding.metatags",
    "content": "description: This example is on how data binding helps to access a payload through a resource signature parameter.\nkeywords: ballerina, ballerina by example, bbe, http, data binding\n"
  },
  {
    "path": "examples/http-service-data-binding/http_service_data_binding.server.out",
    "content": "$ bal run http_data_binding.bal\n"
  },
  {
    "path": "examples/http-service-data-binding/tests/http_service_data_binding_test.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"localhost:9090\");\n    Album lastAlbum = check httpEndpoint->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    test:assertEquals(lastAlbum, {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n}\n"
  },
  {
    "path": "examples/http-service-file-upload/http_service_file_upload.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\nservice / on new http:Listener(9090) {\n\n    resource function post receiver(http:Request request) returns string|error {\n        stream<byte[], io:Error?> streamer = check request.getByteStream();\n\n        // Writes the incoming stream to a file using the `io:fileWriteBlocksFromStream` API\n        // by providing the file location to which the content should be written.\n        check io:fileWriteBlocksFromStream(\"./files/ReceivedFile.pdf\", streamer);\n        check streamer.close();\n        return \"File Received!\";\n    }\n}\n"
  },
  {
    "path": "examples/http-service-file-upload/http_service_file_upload.md",
    "content": "# HTTP service - File upload\n\nThe input streaming is handled through the Ballerina `stream` type. The resource can access the byte stream of the payload using the `getByteStream` method of the `http:Request`. This is useful when handling continuous payload, file uploads, etc.\n\n::: code http_service_file_upload.bal :::\n\nRun the service as follows.\n\n::: out http_service_file_upload.server.out :::\n\n>**Tip:** You can invoke the service via the [Client file upload](/learn/by-example/http-client-file-upload) example.\n\n## Related links\n- [`getByteStream()` - API documentation](https://lib.ballerina.io/ballerina/http/latest#Request#getByteStream)\n- [`http` module - Specification](/spec/http/#41-service-configuration)\n- [Binary data](/learn/by-example/binary-data/)\n"
  },
  {
    "path": "examples/http-service-file-upload/http_service_file_upload.metatags",
    "content": "description: This example demonstrates the file upload capability through Ballerina streams.\nkeywords: ballerina, ballerina by example, bbe, http, streaming, service, file upload\n"
  },
  {
    "path": "examples/http-service-file-upload/http_service_file_upload.server.out",
    "content": "$ bal run http_service_file_upload.bal\n"
  },
  {
    "path": "examples/http-service-jwt-authentication/http_service_jwt_authentication.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with JWT authentication and can be authorized optionally.\n// JWT authentication can be enabled by setting the `http:JwtValidatorConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type configurations for the `scopes` field.\n@http:ServiceConfig {\n    auth: [\n        {\n            jwtValidatorConfig: {\n                issuer: \"wso2\",\n                audience: \"ballerina\",\n                signatureConfig: {\n                    certFile: \"../resource/path/to/public.crt\"\n                },\n                scopeKey: \"scp\"\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice / on securedEP {\n\n    // It is optional to override the authentication and authorization configurations at the resource levels.\n    // Otherwise, the service auth configurations are applied automatically to the resources as well.\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-jwt-authentication/http_service_jwt_authentication.md",
    "content": "# HTTP service - JWT authentication\n\nThe `http:Service` and resource method can be secured with JWT and additionally, scopes can be added to enforce authorization. It validates the JWT sent in the `Authorization` header against the provided configurations. Ballerina uses the concept of scopes for authorization. A resource declared in a service can be bound to one/more scope(s). The scope can be included in the JWT using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service/resource are compared against the scope included in the JWT for at least one match between the two sets.\n\n::: code http_service_jwt_authentication.bal :::\n\nRun the service by executing the command below.\n\n::: out http_service_jwt_authentication.server.out :::\n\n>**Tip:** You can invoke the above service via the [self-signed JWT authentication client](/learn/by-example/http-client-self-signed-jwt-authentication) example.\n\n## Related links\n- [`http:JwtValidatorConfig` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#JwtValidatorConfig)\n- [`jwt` module - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n- [HTTP service JWT authentication - Specification](/spec/http/#9113-listener---jwt-auth)\n"
  },
  {
    "path": "examples/http-service-jwt-authentication/http_service_jwt_authentication.metatags",
    "content": "description: This example is on how to secure an HTTP service with JWT authentication in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, jwt auth\n"
  },
  {
    "path": "examples/http-service-jwt-authentication/http_service_jwt_authentication.server.out",
    "content": "$ bal run http_service_jwt_auth.bal\n"
  },
  {
    "path": "examples/http-service-mutual-ssl/http_service_mutual_ssl.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\n// An HTTP listener can be configured to accept new connections that are secured via mutual SSL.\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/server-public.crt\",\n            keyFile: \"../resource/path/to/server-private.key\"\n        },\n        // Enables mutual SSL.\n        mutualSsl: {\n            verifyClient: http:REQUIRE,\n            cert: \"../resource/path/to/client-public.crt\"\n        }\n    }\n);\n\nservice / on securedEP {\n\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-mutual-ssl/http_service_mutual_ssl.client.out",
    "content": "$ curl https://localhost:9090/albums --cert /path/to/client-public.crt --key /path/to/client-private.key --cacert /path/to/server-public.crt\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-service-mutual-ssl/http_service_mutual_ssl.md",
    "content": "# HTTP service - Mutual SSL\n\nThe `http:Listener` with mutual SSL (mTLS) enabled in it allows exposing a connection secured with mutual SSL, which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. The `http:Listener` secured with mutual SSL is created by providing the `secureSocket` configurations, which require the word `require` as the `verifyClient`, the server's public certificate as the `certFile`, the server's private key as the `keyFile`, and the client's certificate as the `cert`. Use this to secure the HTTP connection over mutual SSL.\n\n::: code http_service_mutual_ssl.bal :::\n\nRun the service by executing the command below.\n\n::: out http_service_mutual_ssl.server.out :::\n\nInvoke the service by executing the cURL command below.\n\n::: out http_service_mutual_ssl.client.out :::\n\n>**Tip:** You can invoke the above service via the [Mutual SSL/TLS client](/learn/by-example/http-client-mutual-ssl/) example.\n\n## Related links\n- [`http:ListenerSecureSocket` - API documentation](https://lib.ballerina.io/ballerina/http/latest#ListenerSecureSocket)\n- [HTTP service mutual SSL - Secification](/spec/http/#922-listener---mutual-ssl)\n"
  },
  {
    "path": "examples/http-service-mutual-ssl/http_service_mutual_ssl.metatags",
    "content": "description: This example is on how to secure an HTTP listener with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, http, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/http-service-mutual-ssl/http_service_mutual_ssl.server.out",
    "content": "$ bal run http_service_mutual_ssl.bal\n"
  },
  {
    "path": "examples/http-service-oauth2/http_service_oauth2.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with OAuth2 and by enforcing authorization optionally.\n// It can be enabled by setting the `http:OAuth2IntrospectionConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type configurations for the `scopes` field.\n@http:ServiceConfig {\n    auth: [\n        {\n            oauth2IntrospectionConfig: {\n                url: \"https://localhost:9445/oauth2/introspect\",\n                tokenTypeHint: \"access_token\",\n                scopeKey: \"scp\",\n                clientConfig: {\n                    customHeaders: {\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"},\n                    secureSocket: {\n                        cert: \"../resource/path/to/public.crt\"\n                    }\n                }\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice / on securedEP {\n\n    // It is optional to override the authentication and authorization configurations at the resource levels.\n    // Otherwise, the service auth configurations are applied automatically to the resources as well.\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-oauth2/http_service_oauth2.md",
    "content": "# HTTP service - OAuth2\n\nThe `http:Service` and resource method can be secured with OAuth2 and additionally, scopes can be added to enforce fine-grained authorization. It validates the OAuth2 token sent in the `Authorization` header against the provided configurations. This calls the configured introspection endpoint to validate. Ballerina uses the concept of scopes for authorization. A resource declared in a service can be bound to one/more scope(s). The scope can be included in the introspection response using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service/resource are compared against the scope included in the introspection response for at least one match between the two sets.\n\n::: code http_service_oauth2.bal :::\n\n## Prerequisites\n- An STS endpoint should be up and running.\n\nRun the service by executing the command below.\n\n::: out http_service_oauth2.server.out :::\n\n>**Tip:** You can invoke the above service via the [OAuth2 JWT Bearer grant type client](/learn/by-example/http-client-oauth2-jwt-bearer-grant-type) example.\n\n## Related links\n- [`http:OAuth2IntrospectionConfig` - API documentation](https://lib.ballerina.io/ballerina/http/latest#OAuth2IntrospectionConfig)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [HTTP service oauth2 - Specification](/spec/http/#9114-listener---oauth2)\n"
  },
  {
    "path": "examples/http-service-oauth2/http_service_oauth2.metatags",
    "content": "description: This example is on how to secure an HTTP service with OAuth2 in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, auth, oauth2, introspection\n"
  },
  {
    "path": "examples/http-service-oauth2/http_service_oauth2.server.out",
    "content": "$ bal run http_service_oauth2.bal\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/http_service_payload_constraint_validation.bal",
    "content": "import ballerina/http;\nimport ballerina/constraint;\n\ntype Album record {\n    @constraint:String {\n        maxLength: 5,\n        minLength: 1\n    }\n    string title;\n    string artist;\n};\n\nservice / on new http:Listener(9090) {\n    private Album[] albums = [];\n\n    // The `album` parameter in the payload annotation will get validated according to the constraints added.\n    resource function post albums(Album album) returns http:Created {\n        self.albums.push(album);\n        return http:CREATED;\n    }\n}\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/http_service_payload_constraint_validation.client.out",
    "content": "$ curl -v http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Sarah Vaughan and Clifford Brown\\\", \\\"artist\\\": \\\"Sarah Vaughan\\\"}\"\n*   Trying 127.0.0.1:9090...\n* Connected to localhost (127.0.0.1) port 9090 (#0)\n> POST /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.79.1\n> Accept: */*\n> Content-type:application/json\n> Content-Length: 72\n> \n* Mark bundle as not supporting multiuse\n< HTTP/1.1 400 Bad Request\n< content-type: text/plain\n< content-length: 83\n< server: ballerina\n< date: Thu, 8 Dec 2022 11:13:19 +0530\n< \n* Connection #0 to host localhost left intact\npayload validation failed: Validation failed for '$.title:maxLength' constraint(s).\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/http_service_payload_constraint_validation.md",
    "content": "# REST service - Payload constraint validation\n\nThe Ballerina `constraint` module allows adding additional constraints to the response payload. The `http` resource method uses the `constraint` module to validate the payload against the given constraints. This validation happens soon after the successful data-binding of the request payload before executing the resource method. The constraints can be added to a given data type using different annotations. If the validation fails, a `400 Bad Request` response is returned to the client with the validation error message. Use this to validate the request payload as the application receives it, which protects the server against unnecessary resource method processing and malicious payloads.\n\n::: code http_service_payload_constraint_validation.bal :::\n\nRun the service program by executing the following command.\n\n::: out http_service_payload_constraint_validation.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal. Here, an album with a lengthy title is sent to the service.\n\n::: out http_service_payload_constraint_validation.client.out :::\n\n>**Tip:** You can invoke the above service via the [Send request/Receive response client](/learn/by-example/http-client-send-request-receive-response/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [`http` module - Specification](/spec/http/)\n- [Constraint validation example](/learn/by-example/constraint-validations/)\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/http_service_payload_constraint_validation.metatags",
    "content": "description: This example is on how constraint validation can be done to the payload of a service.\nkeywords: ballerina, ballerina by example, bbe, http, constraint, validation\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/http_service_payload_constraint_validation.server.out",
    "content": "$ bal run http_service_payload_constraint_validation.bal\n"
  },
  {
    "path": "examples/http-service-payload-constraint-validation/tests/http_service_payload_constraint_validation.bal",
    "content": "import ballerina/http;\nimport ballerina/test;\n\n@test:Config{}\nfunction testFunc() returns error? {\n    http:Client httpEndpoint = check new(\"http://localhost:9090\");\n    Album|error response = httpEndpoint->post(\"/albums\", {title:\"Sarah Vaughan and Clifford Brown\", artist:\"Sarah Vaughan\"});\n    if response is http:Error {\n        test:assertEquals(response.detail()[\"statusCode\"], 400);\n        http:ErrorPayload errorResponse = check response.detail()[\"body\"].ensureType();\n        test:assertEquals(errorResponse.message, \"payload validation failed: Validation failed for '$.title:maxLength' constraint(s).\");\n        test:assertEquals(errorResponse.status, 400);\n        test:assertEquals(errorResponse.reason, \"Bad Request\");\n        test:assertEquals(errorResponse.path, \"/albums\");\n        test:assertEquals(errorResponse.method, \"POST\");\n    } else {\n        test:assertFail(\"Expected an error\");\n    }\n}\n"
  },
  {
    "path": "examples/http-service-redirects/http_service_redirects.bal",
    "content": "import ballerina/http;\n\nservice / on new http:Listener(9092) {\n\n    resource function get redirect() returns http:TemporaryRedirect {\n        // Return a redirect response record with the location header.\n        return {\n            headers: {\n                \"Location\": \"http://localhost:9090/albums\"\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "examples/http-service-redirects/http_service_redirects.client.out",
    "content": "$ curl -v localhost:9092/redirect -L\n> GET /redirect HTTP/1.1\n> Host: localhost:9092\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 307 Temporary Redirect\n< Location: http://localhost:9090/albums\n< content-length: 0\n< server: ballerina\n< date: Wed, 11 Jan 2023 10:45:36 +0530\n<\n* Connection #0 to host localhost left intact\n* Issue another request to this URL: 'http://localhost:9090/albums'\n* Found bundle for host localhost: 0x7feb7341b9c0 [can pipeline]\n* Could pipeline, but not asked to!\n*   Trying ::1...\n* TCP_NODELAY set\n* Connected to localhost (::1) port 9090 (#1)\n> GET /albums HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< content-type: application/json\n< content-length: 95\n< server: ballerina\n< date: Wed, 11 Jan 2023 10:45:36 +0530\n<\n* Connection #1 to host localhost left intact\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-service-redirects/http_service_redirects.md",
    "content": "# HTTP service - Redirects\n\nRedirection is important to direct requests to the correct endpoints if the called one is not existing or moved. The HTTP specification provides standard status codes to notify such situation to the caller. The HTTP service responds with `redirect` status code response along with the `location` header of the new endpoint. This can be done using the `http:StatusCodeResponse` records.\n\n::: code http_service_redirects.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the service as follows.\n\n::: out http_service_redirects.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n>**Tip:** You may invoke the service via [Redirect client](../http-client-redirects/) example.\n\n::: out http_service_redirects.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [HTTP service caller - specification](/spec/http/#2341-httpcaller)\n"
  },
  {
    "path": "examples/http-service-redirects/http_service_redirects.metatags",
    "content": "description: This example is on how to perform an HTTP redirect in a Ballerina HTTP service.\nkeywords: ballerina, ballerina by example, bbe, http, redirect\n"
  },
  {
    "path": "examples/http-service-redirects/http_service_redirects.server.out",
    "content": "$ bal run http_service_redirects.bal\n"
  },
  {
    "path": "examples/http-service-redirects/tests/http_service_redirects_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\ntable<Album> key(title) albums = table [\n    {title: \"Blue Train\", artist: \"John Coltrane\"},\n    {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n];\n\n@test:Config {}\nfunction testFunc() returns error? {\n    // Invoking the main function\n    http:Client httpEndpoint = check new(\"localhost:9092\",\n            followRedirects = { enabled: true, maxCount: 5 });\n    // Send a GET request to the specified endpoint\n    Album[] response = check httpEndpoint->get(\"/redirect\");\n    test:assertEquals(response, [{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]);\n}\n\nservice / on new http:Listener(9090) {\n\n    resource function get albums() returns Album[] {\n        return albums.toArray();\n    }\n\n    resource function post albums(Album album) returns Album {\n        albums.add(album);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/http-service-ssl-tls/http_service_ssl_tls.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nlistener http:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\nservice / on securedEP {\n\n    resource function get albums() returns Album[] {\n        return [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n    }\n}\n"
  },
  {
    "path": "examples/http-service-ssl-tls/http_service_ssl_tls.client.out",
    "content": "$ curl https://localhost:9090/albums --cacert /path/to/server-public.crt\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-service-ssl-tls/http_service_ssl_tls.md",
    "content": "# HTTP service - SSL/TLS\n\nThe `http:Listener` can be configured to communicate through HTTPS by providing a certificate file and a private key file. The certificate and the key can be provided through the `secureSocket` field of the listener configuration. Use this to secure the communication and data transfer between the server and the client.\n\n::: code http_service_ssl_tls.bal :::\n\nRun the service by executing the command below.\n\n::: out http_service_ssl_tls.server.out :::\n\nInvoke the service by executing the cURL command below.\n\n::: out http_service_ssl_tls.client.out :::\n\n>**Tip:** You can invoke the above service via the [SSL/TLS client](/learn/by-example/http-client-ssl-tls/) example.\n\n## Related links\n- [`http:ListenerSecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/http/latest#ListenerSecureSocket)\n- [HTTP service SSL/TLS - Specification](/spec/http/#921-listener---ssltls)\n"
  },
  {
    "path": "examples/http-service-ssl-tls/http_service_ssl_tls.metatags",
    "content": "description: This example is on how to secure an HTTP listener with SSL.\nkeywords: ballerina, ballerina by example, bbe, http, ssl, tls\n"
  },
  {
    "path": "examples/http-service-ssl-tls/http_service_ssl_tls.server.out",
    "content": "$ bal run http_service_ssl_tls.bal\n"
  },
  {
    "path": "examples/http-sse-client/http_sse_client.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\npublic function main() returns error? {\n    http:Client clientEp = check new (\"localhost:9090\");\n    // Make a GET request to the \"/stocks\" endpoint and receive a stream of `http:SseEvent`.\n    stream<http:SseEvent, error?> eventStream = check clientEp->/stocks;\n    // Iterate over the stream and handle each event.\n    check from http:SseEvent event in eventStream\n        do {\n            io:println(\"Stock price: \", event.data);\n        };\n}\n"
  },
  {
    "path": "examples/http-sse-client/http_sse_client.client.out",
    "content": "$ bal run http_sse_client.bal\n\nStock price: 249.9963321685791\nStock price: 56.58070945739746\nStock price: 571.2127494812012\nStock price: 217.98820853233337\nStock price: 21.891758739948273\n"
  },
  {
    "path": "examples/http-sse-client/http_sse_client.md",
    "content": "# HTTP client - Server-sent events\n\nThe HTTP client supports receiving real-time data from services using server-sent events (SSE). It allows payload-binding of a stream of `http:SseEvent` when consuming SSE from a service. This payload binding fails if the content type header is not present in the response or does not have the value `text/event-stream`.\n\n::: code http_sse_client.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Server-sent events](/learn/by-example/http-sse-service/) example.\n\nRun the client program by executing the following command.\n\n::: out http_sse_client.client.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [Client action return types - Specification](/spec/http/#243-client-action-return-types)\n"
  },
  {
    "path": "examples/http-sse-client/http_sse_client.metatags",
    "content": "description: This example demonstrates how server-sent events (SSE) can be consumed using an HTTP client.\nkeywords: ballerina, ballerina by example, bbe, http, SSE, client\n"
  },
  {
    "path": "examples/http-sse-service/http_sse_service.bal",
    "content": "import ballerina/http;\nimport ballerina/lang.runtime;\nimport ballerina/random;\n\nservice /stocks on new http:Listener(9090) {\n    // This resource method returns a stream of `http:SseEvent` (with stock prices)\n    // to push real-time data to clients using server-sent events (SSE).\n    resource function get .() returns stream<http:SseEvent, error?> {\n        // Create a new value of type `StockPriceEventGenerator` to generate stock price events.\n        StockPriceEventGenerator generator = new;\n        // Return a new stream that uses the generator to produce events.\n        return new (generator);\n    }\n}\n\n// Define a stream implementor that can be used to create a stream \n// of `http:SseEvent`, representing stock price events.\nclass StockPriceEventGenerator {\n    int eventCounter = 0;\n\n    public isolated function next() returns record {|http:SseEvent value;|}|error? {\n        // If the eventCounter reaches 5, stop generating events by returning nil.\n        if self.eventCounter == 5 {\n            return ();\n        }\n        self.eventCounter += 1;\n        runtime:sleep(1);\n        // Generate a random stock price\n        float stockPrice = (check random:createIntInRange(1, 1000)) * random:createDecimal();\n        http:SseEvent event = {data: stockPrice.toString()};\n        return {value: event};\n    }\n}\n"
  },
  {
    "path": "examples/http-sse-service/http_sse_service.client.out",
    "content": "$ curl -v localhost:9090/stocks\n*   Trying [::1]:9090...\n* Connected to localhost (::1) port 9090\n> GET /stocks/stockA HTTP/1.1\n> Host: localhost:9090\n> User-Agent: curl/8.4.0\n> Accept: */*\n> \n< HTTP/1.1 200 OK\n< content-type: text/event-stream\n< cache-control: no-cache,public\n< transfer-encoding: chunked\n< connection: keep-alive\n< server: ballerina\n< date: Fri, 2 Aug 2024 12:02:04 +0530\n< \ndata: 76.6014928817749\n\ndata: 789.1765828132629\n\ndata: 241.89215344190598\n\ndata: 494.8120536804199\n\ndata: 234.36854779720306\n\n* Connection #0 to host localhost left intact\n"
  },
  {
    "path": "examples/http-sse-service/http_sse_service.md",
    "content": "# HTTP service - Server-sent events\n\nBallerina HTTP services support pushing real-time data to clients using server-sent events (SSE). A stream of type `http:SseEvent` can be returned from service resource methods. This feature automatically handles sending SSE and sets the content type to `text/event-stream` and the transfer encoding to chunked.\n\n::: code http_sse_service.bal :::\n\nRun the service program by executing the following command.\n\n::: out http_sse_service.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_sse_service.client.out :::\n\n>**Tip:** You can invoke the above service via the [Client server-sent events](/learn/by-example/http-sse-client/) example.\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [Resource return types - Specification](/spec/http/#235-return-types)\n"
  },
  {
    "path": "examples/http-sse-service/http_sse_service.metatags",
    "content": "description: This example demonstrates how server-sent events (SSE) can be produced using an HTTP service.\nkeywords: ballerina, ballerina by example, bbe, http, SSE, service\n"
  },
  {
    "path": "examples/http-sse-service/http_sse_service.server.out",
    "content": "$ bal run http_sse_service.bal\n"
  },
  {
    "path": "examples/http-timeout/http_timeout.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Album readonly & record {\n    string title;\n    string artist;\n};\n\npublic function main() returns error? {\n    http:Client albumClient = check new (\"localhost:9090\", {\n        timeout: 10\n    });\n    Album[] payload = check albumClient->/albums;\n    io:println(payload);\n}\n"
  },
  {
    "path": "examples/http-timeout/http_timeout.md",
    "content": "# HTTP client - Timeout\n\nThe `timeout` field is used to gracefully handle response delays that could occur due to network problems or the back-end. The client timeout is configured in the `timeout` field of the client configuration in seconds.\n\n::: code http_timeout.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the program by executing the following command.\n\n::: out http_timeout.out :::\n\n## Related links\n- [`http` module - API documentation](https://lib.ballerina.io/ballerina/http/latest/)\n- [`http` module - Specification](https://ballerina.io/spec/http/)"
  },
  {
    "path": "examples/http-timeout/http_timeout.metatags",
    "content": "description: This example is on how to use an HTTP timeout in Ballerina. This will set a timeout for the requests to get a response and will return an error if a response is not returned within the given timeout.\nkeywords: ballerina, ballerina by examples, bbe, http, resiliency, timeout\n"
  },
  {
    "path": "examples/http-timeout/http_timeout.out",
    "content": "$ bal run http_timeout.bal\n"
  },
  {
    "path": "examples/http-timeout/tests/http_timeout_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\nimport ballerina/lang.runtime;\n\n@test:Config {}\nfunction testFunc() returns error? {\n    http:Client backendClientEP = check new (\"localhost:8080\", {\n        timeout: 10\n    });\n    string|error response = backendClientEP->get(\"/greeting\");\n    if response is error {\n        test:assertEquals(response.message(), \"Idle timeout triggered before initiating inbound response\");\n    } else {\n        test:assertFail(\"Unexpected response\");\n    }\n}\n\nservice / on new http:Listener(8080) {\n    resource function get greeting() returns string {\n        runtime:sleep(15);\n        return \"Hello World!!!\";\n    }\n}\n"
  },
  {
    "path": "examples/http-trace-logs/http_trace_logs.bal",
    "content": "import ballerina/http;\n\ntype Album readonly & record {|\n    string title;\n    string artist;\n|};\n\nservice /info on new http:Listener(9095) {\n\n    resource function get albums(http:Request req) returns Album[]|error {\n        http:Client albumEP = check new (\"localhost:9090\");\n        Album[] albums = check albumEP->forward(\"/albums\", req);\n        return albums;\n    }\n}\n"
  },
  {
    "path": "examples/http-trace-logs/http_trace_logs.client.out",
    "content": "$ curl http://localhost:9095/info/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n"
  },
  {
    "path": "examples/http-trace-logs/http_trace_logs.md",
    "content": "# HTTP service - Trace logs\n\nBallerina allows enabling HTTP trace logs, which can be used to monitor the HTTP traffic that goes in and out of the application. HTTP trace logs are disabled by default. Set the log level to `TRACE` using the `-Cballerina.http.traceLogConsole=true` runtime argument to enable them. \n\n::: code http_trace_logs.bal :::\n\n## Prerequisites\n- Run the HTTP service given in the [Basic REST service](/learn/by-example/http-basic-rest-service/) example.\n\nRun the service as follows with the runtime argument to enable trace logs.\n\n::: out http_trace_logs.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out http_trace_logs.client.out :::\n\nAdditionally, the `Config.toml` file supports further configurations for advanced use cases, such as configuring the `hostname` and `port` of a socket service to publish the trace logs and writing trace logs to a file using the `file` configuration, which allows specifying the log file location and rotation settings.\n\n::: code Config.toml :::\n\n## Related links\n- [`http:TraceLogAdvancedConfiguration` record](https://lib.ballerina.io/ballerina/http/latest#TraceLogAdvancedConfiguration)\n- [HTTP service trace log - Specification](/spec/http/#823-trace-log)\n"
  },
  {
    "path": "examples/http-trace-logs/http_trace_logs.metatags",
    "content": "description: This example is on how trace logs can be used to monitor the HTTP traffic in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, http, trace logs\n"
  },
  {
    "path": "examples/http-trace-logs/http_trace_logs.server.out",
    "content": "$ bal run http_trace_logs.bal -- -Cballerina.http.traceLogConsole=true\nballerina: HTTP trace log enabled\n\n# In the logs, `http.downstream` refers to the HTTP traffic that flows between the client and Ballerina.\n# while `http.upstream` refers to the HTTP traffic that flows between Ballerina and the backend.\n\n[2022-12-15 11:18:03,126] TRACE {http.tracelog.downstream} - [id: 0x67ba903e] REGISTERED  \n[2022-12-15 11:18:03,157] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] ACTIVE  \n[2022-12-15 11:18:03,187] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] INBOUND: DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)\nGET /info/albums HTTP/1.1\nHost: localhost:9095\nUser-Agent: curl/7.79.1\nAccept: */*  \n[2022-12-15 11:18:03,253] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] INBOUND: EmptyLastHttpContent, 0B  \n[2022-12-15 11:18:03,255] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] READ COMPLETE  \n[2022-12-15 11:18:03,394] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd] REGISTERED  \n[2022-12-15 11:18:03,394] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd] CONNECT: localhost/127.0.0.1:9090, null  \n[2022-12-15 11:18:03,399] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] ACTIVE  \n[2022-12-15 11:18:03,402] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] OUTBOUND: DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)\nGET /albums HTTP/1.1\nUser-Agent: curl/7.79.1\nAccept: */*\nhost: localhost:9090\nconnection: keep-alive\nupgrade: h2c\nHTTP2-Settings: AAEAABAAAAIAAAABAAN_____AAQAAP__AAUAAEAAAAYAACAA\nconnection: HTTP2-Settings,upgrade  \n[2022-12-15 11:18:03,408] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] OUTBOUND: EmptyLastHttpContent, 0B  \n[2022-12-15 11:18:03,408] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] FLUSH  \n[2022-12-15 11:18:03,414] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] INBOUND: DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)\nHTTP/1.1 101 Switching Protocols\nconnection: upgrade\nupgrade: h2c  \n[2022-12-15 11:18:03,417] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] INBOUND: EmptyLastHttpContent, 0B  \n[2022-12-15 11:18:03,419] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] OUTBOUND: 24B\nPRI * HTTP/2.0\n\nSM\n\n  \n[2022-12-15 11:18:03,421] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] OUTBOUND SETTINGS: ack=false settings={MAX_HEADER_LIST_SIZE=8192}  \n[2022-12-15 11:18:03,422] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, correlatedSource: 0x67ba903e, host:/127.0.0.1:61635 - remote:localhost/127.0.0.1:9090] OUTBOUND: 15B\n   \n[2022-12-15 11:18:03,430] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] INBOUND SETTINGS: ack=false settings={MAX_HEADER_LIST_SIZE=8192}  \n[2022-12-15 11:18:03,431] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] OUTBOUND SETTINGS: ack=true  \n[2022-12-15 11:18:03,437] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] INBOUND HEADERS: streamId=1 headers=DefaultHttp2Headers[:status: 200, content-type: application/json, server: ballerina, date: Thu, 15 Dec 2022 11:18:03 +0530] padding=0 endStream=false  \n[2022-12-15 11:18:03,450] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] INBOUND DATA: streamId=1 padding=0 endStream=true length=95 data=95B\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]  \n[2022-12-15 11:18:03,452] TRACE {http.tracelog.upstream} - [id: 0x40eb51fd, L:/127.0.0.1:61635 - R:localhost/127.0.0.1:9090] INBOUND SETTINGS: ack=true  \n[2022-12-15 11:18:03,516] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] OUTBOUND: DefaultFullHttpResponse(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 95, cap: 95, components=1))\nHTTP/1.1 200 OK\ncontent-type: application/json\ncontent-length: 95\nserver: ballerina\ndate: Thu, 15 Dec 2022 11:18:03 +0530, 95B\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]  \n[2022-12-15 11:18:03,517] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] FLUSH  \n[2022-12-15 11:18:03,519] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] READ COMPLETE  \n[2022-12-15 11:18:03,521] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] INACTIVE  \n[2022-12-15 11:18:03,523] TRACE {http.tracelog.downstream} - [id: 0x67ba903e, correlatedSource: n/a, host:/127.0.0.1:9095 - remote:/127.0.0.1:61634] UNREGISTERED \n"
  },
  {
    "path": "examples/identifiers/identifiers.bal",
    "content": "import ballerina/io;\n\n// You can have Unicode identifiers.\nfunction พิมพ์ชื่อ(string ชื่อ) {\n    // Use \\u{H} to specify character using Unicode code point in hex.\n   io:println(ชื่\\u{E2D});\n}\n\n// Prefix reserved keywords with a single quote.\nstring 'from = \"contact@ballerina.io\";\n\n// Prefix non-identifier character with a \\\\.\nstring first\\ name = \"Ballerina\";\n\npublic function main() {\n    พิมพ์ชื่อ(\"ආයුබෝවන්\");\n}"
  },
  {
    "path": "examples/identifiers/identifiers.md",
    "content": "# Identifiers\n\nIdentifier syntax is similar to C. Keywords are reserved.\n\n::: code identifiers.bal :::\n\n::: out identifiers.out :::"
  },
  {
    "path": "examples/identifiers/identifiers.metatags",
    "content": "description: This BBE introduces identifiers in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, identifiers\n"
  },
  {
    "path": "examples/identifiers/identifiers.out",
    "content": "$ bal run identifiers.bal\nආයුබෝවන්\n"
  },
  {
    "path": "examples/identity/identity.bal",
    "content": "import ballerina/io;\n\nclass MyClass {\n    int i = 0;\n}\n\npublic function main() {\n    MyClass obj1 = new MyClass();\n    MyClass obj2 = new MyClass();\n    \n    // `b1` will be true.\n    boolean b1 = (obj1 === obj1);\n    io:println(b1);\n\n    // `b2` will be false.\n    boolean b2 = (obj1 === obj2);\n    io:println(b2);\n\n    // `b3` will be true.\n    boolean b3 = ([1, 2, 3] == [1, 2, 3]);\n    io:println(b3);\n\n    // `b4` will be false.\n    boolean b4 = ([1, 2, 3] === [1, 2, 3]);\n    io:println(b4);\n\n    // `b5` will be true.\n    boolean b5 = (-0.0 == +0.0);\n    io:println(b5);\n\n    // `b6` will be false.\n    boolean b6 = (-0.0 === +0.0);\n    io:println(b6);\n}\n"
  },
  {
    "path": "examples/identity/identity.md",
    "content": "# Identity\n\n`===` and `!==` operators test for identity. Values of mutable basic types are identical if and only if they are stored in the same address.\n\n`==` and `!=` are not defined for objects. `-0.0` and `+0.0` are equal but not identical.\n\n::: code identity.bal :::\n\n::: out identity.out :::"
  },
  {
    "path": "examples/identity/identity.metatags",
    "content": "description: This BBE demonstrates identity in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, identity\n"
  },
  {
    "path": "examples/identity/identity.out",
    "content": "$ bal run identity.bal\ntrue\nfalse\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "examples/if-statement/if_statement.bal",
    "content": "import ballerina/io;\n\nfunction getGrades(int score) returns string {\n    // Parentheses are optional in conditions.\n    // However, curly braces are required in `if/else` statements.\n    if 0 < score && score < 55 {\n        return \"F\";\n    } else if 55 <= score && score < 65 {\n        return \"C\";\n    } else if 65 <= score && score < 75  {\n        return \"B\";\n    } else if 75 <= score && score <= 100 {\n        return \"A\";\n    } else {\n        return \"Invalid grade\";\n    }\n}\n\npublic function main() {\n    int score = 66;\n    string grade = getGrades(score);\n    io:println(grade);\n\n    int|string newScore = 77;\n\n    // The `if` statement can be used for type narrowing.\n    if newScore is int {\n        io:println(getGrades(newScore));\n    } else {\n        io:println(\"Score is not an integer\");\n    }\n\n}\n"
  },
  {
    "path": "examples/if-statement/if_statement.md",
    "content": "# If statement\n\n`if` statements are used for conditional execution. Conditions following `if` must be boolean and if the condition is true, then, the corresponding statement block is executed. If the condition of the `if` statement is false, then, one of the following `else if` blocks executes if the particular `else if` statement condition is true. If none of the conditions are true, then, the `else` block executes.\n\n::: code if_statement.bal :::\n\n::: out if_statement.out :::\n\n## Related links\n- [Boolean](/learn/by-example/boolean/)\n"
  },
  {
    "path": "examples/if-statement/if_statement.metatags",
    "content": "description: This BBE demonstrates the use of `if` statements in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, boolean, operators, if, else, else if\n"
  },
  {
    "path": "examples/if-statement/if_statement.out",
    "content": "$ bal run if_statement.bal\nB\nA\n"
  },
  {
    "path": "examples/ignoring-return-values-and-errors/ignoring_return_values_and_errors.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Allowed only if the return value is `()`.\n    doX();\n\n    // Allowed if the return value does not include an `error`.\n    _ = getX();\n\n    // Use `checkpanic` if you don't want to handle an `error`.\n    checkpanic tryX(true);\n    checkpanic tryX(false);\n\n}\n\nfunction doX() {\n    io:println(\"Do X\");\n}\n\nfunction getX() returns boolean {\n    io:println(\"Get X\");\n    return true;\n}\n\nfunction tryX(boolean x) returns error? {\n    io:println(\"Try X\");\n    if !x {\n        return error(\"error!\");\n    }\n    return;\n}\n"
  },
  {
    "path": "examples/ignoring-return-values-and-errors/ignoring_return_values_and_errors.md",
    "content": "# Ignore return values and errors\n\nBallerina does not allow silently ignoring return values. To ignore a return value, assign it to `_`; this is like  an implicitly declared variable that cannot be referenced. When a return type includes an error, you have to do something  with the error.\n\n`_` is of type any: you cannot use `_` to ignore an error. `checkpanic` is like `check`, but panics on error rather than returning.\n\n::: code ignoring_return_values_and_errors.bal :::\n\n::: out ignoring_return_values_and_errors.out :::"
  },
  {
    "path": "examples/ignoring-return-values-and-errors/ignoring_return_values_and_errors.metatags",
    "content": "description: This BBE demonstrates how return values and errors can be ignored in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, error, ignore value\n"
  },
  {
    "path": "examples/ignoring-return-values-and-errors/ignoring_return_values_and_errors.out",
    "content": "$ bal run ignoring_return_values_and_errors.bal\nDo X\nGet X\nTry X\nTry X\nerror: error!\n        at ignoring_return_values_and_errors:tryX(ignoring_return_values_and_errors.bal:28)\n           ignoring_return_values_and_errors:main(ignoring_return_values_and_errors.bal:12)\n"
  },
  {
    "path": "examples/immutability/immutability.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    int grade;\n    string name;\n    map<int> marks;\n|};\n\npublic function main() {\n    // Creates an immutable `Student` value using an intersection type with `readonly`.\n    Student & readonly student = {\n        grade: 12,\n        name: \"John\",\n        // The applicable contextually-expected type for marks now is `map<int> & readonly`.\n        // Thus, the value for marks will be constructed as an immutable map.\n        marks: {\n            \"Maths\": 75,\n            \"English\": 90\n        }\n    };\n    boolean x = student[\"marks\"] is map<int> & readonly;\n    io:println(x);\n}\n"
  },
  {
    "path": "examples/immutability/immutability.md",
    "content": "# Immutability\n\n`anydata` values can be made immutable. Simple and `string` values are inherently immutable. A structural value can be constructed as mutable or immutable. A value includes an immutable flag.\n\nThe immutable flag is fixed at the time of construction. Attempting to mutate an immutable structure causes a panic at runtime. Immutability is deep: an immutable structure can only have immutable members. An immutable value is safe for concurrent access without locking.\n\n::: code immutability.bal :::\n\n::: out immutability.out :::"
  },
  {
    "path": "examples/immutability/immutability.metatags",
    "content": "description: This BBE demonstrates immutability in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, immutability\n"
  },
  {
    "path": "examples/immutability/immutability.out",
    "content": "$ bal run immutability.bal\ntrue\n"
  },
  {
    "path": "examples/in-memory-message-store/in_memory_message_store.bal",
    "content": "import ballerina/messaging;\nimport ballerina/log;\n\n// Using the in-memory message store implementation\nfinal messaging:Store store = new messaging:InMemoryMessageStore();\n\npublic function main() returns error? {\n    // Store a message\n    check store->store(\"Hello, World\");\n    \n    // Retrieve the message\n    messaging:Message? msg = check store->retrieve();\n    if msg is messaging:Message {\n        log:printInfo(\"Message retrieved\", payload = msg.payload, id = msg.id);\n        \n        // Acknowledge the message with success will remove the message from\n        // the store\n        check store->acknowledge(msg.id);\n    }\n\n    // Try to retrieve the message again\n    msg = check store->retrieve();\n    if msg is () {\n        log:printInfo(\"No messages in the store\");\n    }\n}\n"
  },
  {
    "path": "examples/in-memory-message-store/in_memory_message_store.md",
    "content": "# In-Memory Message Store\n\nThis example demonstrates how to use the built-in `InMemoryMessageStore` implementation provided by the `messaging` library. The `InMemoryMessageStore` is a ready-to-use implementation of the `messaging:Store` interface that's ideal for quick testing and development scenarios where you don't need persistence.\n\n::: code in_memory_message_store.bal :::\n\n::: out in_memory_message_store.out :::\n\n## Related links\n\n- [`messaging` module - API documentation](https://lib.ballerina.io/ballerina/messaging/latest/)\n- [`messaging` module - Specification](https://ballerina.io/spec/messaging/)\n- [Message store type](/learn/by-example/message-store-type/)\n- [RabbitMQ message store](https://central.ballerina.io/ballerinax/rabbitmq/latest#MessageStore)\n"
  },
  {
    "path": "examples/in-memory-message-store/in_memory_message_store.metatags",
    "content": "description: This BBE demonstrates how to use the in-memory message store from the messaging library in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, messaging, store, in-memory\n"
  },
  {
    "path": "examples/in-memory-message-store/in_memory_message_store.out",
    "content": "$ bal run in_memory_message_store.bal\n\ntime=2025-10-08T08:59:48.453+05:30 level=INFO module=\"\" message=\"Message retrieved\" payload=\"Hello, World\" id=\"01f0a3f7-0aaf-15e0-a29f-2cdcb73f2889\"\ntime=2025-10-08T08:59:48.483+05:30 level=INFO module=\"\" message=\"No messages in the store\"\n"
  },
  {
    "path": "examples/included-record-parameters/included_record_parameters.bal",
    "content": "import ballerina/io;\n\ntype Options record {|\n    boolean verbose = false;\n    string? outputFile = ();\n|};\n\n// `foo` has a string parameter `inputFile` and an included record parameter of the\n// `Options` record type.\nfunction foo(string inputFile, *Options options) {\n    io:println(\"Input File:\", inputFile);\n    io:println(\"Options:\", options);\n}\n\npublic function main() {\n    // Call `foo()` by directly passing a value of the `Options` record type.\n    foo(\"file.txt\", {verbose: true});\n\n    // Pass named arguments having the same names as the fields in the `Options` record.\n    foo(\"file.txt\", verbose = true);\n}\n"
  },
  {
    "path": "examples/included-record-parameters/included_record_parameters.md",
    "content": "# Included record parameters\n\nBallerina allows you to define functions with included record parameters using `*T` notation. The function defines records for named parameters, where all the arguments are passed within a record value. But, the caller can pass parameters by name, which are the same as the record field names.\n\n::: code included_record_parameters.bal :::\n\n::: out included_record_parameters.out :::\n"
  },
  {
    "path": "examples/included-record-parameters/included_record_parameters.metatags",
    "content": "description: This BBE demonstrates included record parameters in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, record, included record parameters, record parameters\n"
  },
  {
    "path": "examples/included-record-parameters/included_record_parameters.out",
    "content": "$ bal run included_record_parameters.bal\nInput File:file.txt\nOptions:{\"verbose\":true,\"outputFile\":null}\nInput File:file.txt\nOptions:{\"verbose\":true,\"outputFile\":null}\n"
  },
  {
    "path": "examples/index.json",
    "content": "[\n  {\n    \"title\": \"Hello World\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world main\",\n        \"url\": \"hello-world\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Hello world service\",\n        \"url\": \"hello-world-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Basics\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Programs and modules\",\n        \"url\": \"programs-and-modules\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Main function\",\n        \"url\": \"main-function\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Init function\",\n        \"url\": \"init-function\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Variables and types\",\n        \"url\": \"variables-and-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Identifiers\",\n        \"url\": \"identifiers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Simple basic types\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Integers\",\n        \"url\": \"integers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Floating point numbers\",\n        \"url\": \"floating-point-numbers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Decimal type\",\n        \"url\": \"decimal-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Nil\",\n        \"url\": \"nil\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Boolean\",\n        \"url\": \"boolean\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Byte type\",\n        \"url\": \"byte-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Strings\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Strings\",\n        \"url\": \"strings\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Operators\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n\n      {\n        \"name\": \"Binary operators\",\n        \"url\": \"binary-operators\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Unary operators\",\n        \"url\": \"unary-operators\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Conditional statements\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"If statement\",\n        \"url\": \"if-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Match statement\",\n        \"url\": \"match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Match guard in match statement\",\n        \"url\": \"match-guard-in-match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Binding patterns in match statement\",\n        \"url\": \"binding-patterns-in-match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Functions\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Functions\",\n        \"url\": \"functions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Included record parameters\",\n        \"url\": \"included-record-parameters\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest parameters\",\n        \"url\": \"rest-parameters\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Default values for function parameters\",\n        \"url\": \"default-values-for-function-parameters\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Provide function arguments by name\",\n        \"url\": \"provide-function-arguments-by-name\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest arguments\",\n        \"url\": \"rest-arguments\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Function pointers\",\n        \"url\": \"function-pointers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Function values\",\n        \"url\": \"function-values\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Function types\",\n        \"url\": \"function-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Anonymous function\",\n        \"url\": \"anonymous-function\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Function closure\",\n        \"url\": \"function-closure\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Iteration\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Foreach statement\",\n        \"url\": \"foreach-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"While statement\",\n        \"url\": \"while-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Break statement\",\n        \"url\": \"break-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Continue statement\",\n        \"url\": \"continue-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Range function\",\n        \"url\": \"int-range\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Lang library\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Langlib functions\",\n        \"url\": \"langlib-functions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Types and typing\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Structural typing\",\n        \"url\": \"structural-typing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Unions\",\n        \"url\": \"unions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Errors\",\n        \"url\": \"error-reporting\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Anydata type\",\n        \"url\": \"anydata-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Any type\",\n        \"url\": \"any-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Type definitions\",\n        \"url\": \"type-definitions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Typedesc type\",\n        \"url\": \"typedesc-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Covariance\",\n        \"url\": \"covariance\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Type inference\",\n        \"url\": \"type-inference\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Built-in integer subtypes\",\n        \"url\": \"built-in-integer-subtypes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Built-in string subtype\",\n        \"url\": \"built-in-string-subtype\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"ensureType function\",\n        \"url\": \"ensureType-function\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Dependent types\",\n        \"url\": \"dependent-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Singleton types\",\n        \"url\": \"singleton-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Stream type\",\n        \"url\": \"stream-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Never type\",\n        \"url\": \"never-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Expression-oriented style\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Expression-oriented style\",\n        \"url\": \"expression-oriented-style\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Equality\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Expression equality\",\n        \"url\": \"expression-equality\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Lists\",\n    \"column\": 0,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Arrays\",\n        \"url\": \"arrays\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Nested arrays\",\n        \"url\": \"nested-arrays\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Tuples\",\n        \"url\": \"tuples\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest type in tuples\",\n        \"url\": \"rest-type-in-tuples\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Filler values of a list\",\n        \"url\": \"filler-values-of-a-list\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"List subtyping\",\n        \"url\": \"list-subtyping\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"List equality\",\n        \"url\": \"list-equality\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Binary data\",\n        \"url\": \"binary-data\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Mappings\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Maps\",\n        \"url\": \"maps\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Records\",\n        \"url\": \"records\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Computed field key\",\n        \"url\": \"computed-field-key\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Records\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Optional fields\",\n        \"url\": \"optional-fields\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Open records\",\n        \"url\": \"open-records\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Controlling openness\",\n        \"url\": \"controlling-openness\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Type inclusion for records\",\n        \"url\": \"type-inclusion-for-records\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Default values for record fields\",\n        \"url\": \"default-values-for-record-fields\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Array/Map symmetry\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Array/Map symmetry\",\n        \"url\": \"array-map-symmetry\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Objects\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Object\",\n        \"url\": \"object\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Defining classes\",\n        \"url\": \"defining-classes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Object constructor\",\n        \"url\": \"object-constructor\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Object value from class definition\",\n        \"url\": \"object-value-from-class-definition\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Visibility of object fields and methods\",\n        \"url\": \"visibility-of-object-fields-and-methods\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Init return type\",\n        \"url\": \"init-return-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Object types\",\n        \"url\": \"object-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Object type inclusion\",\n        \"url\": \"object-type-inclusion\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Distinct object types\",\n        \"url\": \"distinct-object-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Object closure\",\n        \"url\": \"object-closure\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Client class\",\n        \"url\": \"client-class\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Start service from service class definition\",\n        \"url\": \"start-service-from-service-class-definition\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Binding patterns\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Binding patterns\",\n        \"url\": \"binding-patterns\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Typed binding pattern\",\n        \"url\": \"typed-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Wildcard binding pattern\",\n        \"url\": \"wildcard-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"List binding patterns\",\n        \"url\": \"list-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest binding pattern in list binding pattern\",\n        \"url\": \"rest-binding-pattern-in-list-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Mapping binding pattern\",\n        \"url\": \"mapping-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest binding pattern in mapping binding pattern\",\n        \"url\": \"rest-binding-pattern-in-mapping-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Error binding pattern\",\n        \"url\": \"error-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rest binding pattern in error binding pattern\",\n        \"url\": \"rest-binding-pattern-in-error-binding-pattern\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Single use of typed binding patterns\",\n        \"url\": \"single-use-of-typed-binding\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Single use of typed binding patterns with on fail clause\",\n        \"url\": \"single-use-with-on-fail-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Iterative use of typed binding patterns\",\n        \"url\": \"iterative-use-of-typed-binding\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"List binding pattern in match statement\",\n        \"url\": \"list-binding-pattern-in-match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Mapping binding pattern in match statement\",\n        \"url\": \"mapping-binding-pattern-in-match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Error binding pattern in match statement\",\n        \"url\": \"error-binding-pattern-in-match-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Tables\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Table\",\n        \"url\": \"table\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Table types\",\n        \"url\": \"table-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Multiple key fields\",\n        \"url\": \"multiple-key-fields\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Structured keys\",\n        \"url\": \"structured-keys\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Query expressions\",\n    \"column\": 1,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Query expressions\",\n        \"url\": \"query-expressions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Sort iterable objects\",\n        \"url\": \"sort-iterable-objects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Let clause\",\n        \"url\": \"let-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Limit clause\",\n        \"url\": \"limit-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Join iterable objects\",\n        \"url\": \"joining-iterable-objects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Outer Join clause\",\n        \"url\": \"outer-join-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Query tables\",\n        \"url\": \"querying-tables\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Create tables with a query\",\n        \"url\": \"create-tables-with-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Create maps with a query\",\n        \"url\": \"create-maps-with-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Create streams with a query\",\n        \"url\": \"create-streams-with-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"On conflict clause\",\n        \"url\": \"on-conflict-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Advanced conflict handling\",\n        \"url\": \"advanced-conflict-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Iterate over XML with a query\",\n        \"url\": \"iterating-over-xml-with-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Nested query expressions\",\n        \"url\": \"nested-query-expressions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Destructure records using a query\",\n        \"url\": \"destructure-records-using-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Querying streams\",\n        \"url\": \"querying-with-streams\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Aggregation\",\n        \"url\": \"aggregation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Query actions\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Query actions\",\n        \"url\": \"query-actions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"JSON\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"JSON type\",\n        \"url\": \"json-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Access JSON elements\",\n        \"url\": \"access-json-elements\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Access optional JSON elements\",\n        \"url\": \"access-optional-json-elements\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Match statement with maps\",\n        \"url\": \"match-statement-with-maps\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Convert from user-defined type to JSON\",\n        \"url\": \"converting-from-user-defined-type-to-json\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Convert from table and XML to JSON\",\n        \"url\": \"converting-from-table-and-xml-to-json\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Convert from JSON to user-defined type\",\n        \"url\": \"convert-from-json-to-user-defined-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Cast JSON to user-defined type\",\n        \"url\": \"casting-json-to-user-defined-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Resource method typing\",\n        \"url\": \"resource-method-typing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"JSON numbers\",\n        \"url\": \"json-numbers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"JSON to record\",\n        \"url\": \"json-to-record\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"JSON to record with projection\",\n        \"url\": \"json-to-record-with-projection\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"JSONPath expressions\",\n        \"url\": \"jsonpath-expressions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Backtick templates\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Raw templates\",\n        \"url\": \"raw-templates\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"String templates\",\n        \"url\": \"string-templates\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML templates\",\n        \"url\": \"xml-templates\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"XML\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"XML data model\",\n        \"url\": \"xml-data-model\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML operations\",\n        \"url\": \"xml-operations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML iteration\",\n        \"url\": \"xml-iteration\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML access\",\n        \"url\": \"xml-access\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML mutation\",\n        \"url\": \"xml-mutation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML subtyping\",\n        \"url\": \"xml-subtyping\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML navigation \",\n        \"url\": \"xml-navigation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML templates and query\",\n        \"url\": \"xml-templates-and-query\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML namespaces\",\n        \"url\": \"xml-namespaces\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XMLNS declarations\",\n        \"url\": \"xmlns-declarations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML to record\",\n        \"url\": \"xml-to-record\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"XML to record with projection\",\n        \"url\": \"xml-to-record-with-projection\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Regular Expressions\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"RegExp type\",\n        \"url\": \"regexp-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"RegExp operations overview\",\n        \"url\": \"regexp-operations-overview\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"RegExp replace operations\",\n        \"url\": \"regexp-replace-operations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"RegExp find operations\",\n        \"url\": \"regexp-find-operations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"RegExp match operations\",\n        \"url\": \"regexp-match-operations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Metadata\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Documentation\",\n        \"url\": \"documentation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Annotations\",\n        \"url\": \"annotations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Network interaction\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Consume services: client objects\",\n        \"url\": \"consuming-services\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Failing intermittently due to GitHub rate limiting\",\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Provide services\",\n        \"url\": \"providing-services\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Module lifecycle\",\n        \"url\": \"module-lifecycle\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Service declaration\",\n        \"url\": \"service-declaration\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Does not include udp client\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Resource methods\",\n        \"url\": \"resource-methods\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Hierarchical resources\",\n        \"url\": \"hierarchical-resources\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Resource path parameters\",\n        \"url\": \"resource-path-parameters\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Configurability\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Configurable variables\",\n        \"url\": \"configurable-variables\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Configure via TOML files\",\n        \"url\": \"configuring-via-toml\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Configure via CLI arguments\",\n        \"url\": \"configuring-via-cli\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Error handling\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Check expression\",\n        \"url\": \"check-expression\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Error subtyping\",\n        \"url\": \"error-subtyping\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Panics\",\n        \"url\": \"panics\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n          \"name\": \"Trap expression\",\n          \"url\": \"trap-expression\",\n          \"verifyBuild\": true,\n          \"verifyOutput\": true,\n          \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Type intersection for error types\",\n        \"url\": \"error-type-intersection\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Error detail\",\n        \"url\": \"error-detail\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Error cause\",\n        \"url\": \"error-cause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Ignore return values and errors\",\n    \"column\": 2,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Ignore return values and errors\",\n        \"url\": \"ignoring-return-values-and-errors\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Mutability and identity\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Identity\",\n        \"url\": \"identity\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Const and final \",\n        \"url\": \"const-and-final\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Enumerations\",\n        \"url\": \"enumerations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Immutability\",\n        \"url\": \"immutability\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Concurrency\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Asynchronous function calls\",\n        \"url\": \"asynchronous-function-calls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Named workers\",\n        \"url\": \"named-workers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Sequence diagrams\",\n        \"url\": \"sequence-diagrams\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Wait for workers\",\n        \"url\": \"waiting-for-workers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Strands\",\n        \"url\": \"strands\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Named worker return values\",\n        \"url\": \"named-worker-return-values\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Alternate wait\",\n        \"url\": \"alternate-wait\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Multiple wait\",\n        \"url\": \"multiple-wait\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Named workers and futures\",\n        \"url\": \"named-workers-and-futures\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Inter-worker message passing\",\n        \"url\": \"inter-worker-message-passing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Alternate receive\",\n        \"url\": \"alternate-receive\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Multiple receive\",\n        \"url\": \"multiple-receive\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Conditional send\",\n        \"url\": \"conditional-send\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Inter-worker failure propagation\",\n        \"url\": \"inter-worker-failure-propagation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Named worker with on fail clause\",\n        \"url\": \"named-worker-with-on-fail-clause\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Synchronize message passing\",\n        \"url\": \"synchronize-message-passing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Asynchronize message passing\",\n        \"url\": \"asynchronize-message-passing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Flush\",\n        \"url\": \"flush\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Fork\",\n        \"url\": \"fork\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Transactions\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Transaction statement\",\n        \"url\": \"transaction-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Check semantics\",\n        \"url\": \"check-semantics\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Rollback\",\n        \"url\": \"rollback\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Retry transaction statement\",\n        \"url\": \"retry-transaction-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Transactional qualifier\",\n        \"url\": \"transactional-qualifier\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Transactional named workers\",\n        \"url\": \"transactional-named-workers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Commit/rollback handlers\",\n        \"url\": \"commit-rollback-handlers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Concurrency safety\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Lock statement\",\n        \"url\": \"lock-statement\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Isolated functions\",\n        \"url\": \"isolated-functions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Readonly type\",\n        \"url\": \"readonly-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Readonly and isolated\",\n        \"url\": \"readonly-and-isolated\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Readonly objects and classes\",\n        \"url\": \"readonly-objects-and-classes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Combining isolated functions and lock\",\n        \"url\": \"combining-isolated-functions-and-lock\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Isolated variables\",\n        \"url\": \"isolated-variables\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Isolated methods\",\n        \"url\": \"isolated-methods\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Isolated objects\",\n        \"url\": \"isolated-objects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Inferring isolated\",\n        \"url\": \"inferring-isolated\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Run strands safely on separate threads\",\n        \"url\": \"run-strands-safely-on-separate-threads\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Interface to external code\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Interface to external code\",\n        \"url\": \"interface-to-external-code\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Testing\",\n    \"column\": 3,\n    \"category\": \"Language concepts\",\n    \"samples\": [\n      {\n        \"name\": \"Assertions\",\n        \"url\": \"testerina-assertions\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Before and after test\",\n        \"url\": \"testerina-before-and-after-test\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Before and after each\",\n        \"url\": \"testerina-before-and-after-each\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Before and after groups\",\n        \"url\": \"testerina-before-and-after-groups\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Before and after suite\",\n        \"url\": \"testerina-before-and-after-suite\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Data-driven tests\",\n        \"url\": \"testerina-data-driven-tests\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Guarantee test execution order\",\n        \"url\": \"testerina-guarantee-test-execution-order\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Group tests\",\n        \"url\": \"testerina-group-tests\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Function mocking\",\n        \"url\": \"testerina-mocking-functions\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Object mocking\",\n        \"url\": \"testerina-mocking-objects\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"REST service\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Basic REST service\",\n        \"url\": \"http-basic-rest-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Service and resource paths\",\n        \"url\": \"http-service-and-resource-paths\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload data binding\",\n        \"url\": \"http-service-data-binding\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload constraint validation\",\n        \"url\": \"http-service-payload-constraint-validation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Path parameter\",\n        \"url\": \"http-path-param\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query parameter\",\n        \"url\": \"http-query-parameter\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Header parameter\",\n        \"url\": \"http-header-param\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send response\",\n        \"url\": \"http-send-response\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send different status codes\",\n        \"url\": \"http-send-different-status-codes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send different status codes with payload\",\n        \"url\": \"http-send-different-status-codes-with-payload\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"http-default-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send cache response\",\n        \"url\": \"http-service-cache-response\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP client\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send request/Receive response\",\n        \"url\": \"http-client-send-request-receive-response\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload data binding\",\n        \"url\": \"http-client-data-binding\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload constraint validation\",\n        \"url\": \"http-client-payload-constraint-validation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Path parameter\",\n        \"url\": \"http-client-path-parameter\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query parameter\",\n        \"url\": \"http-client-query-parameter\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Header parameter\",\n        \"url\": \"http-client-header-parameter\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Enable caching\",\n        \"url\": \"http-caching-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"REST service security\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"http-service-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"http-service-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication file user store\",\n        \"url\": \"http-service-basic-authentication-file-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication LDAP user store\",\n        \"url\": \"http-service-basic-authentication-ldap-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JWT authentication\",\n        \"url\": \"http-service-jwt-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2\",\n        \"url\": \"http-service-oauth2\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP client security\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"http-client-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"http-client-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"http-client-basic-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Bearer token authentication\",\n        \"url\": \"http-client-bearer-token-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Self-signed JWT authentication\",\n        \"url\": \"http-client-self-signed-jwt-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 client credentials grant type\",\n        \"url\": \"http-client-oauth2-client-credentials-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 password grant type\",\n        \"url\": \"http-client-oauth2-password-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 refresh token grant type\",\n        \"url\": \"http-client-oauth2-refresh-token-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 JWT bearer grant type\",\n        \"url\": \"http-client-oauth2-jwt-bearer-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP client resiliency\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Timeout\",\n        \"url\": \"http-timeout\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Retry\",\n        \"url\": \"http-retry\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Circuit breaker\",\n        \"url\": \"http-circuit-breaker\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Load balancer\",\n        \"url\": \"http-load-balancer\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Failover\",\n        \"url\": \"http-failover\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP service advanced\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Default resource\",\n        \"url\": \"http-default-resource\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Request/Response object\",\n        \"url\": \"http-request-response\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Caller object\",\n        \"url\": \"http-caller\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Redirects\",\n        \"url\": \"http-service-redirects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"CORS\",\n        \"url\": \"http-cors\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"100 continue\",\n        \"url\": \"http-100-continue\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Matrix parameter\",\n        \"url\": \"http-matrix-param\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Restrict by media type\",\n        \"url\": \"http-restrict-by-media-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"File upload\",\n        \"url\": \"http-service-file-upload\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Compression\",\n        \"url\": \"http-compression\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Trace logs\",\n        \"url\": \"http-trace-logs\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Access logs\",\n        \"url\": \"http-access-logs\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Cookies\",\n        \"url\": \"http-cookies-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Chunking\",\n        \"url\": \"http-service-chunking\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Sending headers\",\n        \"url\": \"http-send-header\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Response with multiparts\",\n        \"url\": \"http-response-with-multiparts\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Passthrough\",\n        \"url\": \"http-passthrough\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP/2 to HTTP/1.1 downgrade\",\n        \"url\": \"http-2-to-1-1-downgrade-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP/2 server push\",\n        \"url\": \"http-2-0-server-push\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Server-sent events\",\n        \"url\": \"http-sse-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP client advanced\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Redirects\",\n        \"url\": \"http-client-redirects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"File upload\",\n        \"url\": \"http-client-file-upload\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Cookies\",\n        \"url\": \"http-cookies-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Chunking\",\n        \"url\": \"http-client-chunking\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Request with multiparts\",\n        \"url\": \"http-request-with-multiparts\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP/2 to HTTP/1.1 downgrade\",\n        \"url\": \"http-2-to-1-1-downgrade-client\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP/2 prior knowledge\",\n        \"url\": \"http-2-prior-knowledge-client\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP/2 server push\",\n        \"url\": \"http-2-0-client-server-push\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Server-sent events\",\n        \"url\": \"http-sse-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"HTTP service interceptors\",\n    \"column\": 0,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Request interceptor\",\n        \"url\": \"http-request-interceptor\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Response interceptor\",\n        \"url\": \"http-response-interceptor\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"http-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Interceptor error handling\",\n        \"url\": \"http-interceptor-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"GraphQL service\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world\",\n        \"url\": \"graphql-hello-world\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Service as output object\",\n        \"url\": \"graphql-returning-service-objects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Record as output object\",\n        \"url\": \"graphql-returning-record-values\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Input types\",\n        \"url\": \"graphql-input-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutations\",\n        \"url\": \"graphql-mutations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Subscriptions\",\n        \"url\": \"graphql-subscriptions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Input objects\",\n        \"url\": \"graphql-input-objects\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"ID scalar type\",\n        \"url\": \"graphql-id-scalar-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Interfaces\",\n        \"url\": \"graphql-interfaces\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Interfaces implementing interfaces\",\n        \"url\": \"graphql-interfaces-implementing-interfaces\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Union types\",\n        \"url\": \"graphql-service-union-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"graphql-service-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"GraphiQL client\",\n        \"url\": \"graphql-graphiql\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Documentation\",\n        \"url\": \"graphql-documentation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Directives\",\n        \"url\": \"graphql-directives\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Hierarchical resource paths\",\n        \"url\": \"graphql-hierarchical-resource-paths\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"  GraphQL service advanced\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Context object\",\n        \"url\": \"graphql-context\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Field object\",\n        \"url\": \"graphql-service-field-object\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Service interceptors\",\n        \"url\": \"graphql-service-interceptors\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Field interceptors\",\n        \"url\": \"graphql-field-interceptors\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Interceptor configurations\",\n        \"url\": \"graphql-interceptor-configurations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Input constraint validation\",\n        \"url\": \"graphql-input-constraint-validation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"File upload\",\n        \"url\": \"graphql-file-upload\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Dataloader\",\n        \"url\": \"graphql-dataloader\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Custom prefetch methods\",\n        \"url\": \"custom-prefetch-methods\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Operation-level caching\",\n        \"url\": \"graphql-service-operation-level-caching\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Field-level caching\",\n        \"url\": \"graphql-service-field-level-caching\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Cache invalidation\",\n        \"url\": \"graphql-service-cache-invalidation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query Complexity\",\n        \"url\": \"graphql-service-query-complexity\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"GraphQL client\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Query GraphQL endpoint\",\n        \"url\": \"graphql-client-query-endpoint\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Handle partial response\",\n        \"url\": \"graphql-client-handle-partial-response\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Handle error response\",\n        \"url\": \"graphql-client-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"GraphQL service security\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"graphql-service-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"graphql-service-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication file user store\",\n        \"url\": \"graphql-service-basic-auth-file-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication LDAP user store\",\n        \"url\": \"graphql-service-basic-auth-ldap-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JWT authentication\",\n        \"url\": \"graphql-service-jwt-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2\",\n        \"url\": \"graphql-service-oauth2\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"GraphQL client security\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"graphql-client-security-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"graphql-client-security-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"graphql-client-security-basic-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Self-signed JWT authentication\",\n        \"url\": \"graphql-client-security-jwt-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 password grant type\",\n        \"url\": \"graphql-client-security-oauth2-password-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSocket service\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive message\",\n        \"url\": \"websocket-basic-sample\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload constraint validation\",\n        \"url\": \"websocket-service-payload-constraint-validation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"websocket-service-error-handling\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query parameter\",\n        \"url\": \"websocket-query-parameter\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSocket client\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive message\",\n        \"url\": \"websocket-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Payload constraint validation\",\n        \"url\": \"websocket-client-payload-constraint-validation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSocket service security\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"websocket-service-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"websocket-service-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication file user store\",\n        \"url\": \"websocket-service-basic-auth-file-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication LDAP user store\",\n        \"url\": \"websocket-service-basic-auth-ldap-user-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JWT authentication\",\n        \"url\": \"websocket-service-jwt-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2\",\n        \"url\": \"websocket-service-oauth2\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSocket client security\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"websocket-client-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"websocket-client-mutual-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"websocket-client-basic-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Bearer token authentication\",\n        \"url\": \"websocket-client-bearer-token-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Self-signed JWT authentication\",\n        \"url\": \"websocket-client-self-signed-jwt-auth\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 client credentials grant type\",\n        \"url\": \"websocket-client-oauth2-client-cred-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 password grant type\",\n        \"url\": \"websocket-client-oauth2-password-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 refresh token grant type\",\n        \"url\": \"websocket-client-oauth2-refresh-token-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 JWT bearer grant type\",\n        \"url\": \"websocket-client-oauth2-jwt-bearer-grant-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSocket client resiliency\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Timeout\",\n        \"url\": \"websocket-timeout-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Retry\",\n        \"url\": \"websocket-retry-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"WebSub service\",\n    \"column\": 1,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume github events\",\n        \"url\": \"websub-webhook-sample\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Listeners and StopHandlers\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Dynamic listener\",\n        \"url\": \"dynamic-listener\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"StopHandler\",\n        \"url\": \"stop-handler\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"gRPC service\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Simple RPC\",\n        \"url\": \"grpc-service-simple\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Server-side streaming RPC\",\n        \"url\": \"grpc-service-server-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Client-side streaming RPC\",\n        \"url\": \"grpc-service-client-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Bidirectional streaming RPC\",\n        \"url\": \"grpc-service-bidirectional-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send/Receive headers\",\n        \"url\": \"grpc-service-headers\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Server reflection\",\n        \"url\": \"grpc-server-reflection\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Check deadline\",\n        \"url\": \"grpc-service-check-deadline\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"gRPC client\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Simple RPC\",\n        \"url\": \"grpc-client-simple\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Server-side streaming RPC\",\n        \"url\": \"grpc-client-server-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Client-side streaming RPC\",\n        \"url\": \"grpc-client-client-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Bidirectional streaming RPC\",\n        \"url\": \"grpc-client-bidirectional-streaming\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send/Receive headers\",\n        \"url\": \"grpc-client-headers\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Set deadline\",\n        \"url\": \"grpc-client-set-deadline\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Has different naming convention\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"gRPC service security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"grpc-service-ssl-tls\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"grpc-service-mutual-ssl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication file user store\",\n        \"url\": \"grpc-service-basic-auth-file-user-store\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication LDAP user store\",\n        \"url\": \"grpc-service-basic-auth-ldap-user-store\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JWT authentication\",\n        \"url\": \"grpc-service-jwt-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2\",\n        \"url\": \"grpc-service-oauth2\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"gRPC client security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"grpc-client-ssl-tls\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Mutual SSL\",\n        \"url\": \"grpc-client-mutual-ssl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"grpc-client-basic-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Bearer token authentication\",\n        \"url\": \"grpc-client-bearer-token-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Self-signed JWT authentication\",\n        \"url\": \"grpc-client-self-signed-jwt-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 client credentials grant type\",\n        \"url\": \"grpc-client-oauth2-client-credentials-grant-type\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 password grant type\",\n        \"url\": \"grpc-client-oauth2-password-grant-type\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 refresh token grant type\",\n        \"url\": \"grpc-client-oauth2-refresh-token-grant-type\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"OAuth2 JWT bearer grant type\",\n        \"url\": \"grpc-client-oauth2-jwt-bearer-grant-type\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"NATS service\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"nats-basic-sub\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send reply to request message\",\n        \"url\": \"nats-basic-reply\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Constraint validations\",\n        \"url\": \"nats-service-constraint-validation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Consume JetStream message\",\n        \"url\": \"nats-jetstream-sub\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"NATS client\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Publish message\",\n        \"url\": \"nats-basic-pub\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send request message\",\n        \"url\": \"nats-basic-request\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Publish message\",\n        \"url\": \"nats-jetstream-pub\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"NATS service security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"nats-service-secure-connection\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"nats-service-basic-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"NATS client security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"nats-client-secure-connection\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"nats-client-basic-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka service\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"kafka-service-consume-message\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Constraint validation\",\n        \"url\": \"kafka-service-constraint-validation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error handling\",\n        \"url\": \"kafka-service-error-handling\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka producer\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Produce message\",\n        \"url\": \"kafka-producer-produce-message\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka consumer\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Payload data binding\",\n        \"url\": \"kafka-consumer-payload-data-binding\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Consumer record data binding\",\n        \"url\": \"kafka-consumer-consumer-record-data-binding\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Constraint validation\",\n        \"url\": \"kafka-consumer-constraint-validation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka service security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"kafka-service-ssl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"SASL authentication\",\n        \"url\": \"kafka-service-sasl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka producer security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"kafka-producer-ssl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"SASL authentication\",\n        \"url\": \"kafka-producer-sasl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kafka consumer security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"kafka-consumer-ssl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"SASL authentication\",\n        \"url\": \"kafka-consumer-sasl\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"SOAP client\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive\",\n        \"url\": \"soap-client-send-receive\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"SOAP client security\",\n    \"column\": 2,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"soap-client-security-ssl-tsl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Inbound Security\",\n        \"url\": \"soap-client-security-inbound-security-config\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Outbound Security\",\n        \"url\": \"soap-client-security-outbound-security-config\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"RabbitMQ service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"rabbitmq-consumer\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Consume message with acknowledgement\",\n        \"url\": \"rabbitmq-consumer-with-client-acknowledgement\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Transactional consumer\",\n        \"url\": \"rabbitmq-transaction-consumer\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Constraint validation\",\n        \"url\": \"rabbitmq-service-constraint-validation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"RabbitMQ client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Declare a queue\",\n        \"url\": \"rabbitmq-queue-declare\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Produce message\",\n        \"url\": \"rabbitmq-producer\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"rabbitmq-sync-consumer\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Transactional producer\",\n        \"url\": \"rabbitmq-transaction-producer\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Constraint validation\",\n        \"url\": \"rabbitmq-client-constraint-validation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"RabbitMQ service security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"rabbitmq-service-secure-connection\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"rabbitmq-service-basic-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"RabbitMQ client security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"rabbitmq-client-secure-connection\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"rabbitmq-client-basic-auth\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"MQTT service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Subscribe to messages\",\n        \"url\": \"mqtt-service-subscribe-message\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"MQTT client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Publish message\",\n        \"url\": \"mqtt-client-publish-message\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"MQTT service security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"mqtt-service-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"mqtt-service-basic-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"MQTT client security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"mqtt-client-ssl\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Basic authentication\",\n        \"url\": \"mqtt-client-basic-authentication\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires an MQTT server\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"LDAP client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Add/Remove entries\",\n        \"url\": \"ldap-add-remove-entry\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Search for an entry\",\n        \"url\": \"ldap-search-entry\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"JMS service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"jms-service-consume-message\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"JMS message producer\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Produce message\",\n        \"url\": \"jms-producer-produce-message\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Transactions\",\n        \"url\": \"jms-producer-transaction\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"JMS message consumer\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Consume message\",\n        \"url\": \"jms-consumer-consume-message\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Manual acknowledgment\",\n        \"url\": \"jms-consumer-acknowledgement\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"TCP service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive bytes\",\n        \"url\": \"tcp-listener\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"TCP client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive bytes\",\n        \"url\": \"tcp-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service not present\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"TCP service security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"tcp-service-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"TCP client security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"tcp-client-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"UDP service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive datagram\",\n        \"url\": \"udp-listener\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be stopped\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"UDP client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send/Receive datagram\",\n        \"url\": \"udp-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be reached\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send/Receive datagram with connection\",\n        \"url\": \"udp-connect-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Service cannot be reached\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Email service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Receive email\",\n        \"url\": \"receive-email-using-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Email client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Send email\",\n        \"url\": \"send-email\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Receive email\",\n        \"url\": \"receive-email-using-client\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Email service security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"email-service-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Email client security\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"SSL/TLS\",\n        \"url\": \"email-client-ssl-tls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"FTP Service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Receive file\",\n        \"url\": \"ftp-service-receive-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send file\",\n        \"url\": \"ftp-service-send-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"FTP client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Receive file\",\n        \"url\": \"ftp-client-receive-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send file\",\n        \"url\": \"ftp-client-send-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"SFTP Service\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Receive file\",\n        \"url\": \"sftp-service-receive-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send file\",\n        \"url\": \"sftp-service-send-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"SFTP client\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Receive file\",\n        \"url\": \"sftp-client-receive-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Send file\",\n        \"url\": \"sftp-client-send-file\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Database access\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Simple query\",\n        \"url\": \"mysql-query-operation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query with one result\",\n        \"url\": \"mysql-query-row-operation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Query with advanced mapping\",\n        \"url\": \"mysql-query-column-mapping\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"DML and DDL operations\",\n        \"url\": \"mysql-execute-operation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Batch execution\",\n        \"url\": \"mysql-batch-execute-operation\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Atomic transactions\",\n        \"url\": \"mysql-atomic-transaction\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Call stored procedures\",\n        \"url\": \"mysql-call-stored-procedures\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Change data capture\",\n    \"column\": 3,\n    \"category\": \"Network libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Listen to database\",\n        \"url\": \"cdc-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Group events by table\",\n        \"url\": \"cdc-advanced-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Avro\",\n    \"column\": 0,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Serialization/Deserialization\",\n        \"url\": \"avro-serdes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"IO\",\n    \"column\": 0,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Read/write bytes\",\n        \"url\": \"io-bytes\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Read/write strings\",\n        \"url\": \"io-strings\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Read/write CSV\",\n        \"url\": \"io-csv\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Read/write CSV with data mapping\",\n        \"url\": \"io-csv-datamapping\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Read/write JSON\",\n        \"url\": \"io-json\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Read/write XML\",\n        \"url\": \"io-xml\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Messaging\",\n    \"column\": 0,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Message store type\",\n        \"url\": \"message-store-type\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"In-memory message store\",\n        \"url\": \"in-memory-message-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Message Store Listener\",\n        \"url\": \"message-store-listener\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Security\",\n    \"column\": 0,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Cryptographic operations\",\n        \"url\": \"security-crypto\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JWT issue/validate\",\n        \"url\": \"security-jwt-issue-validate\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"URL\",\n    \"column\": 0,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"URL encode/decode operations\",\n        \"url\": \"url-encode-decode\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Time\",\n    \"column\": 1,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"UTC time\",\n        \"url\": \"time-utc\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Time with zone offset\",\n        \"url\": \"time-utc-and-civil\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Time formatting/parsing\",\n        \"url\": \"time-formatting-and-parsing\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Time Zone\",\n        \"url\": \"time-zone\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Cache\",\n    \"column\": 1,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Cache basics\",\n        \"url\": \"cache-basics\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Cache invalidation\",\n        \"url\": \"cache-invalidation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"disableVerificationReason\": \"Intermittently failing with github api rate limiting\",\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Log\",\n    \"column\": 1,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Logging\",\n        \"url\": \"logging\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Logging with context\",\n        \"url\": \"logging-with-context\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Error Logging\",\n        \"url\": \"error-logging\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Configure logging\",\n        \"url\": \"logging-configuration\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Log file rotation\",\n        \"url\": \"log-file-rotation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output and file creation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Child loggers with context\",\n        \"url\": \"child-loggers-with-context\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Logger from configuration\",\n        \"url\": \"logger-from-config\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Custom logger\",\n        \"url\": \"custom-logger\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Sensitive data logging\",\n        \"url\": \"sensitive-data-logging\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"EDI\",\n    \"column\": 1,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"EDI to record conversion\",\n        \"url\": \"edi-to-record\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes generated code\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Record to EDI conversion\",\n        \"url\": \"record-to-edi\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes generated code\",\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"OS\",\n    \"column\": 1,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Environment variables\",\n        \"url\": \"environment-variables\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"File\",\n    \"column\": 2,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"File paths\",\n        \"url\": \"filepaths\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Directories\",\n        \"url\": \"directories\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Files\",\n        \"url\": \"files\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Temp files and directories\",\n        \"url\": \"temp-files-directories\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Directory listener\",\n        \"url\": \"directory-listener\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Random\",\n    \"column\": 2,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Random numbers\",\n        \"url\": \"random-numbers\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Task\",\n    \"column\": 2,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Schedule job recurrence by frequency\",\n        \"url\": \"task-frequency-job-execution\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Schedule one time job\",\n        \"url\": \"task-one-time-job-execution\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Manage scheduled jobs\",\n        \"url\": \"manage-scheduled-jobs\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"UUID\",\n    \"column\": 2,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Generate UUID\",\n        \"url\": \"uuid-generation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes varying output\",\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"UUID operations\",\n        \"url\": \"uuid-operations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"XSLT\",\n    \"column\": 3,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"XSLT transformation\",\n        \"url\": \"xslt-transformation\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"XML data\",\n    \"column\": 3,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"XML to JSON conversion\",\n        \"url\": \"xml-to-json-conversion\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"JSON to XML conversion\",\n        \"url\": \"xml-from-json-conversion\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"XML to record conversion\",\n        \"url\": \"xml-to-record-conversion\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Record to XML conversion\",\n        \"url\": \"xml-from-record-conversion\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"YAML data\",\n    \"column\": 3,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"YAML to anydata\",\n        \"url\": \"yaml-to-anydata\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"YAML to anydata with projection\",\n        \"url\": \"yaml-to-anydata-with-projection\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Serialize to YAML string\",\n        \"url\": \"anydata-to-yaml-string\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"CSV data\",\n    \"column\": 3,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Convert CSV string to records\",\n        \"url\": \"csv-string-to-record-array\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Convert CSV string to arrays\",\n        \"url\": \"csv-string-to-anydata-array\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Parse CSV byte streams to records\",\n        \"url\": \"csv-streams-to-record-array\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Parse CSV lists to custom types\",\n        \"url\": \"parse-csv-lists\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Transform CSV records to custom types\",\n        \"url\": \"transform-csv-records-to-custom-types\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      },\n      {\n        \"name\": \"Handle CSV with custom configurations\",\n        \"url\": \"csv-user-configurations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"isLearnByExample\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Constraint\",\n    \"column\": 3,\n    \"category\": \"Common libraries\",\n    \"samples\": [\n      {\n        \"name\": \"Constraint validations\",\n        \"url\": \"constraint-validations\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Direct LLM calls\",\n    \"column\": 0,\n    \"category\": \"Generative AI\",\n    \"samples\": [\n      {\n        \"name\": \"Direct LLM calls\",\n        \"url\": \"direct-llm-calls\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Direct LLM calls with history\",\n        \"url\": \"direct-llm-calls-with-history\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Direct LLM calls with multimodal input\",\n        \"url\": \"direct-llm-calls-with-multimodal-input\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Retrieval-augmented generation (RAG)\",\n    \"column\": 1,\n    \"category\": \"Generative AI\",\n    \"samples\": [\n      {\n        \"name\": \"RAG with in-memory vector store\",\n        \"url\": \"rag-with-in-memory-vector-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"RAG ingestion with external vector store\",\n        \"url\": \"rag-ingestion-with-external-vector-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"RAG query with external vector store\",\n        \"url\": \"rag-query-with-external-vector-store\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Model context protocol (MCP)\",\n    \"column\": 1,\n    \"category\": \"Generative AI\",\n    \"samples\": [\n      {\n        \"name\": \"MCP service\",\n        \"url\": \"mcp-service\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"MCP advanced service\",\n        \"url\": \"mcp-service-advanced\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disablePlayground\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"AI agents\",\n    \"column\": 2,\n    \"category\": \"Generative AI\",\n    \"samples\": [\n      {\n        \"name\": \"Agent with local tools\",\n        \"url\": \"ai-agent-local-tools\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Agent with MCP integration\",\n        \"url\": \"ai-agent-mcp-integration\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Agent with external endpoint integration\",\n        \"url\": \"ai-agent-external-endpoint-integration\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Chat agents\",\n        \"url\": \"chat-agents\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      },\n      {\n        \"name\": \"Agent with tool kits\",\n        \"url\": \"ai-agent-tool-kit\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys and the output is not fixed\",\n        \"disablePlayground\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Natural expressions\",\n    \"column\": 3,\n    \"category\": \"Generative AI\",\n    \"samples\": [\n      {\n        \"name\": \"Natural expressions\",\n        \"url\": \"natural-expressions\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Requires keys\",\n        \"disablePlayground\": true\n      }\n    ]\n  },\n  {\n    \"title\": \"Docker\",\n    \"column\": 0,\n    \"category\": \"Deployment\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world\",\n        \"url\": \"docker-hello-world\",\n        \"verifyBuild\": true,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Kubernetes\",\n    \"column\": 1,\n    \"category\": \"Deployment\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world\",\n        \"url\": \"kubernetes-hello-world\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"AWS Lambda\",\n    \"column\": 2,\n    \"category\": \"Deployment\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world\",\n        \"url\": \"aws-lambda-hello-world\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Execution context\",\n        \"url\": \"aws-lambda-execution-context\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"S3 trigger\",\n        \"url\": \"aws-lambda-s3-trigger\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"DynamoDB trigger\",\n        \"url\": \"aws-lambda-dynamodb-trigger\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Azure Functions\",\n    \"column\": 3,\n    \"category\": \"Deployment\",\n    \"samples\": [\n      {\n        \"name\": \"Hello world\",\n        \"url\": \"azure-functions-hello-world\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Timer trigger\",\n        \"url\": \"azure-functions-timer-trigger\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"HTTP trigger with queue\",\n        \"url\": \"azure-functions-http-trigger-with-queue\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Cosmos DB trigger\",\n        \"url\": \"azure-functions-cosmosdb-trigger\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs prerequisite condition\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Query data\",\n    \"column\": 0,\n    \"category\": \"Bal persist\",\n    \"samples\": [\n      {\n        \"name\": \"Get all\",\n        \"url\": \"persist-get-all\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Get by key\",\n        \"url\": \"persist-get-by-key\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Select fields\",\n        \"url\": \"persist-select-fields\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Filter and sort\",\n        \"url\": \"persist-filtering\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Relation queries\",\n        \"url\": \"persist-relation-queries\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Write data\",\n    \"column\": 1,\n    \"category\": \"Bal persist\",\n    \"samples\": [\n      {\n        \"name\": \"Create/Create many\",\n        \"url\": \"persist-create\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Update\",\n        \"url\": \"persist-update\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Delete\",\n        \"url\": \"persist-delete\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Needs code generation\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Tracing\",\n    \"column\": 0,\n    \"category\": \"Observability\",\n    \"samples\": [\n      {\n        \"name\": \"Distributed tracing\",\n        \"url\": \"tracing\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  },\n  {\n    \"title\": \"Metrics\",\n    \"column\": 1,\n    \"category\": \"Observability\",\n    \"samples\": [\n      {\n        \"name\": \"Gauge-based metrics\",\n        \"url\": \"gauge-metrics\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      },\n      {\n        \"name\": \"Counter-based metrics\",\n        \"url\": \"counter-metrics\",\n        \"verifyBuild\": false,\n        \"verifyOutput\": false,\n        \"disableVerificationReason\": \"Includes ballerinax components\",\n        \"disablePlayground\": true,\n        \"isLearnByExample\": false\n      }\n    ]\n  }\n]\n"
  },
  {
    "path": "examples/inferring-isolated/inferring_isolated.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // function's default worker, worker `A` and `B` run concurrently.\n    worker A {\n        // It is safe to access the parameters of `sayHello` for the\n        // duration of the function call.\n        string a = sayHello(\"John\");\n        io:println(a);\n    }\n\n    worker B {\n        string b = sayHello(\"Anne\");\n        io:println(b);\n    }\n\n    // `sayHello` is inferred to be an `isolated` function.\n    boolean c = sayHello is isolated function (string str) returns string;\n    io:println(c);\n}\n\nfunction sayHello(string name) returns string {\n    return \"Hello \" + name;\n}\n"
  },
  {
    "path": "examples/inferring-isolated/inferring_isolated.md",
    "content": "# Inferring isolated \n\n`isolated` is a complex feature, which would be a lot for an application developer to understand. A typical Ballerina application consists of a single module that imports multiple library modules. Within a single module, the compiler infers `isolated` qualifiers. An object without mutable fields is inherently `isolated`. It is the application developer's responsibility to use `lock` statements where needed. E.g.,\n\n- accessing `self` in a `service` object with mutable state\n- accessing mutable module-level variables\n\nCompiler can inform developer where missing locks are preventing a `service` object or method from being `isolated`.\n\n::: code inferring_isolated.bal :::\n\nExecuting the above code gives the output below.\n\n::: out inferring_isolated.out :::"
  },
  {
    "path": "examples/inferring-isolated/inferring_isolated.metatags",
    "content": "description: This BBE introduces isolated inference in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, inferring isolated\n"
  },
  {
    "path": "examples/inferring-isolated/inferring_isolated.out",
    "content": "$ bal run inferring_isolated.bal\ntrue\nHello Anne\nHello John\n"
  },
  {
    "path": "examples/init-function/init_function.bal",
    "content": "import ballerina/io;\n\n// Uninitialized integer variable `value`.\nint value;\n\n// Uninitialized final string variable `name`.\nfinal string name;\n\nfunction init() returns error? {\n    // Initialize the `value` variable to 5.\n    value = 5;\n    // Initialize the final variable greeting to `James`.\n    name = \"James\";\n    \n    if value > 3 {\n        // The initialization will fail with this error message.\n        return error(\"Value should less than 3\");\n    }\n}\n\npublic function main() {\n    // This will not be executed because the init function returns an error.\n    io:println(name);\n}\n"
  },
  {
    "path": "examples/init-function/init_function.md",
    "content": "# Init function\n\nThe `init` function will be executed as the last function called in the program initialization phase. Uninitialized module-level `final` or `non-final` variables can be initialized in this function.\n\nThe `init` function must not be declared as public. Its return type must be a subtype of `error?` or `()`. It must have no parameters.\n\n::: code init_function.bal :::\n\n::: out init_function.out :::\n\n## Related links\n- [Functions](/learn/by-example/functions/)\n"
  },
  {
    "path": "examples/init-function/init_function.metatags",
    "content": "description: This BBE demonstrates returning error from an init function and constructing custom errors in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, init function, error\n"
  },
  {
    "path": "examples/init-function/init_function.out",
    "content": "$ bal run init_function.bal\nerror: Value should less than 3\n"
  },
  {
    "path": "examples/init-return-type/init_return_type.bal",
    "content": "import ballerina/io;\n\n// Defines a `class` called `File`.\nclass File {\n\n    string path;\n    string contents;\n    // The `init()` method is used to initialize the `object` when creating a new `object`.\n    function init(string p, string? c) returns error? {\n        self.path = p;\n        self.contents = check c.ensureType(string);\n        return;\n    }\n\n}\n\npublic function main() returns error? {\n    // `new` returns the newly-constructed `File` object.\n    File f = check new File(\"test.txt\", \"Hello World\");\n\n    io:println(f.contents);\n    return;\n}\n"
  },
  {
    "path": "examples/init-return-type/init_return_type.md",
    "content": "# Init return type\n\n`init` function has a return type, which must be a subtype of `error?`. If `init` returns `()`, then, `new` returns the newly constructed `object`. If `init` returns an `error`, then `new` returns that `error`. If `init` does not specify a return type, then the return type defaults to `()` as usual, meaning that `new` will never return an `error`.\n\n::: code init_return_type.bal :::\n\n::: out init_return_type.out :::"
  },
  {
    "path": "examples/init-return-type/init_return_type.metatags",
    "content": "description: This BBE demonstrates init function in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, init, return type\n"
  },
  {
    "path": "examples/init-return-type/init_return_type.out",
    "content": "$ bal run init_return_type.bal\nHello World\n"
  },
  {
    "path": "examples/int-range/int_range.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int[] loop1 = [];\n    // Using `int:range(0, 5, 2)` in the `foreach` statement results in the iteration over a range of integers\n    // from 0 to 5 (excluding) with a step of 2 between each integer (i.e., 0, 2, 4).\n    foreach int i in int:range(0, 5, 2) {\n        loop1.push(i);\n    }\n\n    io:println(loop1);\n\n    int[] loop2 = [];\n    // A negative step also can be used to get a descending set of integers (i.e., 5, 3, 1).\n    foreach int i in int:range(5, 0, -2) {\n        loop2.push(i);\n    }\n\n    io:println(loop2);\n}\n"
  },
  {
    "path": "examples/int-range/int_range.md",
    "content": "# int:range function\n\nThe `int:range` lang library function returns an iterable object, which iterates over a range of integers.\nThis is particularly useful when creating a loop with a decrementing looping variable or increment/decrement with a step.\n\n::: code int_range.bal :::\n\n::: out int_range.out :::\n\n## Related links\n- [Langlib functions](/learn/by-example/langlib-functions)\n- [Foreach statement](/learn/by-example/foreach-statement)\n"
  },
  {
    "path": "examples/int-range/int_range.metatags",
    "content": "description: This BBE demonstrates the `int:range` langlib function in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, foreach, loops, int:range, range\n"
  },
  {
    "path": "examples/int-range/int_range.out",
    "content": "$ bal run int_range.bal\n[0,2,4]\n[5,3,1]\n"
  },
  {
    "path": "examples/integers/integers.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int m = 1;\n\n    // Integer literals can be hexadecimal (but not octal).\n    int n = 0xFFFF;\n\n    // You can use compound assignment operations such as `+=` and `-=`. \n    n += m;\n\n    io:println(n);\n}\n"
  },
  {
    "path": "examples/integers/integers.md",
    "content": "# Integers\n\nThe `int` type is 64-bit signed integers and supports the usual arithmetic operators: `+ - / %`. Integer overflow is a runtime error in Ballerina.\n\n::: code integers.bal :::\n\n::: out integers.out :::"
  },
  {
    "path": "examples/integers/integers.metatags",
    "content": "description: This BBE introduces Ballerina int type.\nkeywords:  ballerina, ballerina by example, bbe, integers, int, int type\n"
  },
  {
    "path": "examples/integers/integers.out",
    "content": "$ bal run integers.bal\n65536\n"
  },
  {
    "path": "examples/inter-worker-failure-propagation/inter_worker_failure_propagation.bal",
    "content": "import ballerina/io;\n\nint counter = 0;\n\nfunction demo() returns int|error {\n    worker A returns error? {\n        // Workers may need to call functions that can return an `error`. \n        // Pairing up of sends and receives guarantees that each send will be received and vice-versa\n        // provided that the worker has failed on both sending and receiving.\n        error? res = foo();\n        if res is error {\n            return res;\n        }\n        42 -> function;\n    }\n\n    // Send to or receive from failed worker will propagate the failure.\n    int x = check <- A;\n\n    return x;\n}\n\nfunction foo() returns error? {\n    if counter == 1 {\n        return error(\"maximum count exceeded\");\n    }\n\n    counter += 1;\n}\n\npublic function main() returns error? {\n    int a = check demo();\n    io:println(a);\n\n    int b = check demo();\n    io:println(b);\n}\n"
  },
  {
    "path": "examples/inter-worker-failure-propagation/inter_worker_failure_propagation.md",
    "content": "# Inter-worker failure propagation\n\nWorkers may need to call functions that can return an `error`. Pairing up of sends and receives guarantees that each send will be received, and vice-versa, provided neither sending nor receiving worker  has failed. Send to or receive from failed worker will propagate the failure.\n\n::: code inter_worker_failure_propagation.bal :::\n\n::: out inter_worker_failure_propagation.out :::"
  },
  {
    "path": "examples/inter-worker-failure-propagation/inter_worker_failure_propagation.metatags",
    "content": "description: This BBE demonstrates inter-worker failure propagation\nkeywords: ballerina, ballerina by example, bbe, worker, failure\n"
  },
  {
    "path": "examples/inter-worker-failure-propagation/inter_worker_failure_propagation.out",
    "content": "$ bal run inter_worker_failure_propagation.bal\n42\nerror: maximum count exceeded\n"
  },
  {
    "path": "examples/inter-worker-message-passing/inter_worker_message_passing.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n\n    worker A {\n        // Use `-> W` to send a message to worker `W`.\n        1 -> B;\n        2 -> C;\n    }\n\n    worker B {\n        // Use `<- W` to receive a message from worker `W`.\n        int x1 = <- A;\n\n        // Use `function` to refer to the function's default worker.\n        x1 -> function;\n    }\n\n    worker C {\n        int x2 = <- A;\n        x2 -> function;\n    }\n\n    int y1 = <- B;\n    int y2 = <- C;\n\n    io:println(y1 + y2);\n}\n"
  },
  {
    "path": "examples/inter-worker-message-passing/inter_worker_message_passing.md",
    "content": "# Inter-worker message passing\n\nUse `-> W` or `<- W` to send a message to or receive a message from worker `W` (use `function` to refer to the function's default worker). The messages are copied using `clone()`. It implies immutable values are passed without a copy.\n\nMessage sends and receives are paired up at compile-time. Each pair turns into a horizontal line in the sequence diagram. Easy to use and safe, but limited expressiveness.\n\n::: code inter_worker_message_passing.bal :::\n\n::: out inter_worker_message_passing.out :::"
  },
  {
    "path": "examples/inter-worker-message-passing/inter_worker_message_passing.metatags",
    "content": "description: This BBE demonstrates inter-worker message passing\nkeywords: ballerina, ballerina by example, bbe, worker, message passing\n"
  },
  {
    "path": "examples/inter-worker-message-passing/inter_worker_message_passing.out",
    "content": "$ bal run inter_worker_message_passing.bal\n3\n"
  },
  {
    "path": "examples/interface-to-external-code/interface_to_external_code.bal",
    "content": "import ballerina/jballerina.java;\n\n// Returns the `out` field in the `java.lang.System` class.\n// `java.lang.System#out` is of the `java.io.PrintStream` type.\npublic function getStdOut() returns handle = @java:FieldGet {\n    name: \"out\",\n    'class: \"java/lang/System\"\n} external;\n\n// Invoke the `println` method on `java.lang.System#out`, \n// which accepts a `java.lang.String` parameter.\npublic function printInternal(handle receiver, handle strValue) = @java:Method {\n    name: \"println\",\n    'class: \"java/io/PrintStream\",\n    paramTypes: [\"java.lang.String\"]\n} external;\n\npublic function main() {\n    handle stdOut = getStdOut();\n    handle str = java:fromString(\"Hello World\");\n    printInternal(stdOut, str);\n}\n"
  },
  {
    "path": "examples/interface-to-external-code/interface_to_external_code.md",
    "content": "# Interface to external code\n\nBallerina supports interfacing to external code. This can be done by using the `external` keyword, instead of implementing the function body. The implementation figures out how to map to the external implementation. As part of interfacing to an external implementation, Ballerina supports another basic type called `handle`. The `handle` type is basically an opaque handle that can be passed to and from external functions. There is no typing for `handle` and it can be added as a private member of a Ballerina class for better type safety.\n\n::: code interface_to_external_code.bal :::\n\n::: out interface_to_external_code.out :::\n"
  },
  {
    "path": "examples/interface-to-external-code/interface_to_external_code.metatags",
    "content": "description: This BBE demonstrates how to interface to external code in Ballerina.\nkeywords: ballerina, ballerina by example, handle, external, interface to external code, java interoperability\n"
  },
  {
    "path": "examples/interface-to-external-code/interface_to_external_code.out",
    "content": "$ bal run interface_to_external_code.bal\nHello World\n"
  },
  {
    "path": "examples/io-bytes/io_bytes.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Initializes the image paths.\n    string imagePath = \"./files/ballerina.jpg\";\n    string imageCopyPath1 = \"./files/ballerinaCopy1.jpg\";\n    string imageCopyPath2 = \"./files/ballerinaCopy2.jpg\";\n\n    // Reads the file content as a byte array using the given file path.\n    byte[] bytes = check io:fileReadBytes(imagePath);\n    // Writes the already-read content to the given destination file.\n    check io:fileWriteBytes(imageCopyPath1, bytes);\n    io:println(\"Successfully copied the image as a byte array.\");\n\n    // Reads the file as a stream of blocks. The default block size is 4KB.\n    // Here, the default size is overridden by the value 2KB.\n    stream<io:Block, io:Error?> blockStream = check\n    io:fileReadBlocksAsStream(imagePath, 2048);\n    // If the file reading was successful, then,\n    // the content will be written to the given destination file using the given stream.\n    check io:fileWriteBlocksFromStream(imageCopyPath2, blockStream);\n    io:println(\"Successfully copied the image as a stream.\");\n}\n"
  },
  {
    "path": "examples/io-bytes/io_bytes.md",
    "content": "# Read/write bytes\n\nThe Ballerina `io` library contains APIs to read/write bytes from/to a file.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_bytes.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_bytes.out :::\n\n## Related links\n- [Binary data](/learn/by-example/binary-data/)"
  },
  {
    "path": "examples/io-bytes/io_bytes.metatags",
    "content": "description: BBE on how to read/write from/to a bytes file.\nkeywords: ballerina, ballerina by examples, bbe, bytes\n"
  },
  {
    "path": "examples/io-bytes/io_bytes.out",
    "content": "# In the directory, which contains the `.bal` file, create a directory named `files`,\n# and add an image file named `ballerina.jpg` in it as follows.\n# tree .\n# ├── files\n# │   └── ballerina.jpeg\n# └── io_bytes.bal\n$ bal run io_bytes.bal\nSuccessfully copied the image as a byte array.\nSuccessfully copied the image as a stream.\n"
  },
  {
    "path": "examples/io-csv/io_csv.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Initializes the CSV file paths and content.\n    string csvFilePath1 = \"./files/csvFile1.csv\";\n    string csvFilePath2 = \"./files/csvFile2.csv\";\n    string[][] csvContent = [[\"1\", \"James\", \"10000\"], [\"2\", \"Nathan\", \"150000\"],\n    [\"3\", \"Ronald\", \"120000\"], [\"4\", \"Roy\", \"6000\"],\n    [\"5\", \"Oliver\", \"1100000\"]];\n\n    // Writes the given content `string[][]` to a CSV file in csvFilePath1.\n    check io:fileWriteCsv(csvFilePath1, csvContent);\n    // Reads the previously-saved CSV file as a `string[][]`.\n    string[][] readCsv = check io:fileReadCsv(csvFilePath1);\n    io:println(readCsv);\n\n    // Writes the given content as a stream to a CSV file.\n    check io:fileWriteCsvFromStream(csvFilePath2, csvContent.toStream());\n    // Reads the previously-saved CSV file as a stream.\n    stream<string[], io:Error?> csvStream = check\n                                        io:fileReadCsvAsStream(csvFilePath2);\n    // Iterates through the stream and prints the content.\n    check csvStream.forEach(function(string[] val) {\n                              io:println(val);\n                          });\n}"
  },
  {
    "path": "examples/io-csv/io_csv.md",
    "content": "# Read/write CSV\n\nThe Ballerina `io` library contains APIs to read/write CSV content from/to a file.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_csv.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_csv.out :::"
  },
  {
    "path": "examples/io-csv/io_csv.metatags",
    "content": "description: BBE on how to read/write from/to a CSV file.\nkeywords: ballerina, ballerina by examples, bbe, csv, table\n"
  },
  {
    "path": "examples/io-csv/io_csv.out",
    "content": "$ bal run io_csv.bal\n[[\"1\",\"James\",\"10000\"],[\"2\",\"Nathan\",\"150000\"],[\"3\",\"Ronald\",\"120000\"],[\"4\",\"Roy\",\"6000\"],[\"5\",\"Oliver\",\"1100000\"]]\n[\"1\",\"James\",\"10000\"]\n[\"2\",\"Nathan\",\"150000\"]\n[\"3\",\"Ronald\",\"120000\"]\n[\"4\",\"Roy\",\"6000\"]\n[\"5\",\"Oliver\",\"1100000\"]\n"
  },
  {
    "path": "examples/io-csv-datamapping/io_csv_datamapping.bal",
    "content": "import ballerina/io;\n\n\n// Defines the record to bind the data.\ntype Employee record{\n    int id;\n    string name;\n    int salary;\n};\n\npublic function main() returns error? {\n    // Initializes the CSV file path and content.\n    string csvFilePath1 = \"./files/csvFile1.csv\";\n    string csvFilePath2 = \"./files/csvFile2.csv\";\n    Employee[] csvContent = [\n        {id: 1, name: \"James\", salary: 10000},\n        {id: 2, name: \"Nathan\", salary: 150000},\n        {id: 3, name: \"Ronald\", salary: 120000},\n        {id: 4, name: \"Roy\", salary: 6000},\n        {id: 5, name: \"Oliver\", salary: 1100000}\n    ];\n\n    // Writes the given content `record[]` to a CSV file.\n    check io:fileWriteCsv(csvFilePath1, csvContent);\n    // Reads the previously-saved CSV file as a `record[]`.\n    Employee[] readCsv = check io:fileReadCsv(csvFilePath1);\n    io:println(readCsv);\n\n    // Writes the given content as a stream to a CSV file.\n    check io:fileWriteCsvFromStream(csvFilePath2, readCsv.toStream());\n    // Reads the previously-saved CSV file as a record stream.\n    stream<Employee, io:Error?> csvStream = check\n                                        io:fileReadCsvAsStream(csvFilePath2);\n    // Iterates through the stream and prints the records.\n    check csvStream.forEach(function(Employee val) {\n                              io:println(val);\n                          });\n}\n"
  },
  {
    "path": "examples/io-csv-datamapping/io_csv_datamapping.md",
    "content": "# Read/write CSV with data mapping\n\nThe Ballerina `io` library contains APIs to read/write CSV content from/to a file and these APIs can be used to bind the CSV data with user-specified records.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_csv_datamapping.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_csv_datamapping.out :::\n"
  },
  {
    "path": "examples/io-csv-datamapping/io_csv_datamapping.metatags",
    "content": "description: BBE on how to read/write from/to a CSV file with data binding.\nkeywords: ballerina, ballerina by examples, bbe, csv, table, data binding\n"
  },
  {
    "path": "examples/io-csv-datamapping/io_csv_datamapping.out",
    "content": "$ bal run io_csv_datamapping.bal\n[{\"id\":1,\"name\":\"James\",\"salary\":10000},{\"id\":2,\"name\":\"Nathan\",\"salary\":150000},{\"id\":3,\"name\":\"Ronald\",\"salary\":120000},{\"id\":4,\"name\":\"Roy\",\"salary\":6000},{\"id\":5,\"name\":\"Oliver\",\"salary\":1100000}]\n{\"id\":1,\"name\":\"James\",\"salary\":10000}\n{\"id\":2,\"name\":\"Nathan\",\"salary\":150000}\n{\"id\":3,\"name\":\"Ronald\",\"salary\":120000}\n{\"id\":4,\"name\":\"Roy\",\"salary\":6000}\n{\"id\":5,\"name\":\"Oliver\",\"salary\":1100000}\n"
  },
  {
    "path": "examples/io-json/io_json.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Initializes the JSON file path and content.\n    string jsonFilePath = \"./files/jsonFile.json\";\n    json jsonContent = {\"Store\": {\n            \"@id\": \"AST\",\n            \"name\": \"Anne\",\n            \"address\": {\n                \"street\": \"Main\",\n                \"city\": \"94\"\n            },\n            \"codes\": [\"4\", \"8\"]\n        }};\n\n    // Writes the given JSON to a file.\n    check io:fileWriteJson(jsonFilePath, jsonContent);\n    // If the write operation was successful, then,\n    // performs a read operation to read the JSON content.\n    json readJson = check io:fileReadJson(jsonFilePath);\n    io:println(readJson);\n}\n"
  },
  {
    "path": "examples/io-json/io_json.md",
    "content": "# Read/write JSON\n\nThe Ballerina `io` library contains APIs to read/write JSON objects from/to a file.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_json.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_json.out :::"
  },
  {
    "path": "examples/io-json/io_json.metatags",
    "content": "description: BBE on how to read/write from/to a JSON file.\nkeywords: ballerina, ballerina by examples, bbe, json\n"
  },
  {
    "path": "examples/io-json/io_json.out",
    "content": "$ bal run io_json.bal\n{\"Store\":{\"@id\":\"AST\",\"name\":\"Anne\",\"address\":{\"street\":\"Main\",\"city\":\"94\"},\"codes\":[\"4\",\"8\"]}}\n"
  },
  {
    "path": "examples/io-strings/io_strings.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Initializes the text path and the content.\n    string textFilePath1 = \"./files/textfile1.txt\";\n    string textFilePath2 = \"./files/textfile2.txt\";\n    string textFilePath3 = \"./files/textfile3.txt\";\n    string textContent = \"Ballerina is an open source programming language.\";\n    string[] lines = [\"The Big Bang Theory\", \"F.R.I.E.N.D.S\",\n    \"Game of Thrones\", \"LOST\"];\n\n    // Writes the given string to a file.\n    check io:fileWriteString(textFilePath1, textContent);\n    // If the write operation was successful, then, reads the content as a string.\n    string readContent = check io:fileReadString(textFilePath1);\n    io:println(readContent);\n\n    // Writes the given array of lines to a file.\n    check io:fileWriteLines(textFilePath2, lines);\n    // If the write operation was successful, then,\n    // performs a read operation to read the lines as an array.\n    string[] readLines = check io:fileReadLines(textFilePath2);\n    io:println(readLines);\n\n    // Writes the given stream of lines to a file.\n    check io:fileWriteLinesFromStream(textFilePath3, lines.toStream());\n    // If the write operation was successful, then,\n    // performs a read operation to read the lines as a stream.\n    stream<string, io:Error?> lineStream = check\n                                    io:fileReadLinesAsStream(textFilePath3);\n    // Iterates through the stream and prints the content.\n    check lineStream.forEach(function(string val) {\n                               io:println(val);\n                           });\n}\n"
  },
  {
    "path": "examples/io-strings/io_strings.md",
    "content": "# Read/write strings\n\nThe Ballerina `io` library contains APIs to read/write text content from/to a file.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_strings.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_strings.out :::"
  },
  {
    "path": "examples/io-strings/io_strings.metatags",
    "content": "description: BBE on how to read/write from/to a text file.\nkeywords: ballerina, ballerina by examples, bbe, text, strings\n"
  },
  {
    "path": "examples/io-strings/io_strings.out",
    "content": "$ bal run io_strings.bal\nBallerina is an open source programming language.\n[\"The Big Bang Theory\",\"F.R.I.E.N.D.S\",\"Game of Thrones\",\"LOST\"]\nThe Big Bang Theory\nF.R.I.E.N.D.S\nGame of Thrones\nLOST\n"
  },
  {
    "path": "examples/io-xml/io_xml.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Initializes the XML file path and content.\n    string xmlFilePath = \"./files/xmlFile.xml\";\n    xml xmlContent = xml `<book>The Lost World</book>`;\n\n    // Writes the given XML to a file.\n    check io:fileWriteXml(xmlFilePath, xmlContent);\n    // If the write operation was successful, then,\n    // performs a read operation to read the XML content.\n    xml readXml = check io:fileReadXml(xmlFilePath);\n    io:println(readXml);\n}\n"
  },
  {
    "path": "examples/io-xml/io_xml.md",
    "content": "# Read/write XML\n\nThe Ballerina `io` library contains APIs to read/write XML content from/to a file.\n\nFor more information on the underlying module, see the [`io` module](https://lib.ballerina.io/ballerina/io/latest/).\n\n::: code io_xml.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out io_xml.out :::"
  },
  {
    "path": "examples/io-xml/io_xml.metatags",
    "content": "description: BBE on how to read/write from/to an XML file.\nkeywords: ballerina, ballerina by examples, bbe, xml\n"
  },
  {
    "path": "examples/io-xml/io_xml.out",
    "content": "$ bal run io_xml.bal\n<book>The Lost World</book>\n"
  },
  {
    "path": "examples/isolated-functions/isolated_functions.bal",
    "content": "import ballerina/io;\n\ntype R record {\n    int v;\n};\n\nfinal int N = getN();\n\nfunction getN() returns int {\n    return 100;\n}\n\n// Can access mutable state that is passed as a parameter.\nisolated function set(R r) returns R {\n    // Can access non-`isolated` module-level state only if the variable\n    // is `final` and the type is a subtype of `readonly` or\n    // `isolated object {}`.\n    r.v = N;\n    return r;\n}\n\nR r = {v: 0};\n\n// This is not an `isolated` function.\nfunction setGlobal(int n) {\n    r.v = n;\n}\n\npublic function main() {\n    setGlobal(200);\n    io:println(r);\n    io:println(set(r));\n}\n"
  },
  {
    "path": "examples/isolated-functions/isolated_functions.md",
    "content": "# Isolated functions\n\nA call to an `isolated` function is concurrency-safe if it is called with arguments that are safe at least until the call returns. \n\nA function defined as `isolated`:\n\n- has access to mutable state only through its parameters\n- has unrestricted access to immutable state\n- can only call functions that are `isolated`\n\nConstraints are enforced at compile-time. `isolated` is a part of the function type. Weaker concept than pure function.\n\n::: code isolated_functions.bal :::\n\nBy executing the above code, it can be seen that the value of `v` is changed to 100 by calling `set` function.\n\n::: out isolated_functions.out :::"
  },
  {
    "path": "examples/isolated-functions/isolated_functions.metatags",
    "content": "description: This BBE introduces isolated functions in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, isolated functions, concurrency safety\n"
  },
  {
    "path": "examples/isolated-functions/isolated_functions.out",
    "content": "$ bal run isolated_functions.bal\n{\"v\":200}\n{\"v\":100}\n"
  },
  {
    "path": "examples/isolated-methods/isolated_methods.bal",
    "content": "import ballerina/io;\n\nclass EvenNumber {\n    int i = 1;\n\n    // `isolated` method.\n    isolated function generate() returns int {\n        lock {\n            // Uses `self` to access mutable field `i`\n            // within a `lock` statement.\n            return self.i * 2;\n        }\n    }\n}\n\npublic function main() {\n    EvenNumber e = new;\n    int c = e.generate();\n    io:println(c);\n}\n"
  },
  {
    "path": "examples/isolated-methods/isolated_methods.md",
    "content": "# Isolated methods\n\nObject methods can be `isolated`. An `isolated` method is same as an `isolated` function with `self` treated as a parameter. An `isolated` method call is concurrency-safe if both the object is safe and the arguments are safe. This is not quite enough for service concurrency. When a `listener` makes calls to a `remote` or `resource` method,\n\n- it can ensure the safety of arguments it passes\n- it has no way to ensure the safety of the object itself (since the object may have fields)\n\n::: code isolated_methods.bal :::\n\nExecuting the above code gives the output below.\n\n::: out isolated_methods.out :::"
  },
  {
    "path": "examples/isolated-methods/isolated_methods.metatags",
    "content": "description: This BBE introduces isolated methods in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, isolated methods\n"
  },
  {
    "path": "examples/isolated-methods/isolated_methods.out",
    "content": "$ bal run isolated_methods.bal\n2\n"
  },
  {
    "path": "examples/isolated-objects/isolated_objects.bal",
    "content": "import ballerina/io;\n\n// An `isolated` object’s mutable state is `isolated` from the\n// rest of the program.\nisolated class Counter {\n    // `n` is a mutable field.\n    private int n = 0;\n\n    isolated function get() returns int {\n        lock {\n            // `n` can only be accessed using `self`.\n            return self.n;\n        }\n    }\n\n    isolated function inc() {\n        lock {\n            self.n += 1;\n        }\n    }\n}\n\npublic function main() {\n    // The object’s mutable state is accessible only via the\n    // object itself making it an “isolated root”.\n    Counter c = new;\n    c.inc();\n    int v = c.get();\n    io:println(v);\n}\n"
  },
  {
    "path": "examples/isolated-objects/isolated_objects.md",
    "content": "# Isolated objects\n\nAn object defined as `isolated` is similar to a module with `isolated` module-level variables. Mutable fields of an `isolated` object,\n\n- must be `private` and so can only be accessed using `self`\n- must be initialized with an `isolated` expression\n- must only be accessed within a `lock` statement\n- `lock` statement must follow the same rules for `self` as for an `isolated` variable\n- a field is mutable unless it is `final` and has a type that is a subtype of `readonly`\n\nIsolated root concept treats `isolated` objects as opaque. Isolated functions can access a `final` variable whose type is an `isolated` object.\n\n::: code isolated_objects.bal :::\n\nExecuting the above code gives the output below.\n\n::: out isolated_objects.out :::"
  },
  {
    "path": "examples/isolated-objects/isolated_objects.metatags",
    "content": "description: This BBE introduces isolated objects in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, isolated objects\n"
  },
  {
    "path": "examples/isolated-objects/isolated_objects.out",
    "content": "$ bal run isolated_objects.bal\n1\n"
  },
  {
    "path": "examples/isolated-variables/isolated_variables.bal",
    "content": "import ballerina/io;\n\n// Initializes an `isolated` variable using\n// an `isolated` expression.\nisolated int[] stack = [];\n\nisolated function push(int n) {\n    // Accesses `isolated` variable within a\n    // `lock` statement.\n    lock {\n        stack.push(n);\n    }\n}\n\nisolated function pop() returns int {\n    lock {\n        return stack.pop();\n    }\n}\n\npublic function main() {\n    push(10);\n    push(20);\n    io:println(pop());\n}\n"
  },
  {
    "path": "examples/isolated-variables/isolated_variables.md",
    "content": "# Isolated variables\n\nWhen a variable is declared as `isolated`, the compiler guarantees that it is an `isolated` root and accessed only within a `lock` statement. An isolated variable declaration must be a non-public module-level variable declaration initialized with an `isolated` expression. A `lock` statement that accesses an `isolated` variable must maintain `isolated` root invariant:\n\n- access only one `isolated` variable\n- call only `isolated` functions\n- transfers of values in and out must use `isolated` expressions\n\nThe `isolated` functions are allowed to access `isolated` module-level variables, provided they follow the above rules.\n\n::: code isolated_variables.bal :::\n\nExecuting the above code gives the output below.\n\n::: out isolated_variables.out :::"
  },
  {
    "path": "examples/isolated-variables/isolated_variables.metatags",
    "content": "description: This BBE introduces isolated variables in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, isolated variables\n"
  },
  {
    "path": "examples/isolated-variables/isolated_variables.out",
    "content": "$ bal run isolated_variables.bal\n20\n"
  },
  {
    "path": "examples/iterating-over-xml-with-query/iterating_over_xml_with_query.bal",
    "content": "import ballerina/io;\n\ntype Book record {|\n    string id;\n    string name;\n|};\n\npublic function main() {\n    xml categories = xml `<categories>\n                       <category>\n                           <id>1</id>\n                           <name>cooking</name>\n                       </category>\n                       <category>\n                           <id>2</id>\n                           <name>children</name>\n                       </category>\n                       <category>\n                           <id>3</id>\n                           <name>fantasy</name>\n                       </category>\n                   </categories>`;\n\n    // Iterates through the `categories` XML sequence, constructs the `Book` records,\n    // and collects them into a table.\n    table<Book> books = from var category in categories/<category>\n                        select {\n                            id: (category/<id>).toString(),\n                            name: (category/<name>).toString()\n                        };\n\n    io:println(books);\n}\n"
  },
  {
    "path": "examples/iterating-over-xml-with-query/iterating_over_xml_with_query.md",
    "content": "# Iterate over XML with query\n\nAn `XML` value can be iterated by using a query expression. A query expression will iterate over each sequence item.\n\n::: code iterating_over_xml_with_query.bal :::\n\n::: out iterating_over_xml_with_query.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/iterating-over-xml-with-query/iterating_over_xml_with_query.metatags",
    "content": "description: This BBE demonstrates iterating XML values, creating a table from XML, and filtering XML values.\nkeywords: ballerina, ballerina by example, bbe, xml, filter, iterate, query\n"
  },
  {
    "path": "examples/iterating-over-xml-with-query/iterating_over_xml_with_query.out",
    "content": "$ bal run iterating_over_xml_with_query.bal\n[{\"id\":\"<id>1</id>\",\"name\":\"<name>cooking</name>\"},{\"id\":\"<id>2</id>\",\"name\":\"<name>children</name>\"},{\"id\":\"<id>3</id>\",\"name\":\"<name>fantasy</name>\"}]\n"
  },
  {
    "path": "examples/iterative-use-of-typed-binding/iterative_use_of_typed_binding.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    int id;\n    string fname;\n    string lname;\n|};\n\npublic function main() {\n    int sum = 0;\n    string names = \"\";\n    [string, int][] personInfoList = getPersonInfo();\n    Person[] personList = getPersonList();\n\n    // The values in the `personInfoList` is bound to the `[name, age]` list binding for each iteration.\n    foreach [string, int] [name, age] in personInfoList {\n        names += \" \" + name;\n        sum += age;\n    }\n    io:println(\"Average age of\", names, \": \", sum / 3);\n\n    // The mapping binding pattern used in the `from` clause binds the record fields with the\n    // specified variable names for every value in the `personList`.\n    var personInfo = from var {id: personId, fname: firstName, lname: lastName} in personList\n        select {\n            id: personId,\n            name: firstName + \" \" + lastName\n        };\n    io:println(personInfo);\n}\n\nfunction getPersonInfo() returns [string, int][] {\n    return [[\"John\", 30], [\"Anne\", 24], [\"Mike\", 21]];\n}\n\nfunction getPersonList() returns Person[] {\n    return [{id: 1001, fname: \"Anne\", lname: \"Frank\"}, {id: 1002, fname: \"John\", lname: \"Hardy\"}];\n}\n"
  },
  {
    "path": "examples/iterative-use-of-typed-binding/iterative_use_of_typed_binding.md",
    "content": "# Iterative use of typed binding patterns\n\nThe iterative use is always followed by the `in` keyword. In this approach, an iterator gets created as a result of evaluating an expression, and the typed binding pattern is matched against each value returned by the iterator. The `in` keyword can be used with the `foreach` statement, `from` clause, and `join` clause in query expressions, and with the `let` expression.\n\n::: code iterative_use_of_typed_binding.bal :::\n\n::: out iterative_use_of_typed_binding.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Single use of typed binding patterns](/learn/by-example/single-use-of-typed-binding/)\n- [Query expressions](/learn/by-example/query-expressions/)\n- [Foreach statement](/learn/by-example/foreach-statement/)\n"
  },
  {
    "path": "examples/iterative-use-of-typed-binding/iterative_use_of_typed_binding.metatags",
    "content": "description: This BBE demonstrates the iterative use of typed binding patterns, iterative use of the list binding, iterative use of mapping binding, iterative use of error binding, typed binding followed by `in`, list binding followed by `in`, mapping binding followed by `in`, error binding followed by `in`, binding pattern in the `from` clause, binding pattern in `join` clause, binding pattern in `let`, and binding pattern in `foreach`.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, typed binding, iterative, list binding, mapping binding, error binding, from, join, let, foreach\n"
  },
  {
    "path": "examples/iterative-use-of-typed-binding/iterative_use_of_typed_binding.out",
    "content": "$ bal run iterative_use_of_typed_binding.bal\nAverage age of John Anne Mike: 25\n[{\"id\":1001,\"name\":\"Anne Frank\"},{\"id\":1002,\"name\":\"John Hardy\"}]\n"
  },
  {
    "path": "examples/jdbc-atomic-transaction/jdbc_atomic_transaction.out",
    "content": "# Create a Ballerina project.\n# Copy the example to the project and add the relevant database driver JAR details to the `Ballerina.toml` file.\n# Execute the command below to build and run the project.\n$ bal run\n\ntime = 2022-06-22T13:55:32.037+05:30 level = ERROR module = \"\" message = \"Error while executing SQL query: INSERT INTO Customers (firstName, lastName, registrationID, creditLimit, country)\\n                                        VALUES (\\'Peter\\', \\'Stuart\\', 4, 5000.75, \\'USA\\'). Unique index or primary key violation: \\\"PUBLIC.CONSTRAINT_INDEX_6 ON PUBLIC.CUSTOMERS(REGISTRATIONID NULLS FIRST) VALUES ( /* 2 */ 4 )\\\"; SQL statement:\\nINSERT INTO Customers (firstName, lastName, registrationID, creditLimit, country)\\n                                        VALUES (\\'Peter\\', \\'Stuart\\', 4, 5000.75, \\'USA\\') [23505-206].\"\ntime = 2022-06-22T13:55:32.038+05:30 level = INFO module = \"\" message = \"One of the queries failed. Rollback transaction.\"\n"
  },
  {
    "path": "examples/jms-consumer-acknowledgement/jms_consumer_acknowledgement.bal",
    "content": "import ballerina/io;\nimport ballerinax/java.jms;\nimport ballerinax/activemq.driver as _;\n\npublic function main() returns error? {\n    jms:Connection connection = check new (\n        initialContextFactory = \"org.apache.activemq.jndi.ActiveMQInitialContextFactory\",\n        providerUrl = \"tcp://localhost:61616\"\n    );\n    jms:Session session = check connection->createSession(jms:CLIENT_ACKNOWLEDGE);\n    jms:MessageConsumer consumer = check session.createConsumer(destination = {\n        'type: jms:QUEUE,\n        name: \"order-queue\"\n    });\n    jms:Message? message = check consumer->receive(5000);\n    if message is jms:MapMessage {\n        map<anydata> payload = message.content;\n        int|error orderId = payload[\"orderId\"].ensureType();\n        if orderId is int {\n            io:println(\"Received message from the JMS provider\", orderId);\n            check consumer->acknowledge(message);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/jms-consumer-acknowledgement/jms_consumer_acknowledgement.md",
    "content": "# JMS message consumer - Manual acknowledgment\n\nThe `jms:MessageConsumer` allows manual acknowledgment for received messages. A `jms:MessageConsumer` can be initialized by using a `jms:Session` object. To configure manual acknowledgment mode, create a `jms:Session` object with the acknowledge mode set to `jms:CLIENT_ACKNOWLEDGE`.\n\n::: code jms_consumer_acknowledgement.bal :::\n\n## Prerequisites\nStart a [ActiveMQ broker](https://activemq.apache.org/getting-started) instance.\n\nRun the program by executing the following command.\n\n::: out jms_consumer_acknowledgement.out :::\n\n>**Tip:** Run the JMS message producer given in the [JMS message producer - Produce message](/learn/by-example/jms-producer-produce-message) example to produce a few sample messages to the queue.\n\n## Related links\n- [`jms:MessageConsumer->acknowledge` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#MessageConsumer-acknowledge)\n- [`jms:MessageConsumer` functions - Specification](https://github.com/ballerina-platform/module-ballerinax-java.jms/blob/master/docs/spec/spec.md#61-functions)\n"
  },
  {
    "path": "examples/jms-consumer-acknowledgement/jms_consumer_acknowledgement.metatags",
    "content": "description: BBE on consuming messages from a JMS provider using Ballerina.\nkeywords: ballerina, ballerina by example, JMS, message consumer, acknowledgement, bbe\n"
  },
  {
    "path": "examples/jms-consumer-acknowledgement/jms_consumer_acknowledgement.out",
    "content": "$ bal run jms_consumer_acknowledgement.bal\n"
  },
  {
    "path": "examples/jms-consumer-consume-message/jms_consumer_consume_message.bal",
    "content": "import ballerina/io;\nimport ballerinax/java.jms;\nimport ballerinax/activemq.driver as _;\n\npublic function main() returns error? {\n    jms:Connection connection = check new (\n        initialContextFactory = \"org.apache.activemq.jndi.ActiveMQInitialContextFactory\",\n        providerUrl = \"tcp://localhost:61616\"\n    );\n    jms:Session session = check connection->createSession();\n    jms:MessageConsumer consumer = check session.createConsumer(destination = {\n        'type: jms:QUEUE,\n        name: \"order-queue\"\n    });\n    jms:Message? message = check consumer->receive(5000);\n    if message is jms:MapMessage {\n        io:println(\"Received message from the JMS provider\", message);\n    }\n}\n"
  },
  {
    "path": "examples/jms-consumer-consume-message/jms_consumer_consume_message.md",
    "content": "# JMS message consumer - Consume messages\n\nThe `jms:MessageConsumer` allows fetching individual messages one by one from a given JMS provider. A `jms:MessageConsumer` can be initialized by using a `jms:Session` object. To pull messages from the JMS provider, use either of the `receive` or `receiveNoWait` methods. It is possible to use automatic or manual acknowledgments similar to the consumer service. Use it to pull messages one by one from a JMS destination in the JMS provider.\n\n::: code jms_consumer_consume_message.bal :::\n\n## Prerequisites\nStart a [ActiveMQ broker](https://activemq.apache.org/getting-started) instance.\n\nRun the program by executing the following command.\n\n::: out jms_consumer_consume_message.out :::\n\n>**Tip:** Run the JMS message producer given in the [JMS message producer - Produce message](/learn/by-example/jms-producer-produce-message) example to produce some messages to the queue.\n\n## Related links\n- [`jms:MessageConsumer->receive` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#MessageConsumer-receive)\n- [`jms:MessageConsumer->receiveNoWait` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#MessageConsumer-receiveNoWait)\n- [`jms:MessageConsumer` functions - Specification](https://github.com/ballerina-platform/module-ballerinax-java.jms/blob/master/docs/spec/spec.md#61-functions)\n"
  },
  {
    "path": "examples/jms-consumer-consume-message/jms_consumer_consume_message.metatags",
    "content": "description: BBE on consuming messages from a JMS provider using Ballerina.\nkeywords: ballerina, ballerina by example, JMS, message consumer, bbe\n"
  },
  {
    "path": "examples/jms-consumer-consume-message/jms_consumer_consume_message.out",
    "content": "$ bal run jms_consumer_consume_message.bal\n"
  },
  {
    "path": "examples/jms-producer-produce-message/jms_producer_produce_message.bal",
    "content": "import ballerina/http;\nimport ballerinax/java.jms;\nimport ballerinax/activemq.driver as _;\n\nservice / on new http:Listener(9090) {\n    private final jms:MessageProducer orderProducer;\n\n    function init() returns error? {\n        jms:Connection connection = check new (\n            initialContextFactory = \"org.apache.activemq.jndi.ActiveMQInitialContextFactory\",\n            providerUrl = \"tcp://localhost:61616\"\n        );\n        jms:Session session = check connection->createSession();\n        self.orderProducer = check session.createProducer({ \n            'type: jms:QUEUE, \n            name: \"order-queue\" \n        });\n    }\n\n    resource function post orders(map<anydata> payoad) returns http:Accepted|error {\n        jms:MapMessage message = {\n            content: payoad\n        };\n        check self.orderProducer->send(message);\n        return http:ACCEPTED;\n    }\n}\n\n"
  },
  {
    "path": "examples/jms-producer-produce-message/jms_producer_produce_message.curl.out",
    "content": "$ curl http://localhost:9090/orders -H \"Content-type:application/json\" -d '{\"orderId\": 1, \"productName\": \"Sport shoe\", \"price\": 27.5, \"isValid\": true}'\n"
  },
  {
    "path": "examples/jms-producer-produce-message/jms_producer_produce_message.md",
    "content": "# JMS message producer - Produce messages\n\nThe `jms:MessageProducer` connects to a given JMS provider, and then sends messages to a specific JMS destination (queue or a topic) in the JMS provider. \nA `jms:MessageProducer` can be initialized by using a `jms:Session` object. Once connected, the `send` method can be used to send messages to a JMS destination in the JMS provider. `jms:TextMessage`, `jms:BytesMessage`, and `jms:MapMesage` can be provided as messages. Use this to send messages to a specific JMS destination. \nThe `sentTo` method of the `jms:MessageProducer` is used to send messages to multiple JMS destinations.\n\n::: code jms_producer_produce_message.bal :::\n\n## Prerequisites\nStart a [ActiveMQ broker](https://activemq.apache.org/getting-started) instance.\n\nRun the program by executing the following command.\n\n::: out jms_producer_produce_message.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out jms_producer_produce_message.curl.out :::\n\n## Related links\n- [`jms:MessageProducer->send` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#MessageProducer-send)\n- [`jms:MessageProducer->sendTo` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#MessageProducer-sendTo)\n- [`jms:MessageProducer` functions - Specification](https://github.com/ballerina-platform/module-ballerinax-java.jms/blob/master/docs/spec/spec.md#51-functions)\n"
  },
  {
    "path": "examples/jms-producer-produce-message/jms_producer_produce_message.metatags",
    "content": "description: BBE on sending messages to a JMS destination using a `jms:MessageProducer` client.\nkeywords: ballerina, ballerina by example, bbe, JMS, message producer\n"
  },
  {
    "path": "examples/jms-producer-produce-message/jms_producer_produce_message.out",
    "content": "$ bal run jms_producer_produce_message.bal\n"
  },
  {
    "path": "examples/jms-producer-transaction/jms_producer_transaction.bal",
    "content": "import ballerina/http;\nimport ballerinax/java.jms;\nimport ballerinax/activemq.driver as _;\n\nservice / on new http:Listener(9090) {\n    private final jms:MessageProducer orderProducer;\n    private final jms:Session session;\n\n    function init() returns error? {\n        jms:Connection connection = check new (\n            initialContextFactory = \"org.apache.activemq.jndi.ActiveMQInitialContextFactory\",\n            providerUrl = \"tcp://localhost:61616\"\n        );\n        self.session = check connection->createSession(jms:SESSION_TRANSACTED);\n        self.orderProducer = check self.session.createProducer();\n    }\n\n    resource function post orders(map<anydata> payoad) returns http:Accepted|error {\n        jms:MapMessage message = {\n            content: payoad\n        };\n        do {\n            check self.orderProducer->sendTo({'type: jms:QUEUE, name: \"order-queue\"}, message);\n            check self.session->'commit();\n            return http:ACCEPTED;\n        } on fail error err {\n            check self.session->'rollback();\n            return err;\n        }\n    }\n}\n"
  },
  {
    "path": "examples/jms-producer-transaction/jms_producer_transaction.curl.out",
    "content": "$ curl http://localhost:9090/orders -H \"Content-type:application/json\" -d '{\"orderId\": 1, \"productName\": \"Sport shoe\", \"price\": 27.5, \"isValid\": true}'\n"
  },
  {
    "path": "examples/jms-producer-transaction/jms_producer_transaction.md",
    "content": "# JMS message producer - Transactions\n\nThe `jms:MessageProducer` can become a transactional producer via the `'commit'` and `'rollback` functionalities of the `jms:Session`. Upon successful execution of the transaction block, the `jms:Session` can commit or roll back in the case of any error. Use this to send messages atomically to a JMS provider.\n\n::: code jms_producer_transaction.bal :::\n\n## Prerequisites\nStart a [ActiveMQ broker](https://activemq.apache.org/getting-started) instance.\n\nRun the program by executing the following command.\n\n::: out jms_producer_transaction.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out jms_producer_transaction.curl.out :::\n\n## Related links\n- [`jms:Session->'commit` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#Session-commit)\n- [`jms:Session->'rollback` function - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#Session-rollback)\n- [`jms:Session` functions - Specification](https://github.com/ballerina-platform/module-ballerinax-java.jms/blob/master/docs/spec/spec.md#32-functions)\n"
  },
  {
    "path": "examples/jms-producer-transaction/jms_producer_transaction.metatags",
    "content": "description: BBE on sending messages transactionally to a JMS destination using a `jms:MessageProducer` client.\nkeywords: ballerina, ballerina by example, bbe, JMS, message producer, transaction\n"
  },
  {
    "path": "examples/jms-producer-transaction/jms_producer_transaction.out",
    "content": "$ bal run jms_producer_transaction.bal\n"
  },
  {
    "path": "examples/jms-service-consume-message/jms_service_consume_message.bal",
    "content": "import ballerinax/java.jms;\nimport ballerina/log;\nimport ballerinax/activemq.driver as _;\n\nlistener jms:Listener jmsListener = check new (\n    initialContextFactory = \"org.apache.activemq.jndi.ActiveMQInitialContextFactory\",\n    providerUrl = \"tcp://localhost:61616\"\n);\n\n@jms:ServiceConfig {\n   queueName: \"order-queue\"\n}\nservice on jmsListener {\n    remote function onMessage(jms:Message message) returns error? {\n        if message is jms:MapMessage {\n            log:printInfo(\"Order message received\", content = message.content);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/jms-service-consume-message/jms_service_consume_message.md",
    "content": "# JMS service - Consume messages\n\nThe `jms:Service` connects to a given JMS provider via the `jms:Listener`, and allows receiving messages asynchronously. A `jms:Listener` is initialized by providing the connection configurations. A `jms:Service` must be configured to subscribe to a JMS destination—either a queue or a topic—using the `jms:ServiceConfig` annotation. Use this to listen to messages sent to a particular JMS destination asynchronously.\n\n\n::: code jms_service_consume_message.bal :::\n\n## Prerequisites\nStart a [ActiveMQ broker](https://activemq.apache.org/getting-started) instance.\n\nRun the program by executing the following command.\n\n::: out jms_service_consume_message.out :::\n\n>**Tip:** Run the JMS message producer given in the [JMS message producer - Produce message](/learn/by-example/jms-producer-produce-message) example to produce some messages to the queue.\n\n## Related links\n- [`jms:Listener` - API documentation](https://lib.ballerina.io/ballerinax/java.jms/latest#Listener)\n- [`jms:Listener` - Specification](https://github.com/ballerina-platform/module-ballerinax-java.jms/blob/master/docs/spec/spec.md#7-message-listener)\n"
  },
  {
    "path": "examples/jms-service-consume-message/jms_service_consume_message.metatags",
    "content": "description: BBE on consuming messages from a JMS provider in an asynchronous manner using Ballerina.\nkeywords: ballerina, ballerina by example, JMS, message consumer, bbe, service, asynchronous\n"
  },
  {
    "path": "examples/jms-service-consume-message/jms_service_consume_message.out",
    "content": "$ bal run jms_service_consume_message.bal\n"
  },
  {
    "path": "examples/joining-iterable-objects/joining_iterable_objects.bal",
    "content": "import ballerina/io;\n\ntype User record {|\n    int id;\n    string name;\n|};\n\ntype Login record {|\n    int userId;\n    string time;\n|};\n\npublic function main() {\n    User[] users = [\n        {id: 1234, name: \"Keith\"},\n        {id: 6789, name: \"Anne\"}\n    ];\n\n    Login[] logins = [\n        {userId: 6789, time: \"20:10:23\"},\n        {userId: 1234, time: \"10:30:02\"},\n        {userId: 3987, time: \"12:05:00\"}\n    ];\n\n    // Inner equijoin.\n    string[] joinResult = from var login in logins\n                          // The `join` clause iterates any iterable value similarly to the\n                          // `from` clause.\n                          join var user in users\n                          // The `on` condition is used to match the `login` with the\n                          // `user` based on the `userId`.\n                          // The iteration is skipped when the condition is not satisfied.\n                          on login.userId equals user.id\n                          select string `${user.name} : ${login.time}`;\n\n    io:println(joinResult);\n\n    // Outer equijoin.\n    string[] outerEquijoin = from var login in logins\n                             outer join var user in users\n                             // If there is no matching pair for all members in the `users`,\n                             // then, the `user` will be `()`,\n                             // and the join-on-condition will be skipped.\n                             on login.userId equals user is () ? () : user.id\n                             select string `${user is () ? \"New user\" : user.name} : ${login.time}`;\n\n    io:println(outerEquijoin);\n}\n"
  },
  {
    "path": "examples/joining-iterable-objects/joining_iterable_objects.md",
    "content": "# Join iterable objects\n\nA `join` clause performs an inner or left outer equi-join. The result is similar to using the nested `from` clauses and a `where` clause. Variables declared in the query expression before the join clause are accessible only on the left side of the join condition, while variables declared in the join clause are accessible only on the right side of the join condition.\n\n::: code joining_iterable_objects.bal :::\n\n::: out joining_iterable_objects.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/joining-iterable-objects/joining_iterable_objects.metatags",
    "content": "description: This BBE demonstrates the `join` clause in Ballerina, joining two tables, joining two lists, joining two maps, the query join, inner join, outer join, and left outer join.\nkeywords: ballerina, ballerina by example, bbe, join clause, query, query expression, join clause, inner join, left outer join, table\n"
  },
  {
    "path": "examples/joining-iterable-objects/joining_iterable_objects.out",
    "content": "$ bal run joining_iterable_objects.bal\n[\"Anne : 20:10:23\",\"Keith : 10:30:02\"]\n[\"Anne : 20:10:23\",\"Keith : 10:30:02\",\"New user : 12:05:00\"]\n"
  },
  {
    "path": "examples/json-numbers/json_numbers.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    int a = 1;\n    float b = 2.1;\n    decimal c = 3.24;\n\n    // The `json` type allows `int|float|decimal`.\n    json[] d = [a, b, c];\n\n    // `toJsonString()` will convert `int|float|decimal` into the JSON numeric\n    // syntax.\n    string e = d.toJsonString();\n    io:println(e);\n\n    // `fromJsonString()` converts JSON numeric syntax into `int`, if possible\n    // and `decimal` otherwise.\n    json f = check e.fromJsonString();\n    io:println(f);\n\n    json[] g = <json[]>f;\n    io:println(typeof g[0]);\n    io:println(typeof g[1]);\n    io:println(typeof g[2]);\n\n    // `cloneWithType()` or `ensureType()` will convert from `int` or `decimal`\n    // into the user's chosen numeric type.\n    float h = check g[2].ensureType();\n    io:println(h);\n\n    // `-0` is an edge case: represented as `float`.\n    string i = \"-0\";\n    io:println(typeof check i.fromJsonString());\n}\n"
  },
  {
    "path": "examples/json-numbers/json_numbers.md",
    "content": "# JSON numbers\n\nBallerina has three numeric types; but JSON has one. The `json` type allows `int|float|decimal`. `toJsonString()` will convert `int|float|decimal` into JSON numeric syntax. `fromJsonString()` converts JSON numeric syntax into `int`, if possible, and otherwise `decimal`.\n\n`cloneWithType()` or `ensureType()` will convert from `int` or `decimal` into the user's chosen numeric type. The net result is that you can use JSON to exchange the full range of all three Ballerina numeric types. `-0` is an edge case: it is represented as a `float`.\n\n::: code json_numbers.bal :::\n\n::: out json_numbers.out :::\n\n## Related links\n- [Casting JSON to user-defined type](/learn/by-example/casting-json-to-user-defined-type/)\n- [Converting to user-defined type](/learn/by-example/converting-to-user-defined-type/)\n- [JSON type](/learn/by-example/json-type/)\n"
  },
  {
    "path": "examples/json-numbers/json_numbers.metatags",
    "content": "description: This BBE demonstrates how to represent numeric value in JSON, convert JSON to numeric representation, convert numeric value to JSON.\nkeywords: ballerina, ballerina by example, bbe, json, numbers, toJsonString, fromJsonString, ensureType\n"
  },
  {
    "path": "examples/json-numbers/json_numbers.out",
    "content": "$ bal run json_numbers.bal\n[1, 2.1, 3.24]\n[1,2.1,3.24]\ntypedesc 1\ntypedesc 2.1\ntypedesc 3.24\n3.24\ntypedesc -0.0\n"
  },
  {
    "path": "examples/json-to-record/json_to_record.bal",
    "content": "import ballerina/data.jsondata;\nimport ballerina/io;\n\ntype Book record {\n    string name;\n    string author;\n    int year;\n};\n\njson jsonContent = {\n    \"name\": \"Clean Code\",\n    \"author\": \"Robert C. Martin\",\n    \"year\": 2008\n};\n\nstring jsonStr = string `\n{\n    \"name\": \"Clean Code\",\n    \"author\": \"Robert C. Martin\",\n    \"year\": 2008\n}`;\n\npublic function main() returns error? {\n    // Convert the JSON value to a record type.\n    Book book1 = check jsondata:parseAsType(jsonContent);\n    io:println(book1);\n\n    // Convert the JSON string to a record type.\n    Book book2 = check jsondata:parseString(jsonStr);\n    io:println(book2);\n\n    byte[] jsonByteArr = jsonStr.toBytes();\n    // Convert the JSON byte array to a record type.\n    Book book3 = check jsondata:parseBytes(jsonByteArr);\n    io:println(book3);\n\n    stream<byte[], error?> byteBlockStream = new (new ByteBlockGenerator(jsonStr));\n    // Convert the JSON byte block stream to a record type.\n    Book book4 = check jsondata:parseStream(byteBlockStream);\n    io:println(book4);\n}\n\n// Defines a class called `ByteBlockGenerator`, which implements the `next()` method.\n// This will be invoked when the `next()` method of the stream gets invoked.\nclass ByteBlockGenerator {\n    private int index = 0;\n    private final byte[] byteArr;\n    private final int arraySize;\n\n    public function init(string data) {\n        self.byteArr = data.toBytes();\n        self.arraySize = self.byteArr.length();\n    }\n\n    public isolated function next() returns record {|byte[] value;|}|error? {\n        if self.index >= self.arraySize {\n            return;\n        }\n        int startIndex = self.index;\n        self.index = startIndex + 4 > self.arraySize ? self.arraySize : startIndex + 3;\n        return {value: self.byteArr.slice(startIndex, self.index)};\n    }\n}\n"
  },
  {
    "path": "examples/json-to-record/json_to_record.md",
    "content": "# JSON to Record conversion\n\nThe `data.jsondata` library provides multiple APIs to perform the conversion from JSON data in the form of a `string`, `byte[]`, `byte-block-stream`, and `json` to a Ballerina record.\n\nFor more information on the underlying module, see the [`data.jsondata` module](https://lib.ballerina.io/ballerina/data.jsondata/latest/).\n\n::: code json_to_record.bal :::\n\n::: out json_to_record.out :::\n"
  },
  {
    "path": "examples/json-to-record/json_to_record.metatags",
    "content": "description: This BBE demonstrates the conversion from JSON source, which can be provided as a string, byte array, byte block stream, or json, into a record in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, json, record, stream, byte array\n"
  },
  {
    "path": "examples/json-to-record/json_to_record.out",
    "content": "$ bal run json_to_record.bal\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"year\":2008}\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"year\":2008}\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"year\":2008}\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\",\"year\":2008}\n"
  },
  {
    "path": "examples/json-to-record-with-projection/json_to_record_with_projection.bal",
    "content": "import ballerina/data.jsondata;\nimport ballerina/io;\n\n// Define a closed record type to capture the required fields from the JSON content.\ntype Book record {|\n    string name;\n    string author;\n|};\n\njson jsonContent = {\n    \"name\": \"Clean Code\",\n    \"author\": \"Robert C. Martin\",\n    \"year\": 2008,\n    \"publisher\": \"Prentice Hall\"\n};\n\nstring jsonStr = string `\n{\n    \"name\": \"The Pragmatic Programmer\",\n    \"author\": \"Andrew Hunt, David Thomas\",\n    \"year\": 1999,\n    \"publisher\": \"Addison-Wesley\"\n}`;\n\npublic function main() returns error? {\n    // Based on the expected type, it selectively converts the JSON content to the record type.\n    Book book = check jsondata:parseAsType(jsonContent);\n    io:println(book);\n\n    // Based on the expected type, it selectively converts the JSON string to the record type.\n    Book book2 = check jsondata:parseString(jsonStr);\n    io:println(book2);\n}\n"
  },
  {
    "path": "examples/json-to-record-with-projection/json_to_record_with_projection.md",
    "content": "# JSON to record conversion with projection\n\nThe `data.jsondata` library provides multiple APIs to selectively convert required fields from JSON data in the form of a `string`, `byte[]`, `byte-block-stream`, and `json` to a Ballerina record.\n\nFor more information on the underlying module, see the [`data.jsondata` module](https://lib.ballerina.io/ballerina/data.jsondata/latest/).\n\n::: code json_to_record_with_projection.bal :::\n\n::: out json_to_record_with_projection.out :::\n"
  },
  {
    "path": "examples/json-to-record-with-projection/json_to_record_with_projection.metatags",
    "content": "description: This BBE illustrates how to selectively convert fields from a JSON source, which can be provided as a string, byte array, byte block stream, or json, into a record in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, json, record, data projection \n"
  },
  {
    "path": "examples/json-to-record-with-projection/json_to_record_with_projection.out",
    "content": "$ bal run json_to_record_with_projection.bal\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n{\"name\":\"The Pragmatic Programmer\",\"author\":\"Andrew Hunt, David Thomas\"}\n"
  },
  {
    "path": "examples/json-type/json_type.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    int id;\n    string name;\n|};\n \npublic function main() returns error? {\n    // As JSON is a union: `()|boolean|int|float|decimal|string|json[]|map<json>`,\n    // the following cases are allowed.\n    json n = null;\n    json i = 21;\n    json s = \"str\";\n    json a = [1, 2];\n    json m = {\"x\": n, \"y\": s, \"z\": a};\n    io:println(m);\n    json[] arr = [m, {\"x\": i}];\n    io:println(arr);\n \n    string rawData = \"{\\\"id\\\": 2, \\\"name\\\": \\\"Georgy\\\"}\";\n    // Get the `json` value from the string.\n    json j = check rawData.fromJsonString();\n    io:println(j);\n \n    // Access the fields of `j` using field access.\n    string name = check j.name;\n    io:println(name);\n \n    // Convert the `json` into a user-defined type.\n    Student student = check j.cloneWithType();\n    io:println(student.id);\n \n    // Convert the user-defined type to a `json`.\n    j = student;\n    io:println(j);\n}\n"
  },
  {
    "path": "examples/json-type/json_type.md",
    "content": "# `json` type\n\nThe `json` type can be explained as a union of the simple basic types, `string`, array of `json`, and `json` mapping. Technically, the `json` type is a union: `()|boolean|int|float|decimal|string|json[]|map<json>`. A `json` value can be converted to and from Ballerina straightforwardly except for the choice of the Ballerina numeric type. Ballerina syntax is compatible with JSON and allows null literal to be compatible with JSON.\n\n`json` is `anydata` without `table` and `xml`. `toJson()` recursively converts `anydata` to `json`. Table values are converted to `json` arrays and `xml` values are converted to strings.\n\n::: code json_type.bal :::\n\n::: out json_type.out :::\n\n## Related links\n- [Access JSON elements](/learn/by-example/access-json-elements/)\n- [Convert from JSON to user-defined type](/learn/by-example/convert-from-json-to-user-defined-type/)\n- [Convert from user-defined type to JSON](/learn/by-example/converting-from-user-defined-type-to-json/)\n- [fromJsonString](https://lib.ballerina.io/ballerina/lang.value/0.0.0#fromJsonString)\n- [cloneWithType](https://lib.ballerina.io/ballerina/lang.value/0.0.0#cloneWithType)"
  },
  {
    "path": "examples/json-type/json_type.metatags",
    "content": "description: This BBE demonstrates how to define JSON, create JSON from basic value, access JSON elements, convert JSON to user-defined type, convert user-defined type to a JSON, and convert string to a JSON in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, json type, json, json array, fromJsonString, check, cloneWithType\n"
  },
  {
    "path": "examples/json-type/json_type.out",
    "content": "$ bal run json_type.bal\n{\"x\":null,\"y\":\"str\",\"z\":[1,2]}\n[{\"x\":null,\"y\":\"str\",\"z\":[1,2]},{\"x\":21}]\n{\"id\":2,\"name\":\"Georgy\"}\nGeorgy\n2\n{\"id\":2,\"name\":\"Georgy\"}\n"
  },
  {
    "path": "examples/jsonpath-expressions/jsonpath_expressions.bal",
    "content": "import ballerina/data.jsondata;\nimport ballerina/io;\n\npublic function main() returns error? {\n    json books = [\n        {\n            title: \"The Great Gatsby\",\n            author: \"F. Scott Fitzgerald\",\n            price: 100,\n            year: 1925\n        },\n        {\n            title: \"To Kill a Mockingbird\",\n            author: \"Harper Lee\",\n            price: 72.5,\n            year: 1960\n        },\n        {\n            title: \"1984\",\n            author: \"George Orwell\",\n            price: 90,\n            year: 1949\n        }\n    ];\n\n    // JSONPath expression to get the list of titles in the books array.\n    json titles = check jsondata:read(books, `$..title`);\n    io:println(titles);\n\n    // JSONPath expression to get the list of published years for the \n    // books that have a price value of more than 80.\n    json years = check jsondata:read(books, `$..[?(@.price > 80)].year`);\n    io:println(years);\n\n    // JSONPath expression to get the total sum of the prices of the books.\n    json sum = check jsondata:read(books, `$..price.sum()`);\n    io:println(sum);\n}\n"
  },
  {
    "path": "examples/jsonpath-expressions/jsonpath_expressions.md",
    "content": "# JSONPath expressions\n\nBallerina supports JSONPath expressions against JSON data through [`ballerina/data.jsondata` module](https://lib.ballerina.io/ballerina/data.jsondata/latest/) module to provide a straightforward method \nfor navigating the structure of JSON data.\nAlternatively, Ballerina supports type based access to JSON data by language itself.\n\n::: code jsonpath_expressions.bal :::\n\n::: out jsonpath_expressions.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Access JSON elements](/learn/by-example/access-json-elements/)"
  },
  {
    "path": "examples/jsonpath-expressions/jsonpath_expressions.metatags",
    "content": "description: This BBE demonstrates JSON path expressions with Ballerina\nkeywords: ballerina, ballerina by example, bbe, json, jsonpath, jsonpath expressions\n"
  },
  {
    "path": "examples/jsonpath-expressions/jsonpath_expressions.out",
    "content": "$ bal run jsonpath_expressions.bal\n[\"The Great Gatsby\",\"To Kill a Mockingbird\",\"1984\"]\n[1925,1949]\n262.5\n"
  },
  {
    "path": "examples/kafka-consumer-constraint-validation/kafka_consumer_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerinax/kafka;\nimport ballerina/io;\n\ntype Order record {\n    int orderId;\n    // Add a constraint to only allow string values of length between 30 and 1.\n    @constraint:String {maxLength: 30, minLength: 1}\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    kafka:Consumer orderConsumer = check new (kafka:DEFAULT_URL, {\n        groupId: \"order-group-id\",\n        topics: \"order-topic\"\n    });\n\n    while true {\n        Order[] orders = check orderConsumer->pollPayload(15);\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                io:println(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-consumer-constraint-validation/kafka_consumer_constraint_validation.md",
    "content": "# Kafka consumer - Constraint validation\n\nThe `kafka:Consumer` connects to a given Kafka server, and then validates the received payloads by the defined constraints. The constraints are added as annotations to the payload record and when the payload is received from the broker, it is validated internally and if validation fails, an error will be logged to the console and the `kafka:Consumer` will be automatically seeked to the next record. This behaviour can be changed by setting `autoSeekOnValidationFailure` configuration to `false`. Then the related error is returned to be handled as needed. The `validation` flag of the`kafka:ConsumerConfiguration` can be set to `false` to stop validating the payloads. Use this to validate the messages received from a Kafka server implicitly.\n\n::: code kafka_consumer_constraint_validation.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_consumer_constraint_validation.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.\n\n## Related links\n- [`kafka:PayloadValidationError` error type - API documentation](https://lib.ballerina.io/ballerinax/kafka/3.4.0#PayloadValidationError)\n- [`kafka:Consumer->seek` function - API documentation](https://lib.ballerina.io/ballerinax/kafka/3.4.0#Consumer#seek)\n- [`kafka` module - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md)\n- [`constraint` module - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n"
  },
  {
    "path": "examples/kafka-consumer-constraint-validation/kafka_consumer_constraint_validation.metatags",
    "content": "description: This example demonstrates validating a payload according to the constraints defined in the payload record.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, listener, service, constraint, validation\n"
  },
  {
    "path": "examples/kafka-consumer-constraint-validation/kafka_consumer_constraint_validation.out",
    "content": "$ bal run kafka_client_constraint_validation.bal\ntime = 2022-11-28T13:56:56.502+05:30 level = INFO module = \"\" message = \"Received valid order for Sport\"\ntime = 2022-11-28T14:19:43.346+05:30 level = ERROR module = \"\" message = \"Payload validation failed\" error = \"Failed to validate payload. If needed, please seek past the record to continue consumption.\"\ntime = 2022-11-28T13:56:56.502+05:30 level = INFO module = \"\" message = \"Received valid order for Sport\"\n"
  },
  {
    "path": "examples/kafka-consumer-consumer-record-data-binding/kafka_consumer_consumer_record_data_binding.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/io;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Create a subtype of `kafka:AnydataConsumerRecord`.\ntype OrderConsumerRecord record {|\n    *kafka:AnydataConsumerRecord;\n    Order value;\n|};\n\npublic function main() returns error? {\n    kafka:Consumer orderConsumer = check new (kafka:DEFAULT_URL, {\n        groupId: \"order-group-id\",\n        topics: \"order-topic\"\n    });\n\n    while true {\n        // Polls the consumer for order records.\n        OrderConsumerRecord[] records = check orderConsumer->poll(15);\n        from OrderConsumerRecord orderRecord in records\n            where orderRecord.value.isValid\n            do {\n                io:println(string `Received valid order for ${orderRecord.value.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-consumer-consumer-record-data-binding/kafka_consumer_consumer_record_data_binding.md",
    "content": "# Kafka consumer - Consumer record data binding\n\nThe consumer record data-binding allows you to directly bind Kafka messages to subtypes of `kafka:AnydataConsumerRecord`. It does this by using the built-in bytes deserializer for both the key and the value. To use this, directly assign the `poll` method’s return value to the declared variable, which is a subtype of `kafka:AnydataConsumerRecord[]`. A subtype of `kafka:AnydataConsumerRecord` can be created by specifying a user defined type for the value field. If the record does not match with the defined type, the related error will be logged to the console and the `kafka:Consumer` will be automatically seeked to the next record. This behaviour can be changed by setting `autoSeekOnValidationFailure` configuration to `false`. Then the related error is returned to be handled as needed. Use this to receive messages from a Kafka server with the metadata of the messages like `kafka:PartitionOffset` and `timestamp`. It is important to note that this only works when `kafka:Producer` also uses the built-in bytes serializer for Ballerina.\n\n::: code kafka_consumer_consumer_record_data_binding.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_consumer_consumer_record_data_binding.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:Consumer->poll` function - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#Consumer#poll)\n- [Kafka client consume messages - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#422-consume-messages)\n"
  },
  {
    "path": "examples/kafka-consumer-consumer-record-data-binding/kafka_consumer_consumer_record_data_binding.metatags",
    "content": "description: This example demonstrates how to use a kafka:Consumer as a simple record consumer.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, client\n"
  },
  {
    "path": "examples/kafka-consumer-consumer-record-data-binding/kafka_consumer_consumer_record_data_binding.out",
    "content": "$ bal run kafka_client_consumer_poll_consumer_record.bal\nReceived valid order for Sport shoe\n"
  },
  {
    "path": "examples/kafka-consumer-payload-data-binding/kafka_consumer_payload_data_binding.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/io;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    kafka:Consumer orderConsumer = check new (kafka:DEFAULT_URL, {\n        groupId: \"order-group-id\",\n        topics: \"order-topic\"\n    });\n\n    while true {\n        // Polls the consumer for payload.\n        Order[] orders = check orderConsumer->pollPayload(15);\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                io:println(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-consumer-payload-data-binding/kafka_consumer_payload_data_binding.md",
    "content": "# Kafka consumer - Payload data binding\n\nThe payload data-binding allows you to directly bind Kafka messages to subtypes of `anydata`. It does this by using the built-in bytes deserializer for both the key and the value. To use this, directly assign the `pollPayload` method’s return value to the declared variable, which is a subtype of `anydata[]`. If the payload does not match with the defined type, the related error will be logged to the console and the `kafka:Consumer` will be automatically seeked to the next record. This behaviour can be changed by setting `autoSeekOnValidationFailure` configuration to `false`. Then the related error is returned to be handled as needed. Use this to receive messages from a Kafka server without the metadata of the messages like `kafka:PartitionOffset` and `timestamp`. It is important to note that this only works when `kafka:Producer` also uses the built-in bytes serializer for Ballerina.\n\n::: code kafka_consumer_payload_data_binding.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_consumer_payload_data_binding.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:Consumer->pollPayload` function - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#Consumer#pollPayload)\n- [Kafka client consume messages - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#422-consume-messages)\n"
  },
  {
    "path": "examples/kafka-consumer-payload-data-binding/kafka_consumer_payload_data_binding.metatags",
    "content": "description: This example demonstrates how to use a kafka:Consumer as a payload consumer.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, client\n"
  },
  {
    "path": "examples/kafka-consumer-payload-data-binding/kafka_consumer_payload_data_binding.out",
    "content": "$ bal run kafka_client_consumer_poll_payload.bal\nReceived valid order for Sport shoe\n"
  },
  {
    "path": "examples/kafka-consumer-sasl/kafka_consumer_sasl.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/io;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    kafka:Consumer orderConsumer = check new (\"localhost:9093\", {\n        groupId: \"order-group-id\",\n        topics: \"order-topic\",\n        // Provide the relevant authentication configurations to authenticate the consumer\n        // by the `kafka:AuthenticationConfiguration`.\n        auth: {\n            // Provide the authentication mechanism used by the Kafka server.\n            mechanism: kafka:AUTH_SASL_PLAIN,\n            // Username and password should be set here in order to authenticate the consumer.\n            username: \"alice\",\n            password: \"alice@123\"\n        },\n        securityProtocol: kafka:PROTOCOL_SASL_PLAINTEXT\n    });\n\n    // Polls the consumer for payload.\n    Order[] orders = check orderConsumer->pollPayload(1);\n\n    from Order 'order in orders\n        where 'order.isValid\n        do {\n            io:println(string `Received valid order for ${'order.productName}`);\n        };\n}\n"
  },
  {
    "path": "examples/kafka-consumer-sasl/kafka_consumer_sasl.md",
    "content": "# Kafka consumer - SASL authentication\n\nThe `kafka:Consumer` connects to a Kafka server via SASL/PLAIN authentication and then, receives the payloads from the server. SASL/PLAIN authentication can be enabled by configuring the `auth`, which requires the authentication mechanism, username, and password. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SASL_PLAINTEXT`. Use this to connect to a Kafka server secured with SASL/PLAIN.\n\n::: code kafka_consumer_sasl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use the [SASL/PLAIN authentication mechanism](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_plain.html#sasl-plain-overview).\n\nRun the program by executing the following command.\n\n::: out kafka_consumer_sasl.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - SASL authentication](/learn/by-example/kafka-producer-sasl) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:AuthenticationConfiguration` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#AuthenticationConfiguration)\n- [Kafka client consumer SASL authentication - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#4212-secure-client)\n"
  },
  {
    "path": "examples/kafka-consumer-sasl/kafka_consumer_sasl.metatags",
    "content": "description: This example is on how to configure a Kafka consumer to use SASL/PLAIN authentication.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, authentication, SASL\n"
  },
  {
    "path": "examples/kafka-consumer-sasl/kafka_consumer_sasl.out",
    "content": "$ bal run kafka_client_consumer_sasl.bal\nReceived valid order for Sport shoe\n"
  },
  {
    "path": "examples/kafka-consumer-ssl/kafka_consumer_ssl.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/io;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    kafka:Consumer orderConsumer = check new (\"localhost:9094\", {\n        groupId: \"order-group-id\",\n        topics: [\"order-topic\"],\n        // Provide the relevant secure socket configurations by using `kafka:SecureSocket`.\n        secureSocket: {\n            cert: \"./resources/path/to/public.crt\",\n            protocol: {\n                // Provide the relevant security protocol.\n                name: kafka:SSL\n            }\n        },\n        // Provide the type of the security protocol to use in the broker connection.\n        securityProtocol: kafka:PROTOCOL_SSL\n    });\n\n    // Polls the consumer for payload.\n    Order[] orders = check orderConsumer->pollPayload(1);\n\n    from Order 'order in orders\n        where 'order.isValid\n        do {\n            io:println(string `Received valid order for ${'order.productName}`);\n        };\n}\n"
  },
  {
    "path": "examples/kafka-consumer-ssl/kafka_consumer_ssl.md",
    "content": "# Kafka consumer - SSL/TLS\n\nThe `kafka:Consumer` connects to a Kafka server via SSL/TLS and then, receives payloads from the server. SSL/TLS can be enabled by configuring the `secureSocket`, which requires a certificate and the protocol name. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SSL`. Use this to connect to a Kafka server secured with SSL/TLS.\n\n::: code kafka_consumer_ssl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use [SSL/TLS](https://docs.confluent.io/3.0.0/kafka/ssl.html#configuring-kafka-brokers).\n\nRun the program by executing the following command.\n\n::: out kafka_consumer_ssl.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - SSL/TLS](/learn/by-example/kafka-producer-ssl) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:SecureSocket` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#SecureSocket)\n- [Kafka secure client - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#4212-secure-client)\n"
  },
  {
    "path": "examples/kafka-consumer-ssl/kafka_consumer_ssl.metatags",
    "content": "description: This example is on how to configure a Kafka consumer to use SSL encryption.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, authentication, SASL\n"
  },
  {
    "path": "examples/kafka-consumer-ssl/kafka_consumer_ssl.out",
    "content": "$ bal run kafka_client_consumer_sasl.bal\nReceived valid order for Sport shoe\n"
  },
  {
    "path": "examples/kafka-producer-produce-message/kafka_producer_produce_message.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/http;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9090) {\n    private final kafka:Producer orderProducer;\n\n    function init() returns error? {\n        self.orderProducer = check new (kafka:DEFAULT_URL);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        check self.orderProducer->send({\n            topic: \"order-topic\",\n            value: newOrder\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/kafka-producer-produce-message/kafka_producer_produce_message.curl.out",
    "content": "$ curl http://localhost:9090/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/kafka-producer-produce-message/kafka_producer_produce_message.md",
    "content": "# Kafka producer - Produce message\n\nThe `kafka:Producer` connects to a given Kafka server, and then sends messages to a specific topic in the server. A `kafka:Producer` is created by giving the Kafka server url. Once connected, `send` method is used to send messages to the Kafka server by providing the relevant topic and the value as the parameters. `anydata` and subtypes of `anydata` can be provided as the values, and these will be serialized using the built-in byte array serializer internally when sending to the server. Use this to send messages to a topic in the Kafka server.\n\n::: code kafka_producer_produce_message.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_producer_produce_message.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out kafka_producer_produce_message.curl.out :::\n\n## Related links\n- [`kafka:Producer->send` function - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#Producer#send)\n- [`kafka:Producer` functions - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#33-functions)\n"
  },
  {
    "path": "examples/kafka-producer-produce-message/kafka_producer_produce_message.metatags",
    "content": "description: This example demonstrates sending messages to a Kafka topic using a kafka:Producer client.\nkeywords: ballerina, ballerina by example, bbe, kafka, producer\n"
  },
  {
    "path": "examples/kafka-producer-produce-message/kafka_producer_produce_message.out",
    "content": "$ bal run kafka_client_producer.bal\n"
  },
  {
    "path": "examples/kafka-producer-sasl/kafka_producer_sasl.bal",
    "content": "import ballerina/http;\nimport ballerinax/kafka;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9090) {\n    private final kafka:Producer orderProducer;\n\n    function init() returns error? {\n        self.orderProducer = check new (\"localhost:9093\", {\n            // Provide the relevant authentication configurations to authenticate the producer by\n            // `kafka:AuthenticationConfiguration`.\n            auth: {\n                // Provide the authentication mechanism used by the Kafka server.\n                mechanism: kafka:AUTH_SASL_PLAIN,\n                // Username and password should be set here in order to authenticate the producer.\n                username: \"alice\",\n                password: \"alice@123\"\n            },\n            securityProtocol: kafka:PROTOCOL_SASL_PLAINTEXT\n        });\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        check self.orderProducer->send({\n            topic: \"order-topic\",\n            value: newOrder\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/kafka-producer-sasl/kafka_producer_sasl.curl.out",
    "content": "$ curl http://localhost:9090/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/kafka-producer-sasl/kafka_producer_sasl.md",
    "content": "# Kafka producer - SASL authentication\n\nThe `kafka:Producer` connects to a Kafka server via SASL/PLAIN authentication and then, sends messages to the server. SASL/PLAIN authentication can be enabled by configuring the `auth`, which requires the authentication mechanism, username, and password. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SASL_PLAINTEXT`. Use this to connect to a Kafka server secured with SASL/PLAIN.\n\n::: code kafka_producer_sasl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use the [SASL/PLAIN authentication mechanism](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_plain.html#sasl-plain-overview).\n\nRun the program by executing the following command.\n\n::: out kafka_producer_sasl.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out kafka_producer_sasl.curl.out :::\n\n## Related links\n- [`kafka:AuthenticationConfiguration` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#AuthenticationConfiguration)\n- [Kafka client producer SASL authentication - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#322-secure-client)\n"
  },
  {
    "path": "examples/kafka-producer-sasl/kafka_producer_sasl.metatags",
    "content": "description: This example is on how to configure a Kafka producer to use SASL/PLAIN authentication.\nkeywords: ballerina, ballerina by example, bbe, kafka, producer, authentication, SASL\n"
  },
  {
    "path": "examples/kafka-producer-sasl/kafka_producer_sasl.out",
    "content": "$ bal run kafka_client_producer_sasl.bal\n"
  },
  {
    "path": "examples/kafka-producer-ssl/kafka_producer_ssl.bal",
    "content": "import ballerina/http;\nimport ballerinax/kafka;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9090) {\n    private final kafka:Producer orderProducer;\n\n    function init() returns error? {\n        self.orderProducer = check new (\"localhost:9094\", {\n            // Provide the relevant secure socket configurations by using `kafka:SecureSocket`.\n            secureSocket: {\n                cert: \"./resources/path/to/public.crt\",\n                protocol: {\n                    // Provide the relevant security protocol.\n                    name: kafka:SSL\n                }\n            },\n            // Provide the type of the security protocol to use in the broker connection.\n            securityProtocol: kafka:PROTOCOL_SSL\n        });\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        check self.orderProducer->send({\n            topic: \"order-topic\",\n            value: newOrder\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/kafka-producer-ssl/kafka_producer_ssl.curl.out",
    "content": "$ curl http://localhost:9090/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/kafka-producer-ssl/kafka_producer_ssl.md",
    "content": "# Kafka producer - SSL/TLS\n\nThe `kafka:Producer` connects to a Kafka server via SSL/TLS and then, sends messages to the server. SSL/TLS can be enabled by configuring the `secureSocket`, which requires a certificate and the protocol name. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SSL`. Use this to connect to a Kafka server secured with SSL.\n\n>**Info:** For more information on the underlying module, see the [`kafka` module](https://lib.ballerina.io/ballerinax/kafka/latest).\n\n::: code kafka_producer_ssl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use [SSL/TLS](https://docs.confluent.io/3.0.0/kafka/ssl.html#configuring-kafka-brokers).\n\nRun the program by executing the following command.\n\n::: out kafka_producer_ssl.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out kafka_producer_ssl.curl.out :::\n\n## Related links\n- [`kafka:SecureSocket` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#SecureSocket)\n- [Kafka secure client - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#322-secure-client)\n"
  },
  {
    "path": "examples/kafka-producer-ssl/kafka_producer_ssl.metatags",
    "content": "description: This example is on how to configure a Kafka producer to use SSL encryption.\nkeywords: ballerina, ballerina by example, bbe, kafka, producer, encryption, SSL\n"
  },
  {
    "path": "examples/kafka-producer-ssl/kafka_producer_ssl.out",
    "content": "$ bal run kafka_client_producer_ssl.bal\nMessage published successfully.\n"
  },
  {
    "path": "examples/kafka-service-constraint-validation/kafka_service_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerinax/kafka;\nimport ballerina/log;\n\ntype Order record {\n    int orderId;\n    // Add a constraint to only allow string values of length between 30 and 1.\n    @constraint:String {maxLength: 30, minLength: 1}\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener kafka:Listener orderListener = new (kafka:DEFAULT_URL, {\n    groupId: \"order-group-id\",\n    topics: \"order-topic\"\n});\n\nservice on orderListener {\n\n    remote function onConsumerRecord(Order[] orders) {\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                log:printInfo(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-service-constraint-validation/kafka_service_constraint_validation.md",
    "content": "# Kafka service - Constraint validation\n\nThe `kafka:Service` connects to a given Kafka server via the `kafka:Listener`, and then validates the received payloads by the defined constraints. The constraints are added as annotations to the payload record and when the payload is received from the broker, it is validated internally and if validation fails, a `kafka:PayloadBindingError` will be logged to the console and the `kafka:Listener` will be automatically seeked to the next record. This behaviour can be changed by setting `autoSeekOnValidationFailure` configuration to `false`. Then the `onError` remote method will be invoked with the related error to be handled as needed. The `validation` flag of the`kafka:ConsumerConfiguration` can be set to `false` to stop validating the payloads. Use this to validate the messages received from a Kafka server implicitly.\n\n::: code kafka_service_constraint_validation.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_service_constraint_validation.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.\n\n## Related links\n- [`kafka:PayloadValidationError` error type - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#PayloadValidationError)\n- [`kafka:Caller->seek` function - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#Caller#seek)\n- [`kafka` module - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md)\n- [`constraint` module - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n"
  },
  {
    "path": "examples/kafka-service-constraint-validation/kafka_service_constraint_validation.metatags",
    "content": "description: This example demonstrates validating a payload according to the constraints defined in the payload record.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, listener, service, constraint, validation\n"
  },
  {
    "path": "examples/kafka-service-constraint-validation/kafka_service_constraint_validation.out",
    "content": "$ bal run kafka_service_constraint_validation.bal\ntime = 2022-11-28T13:56:56.502+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\nerror: Failed to validate payload. {\"partition\":{\"topic\":\"order-topic-4\",\"partition\":0},\"offset\":10}\ncause: Validation failed for '$.productName:maxLength' constraint(s).\ntime = 2022-11-28T13:56:56.502+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/kafka-service-consume-message/kafka_service_consume_message.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/log;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener kafka:Listener orderListener = new (kafka:DEFAULT_URL, {\n    groupId: \"order-group-id\",\n    topics: \"order-topic\"\n});\n\nservice on orderListener {\n\n    remote function onConsumerRecord(Order[] orders) {\n        // The set of orders received by the service are processed one by one.\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                log:printInfo(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-service-consume-message/kafka_service_consume_message.md",
    "content": "# Kafka service - Consume message\n\nThe `kafka:Service` connects to a given Kafka server via the `kafka:Listener`, and allows to directly bind Kafka messages to subtypes of `anydata`. It does this by using the built-in bytes deserializer for both the key and the value. To use this, provide the required payload type as the argument type to the `onConsumerRecord` method, which is a subtype of `anydata[]`. When new messages are received, the `onConsumerRecord` method gets invoked. If the payload does not match the defined type, a `kafka:PayloadBindingError` will be logged to the console and the `kafka:Listener` will be automatically seeked to the next record. This behaviour can be changed by setting `autoSeekOnValidationFailure` configuration to `false`. Then the `onError` remote method will be invoked with the related error to be handled as needed. Use this to listen to a set of topics in a Kafka server and receive messages implicitly.\n\n::: code kafka_service_consume_message.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_service_consume_message.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:Listener` client object - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#Listener)\n- [Kafka service - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#432-usage)\n"
  },
  {
    "path": "examples/kafka-service-consume-message/kafka_service_consume_message.metatags",
    "content": "description: This example demonstrates creating a Kafka service to receive messages in an asynchronous manner.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, listener, service, asynchronous\n"
  },
  {
    "path": "examples/kafka-service-consume-message/kafka_service_consume_message.out",
    "content": "$ bal run kafka_service.bal\ntime = 2022-11-25T14:55:59.366+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/kafka-service-error-handling/kafka_service_error_handling.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/log;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n    int quantity;\n};\n\nlistener kafka:Listener orderListener = new (kafka:DEFAULT_URL, {\n    groupId: \"order-group-id\",\n    topics: \"order-topic\",\n    autoSeekOnValidationFailure: false\n});\n\nservice on orderListener {\n\n    remote function onConsumerRecord(Order[] orders) {\n        // The set of orders received by the service are processed one by one.\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                log:printInfo(string `Received valid order for ${'order.productName}`);\n            };\n    }\n\n    // When an error occurs before the `onConsumerRecord` gets invoked,\n    // `onError` function will get invoked.\n    remote function onError(kafka:Error 'error, kafka:Caller caller) returns error? {\n        // Check whether the `error` is a `kafka:PayloadBindingError` or a `kafka:PayloadValidationError`\n        // and seek past the erroneous record.\n        if 'error is kafka:PayloadBindingError || 'error is kafka:PayloadValidationError {\n            log:printError(\"Payload error occured\", 'error);\n            // The `kafka:PartitionOffset` related to the erroneous record is provided inside\n            // the `kafka:PayloadBindingError`/`kafka:PayloadValidationError`.\n            check caller->seek({\n                partition: 'error.detail().partition,\n                offset: 'error.detail().offset + 1\n            });\n        } else {\n            log:printError(\"An error occured\", 'error);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/kafka-service-error-handling/kafka_service_error_handling.md",
    "content": "# Kafka service - Error handling\n\nThe `kafka:Service` has an `onError` method which is invoked when `kafka:Listener` triggers errors before the `onConsumerRecord` method is invoked. These errors could include payload binding errors or constraint validation errors. In the default behaviour, `kafka:PayloadBindingError`s and `kafka:PayloadValidationError`s are logged to the console and automatically seeked to fetch the next record. To pass these errors to the `onError` method, `autoSeekOnValidationFailure` configuration can be set to `false`. The `onError` method allows the user to handle these errors as needed. If there is no `onError` method in the `kafka:Service`, these are logged to the console with the stack-trace. In addition, `kafka:Service` allows returning errors from the `onConsumerRecord` method. These errors are also logged to the console and the next polling cycle will continue.\n\n::: code kafka_service_error_handling.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance.\n\nRun the program by executing the following command.\n\n::: out kafka_service_error_handling.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - Produce message](/learn/by-example/kafka-producer-produce-message) example to produce some messages to the topic.\n\n## Related links\n- [`kafka` module - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest)\n- [Kafka service - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#432-usage)\n"
  },
  {
    "path": "examples/kafka-service-error-handling/kafka_service_error_handling.metatags",
    "content": "description: This example demonstrates error handling in Kafka services.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, service, asynchronous, error handling\n"
  },
  {
    "path": "examples/kafka-service-error-handling/kafka_service_error_handling.out",
    "content": "$ bal run kafka_service.bal\ntime = 2023-01-05T12:08:23.938+05:30 level = ERROR module = \"\" message = \"Payload error occured\" error = \"Data binding failed. If needed, please seek past the record to continue consumption.\"\n"
  },
  {
    "path": "examples/kafka-service-sasl/kafka_service_sasl.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/log;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener kafka:Listener orderListener = new (\"localhost:9093\", {\n    groupId: \"order-group-id\",\n    // Subscribes to the topic `test-kafka-topic`.\n    topics: [\"order-topic\"],\n    // Provide the relevant authentication configurations to authenticate the consumer\n    // by the `kafka:AuthenticationConfiguration`.\n    auth: {\n        // Provide the authentication mechanism used by the Kafka server.\n        mechanism: kafka:AUTH_SASL_PLAIN,\n        // Username and password should be set here in order to authenticate the consumer.\n        username: \"alice\",\n        password: \"alice@123\"\n    },\n    securityProtocol: kafka:PROTOCOL_SASL_PLAINTEXT\n});\n\nservice on orderListener {\n\n    remote function onConsumerRecord(Order[] orders) {\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                log:printInfo(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-service-sasl/kafka_service_sasl.md",
    "content": "# Kafka service - SASL authentication\n\nThe `kafka:Service` receives messages from the Kafka server using the `kafka:Listener` via SASL/PLAIN authentication. SASL/PLAIN authentication can be enabled by configuring the `auth`, which requires the authentication mechanism, username, and password. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SASL_PLAINTEXT`. Use this to connect to a Kafka server secured with SASL/PLAIN.\n\n::: code kafka_service_sasl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use the [SASL/PLAIN authentication mechanism](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_plain.html#sasl-plain-overview).\n\nRun the program by executing the following command.\n\n::: out kafka_service_sasl.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - SASL authentication](/learn/by-example/kafka-producer-sasl) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:AuthenticationConfiguration` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#AuthenticationConfiguration)\n- [Kafka service SASL authentication - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#4312-secure-listener)\n"
  },
  {
    "path": "examples/kafka-service-sasl/kafka_service_sasl.metatags",
    "content": "description: This example is on how to configure a Kafka listener to use SASL/PLAIN authentication.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, listener, service, asynchronous\n"
  },
  {
    "path": "examples/kafka-service-sasl/kafka_service_sasl.out",
    "content": "$ bal run kafka_service_sasl.bal\ntime = 2022-11-25T14:55:59.366+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/kafka-service-ssl/kafka_service_ssl.bal",
    "content": "import ballerinax/kafka;\nimport ballerina/log;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener kafka:Listener orderListener = new (\"localhost:9094\", {\n    groupId: \"order-group-id\",\n    topics: \"order-topic\",\n    // Provide the relevant secure socket configurations by using `kafka:SecureSocket`.\n    secureSocket: {\n        cert: \"./resources/path/to/public.crt\",\n        protocol: {\n            // Provide the relevant security protocol.\n            name: kafka:SSL\n        }\n    },\n    // Provide the type of the security protocol to use in the broker connection.\n    securityProtocol: kafka:PROTOCOL_SSL\n});\n\nservice on orderListener {\n\n    remote function onConsumerRecord(Order[] orders) {\n        from Order 'order in orders\n            where 'order.isValid\n            do {\n                log:printInfo(string `Received valid order for ${'order.productName}`);\n            };\n    }\n}\n"
  },
  {
    "path": "examples/kafka-service-ssl/kafka_service_ssl.md",
    "content": "# Kafka service - SSL/TLS\n\nThe `kafka:Service` receives messages from the Kafka server using the `kafka:Listener` via SSL/TLS. SSL/TLS can be enabled by configuring the `secureSocket`, which requires a certificate and the protocol name. Further, the mode of security must be configured by setting the `securityProtocol` to `kafka:PROTOCOL_SSL`. Use this to connect to a Kafka server secured with SSL.\n\n::: code kafka_service_ssl.bal :::\n\n## Prerequisites\n- Start a [Kafka broker](https://kafka.apache.org/quickstart) instance configured to use [SSL/TLS](https://docs.confluent.io/3.0.0/kafka/ssl.html#configuring-kafka-brokers).\n\nRun the program by executing the following command.\n\n::: out kafka_service_ssl.out :::\n\n>**Tip:** Run the Kafka client given in the [Kafka producer - SSL/TLS](/learn/by-example/kafka-producer-ssl) example to produce some messages to the topic.\n\n## Related links\n- [`kafka:SecureSocket` record - API documentation](https://lib.ballerina.io/ballerinax/kafka/latest#SecureSocket)\n- [Kafka secure service - Specification](https://github.com/ballerina-platform/module-ballerinax-kafka/blob/master/docs/spec/spec.md#4312-secure-listener)\n"
  },
  {
    "path": "examples/kafka-service-ssl/kafka_service_ssl.metatags",
    "content": "description: This example is on how to configure a Kafka listener to use SSL encryption.\nkeywords: ballerina, ballerina by example, bbe, kafka, consumer, listener, service, asynchronous\n"
  },
  {
    "path": "examples/kafka-service-ssl/kafka_service_ssl.out",
    "content": "$ bal run kafka_service_ssl.bal\ntime = 2022-11-25T14:55:59.366+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/kubernetes-hello-world/Cloud.toml",
    "content": "[container.image]\nrepository=\"wso2inc\"\nname=\"hello\"\ntag=\"v0.1.0\"\n"
  },
  {
    "path": "examples/kubernetes-hello-world/build_output.out",
    "content": "$ bal build --cloud=\"k8s\"\n\nCompiling source\n        wso2/hello:0.1.0\n\nGenerating executable\n\nGenerating artifacts...\n\n        @kubernetes:Service                      - complete 1/1\n        @kubernetes:Deployment                   - complete 1/1\n        @kubernetes:HPA                          - complete 1/1\n        @kubernetes:Docker                       - complete 2/2 \n\n        Execute the below command to deploy the Kubernetes artifacts: \n        kubectl apply -f /home/anjana/bbe-make/k8s/target/kubernetes/hello\n\n        Execute the below command to access service via NodePort: \n        kubectl expose deployment hello-deployment --type=NodePort --name=hello-svc-local\n"
  },
  {
    "path": "examples/kubernetes-hello-world/docker_push.out",
    "content": "$ docker push wso2inc/hello:v0.1.0\n"
  },
  {
    "path": "examples/kubernetes-hello-world/execute_curl.out",
    "content": "$ curl http://192.168.49.2:31360/helloWorld/sayHello\nHello from Kubernetes!\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubectl_apply.out",
    "content": "$ kubectl apply -f /home/wso2/project/target/kubernetes/hello-0.1.0\nservice/helloep-svc created\ndeployment.apps/wso2-hello-0--deployment created\nhorizontalpodautoscaler.autoscaling/wso2-hello-0--hpa created\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubectl_expose.out",
    "content": "$ kubectl expose deployment hello-deployment --type=NodePort --name=hello-svc-local\nservice/hello-svc-local exposed\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubectl_pods.out",
    "content": "$ kubectl get pods\nNAME                                          READY   STATUS    RESTARTS   AGE\nwso2-hello-0--deployment-7d4d56457b-7jlzx       1/1     Running   0          57s\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubectl_svc.out",
    "content": "$ kubectl get svc\nNAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE\nhello-svc               ClusterIP       10.97.140.84        <none>        9090/TCP         13m\nhello-svc-local         NodePort        10.108.87.21        <none>        9090:31360/TCP   2m18s\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubernetes_hello_world.bal",
    "content": "import ballerina/http;\n\n// This code is completely focused on the business logic and it does not depend on the deployment.\n\nlistener http:Listener helloEP = new(9090);\n\nservice http:Service /helloWorld on helloEP {\n    resource function get sayHello() returns string {\n        return \"Hello from Kubernetes!\";\n    }\n}\n"
  },
  {
    "path": "examples/kubernetes-hello-world/kubernetes_hello_world.md",
    "content": "# Kubernetes - Hello world\n\nBallerina supports generating Kubernetes artifacts from code without any additional configuration. This simplifies the experience of developing and deploying Ballerina code in the cloud. Code to Cloud builds the containers and required artifacts by deriving the required values from the code. If you want to override the default values taken by the compiler, you can use a `Cloud.toml` file.\nFor more information, see [Code to Cloud deployment](/learn/code-to-cloud-deployment/).\n\n::: code kubernetes_hello_world.bal :::\n\nBefore you build the package, you need to override some default values taken by the compiler. To do this, create a filed named `Cloud.toml` in the package directory, and add the content below to it.\nFor all the supported key value properties, see [Code to Cloud Specification](https://github.com/ballerina-platform/ballerina-spec/blob/master/c2c/code-to-cloud-spec.md).\n\n::: code Cloud.toml :::\n\nExecute the `bal build` command to build the Ballerina package. Code to Cloud generates only one container per package.\n>**Note:** macOS users with Apple Silicon chips need to set an environment variable named `DOCKER_DEFAULT_PLATFORM` to `linux/amd64`, before building the image. This is because the Ballerina Docker image is not supported on Apple Silicon chips yet. Run `export DOCKER_DEFAULT_PLATFORM=linux/amd64` to set the environment variable.\n\n::: out build_output.out :::\n\nPush the created Docker image to Docker Hub.\n::: out docker_push.out :::\n\nCreate the deployment using the Kubernetes artifacts.\n::: out kubectl_apply.out :::\n\nVerify the Kubernetes pods.\n::: out kubectl_pods.out :::\n\nExpose via NodePort to test in the developer environment.\n::: out kubectl_expose.out :::\n\nGet the External IP and port of the Kubernetes service.\n::: out kubectl_svc.out :::\n\nIf the External IP of the `hello-svc-local` service is `<none>`, you need to follow cluster-specific steps to obtain the external IP. If you are using Minikube, you can use the `minikube ip` command to obtain the IP.\n::: out minikube_ip.out :::\n\nAccess the deployed service via cURL.\n::: out execute_curl.out :::\n"
  },
  {
    "path": "examples/kubernetes-hello-world/minikube_ip.out",
    "content": "$ minikube ip\n192.168.49.2\n"
  },
  {
    "path": "examples/langlib-functions/langlib_functions.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // You can call langlib functions using the method-call syntax.\n    string str = \"abc\".substring(1, 2);\n\n    // `len` will be 1.\n    int len = str.length();\n    io:println(len);\n\n    // `str.length()` is same as `string:length(str)`.\n    len = string:length(str);\n    io:println(len);\n\n    int val = 123;\n    // The `lang.value` module provides functions that work on values of more than one basic type.\n    // `val.toString()` performs a direct conversion of `val` to string.\n    io:println(\"value is \" + val.toString());\n\n    // `val.ensureType()` safely casts a value to a type and\n    // returns an error if the cast is impossible.\n    float|error floatVal = val.ensureType(float);\n    io:println(floatVal);\n\n    int[] evenNumbers = [2, 4, 6 ,8, 10, 12];\n\n    // `value.clone()` returns a clone of a value.\n    int[] clonedEvenNumbers = [2, 4, 6 ,8, 10, 12].clone();\n    // Following statement is `true`.\n    io:println(evenNumbers == clonedEvenNumbers);\n    // Following statement is `false`.\n    io:println(evenNumbers === clonedEvenNumbers);\n\n    // `value.cloneReadOnly()` returns a clone of a value that is read-only.\n    int[] & readonly immutableEvenNumbers = evenNumbers.cloneReadOnly();\n    io:println(immutableEvenNumbers);\n\n    // `value.cloneWithType()` constructs a value with a specified type by cloning another value.\n    float clonedVal = check val.cloneWithType(float);\n    // Following statement is `true`.\n    io:println(clonedVal);\n}\n"
  },
  {
    "path": "examples/langlib-functions/langlib_functions.md",
    "content": "# Langlib functions\n\nLanglib is a library defined by the language providing fundamental operations on built-in data types. Langlib functions can be called using the method-call syntax but these types are not objects.\n\nThere exists a `ballerina/lang.T` module for each built-in type `T` and they are automatically imported using the `T` prefix only if `T` corresponds to a keyword.\n\nThe `lang.value` module provides functions that work on values of more than one basic type.\n\n::: code langlib_functions.bal :::\n\n::: out langlib_functions.out :::\n"
  },
  {
    "path": "examples/langlib-functions/langlib_functions.metatags",
    "content": "description: This BBE introduces Langlib modules in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, langlib, module, Language, Library\n"
  },
  {
    "path": "examples/langlib-functions/langlib_functions.out",
    "content": "$ bal run langlib_functions.bal\n1\n1\nvalue is 123\n123.0\ntrue\nfalse\n[2,4,6,8,10,12]\n123.0\n"
  },
  {
    "path": "examples/ldap-add-remove-entry/ldap_add_remove_entry.bal",
    "content": "import ballerina/io;\nimport ballerina/ldap;\n\npublic function main() returns error? {\n    // Initializes a new LDAP client with credentials.\n    ldap:Client ldapClient = check new (\n        hostName = \"localhost\",\n        port = 389,\n        domainName = \"cn=admin,dc=example,dc=com\",\n        password = \"adminpassword\"\n    );\n\n    // Creates an `ldap:Entry` record for the new entry.\n    ldap:Entry addEntry = {\n        \"objectClass\": [\"top\", \"person\"],\n        \"sn\": \"user\",\n        \"cn\": \"user\"\n    };\n\n    // Adds an entry to the directory server.\n    ldap:LdapResponse addResponse = check ldapClient->add(\"cn=user,dc=example,dc=com\", addEntry);\n    io:println(\"Add Response: \", addResponse.resultCode);\n\n    // Deletes an entry from the directory server.\n    ldap:LdapResponse deleteResponse = check ldapClient->delete(\"cn=user,dc=example,dc=com\");\n    io:println(\"Delete Response: \", deleteResponse.resultCode);\n}\n"
  },
  {
    "path": "examples/ldap-add-remove-entry/ldap_add_remove_entry.md",
    "content": "# LDAP client - Add/Remove entries\n\nThe `ldap:Client` connects to a directory server and performs various operations on directories. Currently, it supports the generic LDAP operations; `add`, `modify`, `modifyDN`, `compare`, `search`, `searchWithType`, `delete`, and `close`.\n\nThe `add` operation creates a new entry in a directory server. It requires a `DN` (Distinguished Name) for the entry and the attributes to be included. The `objectClass` attribute must be specified to define the object classes for the entry, and any attributes required by these object classes should also be included.\n\nThe `delete` operation removes an entry from a directory server. It requires a `DN` (Distinguished Name) of the entry to be deleted.\n\n::: code ldap_add_remove_entry.bal :::\n\n## Prerequisites\n- Ensure that an LDAP server is up and running locally on port 389 while running the example.\n\n- Run the example by executing the command below.\n\n::: out ldap_add_remove_entry.server.out :::\n\n## Related links\n- [`ldap:Client` `add` operation - API documentation](https://central.ballerina.io/ballerina/ldap/latest#Client-add)\n- [`ldap:Client` `delete` operation - API documentation](https://central.ballerina.io/ballerina/ldap/latest#Client-delete)\n- [`ldap` module - API documentation](https://lib.ballerina.io/ballerina/ldap/latest/)\n- [`ldap:Client` - Specification](/spec/ldap/#2-ldap-client)\n"
  },
  {
    "path": "examples/ldap-add-remove-entry/ldap_add_remove_entry.metatags",
    "content": "description: This example is on how to create/delete entries in a directory server using LDAP in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, ldap, add\n"
  },
  {
    "path": "examples/ldap-add-remove-entry/ldap_add_remove_entry.server.out",
    "content": "$ bal run ldap_add_remove_entry.bal\nAdd Response: SUCCESS\nDelete Response: SUCCESS\n"
  },
  {
    "path": "examples/ldap-search-entry/ldap_search_entry.bal",
    "content": "import ballerina/io;\nimport ballerina/ldap;\n\npublic function main() returns error? {\n    // Initializes a new LDAP client with credentials.\n    ldap:Client ldapClient = check new (\n        hostName = \"localhost\",\n        port = 389,\n        domainName = \"cn=admin,dc=example,dc=com\",\n        password = \"adminpassword\"\n    );\n\n    // Searches for an entry in the directory server.\n    ldap:SearchResult searchResult = check ldapClient->search(\n        \"cn=user,dc=example,dc=com\",\n        \"(sn=user)\",\n        ldap:SUB\n    );\n    io:println(\"Search Response: \", searchResult.resultCode);\n}\n"
  },
  {
    "path": "examples/ldap-search-entry/ldap_search_entry.md",
    "content": "# LDAP client - Seacrh for an entry\n\nThe `ldap:Client` connects to a directory server and performs various operations on directories. Currently, it supports the main LDAP operations; `add`, `modify`, `modifyDN`, `compare`, `search`, `searchWithType`, `delete`, and `close`.\n\nThe `search` operation is used to retrieve entries that match specified criteria. The components of an LDAP search request include:\n\n- `baseDN`: Defines the base of the subtree for the search.\n- `filter`: Specifies the criteria that entries must meet.\n- `scope`: Determines extent of the the search coverage within the subtree.\n\nWhen a directory server processes a valid search request, it finds entries within the defined scope that meet the filter criteria. The matching entries are then returned to the client in a `ldap:SearchResult` record.\n\n::: code ldap_search_entry.bal :::\n\n## Prerequisites\n- Ensure that an LDAP server is up and running locally on port 389 while running the example.\n\n- Run the example by executing the command below.\n\n::: out ldap_search_entry.server.out :::\n\n## Related links\n- [`ldap:Client` `search` operation - API documentation](https://central.ballerina.io/ballerina/ldap/latest#Client-search)\n- [`ldap` module - API documentation](https://lib.ballerina.io/ballerina/ldap/latest/)\n- [`ldap:Client` - Specification](/spec/ldap/#2-ldap-client)\n"
  },
  {
    "path": "examples/ldap-search-entry/ldap_search_entry.metatags",
    "content": "description: This example is on how to search for an entry in a directory server using LDAP in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, ldap, search\n"
  },
  {
    "path": "examples/ldap-search-entry/ldap_search_entry.server.out",
    "content": "$ bal run ldap_search_entry.bal\nSearch Response: SUCCESS\n"
  },
  {
    "path": "examples/let-clause/let_clause.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    string first;\n    string last;\n    int mathematics;\n    int english;\n|};\n\npublic function main() {\n    Student[] students = [\n        {first: \"Melina\", last: \"Kodel\", mathematics: 79, english: 83},\n        {first: \"Tom\", last: \"Riddle\", mathematics: 69, english: 45}\n    ];\n\n    int[] names = from var student in students\n                  // The `let` clause binds the variables.\n                  let int sum = (student.mathematics + student.english)\n                  where sum > 0\n                  let int avg = sum / 2\n                  select avg;\n\n    io:println(names);\n\n    // The `let` clause supports multiple variable declarations separated by `,`.\n    names = from var student in students\n                   let int sum = (student.mathematics + student.english), int avg = sum / 2\n                   where sum > 0\n                   select avg;\n\n    io:println(names);\n}\n"
  },
  {
    "path": "examples/let-clause/let_clause.md",
    "content": "# `let` clause\n\nThe `let` clause can be used to define temporary variables inside a query expression. It can occur multiple times anywhere between the `from` and `select` clauses. The semantics are similar to `XQuery FLWOR`.\n\n::: code let_clause.bal :::\n\n::: out let_clause.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/let-clause/let_clause.metatags",
    "content": "description: This BBE demonstrates the `let` clause in Ballerina, defining temporary variables inside a query expression, and defining support variables inside a query expression.\nkeywords: ballerina, ballerina by example, bbe, let clause, query, query expression, where, condition\n"
  },
  {
    "path": "examples/let-clause/let_clause.out",
    "content": "$ bal run let_clause.bal\n[81,57]\n[81,57]\n"
  },
  {
    "path": "examples/limit-clause/limit_clause.bal",
    "content": "import ballerina/io;\n\ntype Employee record {\n    string firstName;\n    string lastName;\n    decimal salary;\n};\n\npublic function main() {\n    Employee[] employees = [\n        {firstName: \"Jones\", lastName: \"Welsh\", salary: 1000.00},\n        {firstName: \"Anne\", lastName: \"Frank\", salary: 5000.00},\n        {firstName: \"Michael\", lastName: \"Cain\", salary: 10000.00},\n        {firstName: \"Tom\", lastName: \"Hiddleston\", salary: 2000.00}\n    ];\n\n    Employee[] top3 = from var e in employees\n                      order by e.salary descending\n                      // The `limit` clause limits the number of output items to 3.\n                      limit 3\n                      select e;\n\n    foreach var emp in top3 {\n        io:println(emp);\n    }\n}\n"
  },
  {
    "path": "examples/limit-clause/limit_clause.md",
    "content": "# `limit` clause\n\nThe `limit` clause limits the number of results from the earlier clauses.\n\n::: code limit_clause.bal :::\n\n::: out limit_clause.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)"
  },
  {
    "path": "examples/limit-clause/limit_clause.metatags",
    "content": "description: This BBE demonstrates the `limit` clause in Ballerina, selecting the top `n` elements in a collection, limiting the results to a given number, and selecting a set of elements in a collection.\nkeywords: ballerina, ballerina by example, bbe, limit clause, query, query expression, limit, collection, filter\n"
  },
  {
    "path": "examples/limit-clause/limit_clause.out",
    "content": "$ bal run limit_clause.bal\n{\"firstName\":\"Michael\",\"lastName\":\"Cain\",\"salary\":10000.00}\n{\"firstName\":\"Anne\",\"lastName\":\"Frank\",\"salary\":5000.00}\n{\"firstName\":\"Tom\",\"lastName\":\"Hiddleston\",\"salary\":2000.00}\n"
  },
  {
    "path": "examples/list-binding-pattern/list_binding_pattern.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n\n    // This will create 2 variables named `id` and `firstname` with the types\n    // `int` and `string`. The string value `\"Doe\"` returned from `getDetails()` \n    // is ignored using `_`.\n    [int, [string, string]] [id, [firstname, _]] = getDetails();\n\n    io:println(id);\n    io:println(firstname);\n}\n\nfunction getDetails() returns [int, [string, string]] {\n    return [1234, [\"John\", \"Doe\"]];\n}\n"
  },
  {
    "path": "examples/list-binding-pattern/list_binding_pattern.md",
    "content": "# List binding pattern\n\nA list binding pattern binds members of a list to variables. It can contain more than one binding pattern. The list binding pattern can be employed with both tuples and arrays.\n\n::: code list_binding_pattern.bal :::\n\n::: out list_binding_pattern.out :::\n\n## Related links\n- [Rest binding pattern in list binding pattern](/learn/by-example/rest-binding-pattern-in-list-binding-pattern/)\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Arrays](/learn/by-example/arrays/)\n- [Tuples](/learn/by-example/tuples/)"
  },
  {
    "path": "examples/list-binding-pattern/list_binding_pattern.metatags",
    "content": "description: This BBE introduces the use of the list binding pattern to bind members of a list, array, or tuple using more than one binding pattern and destructuring a list.\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, list binding pattern, array destructuring, list destructuring, tuple destructuring\n"
  },
  {
    "path": "examples/list-binding-pattern/list_binding_pattern.out",
    "content": "$ bal run list_binding_pattern.bal\n1234\nJohn\n"
  },
  {
    "path": "examples/list-binding-pattern-in-match-statement/list_binding_pattern_in_match_statement.bal",
    "content": "import ballerina/io;\n\nfunction matchCommand(any commands) {\n    match commands {\n        var [show] => {\n            io:println(show);\n        }\n        // The list binding pattern below binds lists that contain three list items\n        // where the third element in the list is the boolean value `true`.\n        var [remove, all, isDir] if isDir is true => {\n            io:println(remove, \" directories \", all);\n        }\n        // The list binding pattern below binds lists that contain three list items.\n        var [remove, all, _] => {\n            io:println(remove, \" files \", all);\n        }\n        // The list binding pattern below binds lists that contain two list items,\n        // in which the second list item is also a list of two items.\n        var [copy, [file1, file2]] => {\n            io:println(copy, \" \", file1, \" into \", file2);\n        }\n        _ => {\n            io:println(\"Unrecognized command.\");\n        }\n    }\n}\n\n\npublic function main() {\n    matchCommand([\"Show\"]);\n    matchCommand([\"Remove\", \"*\", true]);\n    matchCommand([\"Remove\", \"f.txt\", false]);\n    matchCommand([\"Copy\", [\"a.bal\", \"b.bal\"]]);\n    matchCommand(1);\n}\n"
  },
  {
    "path": "examples/list-binding-pattern-in-match-statement/list_binding_pattern_in_match_statement.md",
    "content": "# List binding pattern in match statement\n\nList binding patterns can be used in a match statement to bind parts of successfully matched list items to variables. The rest binding pattern (`...r`) can be used in the list binding pattern to bind the list items that are not explicitly bound in the mapping binding pattern.\n\n::: code list_binding_pattern_in_match_statement.bal :::\n\n::: out list_binding_pattern_in_match_statement.out :::\n\n## Related links\n- [List binding pattern](/learn/by-example/list-binding-pattern/)\n- [Rest binding pattern in list binding pattern](/learn/by-example/rest-binding-pattern-in-list-binding-pattern/)\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Match statement](/learn/by-example/match-statement/)"
  },
  {
    "path": "examples/list-binding-pattern-in-match-statement/list_binding_pattern_in_match_statement.metatags",
    "content": "description: This BBE introduces the use of a list binding pattern to match the list items in a match statement.\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, list binding pattern, match statement, list binding pattern in match statement\n"
  },
  {
    "path": "examples/list-binding-pattern-in-match-statement/list_binding_pattern_in_match_statement.out",
    "content": "$ bal run list_binding_pattern_in_match_statement.bal\nShow\nRemove directories *\nRemove files f.txt\nCopy a.bal into b.bal\nUnrecognized command.\n"
  },
  {
    "path": "examples/list-equality/list_equality.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int[] a = [1];\n    int[1] b = [1];\n    // Output will be `true` as the values are the same.\n    io:println(a == b);\n    \n    // Output will be `false` as the references are different.\n    io:println(a === b);\n    \n    // Output will be `true` as the references are the same.\n    io:println(a === a);\n    \n    // This will assign the reference `a` to `c`.\n    int[] c = a;\n    // Output will be `true` as the references are the same.\n    io:println(a === c);\n\n    string[3][2] orderItems = [[\"carrot\", \"apple\"], [\"avacado\", \"egg\"], [\"fish\", \"banana\"]];\n    string[3][2] orderItems2 = [[\"carrot\", \"apple\"], [\"avacado\", \"egg\"], [\"fish\", \"banana\"]];\n    // Output will be `true` as the order items are the same.\n    io:println(orderItems == orderItems2);\n    \n    // Output will be `false` as the order items are the same.\n    io:println(orderItems != orderItems2);\n    \n    // Output will be `true` as the references are different.\n    io:println(orderItems !== orderItems2);\n\n    string[3][2] orderItems3 = [[\"avacado\", \"egg\"], [\"carrot\", \"apple\"], [\"fish\", \"banana\"]];\n    // Output will be `false` as the order of the items are different.\n    io:println(orderItems == orderItems3);\n}\n"
  },
  {
    "path": "examples/list-equality/list_equality.md",
    "content": "# List equality\n\nYou can use `==` and `!=` on lists to check the deep equality of two lists: two lists are deep equal if they have the same members in the same order. Deep equality only works for `anydata` lists. `===` and `!==` check for the exact equality, which matches the references of the lists.\n\n::: code list_equality.bal :::\n\n::: out list_equality.out :::\n\n## Related links\n- [Tuples](/learn/by-example/tuples)\n- [Arrays](/learn/by-example/arrays)\n- [Expression equality](/learn/by-example/expression-equality)\n- [List sub typing](/learn/by-example/list-subtyping)\n"
  },
  {
    "path": "examples/list-equality/list_equality.metatags",
    "content": "description: Check two list  are equal, check two collections are equal, check two lists have the same members, Check two list are the same reference, Compare two lists\nkeywords: ballerina, ballerina by example, bbe, ==, !=, ===, !==, equality, array, deep, exact\n"
  },
  {
    "path": "examples/list-equality/list_equality.out",
    "content": "$ bal run list_equality.bal\ntrue\nfalse\ntrue\ntrue\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "examples/list-subtyping/list_subtyping.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int[3] numbers = [144, 232, 322];\n    // `numbers`, of type `int[3]`, will be a subtype of `int[]`\n    // since `T[n]` is a subtype of `T[]`\n    io:println(numbers is int[]);\n\n    byte[3] numbers2 = [1, 2, 3];\n    // `numbers2`, of type byte[3], will be a subtype of `int[3]`\n    // since `byte` is a subtype of `int` and lengths are the same\n    io:println(numbers2 is int[3]);\n    \n    // `numbers2`, of type byte[3], will be a subtype of `int[]`\n    // since `byte` is a subtype of `int` and `T[n]` is a subtype of `T[]`\n    io:println(numbers2 is int[]);\n\n    [byte, string] person = [1, \"Mike\"];\n    // `[byte, string]` is a subtype of `[int, anydata]`\n    io:println(person is [int, anydata]);\n    \n    // `[byte, string]` is a subtype of `[int, anydata...]`\n    io:println(person is [int, anydata...]);\n    \n    // `int[3]` is a subtype of `[int, anydata...]`\n    io:println(numbers is [int, anydata...]);\n}\n"
  },
  {
    "path": "examples/list-subtyping/list_subtyping.md",
    "content": "# List subtyping\n\nAn array with a length is a subtype of an array of same member type descriptor without a length. Two arrays with the same length or  without a length is a subtype of the other if the member type descriptor is a subtype of the other. Tuple type `T` is a subtype of  type `T1` if the set of values allowed in `T` is a sub set of values allowed in `T1`\n\n::: code list_subtyping.bal :::\n\n::: out list_subtyping.out :::\n\n## Related links\n- [Tuples](/learn/by-example/tuples)\n- [Arrays](/learn/by-example/arrays)\n- [List equality](/learn/by-example/list-equality)\n"
  },
  {
    "path": "examples/list-subtyping/list_subtyping.metatags",
    "content": "description: Check one list is a subset of another, Check one list can contains another list, Check one array is sub type of another\nkeywords: ballerina, ballerina by example, bbe, array, collection, tuple, sub type\n\n"
  },
  {
    "path": "examples/list-subtyping/list_subtyping.out",
    "content": "$ bal run list_subtyping.bal\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n"
  },
  {
    "path": "examples/lock-statement/lock_statement.bal",
    "content": "import ballerina/io;\n\nint n = 0;\n\nfunction inc() {\n    // Locks the global variable `n` and increments it by 1.\n    lock {\n        n += 1;\n    }\n\n    io:println(n);\n}\n\npublic function main() {\n    inc();\n}\n"
  },
  {
    "path": "examples/lock-statement/lock_statement.md",
    "content": "# Lock statement\n\nThe `lock` statement allows mutable state to be safely accessed from multiple strands that are running on separate threads. Semantics are like an atomic section. The execution of the outermost `lock` block is not interleaved. Naive implementation uses single, global, recursive lock. Efficient implementation can do compile-time lock inference.\n\n::: code lock_statement.bal :::\n\nExecuting the above code gives the output below.\n\n::: out lock_statement.out :::"
  },
  {
    "path": "examples/lock-statement/lock_statement.metatags",
    "content": "description: This BBE introduces lock statement in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, lock statement\n"
  },
  {
    "path": "examples/lock-statement/lock_statement.out",
    "content": "$ bal run lock_statement.bal\n1\n"
  },
  {
    "path": "examples/log-file-rotation/app_log_rotation.out",
    "content": "$ ls -la logs/\ntotal 16\ndrwxr-xr-x@ 4 wso2  staff   128 Jan  5 21:20 .\ndrwxr-xr-x@ 9 wso2  staff   288 Jan  5 21:20 ..\n-rw-r--r--@ 1 wso2  staff  2325 Jan  5 21:20 app-20260105-212048.log\n-rw-r--r--@ 1 wso2  staff   248 Jan  5 21:20 app.log\n\n$ cat logs/app-*.log\ntime=2026-01-05T21:20:42.771+05:30 level=INFO module=\"\" message=\"Starting log rotation demonstration\"\ntime=2026-01-05T21:20:42.801+05:30 level=INFO module=\"\" message=\"Application started\" version=\"1.0.0\"\ntime=2026-01-05T21:20:42.804+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req1\" endpoint=\"/api/users\" responseTime=126\ntime=2026-01-05T21:20:42.806+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req2\" endpoint=\"/api/users\" responseTime=127\ntime=2026-01-05T21:20:42.808+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req3\" endpoint=\"/api/users\" responseTime=128\ntime=2026-01-05T21:20:42.810+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req4\" endpoint=\"/api/users\" responseTime=129\ntime=2026-01-05T21:20:42.811+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req5\" endpoint=\"/api/users\" responseTime=130\ntime=2026-01-05T21:20:44.815+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req6\" endpoint=\"/api/users\" responseTime=131\ntime=2026-01-05T21:20:44.816+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req7\" endpoint=\"/api/users\" responseTime=132\ntime=2026-01-05T21:20:44.818+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req8\" endpoint=\"/api/users\" responseTime=133\ntime=2026-01-05T21:20:44.819+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req9\" endpoint=\"/api/users\" responseTime=134\ntime=2026-01-05T21:20:44.820+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req10\" endpoint=\"/api/users\" responseTime=135\ntime=2026-01-05T21:20:46.823+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req11\" endpoint=\"/api/users\" responseTime=136\ntime=2026-01-05T21:20:46.824+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req12\" endpoint=\"/api/users\" responseTime=137\ntime=2026-01-05T21:20:46.825+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req13\" endpoint=\"/api/users\" responseTime=138\ntime=2026-01-05T21:20:46.826+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req14\" endpoint=\"/api/users\" responseTime=139\ntime=2026-01-05T21:20:46.827+05:30 level=INFO module=\"\" message=\"Processing request\" requestId=\"req15\" endpoint=\"/api/users\" responseTime=140\n"
  },
  {
    "path": "examples/log-file-rotation/log_file_rotation.bal",
    "content": "import ballerina/log;\nimport ballerina/lang.runtime;\n\npublic function main() {\n    // Root logger is configured in Config.toml with TIME_BASED rotation\n    // Logs will be written to ./logs/app.log\n    log:printInfo(\"Starting log rotation demonstration\");\n    log:printInfo(\"Application started\", version = \"1.0.0\");\n\n    foreach int i in 1...15 {\n        log:printInfo(\"Processing request\",\n            requestId = string `req${i}`,\n            endpoint = \"/api/users\",\n            responseTime = 125 + i);\n\n        if i % 5 == 0 {\n            // Sleep to demonstrate time-based rotation (5 second threshold)\n            runtime:sleep(2);\n        }\n    }\n\n    log:printInfo(\"Application processing completed\");\n    log:printInfo(\"Log rotation demonstration complete. Check ./logs directory for rotated log files.\");\n}\n"
  },
  {
    "path": "examples/log-file-rotation/log_file_rotation.md",
    "content": "# Log file rotation\n\nLog file rotation helps manage log file sizes by automatically creating backups when certain conditions are met, preventing disk space issues. This example demonstrates TIME_BASED rotation configured through `Config.toml`.\n\n## Configuring File Rotation\n\nThe root logger is configured in `Config.toml` with TIME_BASED rotation. All logs using the default logger will automatically benefit from this rotation policy.\n\n::: code Config.toml :::\n\n::: code log_file_rotation.bal :::\n\nRun the example to see rotation in action:\n\n::: out log_file_rotation.out :::\n\n## How Rotation Works\n\nWhen a log file rotates, it's renamed with a timestamp suffix and a new file is created:\n\n```\nlogs/\n  app.log                            (current log file)\n  app-20251223-225602.log            (rotated backup)\n  app-20251223-223015.log            (older backup)\n```\n\nOlder backups beyond `maxBackupFiles` are automatically deleted.\n\n### Application Log Rotation Output\n\n::: out app_log_rotation.out :::\n\n## Configuration Options\n\nRotation policies support these configuration parameters:\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| `policy` | `\"BOTH\"` | Rotation trigger: `\"SIZE_BASED\"`, `\"TIME_BASED\"`, or `\"BOTH\"` |\n| `maxFileSize` | 10485760 | Maximum file size in bytes (10MB default) |\n| `maxAge` | 86400 | Maximum file age in seconds (24 hours default) |\n| `maxBackupFiles` | 10 | Number of rotated backup files to retain |\n\n> **Note:** This example uses a small threshold (5 seconds) to make rotation observable during demonstration. In production, use realistic values such as `maxAge = 86400` (24 hours).\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#35-configure-log-rotation)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest/)\n"
  },
  {
    "path": "examples/log-file-rotation/log_file_rotation.metatags",
    "content": "description: BBE on how to configure log file rotation in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, log, rotation, file rotation, log management, size based, time based\n"
  },
  {
    "path": "examples/log-file-rotation/log_file_rotation.out",
    "content": "$ bal run log_file_rotation.bal\n"
  },
  {
    "path": "examples/logger-from-config/audit_logs.out",
    "content": "{\"time\":\"2026-01-05T21:22:17.164+05:30\", \"level\":\"INFO\", \"module\":\"\", \"message\":\"User action recorded\", \"action\":\"login\", \"userId\":\"alice123\", \"env\":\"prod\", \"nodeId\":\"server-001\", \"component\":\"audit\", \"compliance\":\"SOX\"}\n{\"time\":\"2026-01-05T21:22:17.176+05:30\", \"level\":\"INFO\", \"module\":\"\", \"message\":\"User action recorded\", \"action\":\"file_access\", \"userId\":\"bob456\", \"env\":\"prod\", \"nodeId\":\"server-001\", \"component\":\"audit\", \"compliance\":\"SOX\"}\n"
  },
  {
    "path": "examples/logger-from-config/logger_from_config.bal",
    "content": "import ballerina/log;\n\n// Define specialized logger configurations for different purposes\nfinal readonly & log:Config auditConfig = {\n    level: log:INFO,\n    format: log:JSON_FORMAT,\n    destinations: [{\n        path: \"./logs/audit.log\",\n        rotation: {\n            policy: log:SIZE_BASED,\n            maxFileSize: 10485760,  // 10MB\n            maxBackupFiles: 10\n        }\n    }],\n    keyValues: {\"component\": \"audit\", \"compliance\": \"SOX\"}\n};\n\nfinal readonly & log:Config metricsConfig = {\n    level: log:DEBUG,\n    format: log:LOGFMT,\n    destinations: [{\n        path: \"./logs/metrics.log\",\n        rotation: {\n            policy: log:TIME_BASED,\n            maxAge: 86400,  // 24 hours\n            maxBackupFiles: 7\n        }\n    }],\n    keyValues: {\"component\": \"metrics\", \"retention\": \"30days\"}\n};\n\nfunction processAuditEvent(string action, string userId) returns error? {\n    // Create audit logger from configuration\n    log:Logger auditLogger = check log:fromConfig(auditConfig);\n\n    // Audit logs automatically include the component and compliance context\n    auditLogger.printInfo(\"User action recorded\",\n                        action = action,\n                        userId = userId);\n}\n\nfunction recordMetrics(string metricName, decimal value, string unit) returns error? {\n    // Create metrics logger from configuration\n    log:Logger metricsLogger = check log:fromConfig(metricsConfig);\n\n    // Add operation-specific context to metrics logger\n    log:Logger operationLogger = check metricsLogger.withContext(operation = \"performance_monitoring\");\n\n    operationLogger.printDebug(\"Recording performance metric\");\n    operationLogger.printInfo(\"Performance metric recorded\",\n                            metric = metricName,\n                            value = value,\n                            unit = unit);\n}\n\npublic function main() returns error? {\n    // Regular application logs using root logger\n    log:printInfo(\"Application started\", version = \"1.2.0\");\n\n    // Use specialized loggers with unique configurations\n    check processAuditEvent(\"login\", \"alice123\");\n    check processAuditEvent(\"file_access\", \"bob456\");\n\n    check recordMetrics(\"response_time\", 245.5, \"ms\");\n    check recordMetrics(\"memory_usage\", 78.2, \"percent\");\n\n    log:printInfo(\"Application processing completed\");\n}\n"
  },
  {
    "path": "examples/logger-from-config/logger_from_config.md",
    "content": "# Logger from configuration\n\nThis example demonstrates how to create specialized loggers with unique configurations. Each logger can have its own format, destinations, log level, file rotation policy, and default context.\n\n::: code logger_from_config.bal :::\n\nThe example creates two specialized loggers:\n- **Audit logger**: Uses SIZE_BASED rotation (10MB file size limit) with JSON format\n- **Metrics logger**: Uses TIME_BASED rotation (24-hour age limit) with LOGFMT format\n\n> **Note:** All loggers created from the configuration automatically inherit the default context of the root logger.\n\n::: code Config.toml :::\n\nTerminal output:\n::: out logger_from_config.out :::\n\nAudit logs:\n::: out audit_logs.out :::\n\nMetrics logs:\n::: out metrics_logs.out :::\n\nNotice how each logger type produces different output but all share the default context. Each logger can also have its own rotation policy - the audit logger rotates based on file size (ideal for high-volume logs), while the metrics logger rotates based on time (ideal for daily rollover). This pattern is ideal for applications that need different logging behaviors for different concerns (audit trails, performance monitoring, security events, etc.).\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#432-loggers-with-unique-logging-configuration)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/logger-from-config/logger_from_config.metatags",
    "content": "description: BBE on how to create specialized loggers with unique configurations.\nkeywords: ballerina, ballerina by examples, bbe, log, fromConfig, configuration, specialized logger\n"
  },
  {
    "path": "examples/logger-from-config/logger_from_config.out",
    "content": "$ bal run logger_from_config.bal\n\ntime=2026-01-05T21:22:17.128+05:30 level=INFO module=\"\" message=\"Application started\" version=\"1.2.0\" env=\"prod\" nodeId=\"server-001\"\ntime=2026-01-05T21:22:17.188+05:30 level=INFO module=\"\" message=\"Application processing completed\" env=\"prod\" nodeId=\"server-001\"\n"
  },
  {
    "path": "examples/logger-from-config/metrics_logs.out",
    "content": "time=2026-01-05T21:22:17.179+05:30 level=DEBUG module=\"\" message=\"Recording performance metric\" env=\"prod\" nodeId=\"server-001\" component=\"metrics\" retention=\"30days\" operation=\"performance_monitoring\"\ntime=2026-01-05T21:22:17.183+05:30 level=INFO module=\"\" message=\"Performance metric recorded\" metric=\"response_time\" value=245.5 unit=\"ms\" env=\"prod\" nodeId=\"server-001\" component=\"metrics\" retention=\"30days\" operation=\"performance_monitoring\"\ntime=2026-01-05T21:22:17.185+05:30 level=DEBUG module=\"\" message=\"Recording performance metric\" env=\"prod\" nodeId=\"server-001\" component=\"metrics\" retention=\"30days\" operation=\"performance_monitoring\"\ntime=2026-01-05T21:22:17.187+05:30 level=INFO module=\"\" message=\"Performance metric recorded\" metric=\"memory_usage\" value=78.2 unit=\"percent\" env=\"prod\" nodeId=\"server-001\" component=\"metrics\" retention=\"30days\" operation=\"performance_monitoring\"\n"
  },
  {
    "path": "examples/logging/logging.bal",
    "content": "import ballerina/log;\n\npublic function main() {\n    // Log messages at different levels\n    log:printDebug(\"This is a debug message\");\n    log:printInfo(\"Application started successfully\");\n    log:printWarn(\"This is a warning message\");\n    log:printError(\"This is an error message\");\n}\n"
  },
  {
    "path": "examples/logging/logging.md",
    "content": "# Logging\n\nThis example demonstrates how to log messages at different levels in Ballerina. The log module provides four log levels in order of priority: ERROR, WARN, INFO, and DEBUG.\n\n::: code logging.bal :::\n\nBy default, only INFO and higher level logs (INFO, WARN, ERROR) are displayed. DEBUG logs are filtered out unless explicitly configured.\n\n::: out logging.out :::\n\n> **Note:** The DEBUG message is not shown in the output because the default log level is INFO.\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#2-logging)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/logging/logging.metatags",
    "content": "description: BBE on how to log messages in Ballerina at different log levels including 'DEBUG', 'ERROR', 'INFO', and 'WARN'.\nkeywords: ballerina, ballerina by examples, bbe, log, level, debug, info, warn, error\n"
  },
  {
    "path": "examples/logging/logging.out",
    "content": "$ bal run logging.bal\ntime=2025-08-25T18:08:00.546+05:30 level=INFO module=\"\" message=\"Application started successfully\"\ntime=2025-08-25T18:08:00.563+05:30 level=WARN module=\"\" message=\"This is a warning message\"\ntime=2025-08-25T18:08:00.564+05:30 level=ERROR module=\"\" message=\"This is an error message\"\n"
  },
  {
    "path": "examples/logging/tests/log_api_test.bal",
    "content": "import ballerina/test;\nimport ballerina/log;\n\nlog:PrintableRawTemplate|string printDebug = \"\";\nlog:PrintableRawTemplate|string printError = \"\";\nlog:PrintableRawTemplate|string printInfo = \"\";\nlog:PrintableRawTemplate|string printWarn = \"\";\n\n// This is the mock function, which will replace the real function.\n\n@test:Mock {\n    moduleName: \"ballerina/log\",\n    functionName: \"printDebug\"\n}\ntest:MockFunction mock_printDebug = new();\n\npublic function mockPrintDebug(string|log:PrintableRawTemplate msg, error? err = (),\nerror:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n    printDebug = msg;\n}\n\n@test:Mock {\n    moduleName: \"ballerina/log\",\n    functionName: \"printError\"\n}\ntest:MockFunction mock_printError = new();\n\npublic function mockPrintError(string|log:PrintableRawTemplate msg, error? err = (),\nerror:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n    printError = msg;\n}\n\n@test:Mock {\n    moduleName: \"ballerina/log\",\n    functionName: \"printInfo\"\n}\ntest:MockFunction mock_printInfo = new();\n\npublic function mockPrintInfo(string|log:PrintableRawTemplate msg, error? err = (),\nerror:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n    printInfo = msg;\n}\n\n@test:Mock {\n    moduleName: \"ballerina/log\",\n    functionName: \"printWarn\"\n}\ntest:MockFunction mock_printWarn = new();\n\npublic function mockPrintWarn(string|log:PrintableRawTemplate msg, error? err = (),\nerror:StackFrame[]? stackTrace = (), *log:KeyValues keyValues) {\n    printWarn = msg;\n}\n\n@test:Config {}\nfunction testFunc() {\n    test:when(mock_printDebug).call(\"mockPrintDebug\");\n    test:when(mock_printError).call(\"mockPrintError\");\n    test:when(mock_printInfo).call(\"mockPrintInfo\");\n    test:when(mock_printWarn).call(\"mockPrintWarn\");\n\n    // Invoking the main function.\n    main();\n    test:assertEquals(printDebug, \"This is a debug message\");\n    test:assertEquals(printError, \"This is an error message\");\n    test:assertEquals(printInfo, \"Application started successfully\");\n    test:assertEquals(printWarn, \"This is a warning message\");\n}\n"
  },
  {
    "path": "examples/logging-configuration/ModuleConfig.toml",
    "content": "[[ballerina.log.modules]]\nname = \"[ORG_NAME]/[MODULE_NAME]\"\nlevel = \"[LOG_LEVEL]\"\n"
  },
  {
    "path": "examples/logging-configuration/logging_configuration.bal",
    "content": "import ballerina/log;\n\npublic function main() {\n    // These log messages will be formatted and filtered according to Config.toml\n    log:printDebug(\"Debug message - application initialization\");\n    log:printInfo(\"Application started\", version = \"1.0.0\");\n    log:printWarn(\"High memory usage detected\", memoryUsage = \"85%\");\n    log:printError(\"Failed to connect to external service\", serviceName = \"PaymentAPI\", timeout = \"30s\");\n\n    // Logs will include the root context configured in Config.toml\n    log:printInfo(\"User session created\", userId = \"user123\", sessionId = \"sess-456\");\n}\n"
  },
  {
    "path": "examples/logging-configuration/logging_configuration.md",
    "content": "# Log configuration\n\nThis example demonstrates how to configure logging behavior using the `Config.toml` file. You can control the log level, format, output destinations, file rotation, and add root context that appears in all log messages.\n\n::: code Config.toml :::\n\nThe configuration above sets:\n\n- **level**: `DEBUG` to show all log levels. This is set to the root logger, affecting all modules unless overridden\n- **format**: `json` for structured JSON output\n- **destinations**: Logs to a file with automatic rotation\n- **rotation**: TIME_BASED policy to rotate log files based on age\n  - `maxAge`: Maximum age of log files in seconds (5 seconds for demo)\n  - `maxBackupFiles`: Number of rotated backup files to retain\n- **keyValues**: Root context added to all logs\n\n::: code logging_configuration.bal :::\n\nWhen you run the application with this configuration, all log messages will be in JSON format and include the root context.\n\nThe log messages will be written to the specified file (`./logs/app.log`) and will automatically rotate based on the configured policy.\n\n> **Note:** Ensure that the application has write permissions to the specified log file path.\n\n::: out logging_configuration.out :::\n\n> **Tip:** Each module can also be assigned its own log level. To assign a log level to a module, provide the following entry in the `Config.toml` file:\n\n::: code ModuleConfig.toml :::\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#3-configure-logging)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/logging-configuration/logging_configuration.metatags",
    "content": "description: BBE on how to configure logging behavior using Config.toml including log level, format, destinations, and root context.\nkeywords: ballerina, ballerina by examples, bbe, log, configuration, config.toml, format, level\n"
  },
  {
    "path": "examples/logging-configuration/logging_configuration.out",
    "content": "{\"time\":\"2025-08-25T18:13:34.598+05:30\", \"level\":\"DEBUG\", \"module\":\"\", \"message\":\"Debug message - application initialization\", \"env\":\"prod\", \"nodeId\":\"server-001\"}\n{\"time\":\"2025-08-25T18:13:34.615+05:30\", \"level\":\"INFO\", \"module\":\"\", \"message\":\"Application started\", \"version\":\"1.0.0\", \"env\":\"prod\", \"nodeId\":\"server-001\"}\n{\"time\":\"2025-08-25T18:13:34.617+05:30\", \"level\":\"WARN\", \"module\":\"\", \"message\":\"High memory usage detected\", \"memoryUsage\":\"85%\", \"env\":\"prod\", \"nodeId\":\"server-001\"}\n{\"time\":\"2025-08-25T18:13:34.618+05:30\", \"level\":\"ERROR\", \"module\":\"\", \"message\":\"Failed to connect to external service\", \"serviceName\":\"PaymentAPI\", \"timeout\":\"30s\", \"env\":\"prod\", \"nodeId\":\"server-001\"}\n{\"time\":\"2025-08-25T18:13:34.618+05:30\", \"level\":\"INFO\", \"module\":\"\", \"message\":\"User session created\", \"userId\":\"user123\", \"sessionId\":\"sess-456\", \"env\":\"prod\", \"nodeId\":\"server-001\"}\n"
  },
  {
    "path": "examples/logging-with-context/logging_with_context.bal",
    "content": "import ballerina/log;\nimport ballerina/time;\n\npublic type User record {|\n    string name;\n    int age;\n|};\n\npublic function main() {\n    // Log with key-value pairs for additional context\n    log:printInfo(\"User authentication attempt\", userId = \"john123\", sessionId = \"abc-def-ghi\");\n\n    // Log with different data types\n    log:printInfo(\"Processing order\", orderId = 845315, amount = 99.99, items = 3, success = true);\n\n    // Log with structured data\n    User user = {name: \"Alice\", age: 25};\n    log:printInfo(\"User profile loaded\", user = user);\n\n    // Log with function pointers for dynamic values\n    log:printInfo(\"System status\",\n            current_time = isolated function() returns string {\n                return time:utcToString(time:utcNow());\n            });\n\n    // Log with templates for formatted context\n    string productName = \"Laptop\";\n    int quantity = 5;\n    log:printInfo(`Processing inventory update`,\n            details = `Product: ${productName}, Quantity: ${quantity}`);\n}\n"
  },
  {
    "path": "examples/logging-with-context/logging_with_context.md",
    "content": "# Logging with context\n\nThis example demonstrates how to add contextual information to log messages using key-value pairs. This helps in debugging and monitoring by providing additional metadata with each log entry.\n\n::: code logging_with_context.bal :::\n\nThe key-value pairs can include various data types such as strings, numbers, booleans, records, function pointers, and templates. This contextual information makes logs more informative and easier to analyze.\n\n::: out logging_with_context.out :::\n\nKey-value pairs appear as additional fields in the log output, making it easy to filter and search logs based on specific criteria.\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#2-logging)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/logging-with-context/logging_with_context.metatags",
    "content": "description: BBE on how to add contextual information to log messages using key-value pairs in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, log, context, key-value, metadata\n"
  },
  {
    "path": "examples/logging-with-context/logging_with_context.out",
    "content": "$ bal run logging_with_context.bal\ntime=2025-08-25T18:20:21.418+05:30 level=INFO module=\"\" message=\"User authentication attempt\" userId=\"john123\" sessionId=\"abc-def-ghi\"\ntime=2025-08-25T18:20:21.433+05:30 level=INFO module=\"\" message=\"Processing order\" orderId=845315 amount=99.99 items=3 success=true\ntime=2025-08-25T18:20:21.436+05:30 level=INFO module=\"\" message=\"User profile loaded\" user={\"name\":\"Alice\",\"age\":25}\ntime=2025-08-25T18:20:21.438+05:30 level=INFO module=\"\" message=\"System status\" current_time=\"2025-08-25T12:50:21.440249Z\"\ntime=2025-08-25T18:20:21.449+05:30 level=INFO module=\"\" message=\"Processing inventory update\" details=\"Product: Laptop, Quantity: 5\"\n"
  },
  {
    "path": "examples/main-function/main_function.bal",
    "content": "import ballerina/io;\n\n// The `main` function can accept command-line arguments and return `error` or `nil`.\npublic function main(int value) returns error? {\n    io:println(value);\n\n    if value >= 3 {\n        return error(\"Input should less than 3\");\n    }\n}\n"
  },
  {
    "path": "examples/main-function/main_function.md",
    "content": "# Main function\n\nThe `main` function is the program entry point and the `public` keyword makes this function visible outside the module. It is a compile-time error if visibility is not set to `public` in the `main` function.\n\nThe `main` function can accept the command-line arguments and returns `error` or nil. \n\n::: code main_function.bal :::\n\n::: out main_function.out :::\n\n## Related links\n- [Functions](/learn/by-example/functions/)\n"
  },
  {
    "path": "examples/main-function/main_function.metatags",
    "content": "description: This BBE demonstrates passing comand-line arguments to the main function, returning errors from the main function, and constructing custom errors in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, main function, error, comand-line arguments\n"
  },
  {
    "path": "examples/main-function/main_function.out",
    "content": "$ bal run main_function.bal -- 5\n5\nerror: Input should less than 3\n"
  },
  {
    "path": "examples/manage-scheduled-jobs/manage_scheduled_jobs.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.runtime;\nimport ballerina/task;\nimport ballerina/time;\n\n// Creates a job to be executed by the scheduler.\nclass Job {\n\n    *task:Job;\n    int i = 1;\n    string jobIdentifier;\n\n    // Executes this function when the scheduled trigger fires.\n    public function execute() {\n        self.i += 1;\n        io:println(self.jobIdentifier + \", MyCounter: \", self.i);\n    }\n\n    isolated function init(int i, string jobIdentifier) {\n        self.i = i;\n        self.jobIdentifier = jobIdentifier;\n    }\n}\n\npublic function main() returns error? {\n\n    // Gets the current time.\n    time:Utc currentUtc = time:utcNow();\n    // Increases the time by three seconds to set the starting delay for the scheduling job.\n    time:Utc newTime = time:utcAddSeconds(currentUtc, 5);\n    // Gets the `time:Civil` for the given time.\n    time:Civil time = time:utcToCivil(newTime);\n\n    // Schedules the tasks to execute the job every second.\n    task:JobId id1 = check task:scheduleJobRecurByFrequency(\n                            new Job(0, \"1st Job\"), 1);\n    task:JobId id2 = check task:scheduleJobRecurByFrequency(\n                            new Job(0, \"2nd Job\"), 3);\n    // Schedules the one-time job at the specified time.\n    _ = check task:scheduleOneTimeJob(new Job(0, \"3rd Job\"), time);\n\n    // Waits for 3 seconds.\n    runtime:sleep(3);\n\n    // Gets all the running jobs.\n    task:JobId[] result = task:getRunningJobs();\n    io:println(\"No of running jobs: \", result.length());\n\n    // Pauses the specified job.\n    check task:pauseJob(id1);\n    io:println(\"Pasused the 1st job.\");\n    // Waits for 3 seconds.\n    runtime:sleep(3);\n\n    // Resumes the specified job.\n    check task:resumeJob(id1);\n    io:println(\"Resumed the 1st job.\");\n\n    // Gets all the running jobs.\n    result = task:getRunningJobs();\n    io:println(\"No of running jobs: \", result.length());\n\n     // Waits for 3 seconds.\n    runtime:sleep(3);\n\n    // Unschedules the jobs.\n    check task:unscheduleJob(id1);\n    check task:unscheduleJob(id2);\n}\n"
  },
  {
    "path": "examples/manage-scheduled-jobs/manage_scheduled_jobs.md",
    "content": "# Manage sheduled jobs\n\nThe `task` library provides functions to manage the scheduled jobs such as pause, resume, unscheduled, etc.\n\nFor more information on the underlying module, see the [`task` module](https://lib.ballerina.io/ballerina/task/latest/).\n\n::: code manage_scheduled_jobs.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out manage_scheduled_jobs.out :::\n"
  },
  {
    "path": "examples/manage-scheduled-jobs/manage_scheduled_jobs.metatags",
    "content": "description: This BBE shows how to manage the scheduled jobs in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, task, job, scheduler\n"
  },
  {
    "path": "examples/manage-scheduled-jobs/manage_scheduled_jobs.out",
    "content": "$ bal run manage_scheduled_jobs.bal\n1st Job, MyCounter: 1\n2nd Job, MyCounter: 1\n1st Job, MyCounter: 2\n1st Job, MyCounter: 3\n1st Job, MyCounter: 4\n2nd Job, MyCounter: 2\nNo of running jobs: 3\nPasused the 1st job.\n3rd Job, MyCounter: 1\n2nd Job, MyCounter: 3\nResumed the 1st job.\n1st Job, MyCounter: 5\n1st Job, MyCounter: 6\nNo of running jobs: 2\n1st Job, MyCounter: 7\n1st Job, MyCounter: 8\n1st Job, MyCounter: 9\n1st Job, MyCounter: 10\n2nd Job, MyCounter: 4\n"
  },
  {
    "path": "examples/mapping-binding-pattern/mapping_binding_pattern.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    int id;\n    string fname;\n    string lname;\n|};\n\npublic function main() {\n    // `_` is used to ignore the value of the `id` field.\n    // The values of the `fname` and `lname` fields are bound to the `firstName` and\n    // `lastName` variable names.\n    Person {id: _, fname: firstName, lname: lastName} = getPerson();\n    io:println(firstName + \" \" + lastName);\n\n    // The `fname` and `lname` fields do not have explicitly defined variable names.\n    // `{fname, lname}` is the same as `{fname: fname, lname: lname}`.\n    // The `id` field is ignored as it is not bound to a variable.\n    Person {fname, lname} = getPerson();\n    io:println(fname + \" \" + lname);\n\n    string givenName;\n    string surname;\n\n    // This destructures and assigns the values of the fields in the destructed record\n    // to the variable references.\n    // The values of the `fname` and `lname` fields are assigned to the `givenName` and\n    // `surname` variables.\n    {fname: givenName, lname: surname} = getPerson();\n    io:println(givenName + \" \" + surname);\n}\n\nfunction getPerson() returns Person {\n    Person person = {id: 1001, fname: \"Anne\", lname: \"Frank\"};\n    return person;\n}\n"
  },
  {
    "path": "examples/mapping-binding-pattern/mapping_binding_pattern.md",
    "content": "# Mapping binding pattern\n\nA mapping binding pattern matches a mapping value with its fields. A `record` type will be assigned to the mapping binding pattern if it successfully matches the value. Both the `map` and `record` types can be used in mapping binding patterns. Record destructuring in binding patterns can be used to refer to existing variables as a record, destructure the given value on the right-hand side, and assign the values to each individual variable of the record during the runtime. These binding patterns are especially helpful when dealing with queries and are useful when destructuring JSON values.\n\n::: code mapping_binding_pattern.bal :::\n\n::: out mapping_binding_pattern.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Rest binding pattern in mapping binding pattern](/learn/by-example/rest-binding-pattern-in-mapping-binding-pattern/)\n"
  },
  {
    "path": "examples/mapping-binding-pattern/mapping_binding_pattern.metatags",
    "content": "description: This BBE demonstrates the mapping binding pattern, record typed binding, record destructuring with binding patterns, and JSON destructuring.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, mapping binding pattern, mapping binding, record typed binding, record binding, record destructuring, json destructuring\n"
  },
  {
    "path": "examples/mapping-binding-pattern/mapping_binding_pattern.out",
    "content": "$ bal run mapping_binding_pattern.bal\nAnne Frank\nAnne Frank\nAnne Frank\n"
  },
  {
    "path": "examples/mapping-binding-pattern-in-match-statement/mapping_binding_pattern_in_match_statement.bal",
    "content": "import ballerina/io;\n\ntype Time record {\n    int hours;\n    int minutes;\n};\n\ntype Day record {\n    Time t;\n};\n\nfunction matchTime1(Time pair) {\n    match pair {\n        // The binding pattern below matches the mappings that contain at least the fields with \n        // the `hours` and `seconds` keys. The values of these fields can be accessed via the \n        // `hours` and `seconds` variables within this block.\n        var {hours, minutes} => {\n            io:println(hours, \", \", minutes);\n        }\n    }\n}\n\nfunction matchTime2(Time time) {\n    match time {\n        // The binding pattern below  has a rest binding pattern to capture the additional \n        // fields that may be specified in the open record value assigned to the `time` variable.\n        // Type of the `rest` variable can be considered a map of `anydata`. However, it cannot \n        // contain the `hours` or `minutes` keys.\n        var {hours, minutes, ...rest} => {\n            io:println(hours, \", \", minutes, \", \", rest);\n        }\n    }\n}\n\nfunction matchTime3(Day day) {\n    match day {\n        // The pattern below matches a mapping that has a field with the `t`key\n        // and a value, which is another mapping that contains at least the fields \n        // with the `hours` and `minutes` keys.\n        var {t: {hours, minutes}} => {\n            io:println(hours, \", \", minutes);\n        }\n    }\n}\n\nfunction matchTime4(Time time) {\n    match time {\n        // The binding pattern below has a rest binding pattern to capture the additional \n        // fields that may be specified in the open record value assigned to the `time` variable.\n        // The condition here checks whether the open record has the field `meridiem`.\n        var {hours, minutes, ...rest}\n                if rest[\"meridiem\"] !is () && rest[\"meridiem\"] == \"PM\" => {\n            io:println(hours + 12, \", \", minutes);\n        }\n        _ => {\n            io:println(time.hours, \", \", time.minutes);\n        }\n    }\n}\n\npublic function main() {\n    Time time = {hours: 3, minutes: 20, \"seconds\": 40, \"milli-seconds\": 500};\n    matchTime1(time);\n    matchTime2(time);\n\n    Day day = {t: time};\n    matchTime3(day);\n\n    Time time2 = {hours: 11, minutes: 21, \"seconds\": 52, \"meridiem\": \"PM\"};\n    matchTime4(time2);\n    matchTime4(time);\n}\n"
  },
  {
    "path": "examples/mapping-binding-pattern-in-match-statement/mapping_binding_pattern_in_match_statement.md",
    "content": "# Mapping binding pattern in match statement\n\nMapping binding patterns can be used in a match statement to bind parts of successfully matched mapping values to variables. The rest binding pattern (`...r`) can be used in the mapping binding pattern to bind mapping fields that are not explicitly bound in the binding pattern. This is particularly useful when working with open records.\n\n::: code mapping_binding_pattern_in_match_statement.bal :::\n\n::: out mapping_binding_pattern_in_match_statement.out :::\n\n## Related links\n- [Rest Binding Pattern in Mapping Binding Pattern](/learn/by-example/rest-binding-pattern-in-mapping-binding-pattern/)\n- [Mapping binding pattern](/learn/by-example/mapping-binding-pattern/)\n- [Binding Patterns](/learn/by-example/binding-patterns/)\n- [Match Statement](/learn/by-example/match-statement/)"
  },
  {
    "path": "examples/mapping-binding-pattern-in-match-statement/mapping_binding_pattern_in_match_statement.metatags",
    "content": "description: This BBE introduces the use of mapping binding pattern in match statement, matching mapping values in match statement\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, mapping binding pattern, match statement\n"
  },
  {
    "path": "examples/mapping-binding-pattern-in-match-statement/mapping_binding_pattern_in_match_statement.out",
    "content": "$ bal run mapping_binding_pattern_in_match_statement.bal\n3, 20\n3, 20, {\"seconds\":40,\"milli-seconds\":500}\n3, 20\n23, 21\n3, 20\n"
  },
  {
    "path": "examples/maps/maps.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Creates a `map` constrained by the `int` type.\n    map<int> ages = {\n        \"Tom\": 23,\n        \"Jack\": 34\n    };\n\n    // Gets the entry for `Tom`.\n    int? v = ages[\"Tom\"];\n    io:println(v);\n\n    // As there exists an entry for `Tom`, it can be accessed using the `map:get()` method. \n    // Using `ages[\"Tom\"]` wouldn't work here because its type would be `int?` and  not `int`.\n    int age = ages.get(\"Tom\");\n    io:println(age);\n\n    // Adds a new entry for `Anne`.\n    ages[\"Anne\"] = 19;\n\n    // The `map:hasKey()` method checks whether the map `age` has a member with `Jack` as the key.\n    if ages.hasKey(\"Jack\") {\n        // The member with the key `Jack` can be removed using `map:remove()`.\n        _ = ages.remove(\"Jack\");\n    }\n\n    // `map:keys()` returns the keys as an array of strings.\n    foreach string name in ages.keys() {\n        io:println(name, \" : \", ages[name]);\n    }\n}\n"
  },
  {
    "path": "examples/maps/maps.md",
    "content": "# Maps\n\nThe `map<T>` type is a mapping from strings to `T`. The map syntax is similar to JSON. Maps are mutable. `foreach` can be used to iterate over the values of the map `m`, and `m.keys()`, which returns the keys as an array of strings can be used to iterate over the keys. `m[k]` gets the entry for `k`; `nil` if missing. Use `m.get(k)` when you know that there is an entry for `k`. Two maps are equal (`==`) if they have the same set of keys and the values for each key are equal.\n\n::: code maps.bal :::\n\n::: out maps.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)\n- [Foreach statement](/learn/by-example/foreach-statement/)"
  },
  {
    "path": "examples/maps/maps.metatags",
    "content": "description: This BBE demonstrates creating a map type, storing key-value pairs, getting the keys from a map, and checking the equality of maps.\nkeywords: ballerina, ballerina by example, bbe, maps, key, value, keys\n"
  },
  {
    "path": "examples/maps/maps.out",
    "content": "$ bal run maps.bal\n23\n23\nTom : 23\nAnne : 19\n"
  },
  {
    "path": "examples/match-guard-in-match-statement/match_guard_in_match_statement.bal",
    "content": "import ballerina/io;\n\nconst switchStatus = \"ON\";\n\nfunction matchValue(any val, boolean isObstructed, float powerPercentage) returns string {\n    // The value of the `val` variable is matched against the given value match patterns.\n    match val {\n        // The `if !isObstructed` match guard is used.\n        1 if !isObstructed => {\n            // This block will execute if `!isObstructed` is true.\n            return \"Move forward\";\n        }\n        // Use `|` to match more than one value.\n        2|3 => {\n            return \"Turn\";\n        }\n        //The `if 25.0 < powerPercentage` match guard is used.\n        4 if 25.0 < powerPercentage => {\n            // This block will execute if `25.0 < powerPercentage` is true.\n            return  \"Increase speed\";\n        }\n        \"STOP\" => {\n            return \"STOP\";\n        }\n        switchStatus => {\n            return \"Switch ON\";\n        }\n        // Use `_` to match type `any`.\n        _ => {\n            return \"Invalid instruction\";\n        }\n    }\n}\n\npublic function main() {\n    io:println(matchValue(1, false, 36.0));\n    io:println(matchValue(4, false, 36.0));\n}\n"
  },
  {
    "path": "examples/match-guard-in-match-statement/match_guard_in_match_statement.md",
    "content": "# Match guard in `match` statement\n\nA match-guard is an expression that is used in a `match` clause to determine whether the clause should be executed. A `match` clause will only be executed if its match-guard evaluates to true.\n\nA function call is only allowed with an expression in a match-guard when there is no possibility that it can mutate the value being matched.\n\n::: code match_guard_in_match_statement.bal :::\n\n::: out match_guard_in_match_statement.out :::\n\n## Related links\n- [If statement](/learn/by-example/if-statement/)\n- [Match statement](/learn/by-example/match-statement/)\n"
  },
  {
    "path": "examples/match-guard-in-match-statement/match_guard_in_match_statement.metatags",
    "content": "description: This BBE demonstrates match guards in `match` statements of Ballerina.\nkeywords: ballerina, ballerina by example, bbe, match, default, value match, match guard\n"
  },
  {
    "path": "examples/match-guard-in-match-statement/match_guard_in_match_statement.out",
    "content": "$ bal run match_guard_in_match_statement.bal\nMove forward\nIncrease speed\n"
  },
  {
    "path": "examples/match-statement/match_statement.bal",
    "content": "import ballerina/io;\n\nconst SWITCH_STATUS = \"ON\";\n\nfunction matchValue(any val) returns string {\n    // The value of the `val` variable is matched against the given value match patterns.\n    match val {\n        1 => {\n            return \"Move forward\";\n        }\n        // Use `|` to match more than one value.\n        2|3 => {\n            return \"Turn\";\n        }\n        \"STOP\" => {\n            return \"STOP\";\n        }\n        SWITCH_STATUS => {\n            return \"Switch ON\";\n        }\n        // Use `_` to match type `any`.\n        _ => {\n            return \"Invalid instruction\";\n        }\n    }\n\n}\n\npublic function main() {\n    io:println(matchValue(1));\n    io:println(matchValue(2));\n    io:println(matchValue(\"STOP\"));\n    io:println(matchValue(SWITCH_STATUS));\n    io:println(matchValue(\"default\"));\n}\n"
  },
  {
    "path": "examples/match-statement/match_statement.md",
    "content": "# Match statement\n\n`match` statement is similar to `switch` statement in some other languages. It matches the value, not the type. `==` is used to test whether the left hand side matches the value being matched. The left hand side can be a simple literal (`nil`, `boolean`, `int`, `float`, `string`) identifier referring to a constant.\n\nLeft hand side of `_` matches if the value is of type `any`. You can use `|` to match more than one value.\n\n::: code match_statement.bal :::\n\n::: out match_statement.out :::\n\n## Related links\n- [If statement](/learn/by-example/if-statement/)\n"
  },
  {
    "path": "examples/match-statement/match_statement.metatags",
    "content": "description: This BBE demonstrates the `match` statement in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, match, default, value match\n"
  },
  {
    "path": "examples/match-statement/match_statement.out",
    "content": "$ bal run match_statement.bal\nMove forward\nTurn\nSTOP\nSwitch ON\nInvalid instruction\n"
  },
  {
    "path": "examples/match-statement-with-maps/match_statement_with_maps.bal",
    "content": "import ballerina/io;\n \nfunction execute(json j) {\n   \tmatch j {\n   \t    // A `match` statement can be used to match maps.\n   \t    // Patterns on the left hand side in a match statement can have variable\n   \t    // parts that can be captured.\n   \t    {command: \"print\", amount: var x} => {\n   \t        if x is int {\n   \t            io:println(\"Int: \", x);\n   \t        }\n   \t    }\n\t\n   \t    _ => {\n   \t        io:println(\"invalid command\");\n   \t    }\n   \t}\n}\n \npublic function main() {\n   \texecute({command: \"print\", amount: 100, status: \"pending\"});\n   \texecute({command: \"print\", amount: 10});\n   \texecute({command: \"subtract\", amount: 100});\n}\n"
  },
  {
    "path": "examples/match-statement-with-maps/match_statement_with_maps.md",
    "content": "# Match statement with maps\n\nMatch statement can be used to match maps. Patterns on the left hand side in a match statement can have variable parts that can be captured. Useful for working directly with `json`. Match semantics are open (may have fields other than those specified in the pattern).\n\n::: code match_statement_with_maps.bal :::\n\n::: out match_statement_with_maps.out :::\n\n## Related links\n- [JSON type](/learn/by-example/json-type/)\n- [Match statement](/learn/by-example/match-statement/)"
  },
  {
    "path": "examples/match-statement-with-maps/match_statement_with_maps.metatags",
    "content": "description: This BBE demonstrates how to match json to pattern and check json has required structure in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, match, json, map\n"
  },
  {
    "path": "examples/match-statement-with-maps/match_statement_with_maps.out",
    "content": "$ bal run match_statement_with_maps.bal\nInt: 100\nInt: 10\ninvalid command\n"
  },
  {
    "path": "examples/mcp-service/mcp_service.bal",
    "content": "import ballerina/log;\nimport ballerina/mcp;\nimport ballerina/random;\nimport ballerina/time;\n\ntype Weather record {|\n    string location;\n    decimal temperature;\n    int humidity;\n    int pressure;\n    string condition;\n    string timestamp;\n|};\n\ntype ForecastItem record {|\n    string date;\n    int high;\n    int low;\n    string condition;\n    int precipitationChance;\n    int windSpeed;\n|};\n\ntype WeatherForecast record {|\n    string location;\n    ForecastItem[] forecast;\n|};\n\n// Define an MCP service attached to the MCP listener on port 9090.\nlistener mcp:Listener mcpListener = new (9090);\n\nservice mcp:Service /mcp on mcpListener {\n\n    // The remote methods defined in this service become MCP tools.\n    // The MCP listener handles listing and calling the tools on MCP requests.\n    // The tool descriptions and schema are generated from the method signatures \n    // and the documentation.\n    # Get current weather for a city.\n    # \n    # + city - City name (e.g., \"New York\", \"Tokyo\")\n    # + return - Current weather data for the specified city\n    remote function getCurrentWeather(string city) returns Weather|error {\n        Weather mockWeather = check getMockWeather(city);\n        log:printInfo(string `Weather data retrieved for ${\n                        city}: ${mockWeather.condition}, ${mockWeather.temperature}°C`);\n        return mockWeather;\n    };\n\n    # Get weather forecast for upcoming days.\n    #\n    # + location - City name or coordinates (e.g., \"London\", \"40.7128,-74.0060\") \n    # + days - Number of days to forecast (1 - 7)\n    # + return - Weather forecast for the specified location and days\n    remote function getWeatherForecast(string location, int days) returns WeatherForecast|error {\n        WeatherForecast mockForecast = {\n            forecast: check getMockForecastItems(days), \n            location\n        };\n        log:printInfo(string `Forecast generated for ${location}: ${days} days with random data`);\n        return mockForecast;\n    }\n}\n\nfunction getMockWeather(string city) returns Weather|error => {\n    condition: \"Sunny\",\n    humidity: check random:createIntInRange(30, 70),\n    location: city,\n    pressure: check random:createIntInRange(1000, 1025),\n    temperature: <decimal> check random:createIntInRange(15, 30),\n    timestamp: time:utcToString(time:utcNow())\n};\n\nfunction getMockForecastItems(int days) returns ForecastItem[]|error {\n    string[] conditions = [\"Sunny\", \"Cloudy\", \"Rainy\", \"Windy\", \"Stormy\", \"Snowy\"];\n    return from int i in 1 ... days\n        select {\n            condition: conditions[check random:createIntInRange(0, conditions.length() - 1)],\n            date: time:utcToString(time:utcAddSeconds(time:utcNow(), i * 86400)),\n            high: check random:createIntInRange(20, 30),\n            low: check random:createIntInRange(10, 20),\n            precipitationChance: check random:createIntInRange(10, 50),\n            windSpeed: check random:createIntInRange(5, 20)\n        };\n}\n"
  },
  {
    "path": "examples/mcp-service/mcp_service.md",
    "content": "# Model Context Protocol (MCP) service\n\nThe Model Context Protocol (MCP) is a standard for connecting AI applications to external data sources, tools, and workflows (prompts). \n\nBallerina's MCP library allows you to create MCP servers that expose tools. Remote methods of a `mcp:Service` service declaration automatically become MCP tools that AI assistants can discover and call.\n\nThis example demonstrates how to create an MCP server that exposes weather-related tools, allowing AI assistants to discover and use tools to retrieve current weather data and forecasts for different locations.\n\nFor more information on the underlying module, see the [`ballerina/mcp` module](https://lib.ballerina.io/ballerina/mcp/latest/).\n\n::: code mcp_service.bal :::\n\n::: out mcp_service.out :::\n\n## Related links\n\n- [AI agents integrated with MCP servers example](/learn/by-example/ai-agent-mcp-integration/)\n"
  },
  {
    "path": "examples/mcp-service/mcp_service.metatags",
    "content": "description: This BBE demonstrates how to implement an MCP server.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, mcp\n"
  },
  {
    "path": "examples/mcp-service/mcp_service.out",
    "content": "$ bal run mcp_service.bal\n\n"
  },
  {
    "path": "examples/mcp-service-advanced/mcp_service_advanced.bal",
    "content": "import ballerina/log;\nimport ballerina/mcp;\nimport ballerina/random;\nimport ballerina/time;\n\ntype Weather record {|\n    string location;\n    decimal temperature;\n    int humidity;\n    int pressure;\n    string condition;\n    string timestamp;\n|};\n\ntype ForecastItem record {|\n    string date;\n    int high;\n    int low;\n    string condition;\n    int precipitationChance;\n    int windSpeed;\n|};\n\ntype WeatherForecast record {|\n    string location;\n    ForecastItem[] forecast;\n|};\n\n// Define an MCP service attached to the MCP listener on port 9090.\nlistener mcp:Listener mcpListener = new (9090);\n\n// Note how the service is declared with the `mcp:AdvancedService` type.\nservice mcp:AdvancedService /mcp on mcpListener {\n\n    isolated remote function onListTools() returns mcp:ListToolsResult|mcp:ServerError => {\n        tools: [\n            {\n                name: \"getCurrentWeather\",\n                description: \"Get current weather conditions for a location\",\n                inputSchema: {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"city\": {\n                            \"type\": \"string\",\n                            \"description\": \"City name or coordinates (e.g., 'London', '40.7128,-74.0060')\"\n                        }\n                    },\n                    \"required\": [\"city\"]\n                }\n            },\n            {\n                name: \"getWeatherForecast\",\n                description: \"Get a 5-day weather forecast for a location\",\n                inputSchema: {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"city\": {\n                            \"type\": \"string\",\n                            \"description\": \"City name or coordinates (e.g., 'London', '40.7128,-74.0060')\"\n                        },\n                        \"days\": {\n                            \"type\": \"integer\",\n                            \"description\": \"Number of days to forecast\",\n                            \"minimum\": 1,\n                            \"maximum\": 7\n                        }\n                    },\n                    \"required\": [\"city\", \"days\"]\n                }\n            }\n        ]\n    };\n\n    isolated remote function onCallTool(mcp:CallToolParams params, mcp:Session? session) \n            returns mcp:CallToolResult|mcp:ServerError {\n        string name = params.name;\n        do {\n            if name == \"getCurrentWeather\" {\n                // Attempt parsing the `arguments` field as a mapping consisting \n                // with fields for each parameter type.\n                record {| string city; |} arguments = check params.arguments.cloneWithType();\n                // Use the arguments in the function call.\n                Weather weather = check getCurrentWeather(arguments.city);\n                return {content: [{'type: \"text\", text: weather.toJsonString()}]};\n            } \n            \n            if name == \"getWeatherForecast\" {\n                record {| string location; int days; |} {location, days} = check params.arguments.cloneWithType();\n                WeatherForecast forecast = check getWeatherForecast(location, days);\n                return {content: [{'type: \"text\", text: forecast.toJsonString()}]};\n            }\n        } on fail {\n            return error(\"Invalid arguments\");\n        }\n        \n        return error(\"Unknown tool: \" + name);\n    }\n}\n\nisolated function getCurrentWeather(string city) returns Weather|error {\n    Weather mockWeather = check getMockWeather(city);\n    log:printInfo(string `Weather data retrieved for ${\n                    city}: ${mockWeather.condition}, ${mockWeather.temperature}°C`);\n    return mockWeather;\n}\n\nisolated function getWeatherForecast(string location, int days) returns WeatherForecast|error {\n    WeatherForecast mockForecast = {\n        forecast: check getMockForecastItems(days), \n        location\n    };\n    log:printInfo(string `Forecast generated for ${location}: ${days} days with random data`);\n    return mockForecast;\n}\n\nisolated function getMockWeather(string city) returns Weather|error => {    \n    condition: \"Sunny\",\n    humidity: check random:createIntInRange(30, 70),\n    location: city,\n    pressure: check random:createIntInRange(1000, 1025),\n    temperature: <decimal> check random:createIntInRange(15, 30),\n    timestamp: time:utcToString(time:utcNow())\n};\n\nisolated function getMockForecastItems(int days) returns ForecastItem[]|error {\n    string[] conditions = [\"Sunny\", \"Cloudy\", \"Rainy\", \"Windy\", \"Stormy\", \"Snowy\"];\n    return from int i in 1 ... days\n        select {\n            condition: conditions[check random:createIntInRange(0, conditions.length() - 1)],\n            date: time:utcToString(time:utcAddSeconds(time:utcNow(), i * 86400)),\n            high: check random:createIntInRange(20, 30),\n            low: check random:createIntInRange(10, 20),\n            precipitationChance: check random:createIntInRange(10, 50),\n            windSpeed: check random:createIntInRange(5, 20)\n        };\n}\n"
  },
  {
    "path": "examples/mcp-service-advanced/mcp_service_advanced.md",
    "content": "# Model Context Protocol (MCP) advanced service\n\nThe Model Context Protocol (MCP) is a standard for connecting AI applications to external data sources, tools, and workflows (prompts). \n\nBallerina's MCP library allows you to create MCP servers that expose tools. A `mcp:AdvancedService` service expects two remote methods, namely `onListTools` and `onCallTool`, to allow AI assistants to discover and call tools respectively.\n\nThis example demonstrates how to create an MCP server that exposes weather-related tools via explicit MCP methods, allowing AI assistants to discover and use tools to retrieve current weather data and forecasts for different locations.\n\nFor more information on the underlying module, see the [`ballerina/mcp` module](https://lib.ballerina.io/ballerina/mcp/latest/).\n\n::: code mcp_service_advanced.bal :::\n\n::: out mcp_service_advanced.out :::\n\n## Related links\n\n- [The AI agents integrated with MCP servers example](/learn/by-example/ai-agent-mcp-integration/)\n"
  },
  {
    "path": "examples/mcp-service-advanced/mcp_service_advanced.metatags",
    "content": "description: This BBE demonstrates how to implement an MCP server, with explicit tool retrieval and usage methods.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, mcp\n"
  },
  {
    "path": "examples/mcp-service-advanced/mcp_service_advanced.out",
    "content": "$ bal run mcp_service_advanced.bal\n\n"
  },
  {
    "path": "examples/message-store-listener/message_store_listener.bal",
    "content": "import ballerina/messaging;\nimport ballerina/log;\n\n// Create the main message store\nmessaging:Store msgStore = new messaging:InMemoryMessageStore();\n\n// Create the dead-letter message store\nmessaging:Store dlStore = new messaging:InMemoryMessageStore();\n\n// Create the message store listener\nlistener messaging:StoreListener msgStoreListener = new (msgStore, {\n    pollingInterval: 10,\n    maxRetries: 2,\n    retryInterval: 2,\n    deadLetterStore: dlStore\n});\n\n// Create the service to process messages\nservice on msgStoreListener {\n    isolated remote function onMessage(anydata payload) returns error? {\n        log:printInfo(\"message received\", payload = payload);\n\n        // Simulate error scenario\n        if payload == \"error\" {\n            return error(\"Simulated processing error\");\n        }\n    }\n}\n\npublic function main() returns error? {\n    // Store a message\n    check msgStore->store(\"Hello, World!\");\n\n    // Store a message to simulate error scenario\n    check msgStore->store(\"error\");\n}\n"
  },
  {
    "path": "examples/message-store-listener/message_store_listener.md",
    "content": "# Message Store Listener\n\nThis example demonstrates how to use message store listeners for automated message processing. The `StoreListener` provides a polling-based mechanism to automatically retrieve and process messages from a message store, with built-in support for retries and dead letter handling.\n\n::: code message_store_listener.bal :::\n\n> **Tip:** Enable debug logs to see internal logs related to message flow\n\n::: code Config.toml :::\n\n::: out message_store_listener.out :::\n\n## Related links\n\n- [`messaging` module - API documentation](https://lib.ballerina.io/ballerina/messaging/latest/)\n- [`messaging` module - Specification](https://ballerina.io/spec/messaging/)\n"
  },
  {
    "path": "examples/message-store-listener/message_store_listener.metatags",
    "content": "description: This BBE demonstrates how to implement a message store listener using the messaging library in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, messaging, store, in-memory, store listener, dead-letter store, dlq, poll\n"
  },
  {
    "path": "examples/message-store-listener/message_store_listener.out",
    "content": "$ bal run message_store_listener.bal\n\ntime=2025-08-25T12:28:32.268+05:30 level=INFO module=\"\" message=\"message received\" payload=\"Hello, World!\"\ntime=2025-08-25T12:28:42.241+05:30 level=INFO module=\"\" message=\"message received\" payload=\"error\"\ntime=2025-08-25T12:28:42.247+05:30 level=ERROR module=ballerina/messaging message=\"error occurred while processing message\" error={\"causes\":[],\"message\":\"Simulated processing error\",\"detail\":{},\"stackTrace\":[{\"callableName\":\"onMessage\",\"moduleName\":\"$anonType$_0\",\"fileName\":\"message_store_listener.bal\",\"lineNumber\":25},{\"callableName\":\"execute\",\"moduleName\":\"ballerina.messaging.1.PollAndProcessMessages\",\"fileName\":\"msg_listener.bal\",\"lineNumber\":201}]} msgId=\"01f08180-e965-11c0-ad70-3bc9eb7490bd\"\ntime=2025-08-25T12:28:44.268+05:30 level=INFO module=\"\" message=\"message received\" payload=\"error\"\ntime=2025-08-25T12:28:44.272+05:30 level=ERROR module=ballerina/messaging message=\"error processing message on retry\" error={\"causes\":[],\"message\":\"Simulated processing error\",\"detail\":{},\"stackTrace\":[{\"callableName\":\"onMessage\",\"moduleName\":\"$anonType$_0\",\"fileName\":\"message_store_listener.bal\",\"lineNumber\":25},{\"callableName\":\"execute\",\"moduleName\":\"ballerina.messaging.1.PollAndProcessMessages\",\"fileName\":\"msg_listener.bal\",\"lineNumber\":211}]} retryAttempt=1 msgId=\"01f08180-e965-11c0-ad70-3bc9eb7490bd\"\ntime=2025-08-25T12:28:46.278+05:30 level=INFO module=\"\" message=\"message received\" payload=\"error\"\ntime=2025-08-25T12:28:46.281+05:30 level=ERROR module=ballerina/messaging message=\"error processing message on retry\" error={\"causes\":[],\"message\":\"Simulated processing error\",\"detail\":{},\"stackTrace\":[{\"callableName\":\"onMessage\",\"moduleName\":\"$anonType$_0\",\"fileName\":\"message_store_listener.bal\",\"lineNumber\":25},{\"callableName\":\"execute\",\"moduleName\":\"ballerina.messaging.1.PollAndProcessMessages\",\"fileName\":\"msg_listener.bal\",\"lineNumber\":211}]} retryAttempt=2 msgId=\"01f08180-e965-11c0-ad70-3bc9eb7490bd\"\ntime=2025-08-25T12:28:46.286+05:30 level=DEBUG module=ballerina/messaging message=\"message stored in dead letter store after max retries\" msgId=\"01f08180-e965-11c0-ad70-3bc9eb7490bd\"\n"
  },
  {
    "path": "examples/message-store-type/message_store_type.bal",
    "content": "import ballerina/log;\nimport ballerina/messaging;\nimport ballerina/uuid;\n\n// Custom message store implementation using a simple in-memory map\nisolated client class CustomMessageStore {\n    *messaging:Store;\n\n    private final map<readonly & messaging:Message> messages = {};\n    private final map<readonly & messaging:Message> pendingMessages = {};\n\n    isolated remote function store(anydata payload) returns error? {\n        string id = uuid:createType1AsString();\n\n        lock {\n            self.messages[id] = {\n                id,\n                payload: payload.cloneReadOnly()\n            };\n        }\n\n        log:printInfo(\"Message stored\", id = id);\n    }\n\n    isolated remote function retrieve() returns messaging:Message|error? {\n        lock {\n            string[] keys = self.messages.keys();\n            if keys.length() > 0 {\n                string id = keys[0];\n                readonly & messaging:Message message = self.messages.get(id);\n                // Move message to pending state\n                self.pendingMessages[id] = message;\n                _ = self.messages.remove(id);\n                return message;\n            }\n            return;\n        }\n    }\n\n    isolated remote function acknowledge(string id, boolean success = true) returns error? {\n        lock {\n            if self.pendingMessages.hasKey(id) {\n                if success {\n                    _ = self.pendingMessages.remove(id);\n                    log:printInfo(\"Message acknowledged\", id = id);\n                } else {\n                    // Move message back to available state for negative ack\n                    readonly & messaging:Message message = self.pendingMessages.get(id);\n                    self.messages[id] = message;\n                    _ = self.pendingMessages.remove(id);\n                    log:printInfo(\"Message negative acknowledged\", id = id);\n                }\n            }\n        }\n    }\n}\n\npublic function main() returns error? {\n    // Create an instance of the custom message store\n    messaging:Store customStore = new CustomMessageStore();\n\n    // Store and process a message\n    check customStore->store(\"Hello, World!\");\n\n    messaging:Message? msg = check customStore->retrieve();\n    if msg is messaging:Message {\n        log:printInfo(\"Retrieved message\", payload = msg.payload, id = msg.id);\n        // Acknowledge the message\n        check customStore->acknowledge(msg.id);\n    }\n\n    // Demonstrate negative acknowledgment\n    check customStore->store(\"Test message\");\n    msg = check customStore->retrieve();\n    if msg is messaging:Message {\n        log:printInfo(\"Retrieved message for negative ack\", payload = msg.payload, id = msg.id);\n        check customStore->acknowledge(msg.id, false);\n\n        // Retrieve the same message again after negative ack\n        msg = check customStore->retrieve();\n        if msg is messaging:Message {\n            log:printInfo(\"Message available again after negative ack\", payload = msg.payload, id = msg.id);\n            check customStore->acknowledge(msg.id);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/message-store-type/message_store_type.md",
    "content": "# Message Store Type\n\nThe `messaging` package in Ballerina provides messaging capabilities through the `Store` interface. This example demonstrates how to implement a custom message store by creating your own implementation of the `messaging:Store` type.\n\nThe `messaging:Store` interface defines the contract for message storage, retrieval, and acknowledgment operations. By implementing this interface, you can create custom message stores that suit your specific requirements while maintaining compatibility with the messaging framework.\n\n::: code message_store_type.bal :::\n\n::: out message_store_type.out :::\n\n## Related links\n\n- [`messaging` module - API documentation](https://lib.ballerina.io/ballerina/messaging/latest/)\n- [`messaging` module - Specification](https://ballerina.io/spec/messaging/)\n- [In-memory message store](/learn/by-example/in-memory-message-store/)\n"
  },
  {
    "path": "examples/message-store-type/message_store_type.metatags",
    "content": "description: This BBE demonstrates how to implement the messaging:Store type to create a custom message store in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, messaging, store, custom, implementation, type\n"
  },
  {
    "path": "examples/message-store-type/message_store_type.out",
    "content": "$ bal run message_store_type.bal\n\ntime=2025-10-08T08:54:37.054+05:30 level=INFO module=\"\" message=\"Message stored\" id=\"01f0a3f6-5150-1888-861d-4d6c2cf6fef8\"\ntime=2025-10-08T08:54:37.065+05:30 level=INFO module=\"\" message=\"Retrieved message\" payload=\"Hello, World!\" id=\"01f0a3f6-5150-1888-861d-4d6c2cf6fef8\"\ntime=2025-10-08T08:54:37.066+05:30 level=INFO module=\"\" message=\"Message acknowledged\" id=\"01f0a3f6-5150-1888-861d-4d6c2cf6fef8\"\ntime=2025-10-08T08:54:37.068+05:30 level=INFO module=\"\" message=\"Message stored\" id=\"01f0a3f6-5150-1888-a339-6e9cd9fc0e8f\"\ntime=2025-10-08T08:54:37.069+05:30 level=INFO module=\"\" message=\"Retrieved message for negative ack\" payload=\"Test message\" id=\"01f0a3f6-5150-1888-a339-6e9cd9fc0e8f\"\ntime=2025-10-08T08:54:37.070+05:30 level=INFO module=\"\" message=\"Message negative acknowledged\" id=\"01f0a3f6-5150-1888-a339-6e9cd9fc0e8f\"\ntime=2025-10-08T08:54:37.071+05:30 level=INFO module=\"\" message=\"Message available again after negative ack\" payload=\"Test message\" id=\"01f0a3f6-5150-1888-a339-6e9cd9fc0e8f\"\ntime=2025-10-08T08:54:37.071+05:30 level=INFO module=\"\" message=\"Message acknowledged\" id=\"01f0a3f6-5150-1888-a339-6e9cd9fc0e8f\"\n\n"
  },
  {
    "path": "examples/meta.json",
    "content": "{\n  \"githubBallerinaByExampleBaseURL\": \"https://github.com/ballerina-platform/ballerina-distribution/tree/\"\n}\n"
  },
  {
    "path": "examples/module-lifecycle/module_lifecycle.bal",
    "content": "import ballerina/io;\n\n// Usually, it is an error to import a module without using it but if you want to import a module because of what its initialization does,\n// then, use `as _` as done in this example.\nimport ballerina/grpc as _;\n\n// A module can have an `init` function just like an object.\n// The initialization of a module ends by calling its `init` function if there is one.\nfunction init() {\n    io:println(\"Hello world\");\n}\n"
  },
  {
    "path": "examples/module-lifecycle/module_lifecycle.md",
    "content": "# Module lifecycle\n\nAll modules are initialized at program startup. Module initialization is ordered so that if module A imports module B, then module A is initialized after module B. The initialization phase ends by calling the `main` function if there is one.\n\nA module's listeners are registered during module initialization. If there are registered listeners, then the initialization phase is followed by the listening phase.\n\nThe listening phase starts by calling the `start` method on each registered listener. The listening phase is terminated by signal (e.g. `SIGINT`, `SIGTERM`).\n\n::: code module_lifecycle.bal :::\n\n::: out module_lifecycle.out :::"
  },
  {
    "path": "examples/module-lifecycle/module_lifecycle.metatags",
    "content": "description: This BBE explains module lifecycle and its various phases.\nkeywords:  ballerina, ballerina by example, bbe, module initialization, listener\n"
  },
  {
    "path": "examples/module-lifecycle/module_lifecycle.out",
    "content": "$ bal run module_lifecycle.bal\nHello world\n"
  },
  {
    "path": "examples/mqtt-client-basic-authentication/mqtt_client_basic_authentication.bal",
    "content": "import ballerina/http;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nservice / on new http:Listener(9090) {\n    private final mqtt:Client temperaturePublisher;\n\n    function init() returns error? {\n        self.temperaturePublisher = check new (\"tcp://localhost:1883\", \"temperature-pub-client\", {\n            connectionConfig: {\n                username: \"alice\",\n                password: \"alice@123\"\n            }\n        });\n    }\n\n    resource function post temperature(TemperatureDetails temperatureDetails) returns http:Accepted|error {\n        _ = check self.temperaturePublisher->publish(\"mqtt/topic\", {\n            payload: temperatureDetails.toJsonString().toBytes()\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-client-basic-authentication/mqtt_client_basic_authentication.curl.out",
    "content": "$ curl http://localhost:9090/temperature -H \"Content-type:application/json\" -d \"{\\\"deviceId\\\": \\\"device-id-1\\\", \\\"timestamp\\\": [1692679864,0.822397000], \\\"temperature\\\": 27.5}\"\n"
  },
  {
    "path": "examples/mqtt-client-basic-authentication/mqtt_client_basic_authentication.md",
    "content": "# MQTT client - Basic authentication\n\nThe `mqtt:Client` connects to an MQTT server via basic authentication and then, sends messages to the server. Basic authentication can be enabled by configuring the `username` and `password` in the `connectionConfig` of the `mqtt:ClientConfiguration`. This can be used to connect to an MQTT server secured with basic authentication.\n\n::: code mqtt_client_basic_authentication.bal :::\n\n## Prerequisites\n- Start an [MQTT broker](https://mqtt.org/software/) instance, which is configured to use basic authentication.\n- Run the MQTT service given in the [MQTT service - Basic authentication](/learn/by-example/mqtt-service-basic-authentication) example.\n\nRun the program by executing the following command.\n\n::: out mqtt_client_basic_authentication.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mqtt_client_basic_authentication.curl.out :::\n\n## Related links\n- [`mqtt:ClientConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#ClientConfiguration)\n- [MQTT client basic authentication - Specification](/spec/mqtt/#322-secure-client)\n"
  },
  {
    "path": "examples/mqtt-client-basic-authentication/mqtt_client_basic_authentication.metatags",
    "content": "description: How to configure an MQTT client to use basic authentication.\nkeywords: ballerina, ballerina by example, bbe, mqtt, client, authentication, iot\n"
  },
  {
    "path": "examples/mqtt-client-basic-authentication/mqtt_client_basic_authentication.out",
    "content": "$ bal run mqtt_publisher_basic_auth.bal\n"
  },
  {
    "path": "examples/mqtt-client-publish-message/mqtt_client_publish_message.bal",
    "content": "import ballerina/http;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nservice / on new http:Listener(9090) {\n    private final mqtt:Client temperaturePublisher;\n\n    function init() returns error? {\n        self.temperaturePublisher = check new (mqtt:DEFAULT_URL, \"temperature-pub-client\");\n    }\n\n    resource function post temperature(TemperatureDetails temperatureDetails) returns http:Accepted|error {\n        _ = check self.temperaturePublisher->publish(\"mqtt/topic\", {\n            payload: temperatureDetails.toJsonString().toBytes()\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-client-publish-message/mqtt_client_publish_message.curl.out",
    "content": "$ curl http://localhost:9090/temperature -H \"Content-type:application/json\" -d \"{\\\"deviceId\\\": \\\"device-id-1\\\", \\\"timestamp\\\": [1692679864,0.822397000], \\\"temperature\\\": 27.5}\"\n"
  },
  {
    "path": "examples/mqtt-client-publish-message/mqtt_client_publish_message.md",
    "content": "# MQTT client - Publish message\n\nThe `mqtt:Client` connects to a given MQTT server, and then, publishes messages to a specific topic in the server. An `mqtt:CLient` is created by giving the MQTT server URL and a unique ID. Once connected, the `publish` method is used to send messages to the MQTT server by providing the relevant topic and the message as the parameters. Use this to send messages to a topic in the MQTT server.\n\n::: code mqtt_client_publish_message.bal :::\n\n## Prerequisites\n- Start an [MQTT broker](https://mqtt.org/software/) instance.\n- Run the MQTT service given in the [MQTT service - Subscribe to messages](/learn/by-example/mqtt-service-subscribe-message) example.\n\nRun the program by executing the following command.\n\n::: out mqtt_client_publish_message.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mqtt_client_publish_message.curl.out :::\n\n## Related links\n- [`mqtt:Client->publish` function - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#Client-publish)\n- [`mqtt:Client` functions - Specification](/spec/mqtt/#33-functions)\n"
  },
  {
    "path": "examples/mqtt-client-publish-message/mqtt_client_publish_message.metatags",
    "content": "description: How to send messages to a MQTT topic using a `mqtt:Client`.\nkeywords: ballerina, ballerina by example, bbe, mqtt, publisher, iot\n"
  },
  {
    "path": "examples/mqtt-client-publish-message/mqtt_client_publish_message.out",
    "content": "$ bal run mqtt_publisher.bal\n"
  },
  {
    "path": "examples/mqtt-client-ssl/mqtt_client_ssl.bal",
    "content": "import ballerina/http;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nservice / on new http:Listener(9090) {\n    private final mqtt:Client temperaturePublisher;\n\n    function init() returns error? {\n        self.temperaturePublisher = check new (\"ssl://localhost:8883\", \"temperature-pub-client\", {\n            connectionConfig: {\n                secureSocket: {\n                    cert: \"./resources/path/to/public.crt\"\n                }\n            }\n        });\n    }\n\n    resource function post temperature(TemperatureDetails temperatureDetails) returns http:Accepted|error {\n        _ = check self.temperaturePublisher->publish(\"mqtt/topic\", {\n            payload: temperatureDetails.toJsonString().toBytes()\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-client-ssl/mqtt_client_ssl.curl.out",
    "content": "$ curl http://localhost:9090/temperature -H \"Content-type:application/json\" -d \"{\\\"deviceId\\\": \\\"device-id-1\\\", \\\"timestamp\\\": [1692679864,0.822397000], \\\"temperature\\\": 27.5}\"\n"
  },
  {
    "path": "examples/mqtt-client-ssl/mqtt_client_ssl.md",
    "content": "# MQTT client - SSL/TLS\n\nThe `mqtt:Client` connects to an MQTT server via SSL/TLS and then, sends messages to the server. SSL/TLS can be enabled by configuring the `secureSocket`, which requires a certificate or a truststore. Further, Mutual TLS (mTLS) can be enabled by providing a certificate and private key of the client or a keystore. Use this to connect to an MQTT server secured with SSL.\n\n>**Info:** For more information on the underlying module, see the [`mqtt` module](https://lib.ballerina.io/ballerina/mqtt/latest).\n\n::: code mqtt_client_ssl.bal :::\n\n## Prerequisites\n- Start an [MQTT broker](https://mqtt.org/software/) instance, which is configured to use SSL/TLS.\n- Run the MQTT service given in the [MQTT service - SSL/TLS](/learn/by-example/mqtt-service-ssl) example.\n\nRun the program by executing the following command.\n\n::: out mqtt_client_ssl.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mqtt_client_ssl.curl.out :::\n\n## Related links\n- [`mqtt:SecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#SecureSocket)\n- [MQTT secure client - Specification](/spec/mqtt/#322-secure-client)\n"
  },
  {
    "path": "examples/mqtt-client-ssl/mqtt_client_ssl.metatags",
    "content": "description: How to configure a MQTT client to use SSL encryption.\nkeywords: ballerina, ballerina by example, bbe, mqtt, publisher, encryption, SSL\n"
  },
  {
    "path": "examples/mqtt-client-ssl/mqtt_client_ssl.out",
    "content": "$ bal run mqtt_client_ssl.bal\n"
  },
  {
    "path": "examples/mqtt-service-basic-authentication/mqtt_service_basic_authentication.bal",
    "content": "import ballerina/lang.value;\nimport ballerina/log;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nlistener mqtt:Listener temperatureSubscriber = new (\"tcp://localhost:1883\", \"temperature-sub-client\", \"mqtt/topic\", {\n    connectionConfig: {\n        username: \"alice\",\n        password: \"alice@123\"\n    }\n});\n\nservice on temperatureSubscriber {\n    remote function onMessage(mqtt:Message message) returns error? {\n        TemperatureDetails details = check value:fromJsonStringWithType(check string:fromBytes(message.payload));\n        log:printInfo(string `Received temperature details from device: ${details.deviceId} at\n            ${time:utcToString(details.timestamp)} with temperature: ${details.temperature}`);\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-service-basic-authentication/mqtt_service_basic_authentication.md",
    "content": "# MQTT service - Basic authentication\n\nThe `mqtt:Service` receives messages from the MQTT server using the `mqtt:Listener` via basic authentication. Basic authentication can be enabled by configuring the `username` and `password` in the `connectionConfig` of the `mqtt:ListenerConfiguration`. Use this to connect to an MQTT server secured with basic authentication.\n\n::: code mqtt_service_basic_authentication.bal :::\n\n## Prerequisites\n- Start a [MQTT broker](https://mqtt.org/software/) instance configured to use basic authentication.\n\nRun the program by executing the following command.\n\n::: out mqtt_service_basic_authentication.out :::\n\n>**Tip:** Run the MQTT client given in the [MQTT publisher - Basic authentication](/learn/by-example/mqtt-client-basic-authentication) example to produce some messages to the topic.\n\n## Related links\n- [`mqtt:ListenerConfiguration` record - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#ListenerConfiguration)\n- [MQTT service basic authentication - Specification](/spec/mqtt/#422-secure-listener)\n"
  },
  {
    "path": "examples/mqtt-service-basic-authentication/mqtt_service_basic_authentication.metatags",
    "content": "description: How to configure a MQTT listener to use basic authentication.\nkeywords: ballerina, ballerina by example, bbe, mqtt, listener, service, iot\n"
  },
  {
    "path": "examples/mqtt-service-basic-authentication/mqtt_service_basic_authentication.out",
    "content": "$ bal run mqtt_auth_service.bal\ntime=2023-08-16T16:48:03.259+05:30 level=INFO module=\"\" message=\"Received temperature details from device: device-id-1 at 2023-08-16T11:18:03.212400160Z with temperature: 27.5\"\n"
  },
  {
    "path": "examples/mqtt-service-ssl/mqtt_service_ssl.bal",
    "content": "import ballerina/lang.value;\nimport ballerina/log;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nlistener mqtt:Listener temperatureSubscriber = new (\"ssl://localhost:8883\", \"temperature-sub-client\", \"mqtt/topic\", {\n    connectionConfig: {\n        // Provide the relevant secure socket configurations by using `mqtt:SecureSocket`.\n        secureSocket: {\n            cert: \"./resources/path/to/public.crt\"\n        }\n    }\n});\n\nservice on temperatureSubscriber {\n    remote function onMessage(mqtt:Message message) returns error? {\n        TemperatureDetails details = check value:fromJsonStringWithType(check string:fromBytes(message.payload));\n        log:printInfo(string `Received temperature details from device: ${details.deviceId} at\n            ${time:utcToString(details.timestamp)} with temperature: ${details.temperature}`);\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-service-ssl/mqtt_service_ssl.md",
    "content": "# MQTT service - SSL/TLS\n\nThe `mqtt:Service` receives messages from the MQTT server using the `mqtt:Listener` via SSL/TLS. SSL/TLS can be enabled by configuring the `secureSocket`, which requires a certificate or a truststore. Further, Mutual TLS (mTLS) can be enabled by providing a certificate and private key of the service or a keystore. Use this to connect to an MQTT server secured with SSL.\n\n::: code mqtt_service_ssl.bal :::\n\n## Prerequisites\n- Start an [MQTT broker](https://mqtt.org/software/) instance, which is configured to use SSL/TLS.\n\nRun the program by executing the following command.\n\n::: out mqtt_service_ssl.out :::\n\n>**Tip:** Run the MQTT client given in the [MQTT client - SSL/TLS](/learn/by-example/mqtt-client-ssl) example to publish some messages to the topic.\n\n## Related links\n- [`mqtt:SecureSocket` record - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#SecureSocket)\n- [MQTT secure service - Specification](/spec/mqtt/#422-secure-listener)\n"
  },
  {
    "path": "examples/mqtt-service-ssl/mqtt_service_ssl.metatags",
    "content": "description: How to configure an MQTT listener to use SSL encryption.\nkeywords: ballerina, ballerina by example, bbe, mqtt, listener, service, iot, SSL\n"
  },
  {
    "path": "examples/mqtt-service-ssl/mqtt_service_ssl.out",
    "content": "$ bal run mqtt_service_ssl.bal\ntime=2023-08-16T16:48:03.259+05:30 level=INFO module=\"\" message=\"Received temperature details from device: device-id-1 at 2023-08-16T11:18:03.212400160Z with temperature: 27.5\"\n"
  },
  {
    "path": "examples/mqtt-service-subscribe-message/mqtt_service_subscribe_message.bal",
    "content": "import ballerina/lang.value;\nimport ballerina/log;\nimport ballerina/mqtt;\nimport ballerina/time;\n\ntype TemperatureDetails readonly & record {\n    string deviceId;\n    time:Utc timestamp;\n    decimal temperature;\n};\n\nservice on new mqtt:Listener(mqtt:DEFAULT_URL, \"temperature-sub-client\", \"mqtt/topic\") {\n    remote function onMessage(mqtt:Message message) returns error? {\n        TemperatureDetails details = check value:fromJsonStringWithType(check string:fromBytes(message.payload));\n        log:printInfo(string `Received temperature details from device: ${details.deviceId} at\n            ${time:utcToString(details.timestamp)} with temperature: ${details.temperature}`);\n    }\n}\n"
  },
  {
    "path": "examples/mqtt-service-subscribe-message/mqtt_service_subscribe_message.md",
    "content": "# MQTT service - Subscribe to messages\n\nThe `mqtt:Service` connects to a given MQTT server via the `mqtt:Listener`, and allows to receive messages from different topics. Once new messages are received from a subscribed topic, the `onMessage` method gets invoked. If there are errors when invoking the method, the `onError` remote method will be invoked with the relevant `error`. If the method is not implemented, the error will be logged to the console. This can be used to receive messages from a set of topics in an MQTT server.\n\n::: code mqtt_service_subscribe_message.bal :::\n\n## Prerequisites\n- Start a [MQTT broker](https://mqtt.org/software/) instance.\n\nRun the program by executing the following command.\n\n::: out mqtt_service_subscribe_message.out :::\n\n>**Tip:** Run the MQTT client given in the [MQTT client - Publish message](/learn/by-example/mqtt-client-publish-message) example to publish some messages to the topic.\n\n## Related links\n- [`mqtt:Listener` client object - API documentation](https://lib.ballerina.io/ballerina/mqtt/latest#Listener)\n- [MQTT service - Specification](/spec/mqtt/#43-usage)\n"
  },
  {
    "path": "examples/mqtt-service-subscribe-message/mqtt_service_subscribe_message.metatags",
    "content": "description: Create an MQTT service to subscribe to messages from an MQTT server using Ballerina.\nkeywords: ballerina, ballerina by example, bbe, mqtt, subscriber, listener, service, iot\n"
  },
  {
    "path": "examples/mqtt-service-subscribe-message/mqtt_service_subscribe_message.out",
    "content": "$ bal run mqtt_service.bal\ntime=2023-08-16T16:48:03.259+05:30 level=INFO module=\"\" message=\"Received temperature details from device: device-id-1 at 2023-08-16T11:18:03.212400160Z with temperature: 27.5\"\n"
  },
  {
    "path": "examples/multiple-key-fields/multiple_key_fields.bal",
    "content": "import ballerina/io;\n\ntype Employee record {\n    readonly string firstName;\n    readonly string lastName;\n    int salary;\n};\n\npublic function main() {\n    // `employees` has a key sequence with the `firstName` and `lastName` fields.\n    table<Employee> key(firstName, lastName) employees = table [\n            {firstName: \"John\", lastName: \"Smith\", salary: 100},\n            {firstName: \"John\", lastName: \"Bloggs\", salary: 200}\n        ];\n\n    // The key sequence provides keyed access to members of the `table`.\n    Employee? e = employees[\"John\", \"Bloggs\"];\n    io:println(e);\n\n    // `employees` has a key sequence with the `firstName` and `lastName` fields.\n    table<Employee> key<[string, string]> employees2 = table key(firstName, lastName) [\n            {firstName: \"John\", lastName: \"Smith\", salary: 100},\n            {firstName: \"John\", lastName: \"Bloggs\", salary: 200}\n        ];\n\n    e = employees2[\"John\", \"Smith\"];\n    io:println(e);\n}\n"
  },
  {
    "path": "examples/multiple-key-fields/multiple_key_fields.md",
    "content": "# Multiple key fields\n\nA `table` provides access to its members using a key that comes from the `readonly` fields of the member. It is a key sequence, which is used to provide keyed access to its members. The key sequence is an ordered sequence of the field names.\n\n::: code multiple_key_fields.bal :::\n\n::: out multiple_key_fields.out :::\n\n## Related links\n- [Table](/learn/by-example/table/)\n- [Structured keys](/learn/by-example/multiple-key-fields/)\n- [Maps](/learn/by-example/maps/)\n"
  },
  {
    "path": "examples/multiple-key-fields/multiple_key_fields.metatags",
    "content": "description: This BBE demonstrates how to create table with multiple keys, get entry from multiple key table.\nkeywords: ballerina, ballerina by example, bbe, multiple key fields, keys, table, map\n"
  },
  {
    "path": "examples/multiple-key-fields/multiple_key_fields.out",
    "content": "$ bal run multiple_key_fields.bal\n{\"firstName\":\"John\",\"lastName\":\"Bloggs\",\"salary\":200}\n{\"firstName\":\"John\",\"lastName\":\"Smith\",\"salary\":100}\n"
  },
  {
    "path": "examples/multiple-receive/multiple_receive.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/lang.runtime;\n\ntype Response record {\n    record {\n        string 'worker;\n    } args;\n};\n\ntype Result record {\n    string|error a;\n    string|error b;\n};\n\nfunction fetch(string workerParam) returns string|error {\n    http:Client cl = check new (\"https://postman-echo.com\");\n    Response response = check cl->/get('worker = workerParam);\n    return response.args.'worker;\n}\n\npublic function main() {\n    // Workers `w1` and `w2` call the `fetch` function to retrieve content. The workers \n    // send the result of calling the `fetch` function to the default worker.\n    worker w1 {\n        fetch(\"w1\") -> function;\n    }\n\n    worker w2 {\n        runtime:sleep(2);\n        fetch(\"w2\") -> function;\n    }\n\n    // The multiple receive action is used to receive values from both workers.\n    Result result = <- {a: w1, b: w2};\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/multiple-receive/multiple_receive.md",
    "content": "# Multiple receive\n\nThe multiple receive action can be used to receive values corresponding to multiple send actions. It operates by waiting for the receipt of values from all the send actions, subsequently constructing a mapping value containing those values.\n\n::: code multiple_receive.bal :::\n\n::: out multiple_receive.out :::\n"
  },
  {
    "path": "examples/multiple-receive/multiple_receive.metatags",
    "content": "description: This BBE demonstrates the use of the multiple receive action in inter-worker communication\nkeywords: ballerina, ballerina by example, bbe, worker, multiple receive\n"
  },
  {
    "path": "examples/multiple-receive/multiple_receive.out",
    "content": "$ bal run multiple_receive.bal\n{\"a\":\"w1\",\"b\":\"w2\"}\n"
  },
  {
    "path": "examples/multiple-wait/multiple_wait.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\ntype Result record {\n    string|error a;\n    string|error b;\n};\n\nfunction multiFetch(string urlA, string urlB) returns Result {\n    worker WA returns string|error {\n        return fetch(urlA);\n    }\n    worker WB returns string|error {\n        return fetch(urlB);\n    }\n\n    // The `wait` action can be used to wait for multiple named workers.\n    return wait {a: WA, b: WB};\n}\n\npublic function main() returns error? {\n    Result res = multiFetch(\"https://postman-echo.com/get?lang=ballerina\",\n                            \"https://postman-echo.com/get?greeting=hello\");\n    io:println(res);\n    return;\n}\n\nfunction fetch(string url) returns string|error {\n    http:Client cl = check new (url);\n    map<json> payload = check cl->get(\"\");\n    return payload[\"args\"].toString();\n}\n"
  },
  {
    "path": "examples/multiple-wait/multiple_wait.md",
    "content": "# Multiple wait\n\nThe `wait` action can be used to wait for multiple named workers. Works with futures also.\n\n::: code multiple_wait.bal :::\n\n::: out multiple_wait.out :::"
  },
  {
    "path": "examples/multiple-wait/multiple_wait.metatags",
    "content": "description: This BBE demonstrates the multiple wait action\nkeywords: ballerina, ballerina by example, bbe, multiple wait, worker\n"
  },
  {
    "path": "examples/multiple-wait/multiple_wait.out",
    "content": "$ bal run multiple_wait.bal\n{\"a\":\"{\"lang\":\"ballerina\"}\",\"b\":\"{\"greeting\":\"hello\"}\"}\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_transaction.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Order` record to load records from `sales_order` table.\ntype Order record {|\n    string id;\n    string orderDate;\n    string productId;\n    int quantity;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function post 'order(Order salesOrder) returns http:Created|error {\n        transaction {\n            // Insert into the `sales_order` table.\n            _ = check self.db->execute(`INSERT INTO MUSIC_STORE.sales_order VALUES \n                                        (${salesOrder.id}, ${salesOrder.orderDate},\n                                         ${salesOrder.productId}, ${salesOrder.quantity});`);\n\n            // Update product quantity as per the order.\n            sql:ExecutionResult inventoryUpdate = check self.db->execute(\n                                        `UPDATE inventory \n                                        SET quantity = quantity - ${salesOrder.quantity} \n                                        WHERE id = ${salesOrder.productId}`);\n\n            // If the product is not found, rollback or commit transaction.\n            if inventoryUpdate.affectedRowCount == 0 {\n                rollback;\n                return error(string `Product ${salesOrder.productId} not found.`);\n            } else {\n                check commit;\n                return http:CREATED;\n            }\n        } on fail error e {\n            // In case of error, the transaction block is rolled back automatically.\n            if e is sql:DatabaseError {\n                if e.detail().errorCode == 3819 {\n                    return error(string `Product ${salesOrder.productId} is out of stock.`);\n                }\n            }\n            return e;\n        }\n    }\n}\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_transaction.client.out",
    "content": "$ curl http://localhost:8080/order -d \"{\\\"id\\\":\\\"S-123\\\", \\\"orderDate\\\":\\\"2022-12-08\\\", \\\"productId\\\":\\\"A-123\\\", \\\"quantity\\\":11}\" -H \"Content-Type: application/json\"\nProduct  A-123  is out of stock.\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_transaction.md",
    "content": "# Database Access - Atomic transactions\n\nThe `mysql:Client` supports atomic units of work with multiple SQL statements. To achieve atomic database transactions use the Ballerina `transaction` package with the `mysql:Client`. The database makes all changes permanent when the transaction is committed or undoes all changes when the transaction is rolled back.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_atomic_transaction.bal :::\n\n## Prerequisite\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_atomic_transaction.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal to post a new order.\n\n::: out mysql_atomic_transaction.client.out :::\n\nThe syntax for using XA transactions (distributed transactions across multiple resources) is the same. Additionally, `useXADatasource` option should be enabled in the client,\n\n::: code mysql_atomic_xa_transaction.bal :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_transaction.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client to execute a batch of DDL/DML operations inside a transaction block in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, mysql, insert, update, delete, batch update, transaction\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_transaction.server.out",
    "content": "$ bal run mysql_atomic_transaction.bal\n"
  },
  {
    "path": "examples/mysql-atomic-transaction/mysql_atomic_xa_transaction.bal",
    "content": "mysql:Client mysqlClient = check new (user = \"root\", password = \"Test@123\", database = \"CUSTOMER\",\n                                      options = {useXADatasource: true});\n"
  },
  {
    "path": "examples/mysql-batch-execute-operation/mysql_batch_execute_operation.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Album` record to load records from `albums` table.\ntype Album record {|\n    string id;\n    string title;\n    string artist;\n    float price;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function post albums(Album[] albums) returns http:Created|error {\n        // Create a batch parameterized query.\n        sql:ParameterizedQuery[] insertQueries = from Album album in albums\n            select `INSERT INTO albums (id, title, artist, price)\n                    VALUES (${album.id}, ${album.title}, ${album.artist}, ${album.price})`;\n\n        // Insert records in a batch.\n        _ = check self.db->batchExecute(insertQueries);\n        return http:CREATED;\n    }\n}\n"
  },
  {
    "path": "examples/mysql-batch-execute-operation/mysql_batch_execute_operation.client.out",
    "content": "$ curl http://localhost:8080/albums -d \"[{\\\"id\\\": \\\"B-121\\\", \\\"title\\\": \\\"Anti\\\", \\\"artist\\\":\\\"Rihanna\\\", \\\"price\\\": 23.99}]\" -H \"Content-Type: application/json\"\n"
  },
  {
    "path": "examples/mysql-batch-execute-operation/mysql_batch_execute_operation.md",
    "content": "# Database Access - Batch execution\n\nThe `mysql:Client` allows executing a batch of DDL/DML statements with the use of `batchExecute` method. This method requires `sql:ParameterizedQuery[]`-typed SQL statements as arguments.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_batch_execute_operation.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_batch_execute_operation.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal to insert new record.\n\n::: out mysql_batch_execute_operation.client.out :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-batch-execute-operation/mysql_batch_execute_operation.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client to execute a batch of DDL/DML operations in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, mysql, insert, update, delete, batch update\n"
  },
  {
    "path": "examples/mysql-batch-execute-operation/mysql_batch_execute_operation.server.out",
    "content": "$ bal run mysql_batch_execute_operation.bal\n"
  },
  {
    "path": "examples/mysql-call-stored-procedures/mysql_call_stored_procedures.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Order` record to load records from `sales_order` table.\ntype Order record {|\n    string id;\n    @sql:Column {name: \"order_date\"}\n    string orderDate;\n    @sql:Column {name: \"product_id\"}\n    string productId;\n    int quantity;\n|};\n\ntype Orders record {|\n    int total;\n    Order[] orders;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function get orders/[string orderDate]() returns Orders|error {\n        // Initializes the `INOUT` and `OUT` parameters for the procedure call.\n        sql:DateValue filterDate = new (orderDate);\n        sql:IntegerOutParameter total = new ();\n\n        // Call the `get_sales_order` stored procedure.\n        sql:ProcedureCallResult result =\n            check self.db->call(`{CALL get_sales_order(${filterDate}, ${total})}`, [Order]);\n\n        // Process procedure-call parameters.\n        int totalCount = check total.get();\n\n        Order[] orders = [];\n        // Process procedure-call query results.\n        stream<record {}, error?>? resultStream = result.queryResult;\n        if resultStream !is () {\n            stream<Order, error?> orderStream = <stream<Order, error?>>resultStream;\n            orders = check from Order 'order in orderStream\n                select 'order;\n        }\n\n        // Cleans up the resources.\n        check result.close();\n\n        return {\n            total: totalCount,\n            orders: orders\n        };\n    }\n}\n"
  },
  {
    "path": "examples/mysql-call-stored-procedures/mysql_call_stored_procedures.client.out",
    "content": "$ curl http://localhost:8080/orders/2022-12-09\n{\"total\":2, \"orders\":[{\"id\":\"S-123\", \"orderDate\":\"2022-12-09\", \"productId\":\"A-123\", \"quantity\":2}, {\"id\":\"S-321\", \"orderDate\":\"2022-12-09\", \"productId\":\"A-321\", \"quantity\":1}]}\n"
  },
  {
    "path": "examples/mysql-call-stored-procedures/mysql_call_stored_procedures.md",
    "content": "# Database Access - Call stored procedures\n\nThe `mysql:Client` allows executing a stored procedure with the use of `call` method. This method requires a `sql:ParameterizedQuery`-typed SQL CALL statement as the argument.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_call_stored_procedures.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_call_stored_procedures.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal to post a new order.\n\n::: out mysql_call_stored_procedures.client.out :::\n\nIf the procedure returns more than one result set, then those can be accessed by using,\n```ballerina\nboolean isAvailable = getNextQueryResult();\n```\nThis will return whether next result set is available and update `queryResult` with the next result set.\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-call-stored-procedures/mysql_call_stored_procedures.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client to execute a stored procedure in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, mysql, call, stored procedure, delete, procedure\n"
  },
  {
    "path": "examples/mysql-call-stored-procedures/mysql_call_stored_procedures.server.out",
    "content": "$ bal run mysql_call_stored_procedures.bal\n"
  },
  {
    "path": "examples/mysql-execute-operation/mysql_execute_operation.bal",
    "content": "import ballerina/http;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\ntype Album record {|\n    string id;\n    string title;\n    string artist;\n    float price;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function post album(Album album) returns Album|error {\n        _ = check self.db->execute(`\n            INSERT INTO Albums (id, title, artist, price)\n            VALUES (${album.id}, ${album.title}, ${album.artist}, ${album.price});`);\n        return album;\n    }\n}\n"
  },
  {
    "path": "examples/mysql-execute-operation/mysql_execute_operation.client.out",
    "content": "curl http://localhost:8080/album -d \"{\\\"id\\\": \\\"B-123\\\", \\\"title\\\": \\\"Loud\\\", \\\"artist\\\":\\\"Rihanna\\\", \\\"price\\\": 23.99}\" -H \"Content-Type: application/json\"\n{\"id\":\"B-123\", \"title\":\"Loud\", \"artist\":\"Rihanna\", \"price\":23.99}"
  },
  {
    "path": "examples/mysql-execute-operation/mysql_execute_operation.md",
    "content": "# Database Access - DML and DDL operations\n\nThe `mysql:Client` allows executing a DDL/DML statement with the use of `execute` method. This method requires a `sql:ParameterizedQuery`-typed SQL DDL/DML statement as the argument.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_execute_operation.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_execute_operation.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mysql_execute_operation.client.out :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-execute-operation/mysql_execute_operation.metatags",
    "content": "description: This BBE demonstrates the use of a MySQL client with DDL and DML operations in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, mysql, insert, update, delete\n"
  },
  {
    "path": "examples/mysql-execute-operation/mysql_execute_operation.server.out",
    "content": "$ bal run mysql_execute_operation.bal\n"
  },
  {
    "path": "examples/mysql-prerequisite/README.md",
    "content": "# Database Access Ballerina By Example - Prerequisites\n\n`Database Access` BBEs are based on a Music Store use-case.\n\nTo set up the MySQL database to run the BBEs, run the bal files by executing the command `bal run`.\n1. setup_database.bal - This creates the `MUSIC_STORE` database and necessary tables.\n2. create_stored_procedure.bal - This creates the `get_sales_order` procedure.\n"
  },
  {
    "path": "examples/mysql-prerequisite/create_stored_procedure.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Initializes the database as a prerequisite to `Database Access - Call stored procedures` sample.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n\n    // Creates the necessary stored procedures using the execute command.\n    _ = check mysqlClient->execute(`CREATE PROCEDURE MUSIC_STORE.get_sales_order(INOUT date DATE, OUT totalCount INT)\n                                    BEGIN\n                                    \tSELECT count(id) INTO totalCount FROM sales_order WHERE order_date = date;\n                                        SELECT * FROM sales_order WHERE order_date = date;\n                                    END`);\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/mysql-prerequisite/setup_database.bal",
    "content": "import ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// Initializes the database as a prerequisite to `Database Access` samples.\npublic function main() returns sql:Error? {\n    mysql:Client mysqlClient = check new (host = \"localhost\", port = 3306, user = \"root\",\n                                          password = \"Test@123\");\n\n    // Creates a database.\n    _ = check mysqlClient->execute(`CREATE DATABASE MUSIC_STORE;`);\n\n    // Creates `albums` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE MUSIC_STORE.albums (\n                                        id VARCHAR(100) NOT NULL PRIMARY KEY,\n                                        title VARCHAR(100),\n                                        artist VARCHAR(100),\n                                        price REAL\n                                    );`);\n\n    // Adds the records to the `albums` table.\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.albums\n                                    VALUES(\"A-123\", \"Lemonade\", \"Beyonce\", 18.98);`);\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.albums\n                                    VALUES(\"A-321\", \"Renaissance\", \"Beyonce\", 24.98);`);\n\n    // Creates `artists` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE MUSIC_STORE.artists (\n                                      artist_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,\n                                      first_name VARCHAR(300),\n                                      last_name VARCHAR(300)\n                                    );`);\n\n    // Adds the records to the `artists` table.\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.artists\n                                    VALUES (1, \"Beyonce\", \"Knowles\");`);\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.artists\n                                    VALUES (2, \"Rihanna\", \"Fenty\");`);\n\n    // Creates `inventory` in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE MUSIC_STORE.inventory (\n                                      id varchar(100) NOT NULL PRIMARY KEY,\n                                      title varchar(100) DEFAULT NULL,\n                                      artist varchar(100) DEFAULT NULL,\n                                      price double DEFAULT NULL,\n                                      quantity int NOT NULL,\n                                      CHECK (quantity > 0)\n                                    );`);\n\n    // Adds the records to the `inventory` table.\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.inventory\n                                    VALUES (\"A-123\", \"Lemonade\", \"Beyonce\", 18.98, 10);`);\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.inventory\n                                    VALUES (\"A-321\", \"Renaissance\", \"Beyonce\", 24.98, 100);`);\n\n    // Creates `sales_order` table in the database.\n    _ = check mysqlClient->execute(`CREATE TABLE MUSIC_STORE.sales_order (\n                                      id varchar(100) NOT NULL PRIMARY KEY,\n                                      order_date DATE NOT NULL,\n                                      product_id varchar(100) NOT NULL,\n                                      quantity int\n                                    );`);\n\n    // Adds the records to the `sales_order` table.\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.sales_order VALUES\n                                    (\"S-123\", \"2022-12-09\", \"A-123\", 2);`);\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.sales_order VALUES\n                                    (\"S-321\", \"2022-12-09\", \"A-321\", 1);`);\n    _ = check mysqlClient->execute(`INSERT INTO MUSIC_STORE.sales_order VALUES\n                                    (\"S-456\", \"2022-12-10\", \"A-321\", 3);`);\n\n    check mysqlClient.close();\n}\n"
  },
  {
    "path": "examples/mysql-query-column-mapping/mysql_query_column_mapping.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Album` record to load records from `albums` table.\ntype Artist record {|\n    @sql:Column {name: \"artist_id\"}\n    int artistId;\n    @sql:Column {name: \"last_name\"}\n    string lastName;\n    @sql:Column {name: \"first_name\"}\n    string firstName;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function get artists() returns Artist[]|error {\n        // Execute simple query to retrieve all records from the `artist` table.\n        stream<Artist, sql:Error?> artistStream = self.db->query(`SELECT * FROM artists;`);\n\n        // Process the stream and convert results to Artist[] or return error.\n        return from Artist artist in artistStream\n            select artist;\n    }\n}\n"
  },
  {
    "path": "examples/mysql-query-column-mapping/mysql_query_column_mapping.client.out",
    "content": "$ curl http://localhost:8080/artists\n[{\"artistId\":1, \"lastName\":\"Knowles\", \"firstName\":\"Beyonce\"}, {\"artistId\":2, \"lastName\":\"Fenty\", \"firstName\":\"Rihanna\"}]\n"
  },
  {
    "path": "examples/mysql-query-column-mapping/mysql_query_column_mapping.md",
    "content": "# Database Access - Query with advanced mapping\n\nThe `mysql:Client` allows querying the database with the use of `query` method. To map the table column name with a different Ballerina record field use the `sql:Column` annotation. \n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_query_column_mapping.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_query_column_mapping.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mysql_query_column_mapping.client.out :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-query-column-mapping/mysql_query_column_mapping.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client for query operations with advanced mapping for column names.\nkeywords: ballerina, ballerina by example, bbe, mysql\n"
  },
  {
    "path": "examples/mysql-query-column-mapping/mysql_query_column_mapping.server.out",
    "content": "$ bal run mysql_query_column_mapping.bal\n"
  },
  {
    "path": "examples/mysql-query-operation/mysql_query_operation.md",
    "content": "# Database Access - Simple query\n\nThe `mysql:Client` allows querying the database with the use of `query` method. This method requires a `sql:ParameterizedQuery`-typed SQL statement as the argument.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_simple_query.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_simple_query.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mysql_simple_query.client.out :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-query-operation/mysql_query_operation.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client select query operations with the stream return type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, MySQL, query, select, data\n"
  },
  {
    "path": "examples/mysql-query-operation/mysql_simple_query.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Album` record to load records from `albums` table.\ntype Album record {|\n    string id;\n    string title;\n    string artist;\n    float price;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function get albums() returns Album[]|error {\n        // Execute simple query to retrieve all records from the `albums` table.\n        stream<Album, sql:Error?> albumStream = self.db->query(`SELECT * FROM albums`);\n\n        // Process the stream and convert results to Album[] or return error.\n        return from Album album in albumStream\n            select album;\n    }\n}\n"
  },
  {
    "path": "examples/mysql-query-operation/mysql_simple_query.client.out",
    "content": "$ curl http://localhost:8080/albums\n[{\"id\":\"A-123\", \"title\":\"Lemonade\", \"artist\":\"Beyonce\", \"price\":18.98}, {\"id\":\"A-321\", \"title\":\"Renaissance\", \"artist\":\"Beyonce\", \"price\":24.98}]\n"
  },
  {
    "path": "examples/mysql-query-operation/mysql_simple_query.server.out",
    "content": "$ bal run mysql_simple_query.bal\n"
  },
  {
    "path": "examples/mysql-query-row-operation/mysql_query_row.bal",
    "content": "import ballerina/http;\nimport ballerina/sql;\nimport ballerinax/mysql;\nimport ballerinax/mysql.driver as _;\n\n// The `Album` record to load records from `albums` table.\ntype Album record {|\n    string id;\n    string title;\n    string artist;\n    float price;\n|};\n\nservice / on new http:Listener(8080) {\n    private final mysql:Client db;\n\n    function init() returns error? {\n        // Initiate the mysql client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.db = check new (\"localhost\", \"root\", \"Test@123\", \"MUSIC_STORE\", 3306);\n    }\n\n    resource function get albums/[string id]() returns Album|http:NotFound|error {\n        // Execute simple query to fetch record with requested id.\n        Album|sql:Error result = self.db->queryRow(`SELECT * FROM albums WHERE id = ${id}`);\n\n        // Check if record is available or not\n        if result is sql:NoRowsError {\n            return http:NOT_FOUND;\n        } else {\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "examples/mysql-query-row-operation/mysql_query_row.client.out",
    "content": "$ curl http://localhost:8080/albums/A-123\n{\"id\":\"A-123\", \"title\":\"Lemonade\", \"artist\":\"Beyonce\", \"price\":18.98}\n"
  },
  {
    "path": "examples/mysql-query-row-operation/mysql_query_row.server.out",
    "content": "$ bal run mysql_query_row.bal\n"
  },
  {
    "path": "examples/mysql-query-row-operation/mysql_query_row_operation.md",
    "content": "# Database Access - Query with one result\n\nThe `mysql:Client` allows querying the database for utmost one result with the use of `queryRow` method. This method requires a `sql:ParameterizedQuery`-typed SQL statement as the argument.\n\n> **Tip**: Checkout [`ballerinax/mssql`](https://central.ballerina.io/ballerinax/mssql), [`ballerinax/postgresql`](https://central.ballerina.io/ballerinax/postgresql), [`ballerinax/oracledb`](https://central.ballerina.io/ballerinax/oracledb), [`ballerinax/java.jdbc`](https://central.ballerina.io/ballerinax/java.jdbc) for other supported database clients.\n\n::: code mysql_query_row.bal :::\n\n## Prerequisites\n- To set up the database, see the [Database Access Ballerina By Example - Prerequisites](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/mysql-prerequisite).\n\nRun the service.\n\n::: out mysql_query_row.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out mysql_query_row.client.out :::\n\n## Related links\n- [`mysql:Client` - API documentation](https://lib.ballerina.io/ballerinax/mysql/latest/)\n- [`mysql:Client` - Specification](https://github.com/ballerina-platform/module-ballerinax-mysql/blob/master/docs/spec/spec.md#2-client)\n"
  },
  {
    "path": "examples/mysql-query-row-operation/mysql_query_row_operation.metatags",
    "content": "description: This BBE demonstrates how to use the MySQL client select query row operations.\nkeywords: ballerina, ballerina by example, bbe, MySQL, query, select, data\n"
  },
  {
    "path": "examples/named-worker-return-values/named_worker_return_values.bal",
    "content": "import ballerina/io;\n\nfunction demo(string s) returns int|error {\n    // Named workers have a return type, which defaults to nil if not specified.\n    worker A returns int|error {\n        // A return statement in a named worker terminates the worker, not the function.\n        // Similarly, when `check` is used and the expression evaluates to an `error`,\n        // the `error` value is returned terminating only the worker.\n        int x = check int:fromString(s);\n        return x + 1;\n    }\n\n    io:println(\"In function worker\");\n\n    // Waiting on a named worker will give its return value.\n    int y = check wait A;\n\n    return y + 1;\n}\n\npublic function main() returns error? {\n    int res = check demo(\"50\");\n    io:println(res);\n\n    res = check demo(\"50m\");\n    io:println(res);\n}\n"
  },
  {
    "path": "examples/named-worker-return-values/named_worker_return_values.md",
    "content": "# Named worker return values\n\nNamed workers have a return type, which defaults to nil. A `return` statement in a named worker terminates the worker, not the function. \n\nSimilarly, when `check` is used and the expression evaluates to an `error`, the `error` value is returned terminating the worker. Waiting on a named worker will give its return value.\n\n::: code named_worker_return_values.bal :::\n\n::: out named_worker_return_values.out :::"
  },
  {
    "path": "examples/named-worker-return-values/named_worker_return_values.metatags",
    "content": "description: This BBE demonstrates named workers with return values\nkeywords: ballerina, ballerina by example, bbe, worker, return\n"
  },
  {
    "path": "examples/named-worker-return-values/named_worker_return_values.out",
    "content": "$ bal run named_worker_return_values.bal\nIn function worker\n52\nIn function worker\nerror: {ballerina/lang.int}NumberParsingError {\"message\":\"'string' value '50m' cannot be converted to 'int'\"}\n"
  },
  {
    "path": "examples/named-worker-with-on-fail-clause/named_worker_with_on_fail_clause.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int[] values = [2, 3, 4, 5];\n    int value = 0;\n\n    worker w1 {\n        int index = check getIndex(values, value);\n        index -> function;\n    } on fail {\n        // Handle the error thrown in the worker body.\n        -1 -> function;\n    }\n\n    int|error:NoMessage result = <- w1 | w1;\n    io:println(result);\n}\n\nfunction getIndex(int[] values, int value) returns int|error =>\n    let int? index = values.indexOf(value) in index ?: error(\"value not found\");\n"
  },
  {
    "path": "examples/named-worker-with-on-fail-clause/named_worker_with_on_fail_clause.md",
    "content": "# Named worker with on fail clause\n\nThe `on fail` clause can be used with a named worker, to handle any errors that occur within the worker's body.\n\n::: code named_worker_with_on_fail_clause.bal :::\n\n::: out named_worker_with_on_fail_clause.out :::\n"
  },
  {
    "path": "examples/named-worker-with-on-fail-clause/named_worker_with_on_fail_clause.metatags",
    "content": "description: This BBE demonstrates the use of `on fail` clause with named workers\nkeywords: ballerina, ballerina by example, bbe, worker, named workers, on fail\n"
  },
  {
    "path": "examples/named-worker-with-on-fail-clause/named_worker_with_on_fail_clause.out",
    "content": "$ bal run named_worker_with_on_fail_clause.bal\n-1\n"
  },
  {
    "path": "examples/named-workers/named_workers.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Code before any named workers are executed before named workers start.\n    io:println(\"Initializing\");\n    final string greeting = \"Hello\";\n\n    // A function can declare named workers, which run concurrently with the function's default worker\n    // and other named workers.\n    worker A {\n        // Variables declared before all named workers and function parameters are accessible by named workers.\n        io:println(greeting + \" from worker A\");\n\n    }\n\n    worker B {\n        io:println(greeting + \" from worker B\");\n    }\n\n    io:println(greeting + \" from function worker\");\n}\n"
  },
  {
    "path": "examples/named-workers/named_workers.md",
    "content": "# Named workers\n\nNormally, all of a function's code belongs to the function's default worker,  which has a single logical thread of control. A function can also declare named workers, which run concurrently with the function's default worker and other named workers.\n\nCode before any named workers is executed before named workers start. Variables declared before all named workers and function parameters are accessible in named workers.\n\n::: code named_workers.bal :::\n\n::: out named_workers.out :::"
  },
  {
    "path": "examples/named-workers/named_workers.metatags",
    "content": "description: This BBE demonstrates how workers can be used for concurrency\nkeywords: ballerina, ballerina by example, bbe, worker, concurrency\n"
  },
  {
    "path": "examples/named-workers/named_workers.out",
    "content": "$ bal run named_workers.bal\nInitializing\nHello from function worker\nHello from worker B\nHello from worker A\n"
  },
  {
    "path": "examples/named-workers-and-futures/named_workers_and_futures.bal",
    "content": "import ballerina/io;\n\nfunction demo() returns future<int> {\n    worker A returns int {\n        return 42;\n    }\n\n    // A reference to a named worker can be implicitly converted into a `future`.\n    return A;\n}\n\ntype FuncInt function () returns int;\n\nfunction startInt(FuncInt f) returns future<int> {\n    // `start` is sugar for calling a function with a named worker and returning the named worker as a `future`.\n    return start f();\n}\n\npublic function main() returns error? {\n    future<int> a = demo();\n    int b = check wait a;\n    io:println(b);\n\n    future<int> c = startInt(() => 100);\n    int d = check wait c;\n    io:println(d);\n}\n"
  },
  {
    "path": "examples/named-workers-and-futures/named_workers_and_futures.md",
    "content": "# Named workers and futures\n\nFutures and workers are the same thing. A reference to a named worker can be implicitly converted into a `future`. `start` is sugar for calling a function with a named worker and returning the named worker as a `future`.\n\nCancellation of futures only happens at yield points.\n\n::: code named_workers_and_futures.bal :::\n\n::: out named_workers_and_futures.out :::"
  },
  {
    "path": "examples/named-workers-and-futures/named_workers_and_futures.metatags",
    "content": "description: This BBE demonstrates futures\nkeywords: ballerina, ballerina by example, bbe, future\n"
  },
  {
    "path": "examples/named-workers-and-futures/named_workers_and_futures.out",
    "content": "$ bal run named_workers_and_futures.bal\n42\n100\n"
  },
  {
    "path": "examples/nats-basic-pub/nats_basic_pub.bal",
    "content": "import ballerina/http;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final nats:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the NATS client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (nats:DEFAULT_URL);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Produces a message to the specified subject.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            subject: \"orders.valid\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/nats-basic-pub/nats_basic_pub.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/nats-basic-pub/nats_basic_pub.md",
    "content": "# NATS client - Publish message\n\nThe `nats:Client` allows publishing messages to a given subject. A `nats:Client` is created by passing the URL of the NATS broker. To publish messages, the `publishMessage` method is used, which requires the message and subject as arguments. Use it to publish messages that can be received by one or more subscribers.\n\n::: code nats_basic_pub.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n- Run the NATS service given in the [NATS service - Consume message](/learn/by-example/nats-basic-sub/) example.\n\nRun the client program by executing the following command.\n\n::: out nats_basic_pub.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out nats_basic_pub.client.out :::\n\n## Related links\n- [`nats:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#Client)\n- [NATS publishing - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#3-publishing)\n"
  },
  {
    "path": "examples/nats-basic-pub/nats_basic_pub.metatags",
    "content": "description: This example demonstrates producing a message to a subject in the NATS basic server.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, server, publish, subscribe\n"
  },
  {
    "path": "examples/nats-basic-pub/nats_basic_pub.server.out",
    "content": "$ bal run nats_basic_pub.bal\n"
  },
  {
    "path": "examples/nats-basic-reply/nats_basic_reply.bal",
    "content": "import ballerina/log;\nimport ballerinax/nats;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Binds the consumer to listen to the messages published to the 'orders.valid' subject.\nservice \"orders.valid\" on new nats:Listener(nats:DEFAULT_URL) {\n\n    remote function onRequest(Order 'order) returns string|error {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n            return \"Received valid order!\";\n        } else {\n            return \"Received invalid order!\";\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-basic-reply/nats_basic_reply.md",
    "content": "# NATS service - Send reply to request message\n\nThe `nats:Service` allows listening to a given subject for incoming messages and sending responses. A `nats:Listener` is created by passing the URL of the NATS broker. A `nats:Service` attached to the listener can be used to send replies to incoming request messages using the `onRequest` remote method. The subject to listen to should be given as the service name or in the `subject` field of the `nats:ServiceConfig`. Use it to send reply messages to the request messages consumed by the subscriber.\n\n::: code nats_basic_reply.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the service by executing the following command.\n\n::: out nats_basic_reply.out :::\n\n>**Tip:** You can invoke the above service via the [NATS client](/learn/by-example/nats-basic-request/).\n\n## Related links\n- [`nats` package - API documentation](https://lib.ballerina.io/ballerinax/nats/latest)\n- [NATS subscribing - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#4-subscribing)\n"
  },
  {
    "path": "examples/nats-basic-reply/nats_basic_reply.metatags",
    "content": "description: This example demonstrates sending a reply message to a request received by a NATS subject.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, server, request, reply\n"
  },
  {
    "path": "examples/nats-basic-reply/nats_basic_reply.out",
    "content": "$ bal run nats-basic-reply.bal\ntime = 2021-05-19T10:14:09.200+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/nats-basic-request/nats_basic_request.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic type StringMessage record {|\n    *nats:AnydataMessage;\n    string content;\n|};\n\nservice / on new http:Listener(9092) {\n    private final nats:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the NATS client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (nats:DEFAULT_URL);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n    \n        // Sends a request and returns the reply.\n        StringMessage reply = check self.orderClient->requestMessage({\n            content: newOrder,\n            subject: \"orders.valid\"\n        });\n\n        log:printInfo(\"Reply message: \" + reply.content);\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/nats-basic-request/nats_basic_request.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/nats-basic-request/nats_basic_request.md",
    "content": "# NATS client - Send request message\n\nThe `nats:Client` allows sending request messages to a given subject. A `nats:Client` is created by passing the URL of the NATS broker. The `requestMessage` method can be used to send requests to the NATS server by providing a target subject, an optional reply subject, the message content, and an optional duration for the timeout. After the request is sent, the application waits on the response with the given timeout. Use it to send request messages, which expect a reply back.\n\n::: code nats_basic_request.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n- Run the NATS service given in the [NATS service - Send reply to request message](/learn/by-example/nats-basic-reply/) example.\n\nRun the client program by executing the following command.\n\n::: out nats_basic_request.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out nats_basic_request.client.out :::\n\n## Related links\n- [`nats:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#Client)\n- [NATS publishing - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#3-publishing)\n"
  },
  {
    "path": "examples/nats-basic-request/nats_basic_request.metatags",
    "content": "description: This example demonstrates sending a request to a NATS subject in a basic NATS server.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, server, request, reply\n"
  },
  {
    "path": "examples/nats-basic-request/nats_basic_request.server.out",
    "content": "$ bal run nats_basic_request.bal\ntime = 2022-12-13T20:48:14.375+05:30 level = INFO module = \"\" message = \"Reply message: Received valid order!\"\n"
  },
  {
    "path": "examples/nats-basic-sub/nats_basic_sub.bal",
    "content": "import ballerina/log;\nimport ballerinax/nats;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Binds the consumer to listen to the messages published to the 'orders.valid' subject.\nservice \"orders.valid\" on new nats:Listener(nats:DEFAULT_URL) {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-basic-sub/nats_basic_sub.md",
    "content": "# NATS service - Consume message\n\nThe `nats:Service` listens to the given subject for incoming messages. When a publisher sends a message to a subject, any active service listening to that subject receives the message. A `nats:Listener`  is created by passing the URL of the NATS broker. A `nats:Service` attached to the `nats:Listener` can be used to listen to a specific subject and consume incoming messages. The subject to listen to should be given as the service name or in the `subject` field of the `nats:ServiceConfig`. Use it to listen to messages sent to a particular subject.\n\n::: code nats_basic_sub.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the service by executing the following command.\n\n::: out nats_basic_sub.out :::\n\n>**Tip:** You can invoke the above service via the [NATS client](/learn/by-example/nats-basic-pub/).\n\n## Related links\n- [`nats` package - API documentation](https://lib.ballerina.io/ballerinax/nats/latest)\n- [NATS subscribing - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#4-subscribing)\n"
  },
  {
    "path": "examples/nats-basic-sub/nats_basic_sub.metatags",
    "content": "description: This example demonstrates consuming messages from a NATS subject in a basic NATS server.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, server, publish, subscribe\n"
  },
  {
    "path": "examples/nats-basic-sub/nats_basic_sub.out",
    "content": "$ bal run nats-basic-sub.bal\ntime = 2021-05-19T10:15:49.269+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/nats-client-basic-auth/nats_client_basic_auth.bal",
    "content": "import ballerina/http;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final nats:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the NATS client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (nats:DEFAULT_URL,\n           // To secure the client connections using username/password authentication, provide the credentials\n           // with the `nats:Credentials` record.\n           auth = {\n               username: \"alice\",\n               password: \"alice@123\"\n           }\n        );\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Produces a message to the specified subject.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            subject: \"orders.valid\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/nats-client-basic-auth/nats_client_basic_auth.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/nats-client-basic-auth/nats_client_basic_auth.md",
    "content": "# NATS client - Basic authentication\n\nThe NATS authentication allows securing the client communication with the server. In this example, the underlying connection of the client is secured with Basic Authentication. A secured `nats:Client` can be created by passing the URL of the NATS broker and providing the authentication details using the `nats:Credentials` record. Use it to authenticate client connections using a username and password.\n\n::: code nats_client_basic_auth.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the client program by executing the following command.\n\n::: out nats_client_basic_auth.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out nats_client_basic_auth.client.out :::\n\n## Related links\n- [`nats:Credentials` - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#Credentials)\n- [NATS connection - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/nats-client-basic-auth/nats_client_basic_auth.metatags",
    "content": "description: This example demonstrates producing a message to a NATS subject using a connection with basic authentication.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, ssl, tls, authentication\n"
  },
  {
    "path": "examples/nats-client-basic-auth/nats_client_basic_auth.server.out",
    "content": "$ bal run nats_client_basic_auth.bal\n"
  },
  {
    "path": "examples/nats-client-secure-connection/nats_client_secure_connection.bal",
    "content": "import ballerina/http;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final nats:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the NATS client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (nats:DEFAULT_URL,\n            // To secure the client connection using TLS/SSL, the client needs to be configured with\n            // a certificate file of the server.\n            secureSocket = {\n                cert: \"../resource/path/to/public.crt\"\n            }\n        );\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Produces a message to the specified subject.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            subject: \"orders.valid\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/nats-client-secure-connection/nats_client_secure_connection.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/nats-client-secure-connection/nats_client_secure_connection.md",
    "content": "# NATS client - SSL/TLS\n\nThe `nats:Client` can be configured to connect to the server via SSL/TLS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the `nats:ConnectionConfiguration`. Use this to secure the communication between the client and the server.\n\n::: code nats_client_secure_connection.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the client program by executing the following command.\n\n::: out nats_client_secure_connection.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out nats_client_secure_connection.client.out :::\n\n## Related links\n- [`nats:SecureSocket` - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#SecureSocket)\n- [NATS connection- Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/nats-client-secure-connection/nats_client_secure_connection.metatags",
    "content": "description: This example demonstrates producing a message to a NATS subject using a secured connection.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, ssl, tls, authentication\n"
  },
  {
    "path": "examples/nats-client-secure-connection/nats_client_secure_connection.server.out",
    "content": "$ bal run nats_client_secure_connection.bal\n"
  },
  {
    "path": "examples/nats-jetstream-pub/nats_jetstream_pub.bal",
    "content": "import ballerina/http;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final string SUBJECT_NAME = \"orders\";\n    private final nats:JetStreamClient orderClient;\n\n    function init() returns error? {\n        // Initiate a NATS client passing the URL of the NATS broker.\n        nats:Client natsClient = check new (nats:DEFAULT_URL);\n\n        // Initiate the NATS `JetStreamClient` at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (natsClient);\n        nats:StreamConfiguration config = {\n            name: \"demo\",\n            subjects: [self.SUBJECT_NAME],\n            storageType: nats:MEMORY\n        };\n        _ = check self.orderClient->addStream(config);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Produce a message to the specified subject.\n        check self.orderClient->publishMessage({\n            subject: self.SUBJECT_NAME,\n            content: newOrder.toString().toBytes()\n        });\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/nats-jetstream-pub/nats_jetstream_pub.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/nats-jetstream-pub/nats_jetstream_pub.md",
    "content": "# NATS JetStream client - Publish message\n\nThe `nats:JetStreamClient` allows you to publish messages to a specific subject. To create a `nats:JetStreamClient`, you need to provide a valid instance of the `nats:Client`. Before publishing messages, you should call the `addStream` function to configure the stream. This function requires a `nats:JetStreamConfiguration` object with the `name`, `subjects`, and `storageType` values. To publish messages, you can use the `publishMessage` method, which takes the message content and subject as arguments. This method allows you to send messages that can be received by one or more subscribers.\n\n::: code nats_jetstream_pub.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS JetStream server](https://docs.nats.io/running-a-nats-service/configuration/resource_management).\n- Run the NATS JetStream service given in the [NATS JetStream service - Consume message](/learn/by-example/nats-jetstream-sub/) example.\n\nRun the client program by executing the following command.\n\n::: out nats_jetstream_pub.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out nats_jetstream_pub.client.out :::\n\n## Related links\n- [`nats:JetStreamClient` client object - API documentation](https://lib.ballerina.io/ballerinax/nats/latest/clients/JetStreamClient)\n"
  },
  {
    "path": "examples/nats-jetstream-pub/nats_jetstream_pub.metatags",
    "content": "description: This example demonstrates producing a message to a subject in a NATS JetStream server.\nkeywords: ballerina, ballerina by example, bbe, nats, jetstream, server, publish, subscribe\n"
  },
  {
    "path": "examples/nats-jetstream-pub/nats_jetstream_pub.server.out",
    "content": "$ bal run nats_jetstream_pub.bal\n"
  },
  {
    "path": "examples/nats-jetstream-sub/nats_jestream_sub.bal",
    "content": "import ballerina/log;\nimport ballerinax/nats;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Initiate a NATS client passing the URL of the NATS broker.\nnats:Client natsClient = check new (nats:DEFAULT_URL);\n\n// Initialize a NATS JetStream listener.\nlistener nats:JetStreamListener subscription = new (natsClient);\nconst string SUBJECT_NAME = \"orders\";\n\n@nats:StreamServiceConfig {\n    subject: SUBJECT_NAME,\n    autoAck: false\n}\n// Bind the consumer to listen to the messages published to the 'orders' subject.\nservice nats:JetStreamService on subscription {\n    remote function onMessage(nats:JetStreamMessage message) returns error? {\n        string stringContent = check string:fromBytes(message.content);\n        json jsonContent = check stringContent.fromJsonString();\n        Order 'order = check jsonContent.cloneWithType();\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-jetstream-sub/nats_jestream_sub.md",
    "content": "# NATS JetStream service - Consume message\n\nThe `nats:JetStreamService` listens to a specified subject for incoming messages. Whenever a publisher sends a message to that subject, any active service listening to it will receive the message. You need to provide an instance of the `nats:Client` to create a `nats:JetStreamListener`. Once you have a `nats:JetStreamListener`, you can attach a `nats:JetStreamService` to it in order to listen to a specific subject and consume incoming messages. The subject to listen to can be either specified as the service path or provided in the `subject` field of the `nats:StreamServiceConfig`. This setup allows you to effectively listen to messages sent to a particular subject.\n\n::: code nats_jestream_sub.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS JetStream server](https://docs.nats.io/running-a-nats-service/configuration/resource_management).\n\nRun the service by executing the following command.\n\n::: out nats_jestream_sub.out :::\n\n>**Tip:** You can invoke the above service via the [NATS JetStream client](/learn/by-example/nats-jetstream-pub/).\n\n## Related links\n- [`nats` package - API documentation](https://lib.ballerina.io/ballerinax/nats/latest)\n"
  },
  {
    "path": "examples/nats-jetstream-sub/nats_jestream_sub.metatags",
    "content": "description: This example demonstrates consuming messages from a subject in a NATS JetStream server.\nkeywords: ballerina, ballerina by example, bbe, nats, jetstream, server, publish, subscribe\n"
  },
  {
    "path": "examples/nats-jetstream-sub/nats_jestream_sub.out",
    "content": "$ bal run nats_jetstream_sub.bal\ntime = 2023-06-20T20:17:28.026+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/nats-service-basic-auth/nats_service_basic_auth.bal",
    "content": "import ballerina/log;\nimport ballerinax/nats;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Initializes a NATS listener with TLS/SSL and username/password authentication.\nlistener nats:Listener orderListener = new (nats:DEFAULT_URL,\n    // To secure the client connections using username/password authentication, provide the credentials\n    // with the `nats:Credentials` record.\n    auth = {\n         username: \"alice\",\n         password: \"alice@123\"\n    }\n);\n\n// Binds the consumer to listen to the messages published to the 'orders.valid' subject.\nservice \"orders.valid\" on orderListener {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-service-basic-auth/nats_service_basic_auth.md",
    "content": "# NATS service - Basic authentication\n\nThe NATS authentication allows securing the client communication with the server. In this example, the underlying connection of the listener is secured with Basic Authentication. A secured `nats:Listener` can be created by passing the URL of the NATS broker and providing the authentication details using the `nats:Credentials` record. Use it to authenticate client connections using a username and password.\n\n::: code nats_service_basic_auth.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the service by executing the following command.\n\n::: out nats_service_basic_auth.out :::\n\n## Related links\n- [`nats:Credentials` - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#Credentials)\n- [NATS connection - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/nats-service-basic-auth/nats_service_basic_auth.metatags",
    "content": "description: This example demonstrates consuming messages from a NATS subject using a connection with basic authentication.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, ssl, tls, authentication\n"
  },
  {
    "path": "examples/nats-service-basic-auth/nats_service_basic_auth.out",
    "content": "$ bal run nats-service-basic-auth.bal\ntime = 2021-05-19T10:15:49.269+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/nats-service-constraint-validation/nats_service_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerina/log;\nimport ballerinax/nats;\n\npublic type Order record {\n    int orderId;\n    // Add a constraint to allow only string values of length between 1 and 30.\n    @constraint:String {maxLength: 30, minLength: 1}\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Binds the consumer to listen to the messages published to the 'orders.valid' subject.\nservice \"orders.valid\" on new nats:Listener(nats:DEFAULT_URL) {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n\n    // When an error occurs, `onError` gets invoked.\n    remote function onError(nats:AnydataMessage message, nats:Error err) {\n        if err is nats:PayloadValidationError {\n            log:printError(\"Payload validation failed\", err);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-service-constraint-validation/nats_service_constraint_validation.md",
    "content": "# NATS service - Constraint validation\n\nThe Ballerina constraint module allows you to add additional constraints to the message content. The constraints can be added to a given data type using different annotations. When a message with a constraint is received from the NATS server, it is validated internally. This validation happens soon after the successful data-binding of the message content before executing the `onMessage` remote method. If the validation fails, the `onError` remote method is invoked with the error type `nats:PayloadValidationError`. Use this to validate the message content as the application receives it, which allows you to guard against unnecessary remote method processing and malicious content.\n\n::: code nats_service_constraint_validation.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the service by executing the following command.\n\n::: out nats_service_constraint_validation.out :::\n\n>**Tip:** You can invoke the above service via the [NATS client](/learn/by-example/nats-basic-pub/) example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.\n\n## Related links\n- [`nats:PayloadValidationError` error type - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#PayloadValidationError)\n- [`nats` package - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md)\n- [`constraint` package - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n"
  },
  {
    "path": "examples/nats-service-constraint-validation/nats_service_constraint_validation.metatags",
    "content": "description: This example demonstrates validating a payload according to the constraints defined in the payload record.\nkeywords: ballerina, ballerina by example, bbe, nats, consumer, listener, service, constraint, validation\n"
  },
  {
    "path": "examples/nats-service-constraint-validation/nats_service_constraint_validation.out",
    "content": "$ bal run nats_service_constraint_validation.bal\ntime = 2022-12-05T08:44:43.093+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\ntime = 2022-12-05T08:45:03.136+05:30 level = ERROR module = \"\" message = \"Payload validation failed\" error = \"Validation failed for \\'$.productName:maxLength\\' constraint(s).\"\ntime = 2022-12-05T08:45:19.702+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/nats-service-secure-connection/nats_service_secure_connection.bal",
    "content": "import ballerina/log;\nimport ballerinax/nats;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// Initializes a NATS listener with TLS/SSL and username/password authentication.\nlistener nats:Listener orderListener = new (nats:DEFAULT_URL,\n    // To secure the client connection using TLS/SSL, the client needs to be configured with\n    // a certificate file of the server.\n    secureSocket = {\n        cert: \"../resource/path/to/public.crt\"\n    }\n);\n\n// Binds the consumer to listen to the messages published to the 'orders.valid' subject.\nservice \"orders.valid\" on orderListener {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/nats-service-secure-connection/nats_service_secure_connection.md",
    "content": "# NATS service - SSL/TLS\n\nThe `nats:Listener` can be configured to connect to the server via SSL/TLS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the `nats:ConnectionConfiguration`. Use this to secure the communication between the client and the server.\n\n::: code nats_service_secure_connection.bal :::\n\n## Prerequisites\n- Start an instance of the [NATS server](https://docs.nats.io/nats-concepts/what-is-nats/walkthrough_setup).\n\nRun the service by executing the following command.\n\n::: out nats_service_secure_connection.out :::\n\n## Related links\n- [`nats:SecureSocket` - API documentation](https://lib.ballerina.io/ballerinax/nats/latest#SecureSocket)\n- [NATS connection - Specification](https://github.com/ballerina-platform/module-ballerinax-nats/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/nats-service-secure-connection/nats_service_secure_connection.metatags",
    "content": "description: This example demonstrates consuming messages from a NATS subject using a secured connection.\nkeywords: ballerina, ballerina by example, bbe, nats, basic, ssl, tls, authentication\n"
  },
  {
    "path": "examples/nats-service-secure-connection/nats_service_secure_connection.out",
    "content": "$ bal run nats-service-secure-connection.bal\ntime = 2021-05-19T10:15:49.269+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/natural-expressions/natural_expressions.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Use the default model provider (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider model = check ai:getDefaultModelProvider();\n\n# Represents a tourist attraction.\ntype Attraction record {|\n    # The name of the attraction\n    string name;\n    # The city where the attraction is located\n    string city;\n    # A notable feature or highlight of the attraction\n    string highlight;\n|};\n\nfunction getAttractions(int count, string country, string interest) \n                            returns Attraction[]|error {\n    // Use a natural expression to get attractions.\n    // The JSON schema generated for the expected type (`Attraction[]`) is \n    // used in the request to the large language model, and the\n    // result is automatically parsed into an array of `Attraction` records.\n    Attraction[]|error attractions = \n        // Specify the model provider in the natural expression.\n        // Use insertions to insert expressions (e.g., parameters) into the prompt.\n        natural (model) {\n            Give me the top ${count} tourist attractions in ${country} \n            for visitors interested in ${interest}. \n            \n            For each attraction, the highlight should be one sentence\n            describing what makes it special or noteworthy.\n        };\n    return attractions;\n}\n\npublic function main() returns error? {\n    Attraction[] attractions = check getAttractions(3, \"Sri Lanka\", \"Wildlife\");\n    foreach Attraction attraction in attractions {\n        io:println(\"Name: \", attraction.name);\n        io:println(\"City: \", attraction.city);\n        io:println(\"Highlight: \", attraction.highlight, \"\\n\");\n    }\n}\n"
  },
  {
    "path": "examples/natural-expressions/natural_expressions.md",
    "content": "# Natural expressions\n\nNatural expressions provide a language-level abstraction for integrating with large language models (LLMs), enabling developers to seamlessly combine natural language instructions with Ballerina code while maintaining programming language principles and leveraging the strengths of the type system. Unlike simple method calls, natural expressions clearly distinguish between traditional logic and LLM-driven logic.\n\nNatural expressions use the `ai:ModelProvider` type as a unified interface for working with different LLM providers such as [ballerinax/ai.openai](https://central.ballerina.io/ballerinax/ai.openai/latest), [ballerinax/ai.anthropic](https://central.ballerina.io/ballerinax/ai.anthropic/latest), and others. The expression automatically generates a JSON schema from the expected return type, sends the prompt to the LLM, and binds the response to the specified type.\n\n> Note: This example uses the default model provider implementation. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` model provider implementation.\n\n> Note: This feature is supported on Swan Lake Update 13 - Milestone 3 (2201.13.0-m3) or newer versions. This is currently an experimental feature and requires the `--experimental` flag to be used with `bal` commands.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code natural_expressions.bal :::\n\n::: out natural_expressions.out :::\n\n## Related links\n\n- [Natural Language is Code: A hybrid approach with Natural Programming](https://blog.ballerina.io/posts/2025-04-26-introducing-natural-programming/)\n- [The `ballerinax/ai.anthropic` module](https://central.ballerina.io/ballerinax/ai.anthropic/latest)\n- [The `ballerinax/ai.azure` module](https://central.ballerina.io/ballerinax/ai.azure/latest)\n- [The `ballerinax/ai.openai` module](https://central.ballerina.io/ballerinax/ai.openai/latest)\n- [The `ballerinax/ai.ollama` module](https://central.ballerina.io/ballerinax/ai.ollama/latest)\n- [The `ballerinax/ai.deepseek` module](https://central.ballerina.io/ballerinax/ai.deepseek/latest)\n- [The `ballerinax/ai.mistral` module](https://central.ballerina.io/ballerinax/ai.mistral/latest)\n"
  },
  {
    "path": "examples/natural-expressions/natural_expressions.metatags",
    "content": "description: This BBE demonstrates how to do direct LLM calls using natural expressions.\nkeywords: ballerina, ballerina by example, BBE, ai, llm, model-provider, natural expressions\n"
  },
  {
    "path": "examples/natural-expressions/natural_expressions.out",
    "content": "$ bal run --experimental natural_expressions.bal\nName: Yala National Park\nCity: Yala\nHighlight: Home to the highest density of leopards in the world, Yala offers thrilling wildlife safaris.\n\nName: Wilpattu National Park\nCity: Wilpattu\nHighlight: Famous for its natural lakes and diverse wildlife, including elephants and sloth bears.\n\nName: Udawalawe National Park\nCity: Udawalawe\nHighlight: Known for its large herds of elephants, Udawalawe is a sanctuary for these magnificent creatures.\n"
  },
  {
    "path": "examples/nested-arrays/nested_arrays.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Declare an array of length 3, where the members are arrays of length 2.\n    string[3][2] orderItems = [[\"carrot\", \"apple\"], [\"avocado\", \"egg\"], [\"fish\", \"banana\"]];\n    io:println(orderItems);\n\n    // Declare an array of length 2, where the element type is an array of variable length.\n    string[2][] orderItems2 = [[\"carrot\", \"apple\"], [\"avocado\", \"egg\", \"fish\", \"banana\"]];\n    io:println(orderItems2);\n\n    // Inferring supported only for the first dimension of the array type descriptor\n    string[*][] orderItems3 = [[\"carrot\", \"apple\"], [\"avocado\", \"egg\", \"fish\", \"banana\"]];\n    io:println(orderItems3);\n\n    // Accessing a nested array.\n    // This will access first item of the third order.\n    string item = orderItems3[1][0];\n    io:println(item);\n\n    // Updating a nested array.\n    // This will update first item of the third order.\n    orderItems3[1][0] = \"apple\";\n    io:println(orderItems3);\n}\n"
  },
  {
    "path": "examples/nested-arrays/nested_arrays.md",
    "content": "# Nested arrays\n\nBallerina supports nested arrays where the element type is also an array type `T[p][q][r]`. Specifically, `T[p][q][r]` is interpreted as `((T[r])[q])[p]`. Hence, `T[p][q]` will construct an array of size `p` where the element type is `T[q]`. This is to be aligned with the member access expression where `v[i][j]` will evaluate to a value of type `T` if and only if `0 ≤ i ≤ p` and `0 ≤ j ≤ q`.\n\n::: code nested_arrays.bal :::\n\n::: out nested_arrays.out :::\n\n## Related links\n- [Arrays](/learn/by-example/arrays)\n- [Manipulating an array `(lang.array)`](https://lib.ballerina.io/ballerina/lang.array)\n- [Tuples](/learn/by-example/tuples)\n- [Filler values of a list](/learn/by-example/filler-values-of-a-list)\n- [List sub typing](/learn/by-example/list-subtyping)\n- [List equality](/learn/by-example/list-equality)\n"
  },
  {
    "path": "examples/nested-arrays/nested_arrays.metatags",
    "content": "description: BBE on creating nested array, create multidimensional array, create array of arrays, Accessing a nested array, Updating a nested array.\nkeywords: ballerina, ballerina by example, bbe, collection, array, multidimensional, nested, array of arrays, list, access, update, matrix\n"
  },
  {
    "path": "examples/nested-arrays/nested_arrays.out",
    "content": "$ bal run nested_arrays.bal\n[[\"carrot\",\"apple\"],[\"avocado\",\"egg\"],[\"fish\",\"banana\"]]\n[[\"carrot\",\"apple\"],[\"avocado\",\"egg\",\"fish\",\"banana\"]]\n[[\"carrot\",\"apple\"],[\"avocado\",\"egg\",\"fish\",\"banana\"]]\navocado\n[[\"carrot\",\"apple\"],[\"apple\",\"egg\",\"fish\",\"banana\"]]\n"
  },
  {
    "path": "examples/nested-query-expressions/nested_query_expressions.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    string name;\n    int age;\n|};\n\npublic function main() {\n    Person[] teamA = [{name: \"Alex\", age: 23}, {name: \"John\", age: 24}];\n    Person[] teamB = [{name: \"Ranjan\", age: 30}, {name: \"Bob\", age: 28}];\n\n    var battles = from var personA in teamA\n                  from var personB in teamB\n                  select string `${personA.name} vs ${personB.name}`;\n    io:println(battles);\n}\n"
  },
  {
    "path": "examples/nested-query-expressions/nested_query_expressions.md",
    "content": "# Nested query expressions\n\nIntermediate clauses of a query expression can contain another query expression and there is no limit to the amount of such nested query expressions. This is similar to nested `foreach` statements. Nested query expressions are useful to create complex query expressions. Execution will happen according to the respective clauses.\n\n::: code nested_query_expressions.bal :::\n\n::: out nested_query_expressions.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n"
  },
  {
    "path": "examples/nested-query-expressions/nested_query_expressions.metatags",
    "content": "description: This BBE demonstrates multiple query expressions, nested query expressions, and inner query expressions.\nkeywords: ballerina, ballerina by example, bbe, nested, query, join, inner\n"
  },
  {
    "path": "examples/nested-query-expressions/nested_query_expressions.out",
    "content": "$ bal run nested_query_expressions.bal\n[\"Alex vs Ranjan\",\"Alex vs Bob\",\"John vs Ranjan\",\"John vs Bob\"]\n"
  },
  {
    "path": "examples/never-type/never_type.bal",
    "content": "import ballerina/io;\n\ntype Pair record {\n    int x;\n    int y;\n};\n\nPair p = {\n    x: 1,\n    y: 2,\n    \"color\": \"blue\"\n};\n\n// This is a record with two `x` and `y` optional fields of the `never` type.\n// However, as you cannot have values of the `never` type,\n// the net result is that you cannot have the `x` and `y`fields in the record.\ntype PairRest record { \n    never x?; \n    never y?; \n};\n\n// The function always panics. It never returns normally.\n// Therefore, the return type can be defined as `never`.\nfunction whoops() returns never {\n    panic error(\"whoops\");\n}\n\npublic function main() {\n    // `xml<never>` describes the XML type that has no constituents.\n    // Therefore `x` is an empty XML sequence.\n    xml<never> x = xml ``;\n    io:println(x);\n\n    // The `rest` variable contains the fields in `p` other than `x` and `y`.\n    var {x: _, y: _, ...rest} = p;\n    // Type of `rest` is a subtype of `PairRest`.\n    PairRest pairRest = rest;\n    io:println(pairRest);\n    // Call the function that always panics.\n    whoops();\n}\n"
  },
  {
    "path": "examples/never-type/never_type.md",
    "content": "# Never type\n\nThe `never` type is the type to which no value belongs.\n\n::: code never_type.bal :::\n\n::: out never_type.out :::"
  },
  {
    "path": "examples/never-type/never_type.metatags",
    "content": "description: This BBE demonstrates the `never` type in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, never, never type\n"
  },
  {
    "path": "examples/never-type/never_type.out",
    "content": "bal run never_type.bal\n\n{\"color\":\"blue\"}\nerror: whoops\n\tat never_type:whoops(never_type.bal:25)\n\t   never_type:main(never_type.bal:40)\n"
  },
  {
    "path": "examples/nil/nil.bal",
    "content": "import ballerina/io;\n\n// Here type `int?` indicates that the value of `v` can be an `int` or `()`.\nint? v = ();\n\n// Here the value of `n` cannot be `()`.\nint? n = v == () ? 0 : v;\n\n// Elvis operator `x ?: y` returns `x` if it is not `nil` and `y` otherwise.\nint m = v ?: 0;\n\n// Falling off the end of a function or `return` by itself is equivalent to `return ()`.\nfunction foo() returns () {\n    return ();\n}\n\n// Leaving off return type is equivalent to `returns ()`.\npublic function main() {\n    io:println(v);\n}\n"
  },
  {
    "path": "examples/nil/nil.md",
    "content": "# Nil\n\nBallerina's version of `null` is called nil and written as `()`. Ballerina types do not implicitly allow nil. Type `T?` means `T` or nil. You can use `==` and `!=` to test whether a value is nil: no implicit conversion to `boolean`.\n\n::: code nil.bal :::\n\n::: out nil.out :::\n"
  },
  {
    "path": "examples/nil/nil.metatags",
    "content": "description: This BBE introduces the nil type in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, nil, null\n"
  },
  {
    "path": "examples/nil/nil.out",
    "content": "$ bal run nil.bal\n"
  },
  {
    "path": "examples/object/object.bal",
    "content": "import ballerina/io;\n\nclass Engineer {\n    string name;\n\n    function init(string name) {\n        self.name = name;\n    }\n\n    function getName() returns string {\n        return self.name;\n    }\n}\n\npublic function main() {\n    // Apply the `new` operator with a `class` to get an `object` value.\n    Engineer engineer = new Engineer(\"Alice\");\n\n    // Call the `getName` method using the `obj.method(args)` syntax.\n    string engineerName = engineer.getName();\n    io:println(engineerName);\n\n    // Accessing the `name`  field using the `obj.field` syntax.\n    engineerName = engineer.name;\n    io:println(engineerName);\n}\n"
  },
  {
    "path": "examples/object/object.md",
    "content": "# Object\n\nThe `object` is a basic data type in Ballerina. An object value has named methods and fields and these methods and fields share the same symbol space. This means that it is not possible for an object to have both a field and a method with the same name.\n\nA `class` is used to define an object type and provides a way to construct an object. The `new` expression is used to create an object from a `class` definition.\n\n::: code object.bal :::\n\n::: out object.out :::\n\n## Related links\n- [Defining classes](/learn/by-example/defining-classes/)\n- [Object constructor](/learn/by-example/object-constructor/)\n- [Object value from class definition](/learn/by-example/object-value-from-class-definition/)\n- [Visibility of object fields and methods](/learn/by-example/visibility-of-object-fields-and-methods/)\n- [Object types](/learn/by-example/object-types/)\n- [Object closure](/learn/by-example/object-closure/)\n"
  },
  {
    "path": "examples/object/object.metatags",
    "content": "description: This BBE demonstrates defining a class, creating an object from the class definition, invoking object methods, and accessing object fields in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object, class, new\n"
  },
  {
    "path": "examples/object/object.out",
    "content": "$ bal run object.bal\nAlice\nAlice\n"
  },
  {
    "path": "examples/object-closure/object_closure.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    string[] names = [\"Ana\", \"Alice\", \"Bob\"];\n\n    // Create an object value using an object constructor.\n    var engineer = object {\n        string name = \"\";\n\n        function setName(string name) {\n            // Access the `names` variable as a closure within the `setName` method in the object constructor.\n            names.push(name);\n            self.name = name;\n        }\n    };\n\n    engineer.setName(\"Walter\");\n    io:println(engineer.name);\n    io:println(names);\n}\n"
  },
  {
    "path": "examples/object-closure/object_closure.md",
    "content": "# Object closure\n\nThe object constructor and function can work as a closure, which can access variables outside of its own scope.\n\n::: code object_closure.bal :::\n\n::: out object_closure.out :::\n\n## Related links\n\n- [Function closure](/learn/by-example/function-closure/)\n- [Object constructor](/learn/by-example/object-constructor/)\n"
  },
  {
    "path": "examples/object-closure/object_closure.metatags",
    "content": "description: This BBE demonstrates object closures in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object closure, object constructor, self\n"
  },
  {
    "path": "examples/object-closure/object_closure.out",
    "content": "$ bal run object_closure.bal\nWalter\n[\"Ana\",\"Alice\",\"Bob\",\"Walter\"]\n"
  },
  {
    "path": "examples/object-constructor/object_constructor.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // Create an object value using the object constructor.\n    var engineer = object {\n        string name;\n\n        // The `init` function in the object constructor can not have parameters.\n        function init() {\n            self.name = \"\";\n        }\n\n        function setName(string name) {\n            self.name = name;\n        }\n\n        function getName() returns string {\n            return self.name;\n        }\n    };\n\n    engineer.setName(\"Alice\");\n    io:println(engineer.getName());\n}\n"
  },
  {
    "path": "examples/object-constructor/object_constructor.md",
    "content": "# Object constructor\n\nIn Ballerina, there are two ways to construct an object value with named methods and fields: using an object constructor or using the `new` expression with a `class` definition. The `init` method in an object constructor cannot have parameters.\n\n::: code object_constructor.bal :::\n\n::: out object_constructor.out :::\n\n## Related links\n- [Object value from class definition](/learn/by-example/object-value-from-class-definition/)\n- [Object types](/learn/by-example/object-types/)\n"
  },
  {
    "path": "examples/object-constructor/object_constructor.metatags",
    "content": "description: This BBE demonstrates constructing an object and inferring the object type in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object, object constructor, var\n"
  },
  {
    "path": "examples/object-constructor/object_constructor.out",
    "content": "$ bal run object_constructor.bal\nAlice\n"
  },
  {
    "path": "examples/object-type-inclusion/object_type_inclusion.bal",
    "content": "import ballerina/io;\n\ntype Cloneable object {\n    function clone() returns Cloneable;\n};\n\ntype Person object {\n    // The `Cloneable` object type is included as a part of the interface of\n    // the `Person` object type.\n    *Cloneable;\n\n    string name;\n\n    // `getName()` is a part of the `Person`'s own type.\n    // The `clone()` function is also included from the `Cloneable` type.\n    function getName() returns string;\n};\n\nclass Engineer {\n    // The `Engineer` class includes the `Person` object type.\n    // Therefore, it has to implement both the `clone()` and `getName()` methods.\n    *Person;\n\n    function init(string name) {\n        // The `name` field is included from the `Person` type.\n        self.name = name;\n    }\n\n    // Returning `Engineer` is valid as the `Engineer` type becomes a subtype of the `Cloneable` type\n    // once it includes the `Cloneable` object type.\n    function clone() returns Engineer {\n        return new (self.name);\n    }\n\n    function getName() returns string {\n        return self.name;\n    }\n}\n\npublic function main() {\n    Engineer engineer = new Engineer(\"Alice\");\n    io:println(engineer.getName());\n\n    Engineer engineerClone = engineer.clone();\n    io:println(engineerClone.getName());\n\n    io:println(engineer === engineerClone);\n}\n"
  },
  {
    "path": "examples/object-type-inclusion/object_type_inclusion.md",
    "content": "# Object type inclusion\n\nObject type inclusion enables two things. Firstly, it allows the creation of an object type that includes another object type such that one interface extends another interface. Secondly, it allows creating a class that includes a type like the class implementing the interface. You can include object types using the `*T` syntax.\n\nThe implementation of the object type within the class that includes the type is checked at the compile time.\n\n::: code object_type_inclusion.bal :::\n\n::: out object_type_inclusion.out :::\n\n## Related links\n- [Object types](/learn/by-example/object-types/)\n- [Defining classes](/learn/by-example/defining-classes/)\n- [Type inclusion for records](/learn/by-example/type-inclusion-for-records/)\n"
  },
  {
    "path": "examples/object-type-inclusion/object_type_inclusion.metatags",
    "content": "description: This BBE demonstrates including an object type into another object type, a class implementing an interface, and defining a class in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object types, type inclusion, object type descriptor, class, methods, inheritance, interface\n"
  },
  {
    "path": "examples/object-type-inclusion/object_type_inclusion.out",
    "content": "$ bal run object_type_inclusion.bal\nAlice\nAlice\nfalse\n"
  },
  {
    "path": "examples/object-types/object_types.bal",
    "content": "import ballerina/io;\n\n// The `Hashable` object type with a method called `hash()`, which returns an integer.\ntype Hashable object {\n    function hash() returns int;\n};\n\nfunction h() returns any {\n    var obj = object {\n        // Implements the `hash()` method defined in the `Hashable` object type.\n        function hash() returns int {\n            return 42;\n        }\n\n        // The object can have other methods.\n        function zero() returns int {\n            return 0;\n        }\n    };\n    return obj;\n}\n\npublic function main() {\n    // The returned object matches the pattern of the `Hashable` object type,\n    // which contains a `hash()` method returning an integer.\n    io:println(h() is Hashable);\n}\n"
  },
  {
    "path": "examples/object-types/object_types.md",
    "content": "# Object types\n\nAn object type is a type definition without any implementation. It is similar to an interface as defined in the Java programming language. Object typing is structural and an object type looks like a pattern that the object must match.\n\n::: code object_types.bal :::\n\n::: out object_types.out :::"
  },
  {
    "path": "examples/object-types/object_types.metatags",
    "content": "description: This BBE demonstrates object types in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, object types, object, type\n"
  },
  {
    "path": "examples/object-types/object_types.out",
    "content": "$ bal run object_types.bal\ntrue\n"
  },
  {
    "path": "examples/object-value-from-class-definition/object_value_from_class_definition.bal",
    "content": "import ballerina/io;\n\nclass Engineer {\n    string name;\n\n    function init(string name = \"Null\") {\n        self.name = name;\n    }\n\n    function getName() returns string {\n        return self.name;\n    }\n}\n\npublic function main() {\n    // Explicit new expression.\n    // Object is initialized using the default value in the `init` method.\n    Engineer engineer1 = new Engineer();\n    io:println(engineer1.getName());\n\n    // Object is initialized by passing an argument to the class descriptor with the new expression.\n    Engineer engineer2 = new Engineer(\"Alice\");\n    io:println(engineer2.getName());\n\n    // Object is initialized by passing a named argument to \n    // the class descriptor with the new expression.\n    Engineer engineer3 = new Engineer(name = \"Bob\");\n    io:println(engineer3.getName());\n\n    // Implicit new expression.\n    // Object is initialized using the default value in the `init` method.\n    Engineer engineer4 = new;\n    io:println(engineer4.getName());\n\n    // Object is initialized by passing an argument to the new expression.\n    Engineer engineer5 = new (\"Alice\");\n    io:println(engineer5.getName());\n\n    // Object is initialized by passing a named argument to the new expression.\n    Engineer engineer6 = new (name = \"Bob\");\n    io:println(engineer6.getName());\n}\n"
  },
  {
    "path": "examples/object-value-from-class-definition/object_value_from_class_definition.md",
    "content": "# Object value from class definition\n\nA `class` defines an object type and provides a way to construct an object value.  An object can be constructed from the `class` definition using the implicit and explicit `new` expression. The type of the constructor should be mentioned after `new` for the explicit new expression. For the implicit new expression, the type will be inferred from the expected type.\n\n::: code object_value_from_class_definition.bal :::\n\n::: out object_value_from_class_definition.out :::\n\n## Related links\n- [Object constructor](/learn/by-example/object-constructor/)\n- [Defining classes](/learn/by-example/defining-classes/)\n"
  },
  {
    "path": "examples/object-value-from-class-definition/object_value_from_class_definition.metatags",
    "content": "description: This BBE demonstrates constructing an object using a new expression and defining classes in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, class, methods, new, object\n"
  },
  {
    "path": "examples/object-value-from-class-definition/object_value_from_class_definition.out",
    "content": "$ bal run object_value_from_class_definition.bal\nNull\nAlice\nBob\nNull\nAlice\nBob\n"
  },
  {
    "path": "examples/on-conflict-clause/on_conflict_clause.bal",
    "content": "import ballerina/io;\n\ntype Student record {|\n    readonly int id;\n    string name;\n    int score;\n|};\n\npublic function main() {\n    error onConflictError = error(\"Key Conflict\", message = \"record with same key exists.\");\n\n    table<Student> students = table [\n            {id: 1, name: \"John\", score: 100},\n            {id: 2, name: \"Jane\", score: 150},\n            {id: 1, name: \"John\", score: 200}\n        ];\n\n    // The result of the following will be an error since the key `John` is duplicated.\n    map<int>|error studentScores = map from var {name, score} in students\n                                   select [name, score]\n                                   on conflict onConflictError;\n\n    io:println(studentScores);\n\n    // The value `100` of the key `John` will be replaced by the second occurrence value `200`.\n    map<int> lastRoundScore = map from var student in students\n                              select [student.name, student.score]\n                              on conflict ();\n\n    io:println(lastRoundScore);\n\n    // The result of the following will be an error since the key `1` is duplicated.\n    table<Student> key(id)|error studentScoresTable = table key(id) from var student in students\n                                                      select student\n                                                      on conflict onConflictError;\n\n    io:println(studentScoresTable);\n}\n"
  },
  {
    "path": "examples/on-conflict-clause/on_conflict_clause.md",
    "content": "# `on conflict` clause\n\nWhen constructing a map or a table with a key sequence using a query expression, there can be conflicting keys. The `on conflict` clause can be specified after the `select` clause to handle these cases.\n\nThe `on conflict` clause uses the syntax `on conflict <expression>`, where the expression must be of type `error?`. If a conflicting key is found, and the expression evaluates to an error, that error becomes the result of the query expression. If it evaluates to `null` or the `on conflict` clause is absent, the old value is replaced by the new value.\n\n::: code on_conflict_clause.bal :::\n\n::: out on_conflict_clause.out :::\n\n## Related links\n- [Advanced conflict handling](/learn/by-example/advanced-conflict-handling)\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/on-conflict-clause/on_conflict_clause.metatags",
    "content": "description: This BBE demonstrates handling duplicate keys when constructing a map or a table.\nkeywords: ballerina, ballerina by example, bbe, duplicate, key, map, table, query\n"
  },
  {
    "path": "examples/on-conflict-clause/on_conflict_clause.out",
    "content": "$ bal run on_conflict_clause.bal\nerror(\"Key Conflict\",message=\"record with same key exists.\")\n{\"John\":200,\"Jane\":150}\nerror(\"Key Conflict\",message=\"record with same key exists.\")\n"
  },
  {
    "path": "examples/open-records/open_records.bal",
    "content": "import ballerina/io;\n\n// `Student` type allows additional fields with `anydata` values.\ntype Student record {\n    string name;\n    int age;\n};\n\ntype PartTimeStudent record {|\n    string name;\n    int age;\n    // Rest descriptor allows additional fields with `anydata` values\n    // in the `PartTimeStudent` type.\n    anydata...;\n|};\n\npublic function main() {\n    // Adds an additional `country` field to `s1`.\n    Student s1 = {\n        name: \"John\",\n        age: 25,\n        \"country\": \"UK\"\n    };\n    io:println(s1);\n\n    // Accesses the `age` field in `s1`.\n    int age = s1.age;\n    io:println(age);\n\n    // Accesses the `country` field in `s1`.\n    anydata country = s1[\"country\"];\n    io:println(country);\n\n    // Adds an additional `studyHours` field to `s2`.\n    PartTimeStudent s2 = {\n        name: \"Anne\",\n        age: 23,\n        \"studyHours\": 6\n    };\n\n    // Accesses the `studyHours` field in `s2`.\n    anydata studyHours = s2[\"studyHours\"];\n    io:println(studyHours);\n\n    // Adds an additional `credits` field to `s2`.\n    s2[\"credits\"] = 120.5;\n    io:println(s2);\n\n    // A variable of type `PartTimeStudent` can be used where a `Student` value is expected.\n    Student s3 = s2;\n    io:println(s3);\n\n    // A variable of type `Student` can be used where a `map<anydata>` value is expected.\n    map<anydata> s4 = s3;\n    io:println(s4);\n}\n"
  },
  {
    "path": "examples/open-records/open_records.md",
    "content": "# Open records\n\nA record type that uses either the `{` and `}` delimiters or the `{|` and `|}` delimiters with a rest descriptor is considered open. Open records allow fields other than those explicitly specified. \n\nWhen the record is open due to the use of the  `{` and `}` delimiters, the expected type for any additional field is `anydata`. When the record is open due to the use of a rest descriptor, the expected type for any additional field is the type specified in the rest descriptor.\n\nQuoted keys can be used to specify fields that are not explicitly specified in an open record type.\n\n::: code open_records.bal :::\n\n::: out open_records.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)\n- [Controlling openness](/learn/by-example/controlling-openness/)\n- [Maps](/learn/by-example/maps/)\n- [Anydata type](/learn/by-example/anydata-type/)\n"
  },
  {
    "path": "examples/open-records/open_records.metatags",
    "content": "description: This BBE demonstrates open records, creating an open record, inclusive record type, creating a record with unspecified fields, and accesing rest fields in a record.\nkeywords: ballerina, ballerina by example, bbe, open record, record, record type, rest type, rest field, inclusive record, unspecified fields\n\n"
  },
  {
    "path": "examples/open-records/open_records.out",
    "content": "$ bal run open_records.bal\n{\"name\":\"John\",\"age\":25,\"country\":\"UK\"}\n25\nUK\n6\n{\"name\":\"Anne\",\"age\":23,\"studyHours\":6,\"credits\":120.5}\n{\"name\":\"Anne\",\"age\":23,\"studyHours\":6,\"credits\":120.5}\n{\"name\":\"Anne\",\"age\":23,\"studyHours\":6,\"credits\":120.5}\n"
  },
  {
    "path": "examples/optional-fields/optional_fields.bal",
    "content": "import ballerina/io;\n\ntype FullName record {\n    string firstName;\n    string lastName;\n\n    // The `title` and `middleName` fields are optional.\n    string title?;\n    string middleName?;\n};\n\npublic function main() {\n\n    FullName name = {\n        title: \"Mr\",\n        firstName: \"John\",\n        lastName: \"Doe\"\n    };\n\n    // Use the `?.` operator to access the optional field.\n    io:println(\"Title: \", name?.title);\n\n    // A variable of type `string?` is used to construct an optional field.\n    string? middleName = name[\"middleName\"];\n    io:println(\"Middle name: \", middleName);\n\n    // Remove the optional `title` field by assigning `()`.\n    name.title = ();\n    io:println(name.hasKey(\"title\"));\n\n    // When destructuring the record `name`, if the `title` field is absent,\n    // then, its value becomes nil.\n    var {title, firstName: _, lastName: _} = name;\n    io:println(title is ());\n}\n"
  },
  {
    "path": "examples/optional-fields/optional_fields.md",
    "content": "# Optional fields\n\nFields of a `record` type can be marked as optional. These fields can be omitted when creating a value of the record type. A field `f` of record type `r` can be accessed via optional field access (e.g., `r?.f`) or member access (e.g., `r[\"f\"]`), which will both return `()` if the field is not present in the record value.\n\nA record that contains optional fields can be destructured. If the optional field is not available, the type of the variable becomes `nil`. The optional field value can also be removed from the record by assigning `()` to the optional field.\n\n::: code optional_fields.bal :::\n\n::: out optional_fields.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)"
  },
  {
    "path": "examples/optional-fields/optional_fields.metatags",
    "content": "description: This BBE demonstrates optional record fields by defining a field without a value, destructuring a record with optional fields, and removing the optional field value from a record in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, optional, fields, record\n"
  },
  {
    "path": "examples/optional-fields/optional_fields.out",
    "content": "$ bal run optional_fields.bal\nTitle: Mr\nMiddle name: \nfalse\ntrue\n"
  },
  {
    "path": "examples/outer-join-clause/outer_join_clause.bal",
    "content": "import ballerina/io;\n\ntype Department record {|\n   int id;\n   string name;\n|};\n\ntype Person record {|\n   int id;\n   string fname;\n   string lname;\n|};\n\ntype DeptPerson record {|\n   string fname;\n   string? dept;\n|};\n\npublic function main() {\n    Person p1 = {id: 1, fname: \"Alex\", lname: \"George\"};\n    Person p2 = {id: 2, fname: \"John\", lname: \"Fonseka\"};\n    Person p3 = {id: 3, fname: \"Ted\", lname: \"Perera\"};\n\n    Department d1 = {id: 1, name:\"HR\"};\n    Department d2 = {id: 2, name:\"Operations\"};\n\n    Person[] personList = [p1, p2, p3];\n    Department[] deptList = [d1, d2];\n\n    DeptPerson[] deptPersonList =\n       from Person person in personList\n       // The `outer join` clause performs a left outer equijoin.\n       // For the records for which there is no matching record\n       // on the `deptList`, the resulting record will contain `nil` fields.\n       outer join var dept in deptList\n       on person.id equals dept?.id\n       select {\n           fname : person.fname,\n           dept : dept?.name\n       };\n\n    io:println(deptPersonList);\n}\n"
  },
  {
    "path": "examples/outer-join-clause/outer_join_clause.md",
    "content": "# Outer join clause\n\nThe `outer join` clause performs a left outer equijoin. This join returns each element of the first collection regardless of whether it has any matching elements in the second collection. For the values for which there is no matching value on the second collection, the resulting value will contain `nil`.\n\n::: code outer_join_clause.bal :::\n\n::: out outer_join_clause.out :::"
  },
  {
    "path": "examples/outer-join-clause/outer_join_clause.metatags",
    "content": "description: This BBE demonstrates the outer join clause in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, outer join clause, query, query expression\n"
  },
  {
    "path": "examples/outer-join-clause/outer_join_clause.out",
    "content": "$ bal run outer_join_clause.bal\n[{\"fname\":\"Alex\",\"dept\":\"HR\"},{\"fname\":\"John\",\"dept\":\"Operations\"},{\"fname\":\"Ted\",\"dept\":null}]\n"
  },
  {
    "path": "examples/panics/panics.bal",
    "content": "import ballerina/io;\n\n// `n` must not be `0`.\nfunction divide(int m, int n) returns int {\n\n    if n == 0 {\n        // Panic if `n` is `0`.\n        panic error(\"division by 0\");\n\n    }\n    return m / n;\n}\n\npublic function main() {\n    \n    // Even though `divide(1, 0)` panics, due to the trap expression, the program will not terminate here.\n    int|error x = trap divide(1, 0);\n\n    if x is error {\n        io:println(x);\n    }\n    \n    int y = divide(1, 0);\n\n    // If `divide(1, 0)` panics, the program will terminate and the following code will not be\n    // executed.\n    io:println(y);\n\n}\n"
  },
  {
    "path": "examples/panics/panics.md",
    "content": "# Panics\n\nBallerina distinguishes normal errors from abnormal errors. Normal errors are handled by returning error values. This signals to the caller that they must handle the error. In contrast, abnormal errors such as division by 0 and out-of-memory are typically unrecoverable errors and we need to terminate the execution of the program. This is achieved by a panic statement with an expression that results in an error value such as the error constructor. At runtime, evaluating a panic statement first creates the error value by evaluating the expression and then starts stack unwinding, unless it encounters a `trap` expression. \n\n::: code panics.bal :::\n\n::: out panics.out :::\n"
  },
  {
    "path": "examples/panics/panics.metatags",
    "content": "description: This BBE demonstrates how abnormal errors are handled using panics in Ballerina\nkeywords:  ballerina, ballerina by example, bbe, error, panic\n"
  },
  {
    "path": "examples/panics/panics.out",
    "content": "$ bal run panics.bal\nerror(\"division by 0\")\nerror: division by 0\n        at panics:divide(panics.bal:8)\n           panics:main(panics.bal:23)\n"
  },
  {
    "path": "examples/parse-csv-lists/parse_csv_lists.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\n// Represents the details of an employee.\ntype Employee record {|\n    int empId;\n    string empName;\n    string department;\n    float salary;\n|};\n\n// Represents the salary details of an employee.\ntype EmployeeSalary record {|\n    // This annotation is used to map the empId field in the source CSV record \n    // to the id field in the target record.\n    @csv:Name {\n        value: \"empId\"\n    }\n    int id;\n    float salary;\n|};\n\npublic function main() returns error? {\n    // Sample CSV string array representing employee data.\n    string[][] csvList = [\n        [\"1\", \"John\", \"Engineering\", \"1000.0\"],\n        [\"2\", \"Doe\", \"HR\", \"2000.0\"],\n        [\"3\", \"Jane\", \"Finance\", \"3000.0\"]\n    ];\n\n    // Parse the CSV list into an array of `Employee` records by specifying custom headers.\n    Employee[] employees = check csv:parseList(csvList, {\n        customHeaders: [\"empId\", \"empName\", \"department\", \"salary\"]\n    });\n    io:println(employees);\n\n    // Parse the CSV list into an array of `EmployeeSalary` records by specifying custom headers.\n    // Only the fields specified in the EmployeeSalary type (`id` and `salary`) \n    // are included in the resulting array.\n    EmployeeSalary[] employeeSalaries = check csv:parseList(csvList, {\n        customHeaders: [\"empId\", \"empName\", \"department\", \"salary\"]\n    });\n    io:println(employeeSalaries);\n\n    // Parse the CSV list into an array of `anydata` arrays.\n    anydata[][] employeesArray = check csv:parseList(csvList);\n    io:println(employeesArray);\n}\n"
  },
  {
    "path": "examples/parse-csv-lists/parse_csv_lists.md",
    "content": "# Parse CSV lists to custom types\n\nBallerina enables parsing CSV lists into various data structures, including custom `record` types and arrays. It facilitates parsing CSV lists into record types with specified fields, allowing for both reshaping of the data and maintaining its original structure.\n\n::: code parse_csv_lists.bal :::\n\n::: out parse_csv_lists.out :::\n"
  },
  {
    "path": "examples/parse-csv-lists/parse_csv_lists.metatags",
    "content": "description: This BBE demonstrates the parsing of CSV lists into Ballerina records and arrays, both with and without data projection.\nkeywords: ballerina, ballerina by example, bbe, csv, csv lists, record, record array, parseList, csv data module, data.csv, data projection, csv to record array\n"
  },
  {
    "path": "examples/parse-csv-lists/parse_csv_lists.out",
    "content": "$ bal run parse_csv_lists.bal\n[{\"empId\":1,\"empName\":\"John\",\"department\":\"Engineering\",\"salary\":1000.0},{\"empId\":2,\"empName\":\"Doe\",\"department\":\"HR\",\"salary\":2000.0},{\"empId\":3,\"empName\":\"Jane\",\"department\":\"Finance\",\"salary\":3000.0}]\n[{\"id\":1,\"salary\":1000.0},{\"id\":2,\"salary\":2000.0},{\"id\":3,\"salary\":3000.0}]\n[[1,\"John\",\"Engineering\",1000.0],[2,\"Doe\",\"HR\",2000.0],[3,\"Jane\",\"Finance\",3000.0]]\n"
  },
  {
    "path": "examples/persist-create/persist_create.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    store:EmployeeInsert employee1 = {\n        id: uuid:createType4AsString(),\n        firstName: \"John\",\n        lastName: \"Doe\",\n        gender: \"Male\",\n        birthDate: {\n            year: 1987,\n            month: 7,\n            day: 23\n        },\n        hireDate: {\n            year: 2020,\n            month: 10,\n            day: 10\n        }\n    };\n\n    store:EmployeeInsert employee2 = {\n        id: uuid:createType4AsString(),\n        firstName: \"Jane\",\n        lastName: \"Doe\",\n        gender: \"Female\",\n        birthDate: {\n            year: 1989,\n            month: 7,\n            day: 11\n        },\n        hireDate: {\n            year: 2020,\n            month: 10,\n            day: 10\n        }\n    };\n\n    string[] employeeIds = check sClient->/employees.post([employee1, employee2]);\n    io:println(string `Inserted employee ids: ${employeeIds.toString()}`);\n}\n"
  },
  {
    "path": "examples/persist-create/persist_create.md",
    "content": "# Persist write - Create record/records\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides a `post` resource method to persist record/records to the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd the `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, you can persist record/records to the data store with the `post` resource method.\n\n::: code persist_create.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_create.out :::\n"
  },
  {
    "path": "examples/persist-create/persist_create.metatags",
    "content": "description: This BBE demonstrates the usage of post resource method in the generated persistence client to persist record/records to the data store\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, post, entity\n"
  },
  {
    "path": "examples/persist-create/persist_create.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\nInserted employee ids: [\"394c694f-82ae-4fe9-9947-85948625fea1\",\"639082b7-4be7-4a64-8db2-1e3d1b3313f8\"]\n"
  },
  {
    "path": "examples/persist-create/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-create/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-create/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-delete/persist_create.metatags",
    "content": "description: This BBE demonstrates the usage of delete resource method in the generated persistence client to delete record from the data store.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, delete, entity\n"
  },
  {
    "path": "examples/persist-delete/persist_delete.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    string empId = \"16c6553a-373c-4b29-b1c8-c282f444248c\";\n\n    // Delete employee record with id 16c6553a-373c-4b29-b1c8-c282f444248c\n    store:Employee employee = check sClient->/employees/[empId].delete();\n    io:println(string `Deleted employee record: ${employee.toString()}`);\n}\n"
  },
  {
    "path": "examples/persist-delete/persist_delete.md",
    "content": "# Persist write - Delete record\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides a `delete` resource method to delete records from the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n\n#### Use the generated client API\nUsing the generated client API, you can delete records from the data store with the `delete` resource method.\n\n::: code persist_delete.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_delete.out :::\n"
  },
  {
    "path": "examples/persist-delete/persist_delete.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\nDeleted employee record: {\"id\":\"16c6553a-373c-4b29-b1c8-c282f444248c\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":07,\"day\":23},\"gender\":\"Male\",\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n"
  },
  {
    "path": "examples/persist-delete/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-delete/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-delete/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-filtering/persist_filtering.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\n// A record with subset of fields\ntype EmployeeName record {|\n    string id;\n    string firstName;\n    string lastName;\n|};\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    // Filter Employee records by gender\n    stream<store:Employee, persist:Error?> employees = sClient->/employees;\n    store:Employee[] filtered = check from var employee in employees\n                        where employee.gender == \"Male\"\n                        select employee;\n    foreach store:Employee e in filtered {\n        io:println(e);\n    }\n\n    // Order by Employee records by first name in ascending order, and then by last name in descending order\n    stream<EmployeeName, persist:Error?> empNames = sClient->/employees;\n    EmployeeName[] sorted = check from var e in empNames\n                        order by e.firstName ascending, e.lastName descending\n                        select e;\n    foreach EmployeeName e in sorted {\n        io:println(e.firstName, \" \", e.lastName);\n    }\n\n\n    // Limit the results to 2\n    employees = sClient->/employees;\n    store:Employee[] limited = check from var employee in employees\n                            order by employee.age descending\n                            limit 2\n                            select employee;\n\n    foreach store:Employee e in limited {\n        io:println(e);\n    }\n}\n"
  },
  {
    "path": "examples/persist-filtering/persist_filtering.md",
    "content": "# Persist read - Filter and sort\n\nThe bal persist feature provide support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides `get` resource method to retrieve all records from the data store. As the `get` resource method returns a stream of records, we can use query expressions to do additional filter. For more information, see [Query Expressions](/learn/by-example/query-expressions/).\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, we can retrieve all records from the data store. The `get` resource method returns a stream of records. We can iterate through the stream and print the records.\n\n::: code persist_filtering.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_filtering.out :::\n"
  },
  {
    "path": "examples/persist-filtering/persist_filtering.metatags",
    "content": "description: This BBE demonstrates the usage of query expressions with get resource method in generated persistence client.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, get, entity, filtering, query\n"
  },
  {
    "path": "examples/persist-filtering/persist_filtering.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\n{\"id\":\"581d1bc2-0390-452a-a564-4219e66af395\",\"firstName\":\"Sam\",\"lastName\":\"Curran\",\"birthDate\":{\"year\":1993,\"month\":7,\"day\":23},\"gender\":\"Male\",\"age\":27,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n{\"id\":\"9ae73215-207d-4e62-8596-5f2fd47ff7d5\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":7,\"day\":23},\"gender\":\"Male\",\"age\":33,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\nJane Doe\nJohn Doe\nSam Curran\n{\"id\":\"9ae73215-207d-4e62-8596-5f2fd47ff7d5\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":7,\"day\":23},\"gender\":\"Male\",\"age\":33,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n{\"id\":\"639082b7-4be7-4a64-8db2-1e3d1b3313f8\",\"firstName\":\"Jane\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1989,\"month\":7,\"day\":11},\"gender\":\"Female\",\"age\":31,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n"
  },
  {
    "path": "examples/persist-filtering/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-filtering/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-filtering/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    int age;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-get-all/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-get-all/persist_get_all.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    // Get entire Employee record\n    stream<store:Employee, persist:Error?> employees = sClient->/employees;\n    check from var employee in employees\n        do {\n            io:println(employee);\n        };\n}\n"
  },
  {
    "path": "examples/persist-get-all/persist_get_all.md",
    "content": "# Persist read - Get all records\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\n\nThe generated client API provides a `get` resource method to retrieve all records from the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, we can retrieve all records from the data store. The `get` resource method returns a stream of records. We can iterate through the stream and print the records.\n\n::: code persist_get_all.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_get_all.out :::\n"
  },
  {
    "path": "examples/persist-get-all/persist_get_all.metatags",
    "content": "description: This BBE demonstrates the usage of get resource method in generated persistence client.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, get, entity\n"
  },
  {
    "path": "examples/persist-get-all/persist_get_all.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\n{\"id\":\"394c694f-82ae-4fe9-9947-85948625fea1\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":7,\"day\":23},\"gender\":\"Male\",\"age\":33,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n{\"id\":\"639082b7-4be7-4a64-8db2-1e3d1b3313f8\",\"firstName\":\"Jane\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1989,\"month\":7,\"day\":11},\"gender\":\"Female\",\"age\":31,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n{\"id\":\"581d1bc2-0390-452a-a564-4219e66af395\",\"firstName\":\"Sam\",\"lastName\":\"Curran\",\"birthDate\":{\"year\":1993,\"month\":7,\"day\":23},\"gender\":\"Male\",\"age\":27,\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n"
  },
  {
    "path": "examples/persist-get-all/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-get-all/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_get_by_key.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    string empId = \"16c6553a-373c-4b29-b1c8-c282f444248c\";\n    // Get entire Employee record by key\n    store:Employee employee = check sClient->/employees/[empId];\n    io:println(employee);\n}\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_get_by_key.md",
    "content": "# Persist read - Get record by key\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides `get by key` resource method to retrieve the record by the key from the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, you can retrieve the record by key from the data store. The `get by key` resource method returns a record or error if no records are found for the given key.\n\n::: code persist_get_by_key.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_get_by_key.out :::\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_get_by_key.metatags",
    "content": "description: This BBE demonstrates the usage of get by key resource method in generated persistence client.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, get by key, entity\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_get_by_key.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\n{\"id\":\"16c6553a-373c-4b29-b1c8-c282f444248c\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":07,\"day\":23},\"gender\":\"Male\",\"hireDate\":{\"year\":2020,\"month\":10,\"day\":10}}\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-get-by-key/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n\n    // one-to-many relationship with Department\n    Department department;\n    // one-to-one relationship with Workspace\n    Workspace workspace;\n|};\n\ntype Workspace record {|\n    readonly string id;\n    string workspaceType;\n\n    // one-to-many relationship with Building\n    Building location;\n    // one-to-one relationship with Employee\n    Employee? employee;\n|};\n\ntype Department record {|\n    readonly string no;\n    string deptName;\n\n    // one-to-many relationship with Employee\n    Employee[] employees;\n|};\n\ntype Building record {|\n    readonly string code;\n    string city;\n    string state;\n    string country;\n    string postalCode;\n    string 'type;\n\n    // one-to-many relationship with Workspace\n    Workspace[] workspaces;\n|};\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_relation_queries.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\n// A record with relation fields - one-to-one relation\ntype EmployeeWorkspace record {|\n    string id;\n    string firstName;\n    string lastName;\n    record {|\n        string id;\n        string workspaceType;\n    |} workspace;\n|};\n\n// A record with relation fields - one-to-many relation\ntype DepartmentEmployees record {|\n    string id;\n    string name;\n    record {|\n        string id;\n        string firstName;\n        string lastName;\n    |}[] employees;\n|};\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    // Get record with relation fields for one-to-one relation\n    stream<EmployeeWorkspace, persist:Error?> empWorkspaceStream = sClient->/employees;\n    check from var empWorkspace in empWorkspaceStream\n        do {\n            io:println(empWorkspace);\n        };\n\n    // Get record with relation fields for one-to-many relation\n    stream<DepartmentEmployees, error?> departmentStream = sClient->/departments;\n    check from var department in departmentStream\n        do {\n            io:println(department);\n        };\n}\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_relation_queries.md",
    "content": "# Persist read - Relation queries\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides support to select fields in relational entities when retrieving the records/record from the `get` resource method from the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize persistence in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee`, `Department`, `Workspace`, and `Building` entities with relations in between in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, you can retrieve the record with relations from the data store with both `get` and `get by key` resource methods.\n\n::: code persist_relation_queries.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_relation_queries.out :::\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_relation_queries.metatags",
    "content": "description: This BBE demonstrates the usage of the get/get by key resource method in generated persistence client to retrieve relation fields of an entity from the data store.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, get by key, get, select, entity, relations\n"
  },
  {
    "path": "examples/persist-relation-queries/persist_relation_queries.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\n{\"id\":\"1c09e131-364b-45f0-9f04-5e6a05bf8feb\",\"firstName\":\"John\",\"lastName\":\"Smith\",\"workspace\":{\"id\":\"2c4696cf-a9a5-4b2e-be50-ccd3404394be\",\"workspaceType\":\"Hot Desk\"}}\n{\"id\":\"4a5ae2c5-4df8-44b8-8da1-27585068071e\",\"firstName\":\"Jane\",\"lastName\":\"Doe\",\"workspace\":{\"id\":\"b17f8735-f1b2-45fa-945a-2d9f5479af72\",\"workspaceType\":\"Cubicle\"}}\n{\"id\":\"c53b2b5a-6763-43cf-ae61-de2fd5802eda\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"workspace\":{\"id\":\"3590c557-df63-4f90-bb60-23283655329b\",\"workspaceType\":\"Cubicle\"}}\n{\"no\":\"D004\",\"deptName\":\"Marketing\",\"employees\":[{\"id\":\"4a5ae2c5-4df8-44b8-8da1-27585068071e\",\"firstName\":\"Jane\",\"lastName\":\"Doe\"},{\"id\":\"c53b2b5a-6763-43cf-ae61-de2fd5802eda\",\"firstName\":\"John\",\"lastName\":\"Doe\"}]}\n{\"no\":\"D005\",\"deptName\":\"Sales\",\"employees\":[{\"id\":\"1c09e131-364b-45f0-9f04-5e6a05bf8feb\",\"firstName\":\"John\",\"lastName\":\"Smith\"}]}\n"
  },
  {
    "path": "examples/persist-select-fields/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-select-fields/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-select-fields/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-select-fields/persist_select_fields.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\n// A record with subset of fields\ntype EmployeeName record {|\n    string id;\n    string firstName;\n    string lastName;\n|};\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    // Get only the employee_id, first_name and last_name fields of all the records\n    stream<EmployeeName, persist:Error?> empNames = sClient->/employees;\n    check from var name in empNames\n        do {\n            io:println(name);\n        };\n\n    // Get only the employee_id, first_name and last_name fields of a single record\n    string empId = \"16c6553a-373c-4b29-b1c8-c282f444248c\";\n    EmployeeName employee = check sClient->/employees/[empId];\n    io:println(employee);\n}\n"
  },
  {
    "path": "examples/persist-select-fields/persist_select_fields.md",
    "content": "# Persist read - Select fields\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides support to select a subset of fields of the entity when retrieving the records/record from the `get` resource method from the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, you can retrieve the record with selected fields from the data store with both `get` and `get by key` resource methods.\n\n::: code persist_select_fields.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_select_fields.out :::\n"
  },
  {
    "path": "examples/persist-select-fields/persist_select_fields.metatags",
    "content": "description: This BBE demonstrates the usage of the get/get by key resource method in generated persistence client to retrieve selected fields of an entity from the data store.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, get by key, get, select, entity\n"
  },
  {
    "path": "examples/persist-select-fields/persist_select_fields.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\n{\"id\":\"16c6553a-373c-4b29-b1c8-c282f444248c\",\"firstName\":\"John\",\"lastName\":\"Doe\"}\n{\"id\":\"16c6553a-373c-4b29-b1c8-c282f444248c\",\"firstName\":\"John\",\"lastName\":\"Doe\"}\n"
  },
  {
    "path": "examples/persist-update/persist_generate.out",
    "content": "$ bal persist generate --datastore inmemory --module store\n\nPersist client and entity types generated successfully in the store directory.\n"
  },
  {
    "path": "examples/persist-update/persist_init.out",
    "content": "$ bal persist init\n\nInitialized the package for persistence.\n\nNext steps:\n1. Define your data model in \"persist/model.bal\".\n2. Execute `bal persist add --datastore <datastore> --module <module>` to add an entry to \"Ballerina.toml\" for integrating code generation with the package build process.\nOR\nExecute `bal persist generate --datastore <datastore> --module <module>` for a one-time generation of the client.\n"
  },
  {
    "path": "examples/persist-update/persist_model.bal",
    "content": "import ballerina/persist as _;\nimport ballerina/time;\n\ntype Employee record {|\n    readonly string id;\n    string firstName;\n    string lastName;\n    time:Date birthDate;\n    string gender;\n    time:Date hireDate;\n|};\n"
  },
  {
    "path": "examples/persist-update/persist_update.bal",
    "content": "import ballerina/io;\nimport ballerina/persist;\nimport rainier.store;\n\nstore:Client sClient = check new ();\n\npublic function main() returns error? {\n    string empId = \"16c6553a-373c-4b29-b1c8-c282f444248c\";\n\n    // Update hire date of employee with id 16c6553a-373c-4b29-b1c8-c282f444248c\n    store:Employee employee = check sClient->/employees/[empId].put({\n        hireDate: {\n            year: 2014,\n            month: 5,\n            day: 1\n        }\n    });\n    io:println(string `Updated employee record: ${employee.toString()}`);\n}\n"
  },
  {
    "path": "examples/persist-update/persist_update.md",
    "content": "# Persist write - Update record\n\nThe bal persist feature provides support to manage data persistence in a Ballerina package. It starts with defining the application's data model. Once the model is defined, the client API is generated with resources based on the model. The generated API can be used to query and manipulate the persistent data in the application.\nThe generated client API provides a `put` resource method to update the record in the data store.\n\n> **Note:** This example uses the Ballerina tables as the data store. For more information about other supported data stores, see [Supported Data Stores](/learn/supported-data-stores/).\n\n#### Initialize the project\nExecute the command below to initialize `bal persist` in the project.\n\n::: out persist_init.out :::\n\n#### Model the data\nAdd `Employee` entity with the following fields in the `model.bal` file inside the `persist` directory.\n\n::: code persist_model.bal :::\n\n#### Generate client APIs\nExecute the command below to generate the Ballerina client API.\n\n::: out persist_generate.out :::\n\n> **Note:** The `bal persist generate` command is a one-time generation task, and the generated client code is a part of the project. We can also integrate the client code generation with the project's build process by executing the `bal persist add` command. This command will add the client code generation as a build task in the `Ballerina.toml` file. See [Persist CLI Commands](learn/persist-cli-tool/) for more information.\n\n#### Use the generated client API\nUsing the generated client API, you can update the record in the data store with the `put` resource method.\n\n::: code persist_update.bal :::\n\n#### Run the program\nExecute the command below to run the program.\n\n::: out persist_update.out :::\n"
  },
  {
    "path": "examples/persist-update/persist_update.metatags",
    "content": "description: This BBE demonstrates the usage of put resource method in generated persistence client to update the record in the data store.\nkeywords: ballerina, ballerina by example, bbe, persistence, data store, put, select, entity\n"
  },
  {
    "path": "examples/persist-update/persist_update.out",
    "content": "$ bal run\n\nCompiling source\n        foo/rainier:0.1.0\n\nRunning executable\n\nDeleted employee record: {\"id\":\"16c6553a-373c-4b29-b1c8-c282f444248c\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":{\"year\":1987,\"month\":07,\"day\":23},\"gender\":\"Male\",\"hireDate\":{\"year\":2014,\"month\":5,\"day\":1}}\n"
  },
  {
    "path": "examples/programs-and-modules/programs_and_modules.bal",
    "content": "// This import declaration binds the prefix `io` to the `ballerina/io` package. \n// The prefix by default comes from the last part of the package name.\n\n// The `ballerina` org name is reserved for the Ballerina library packages.\nimport ballerina/io;\n\n// `main` function is the program entry point. \n// `public` makes the function visible outside the package.\npublic function main() {\n    // Here `io:println` means function `println` is in the package bound to prefix `io`.\n    io:println(\"Hello, World!\");\n}\n"
  },
  {
    "path": "examples/programs-and-modules/programs_and_modules.md",
    "content": "# Programs and modules\n\nEvery Ballerina program consists of modules. Modules are one or more `.bal` files. The module names take the form `org/x.y.z`.\n\n::: code programs_and_modules.bal :::\n\n::: out programs_and_modules.out :::"
  },
  {
    "path": "examples/programs-and-modules/programs_and_modules.metatags",
    "content": "description: This BBE introduces Ballerina modules and how you can import them in your program.\nkeywords:  ballerina, ballerina by example, bbe, module, program\n"
  },
  {
    "path": "examples/programs-and-modules/programs_and_modules.out",
    "content": "$ bal run programs_and_modules.bal\nHello, World!\n"
  },
  {
    "path": "examples/provide-function-arguments-by-name/provide_function_arguments_by_name.bal",
    "content": "import ballerina/io;\n\nfunction add(int x, int y, int z) {\n    io:println(\"Sum of x, y and z:\", x + y + z);\n}\n\npublic function main() {\n    // Calls the `add` function using the positional arguments.\n    add(1, 2, 3);\n\n    // Calls the `add` function using the named arguments in the same order as the parameters of the function definition.\n    add(x = 1, y = 2, z = 3);\n\n    // Calls the `add` function using the named arguments in a different order from the order of the parameters in the function definition.\n    add(z = 3, y = 2, x = 1);\n\n    // Calls the `add` function using a combination of named arguments and positional arguments.\n    add(1, z = 3, y = 2);\n}\n"
  },
  {
    "path": "examples/provide-function-arguments-by-name/provide_function_arguments_by_name.md",
    "content": "# Provide function arguments by name\n\nBallerina allows you to call functions with named arguments, which do not have to be in the same order as the parameters.\n \n::: code provide_function_arguments_by_name.bal :::\n\n::: out provide_function_arguments_by_name.out :::\n\n## Related links\n- [Functions](/learn/by-example/functions/)\n- [Included record parameters](/learn/by-example/included-record-parameters/)\n- [Rest arguments](/learn/by-example/rest-arguments/)\n"
  },
  {
    "path": "examples/provide-function-arguments-by-name/provide_function_arguments_by_name.metatags",
    "content": "description: This BBE demonstrates calling functions with named arguments and creating functions in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, named arguments, functions, function definition, parameters\n"
  },
  {
    "path": "examples/provide-function-arguments-by-name/provide_function_arguments_by_name.out",
    "content": "$ bal run provide_function_arguments_by_name.bal\nSum of x, y and z:6\nSum of x, y and z:6\nSum of x, y and z:6\nSum of x, y and z:6\n"
  },
  {
    "path": "examples/providing-services/providing_services.bal",
    "content": "import ballerina/http;\n\n// Listener declarations are allowed at the module level. \n// They are similar to variable declarations, but register the newly created Listener object with the module.\n// If `new` returns an error, then module initialization fails.\nlistener http:Listener h = new (8080);\n"
  },
  {
    "path": "examples/providing-services/providing_services.md",
    "content": "# Provide services\n\nProviding services involves the interaction of three main things. \n\n1. Service objects are the counterpart of client objects. Service objects also have remote methods and they are remotely accessible to clients. Remote method of a client object typically calls the remote method of a service object.\n\n2. Listener is the entity that receives the network input and then it makes calls to remote methods of attached service objects. Listeners are registered with the module as illustrated in the following example.\n\n3. Modules have a lifecycle and they are initialized on program startup. Modules start up the registered listeners after the initialization and shut them down during the program shutdown.\n\n::: code providing_services.bal :::\n\n::: out providing_services.out :::"
  },
  {
    "path": "examples/providing-services/providing_services.metatags",
    "content": "description: This BBE explains various constructs that are related to proving services.\nkeywords:  ballerina, ballerina by example, bbe, Listener, Service, Service Object, Module\n"
  },
  {
    "path": "examples/providing-services/providing_services.out",
    "content": "$ bal run providing_services.bal\n"
  },
  {
    "path": "examples/query-actions/query_actions.bal",
    "content": "import ballerina/io;\n \npublic function main() returns error? {\n    int[] nums = [1, 2, 3, 4];\n    int[] numsTimes10 = [];\n \n    // The `from` clause works similar to a `foreach` statement.\n    check from var i in nums\n        // The `do` statement block is evaluated in each iteration.\n        do {\n            numsTimes10.push(i * 10);\n        };\n \n    io:println(numsTimes10);\n \n    // Print only the even numbers in the `nums` array.\n    // Intermediate clauses such as `let` clause, `join` clause, `order by` clause,\n    // `where clause`, and `limit` clause can also be used.\n    check from var i in nums\n        where i % 2 == 0\n        do {\n            io:println(i);\n        };\n}\n"
  },
  {
    "path": "examples/query-actions/query_actions.md",
    "content": "# Query actions\n\nA query action allows you to use the functionalities of a query expression to iteratively execute a code block like a `foreach` statement. A Query action starts with a `from` clause and ends with a `do` clause. It can contain all the intermediate clauses in a query expression.\n\nThe clauses in a query action are executed in the same way as the clauses in a query expression. If a clause completes early with an error `e`, the result of the query action is `e`. Otherwise, the result is `null`.\n\n::: code query_actions.bal :::\n\n::: out query_actions.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n"
  },
  {
    "path": "examples/query-actions/query_actions.metatags",
    "content": "description: This BBE demonstrates query actions in Ballerina, executing a set of code segments iteratively, a `foreach` statement, using a query expression to execute a set of code segments iteratively.\nkeywords: ballerina, ballerina by example, bbe, query, query action, iterable, foreach, action, do, check\n"
  },
  {
    "path": "examples/query-actions/query_actions.out",
    "content": "$ bal run query_actions.bal\n[10,20,30,40]\n2\n4\n"
  },
  {
    "path": "examples/query-expressions/query_expressions.bal",
    "content": "import ballerina/io;\n \npublic function main() {\n    int[] nums = [1, 2, 3, 4];\n \n    // The `from` clause works similar to a `foreach` statement.\n    int[] numsTimes10 = from var i in nums\n                        // The `select` clause is evaluated for each iteration.\n                        select i * 10;\n    io:println(numsTimes10);\n \n    // A `where` clause can be used to filter iterable values.\n    // It can occur multiple times anywhere between a `from` and `select` clause.\n    // This will pass the frame to the `select` clause only if `i % 2 == 0` is true.\n    int[] evenNums = from int i in nums\n                     where i % 2 == 0\n                     select i;\n    io:println(evenNums);\n \n    // The `order by` clause can be used to sort the result in \n    // `ascending` or `descending` order.\n    int[] numsReversed = from int i in nums\n                         order by i descending\n                         select i;\n    io:println(numsReversed);\n \n    // Iterating a string value using the query expression.\n    string languageName = \"Ballerina\";\n    string newName = from var char in languageName\n                     select char + char;\n \n    io:println(newName);\n}\n"
  },
  {
    "path": "examples/query-expressions/query_expressions.md",
    "content": "# Query expressions\n\nA query expression is similar to the `SQL` query syntax where you can construct a list, a mapping, a table, a stream, or a sequence by iterating over an iterable value.\n\nA query expression consists of a sequence of clauses starting with a `from` clause and ending with a `select` clause.\n\n::: code query_expressions.bal :::\n\n::: out query_expressions.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/query-expressions/query_expressions.metatags",
    "content": "description: This BBE demonstrates query expressions in Ballerina, creating a list value from a query expression, creating a string value from a query expression, iterating a list, iterating an array, iterating a sequence value, filtering an iterable value, filtering a list, and the `where` clause.\nkeywords: ballerina, ballerina by example, bbe, query, iterate, from, select, language integrated queries, where, condition\n"
  },
  {
    "path": "examples/query-expressions/query_expressions.out",
    "content": "$ bal run query_expressions.bal\n[10,20,30,40]\n[2,4]\n[4,3,2,1]\nBBaalllleerriinnaa\n"
  },
  {
    "path": "examples/querying-tables/querying_tables.bal",
    "content": "import ballerina/io;\n\ntype Employee record {|\n    readonly int id;\n    string firstName;\n    string lastName;\n    int salary;\n|};\n\npublic function main() {\n    table<Employee> key(id) employees = table [\n            {id: 1, firstName: \"John\", lastName: \"Smith\", salary: 100},\n            {id: 2, firstName: \"Jane\", lastName: \"Smith\", salary: 150},\n            {id: 4, firstName: \"Fred\", lastName: \"Bloggs\", salary: 200},\n            {id: 7, firstName: \"Bobby\", lastName: \"Clark\", salary: 300},\n            {id: 9, firstName: \"Cassie\", lastName: \"Smith\", salary: 250}\n        ];\n\n    // Since the contextually-expected type for the query expression is `int[]`,\n    // the evaluation of the query expression will result in an integer array.\n    int[] salaries = from var emp in employees\n                     select emp.salary;\n    io:println(salaries);\n\n    // The query expression creates a table based on the contextually-expected type.\n    table<Employee> highPaidEmployees = from Employee emp in employees\n                             where emp.salary > 180\n                             order by emp.firstName\n                             select emp;\n\n    foreach Employee emp in highPaidEmployees {\n        io:println(emp.firstName, \" \", emp.lastName);\n    }\n}\n"
  },
  {
    "path": "examples/querying-tables/querying_tables.md",
    "content": "# Query tables\n\nTables can be combined with query expressions, unlike maps. The basic type of the output of a query expression is determined by the contextually expected type, and the input type.\n\n::: code querying_tables.bal :::\n\n::: out querying_tables.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/querying-tables/querying_tables.metatags",
    "content": "description: This BBE demonstrates querying tables in Ballerina, filtering tables, ordering tables rows, sorting a table, iterating a table, performing table operations, querying a table, and creating an array from a table.\nkeywords: ballerina, ballerina by example, bbe, querying tables, table, query, query expression, filter, order, sort, iterate, array, where\n"
  },
  {
    "path": "examples/querying-tables/querying_tables.out",
    "content": "$ bal run querying_tables.bal\n[100,150,200,300,250]\nBobby Clark\nCassie Smith\nFred Bloggs\n"
  },
  {
    "path": "examples/querying-with-streams/querying_with_streams.bal",
    "content": "import ballerina/io;\n\nclass EvenNumberGenerator {\n    int i = 0;\n    public isolated function next() returns record {|int value;|}|error? {\n        self.i += 2;\n        if self.i > 10 {\n            return ();\n        }\n\n        return {value: self.i};\n    }\n}\n\npublic function main() returns error? {\n    EvenNumberGenerator evenGen = new ();\n\n    // Creates a `stream` passing an `EvenNumberGenerator` object to the `stream` constructor.\n    stream<int, error?> evenNumberStream = new (evenGen);\n\n    // Iterates the `evenNumberStream` until it returns `()`.\n    // If the stream terminates with an error, the result of the query expression will be the error.\n    int[] evenNumbers = check from var number in evenNumberStream\n                        select number;\n\n    io:println(evenNumbers);\n}\n"
  },
  {
    "path": "examples/querying-with-streams/querying_with_streams.md",
    "content": "# Query streams\n\nA query expression can be used to call the `next()` method of a stream iteratively. A binding pattern in a query expression will bind the value of the result from the `next()` operation on the stream. If the stream terminates with an error, result of the query expression will be the error.\n\n::: code querying_with_streams.bal :::\n\n::: out querying_with_streams.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Sort iterable objects using query](/learn/by-example/sort-iterable-objects)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/querying-with-streams/querying_with_streams.metatags",
    "content": "description: This BBE demonstrates querying with streams in Ballerina, iterating a stream object, calling the next method of a stream, using a stream object, and handling the termination value of a stream.\nkeywords: ballerina, ballerina by example, bbe, stream, lazy, value, next, query, check\n"
  },
  {
    "path": "examples/querying-with-streams/querying_with_streams.out",
    "content": "$ bal run querying_with_streams.bal\n[2,4,6,8,10]\n"
  },
  {
    "path": "examples/rabbitmq-client-basic-auth/rabbitmq_client_basic_auth.bal",
    "content": "import ballerina/http;\nimport ballerinax/rabbitmq;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final rabbitmq:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the RabbitMQ client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT,\n            // To secure the client connections using username/password authentication, provide the credentials\n            // with the `rabbitmq:Credentials` record.\n            auth = {\n                 username: \"alice\",\n                 password: \"alice@123\"\n            }\n        );\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Publishes the message using the `newClient` and the routing key named `OrderQueue`.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            routingKey: \"OrderQueue\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-client-basic-auth/rabbitmq_client_basic_auth.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/rabbitmq-client-basic-auth/rabbitmq_client_basic_auth.md",
    "content": "# RabbitMQ client - Basic authentication\n\nThe RabbitMQ authentication allows securing the client communication with the server. After an application connects to RabbitMQ and before it can perform operations, it must authenticate (i.e., present and prove its identity). In this example, the underlying connection of the client is secured with Basic Authentication. A secured `rabbitmq:Client` is created by using the default host and port or custom configurations and by providing the authentication details using the `rabbitmq:Credentials` record. Use it to authenticate client connections using a username and password.\n\n::: code rabbitmq_client_basic_auth.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_client_basic_auth.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out rabbitmq_client_basic_auth.client.out :::\n\n## Related links\n- [`rabbitmq:Credentials` - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Credentials)\n- [RabbitMQ connection - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/rabbitmq-client-basic-auth/rabbitmq_client_basic_auth.metatags",
    "content": "description: This example demonstrates publishing messages to a RabbitMQ queue using a connection with basic authentication.\nkeywords: ballerina, ballerina by example, rabbitmq, ssl, tls, authentication, credentials\n"
  },
  {
    "path": "examples/rabbitmq-client-basic-auth/rabbitmq_client_basic_auth.server.out",
    "content": "$ bal run rabbitmq-client-basic-auth.bal\n"
  },
  {
    "path": "examples/rabbitmq-client-constraint-validation/rabbitmq_client_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerinax/rabbitmq;\nimport ballerina/log;\n\npublic type Order record {\n    int orderId;\n    // Add a constraint to allow only string values of length between 1 and 30.\n    @constraint:String {maxLength: 30, minLength: 1}\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    // Creates a ballerina RabbitMQ client.\n    rabbitmq:Client newClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);\n\n    // Consuming message from the routing key OrderQueue.\n    Order|rabbitmq:PayloadValidationError|rabbitmq:Error 'order = newClient->consumePayload(\"OrderQueue\");\n    if 'order is Order {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        } \n    } else if 'order is rabbitmq:PayloadValidationError {\n        log:printError(\"Payload validation failed\", 'order);\n    } else {\n        log:printError(\"Error occurred while consuming\");    \n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-client-constraint-validation/rabbitmq_client_constraint_validation.md",
    "content": "# RabbitMQ client - Constraint validation\n\nThe Ballerina constraint module allows you to add additional constraints to the message content. The constraints can be added to a given data type using different annotations. When a message with a constraint is received from the RabbitMQ server, it is validated internally. This validation happens soon after the successful data-binding of the message content before returning the message record. If the validation fails, the `rabbitmq:PayloadValidationError` error is returned. Use this to validate the message content as the application receives it, which allows you to guard against unnecessary message content processing and malicious content.\n\n::: code rabbitmq_client_constraint_validation.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_client_constraint_validation.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client](/learn/by-example/rabbitmq-producer/) example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.\n\n## Related links\n- [`rabbitmq:PayloadValidationError` error type - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#PayloadValidationError)\n- [`rabbitmq` package - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest)\n- [`constraint` package - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n"
  },
  {
    "path": "examples/rabbitmq-client-constraint-validation/rabbitmq_client_constraint_validation.metatags",
    "content": "description: This example demonstrates validating a payload according to the constraints defined in the payload record.\nkeywords: ballerina, ballerina by example, bbe, rabbitmq, consumer, listener, service, constraint, validation\n"
  },
  {
    "path": "examples/rabbitmq-client-constraint-validation/rabbitmq_client_constraint_validation.out",
    "content": "$ bal run rabbitmq_client_constraint_validation.bal\ntime = 2022-12-05T08:18:09.346+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\ntime = 2022-12-05T08:18:49.844+05:30 level = ERROR module = \"\" message = \"Payload validation failed\" error = \"Validation failed for \\'$.productName:maxLength\\' constraint(s).\"\ntime = 2022-12-05T08:19:19.214+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/rabbitmq-client-secure-connection/rabbitmq_client_secure_connection.bal",
    "content": "import ballerina/http;\nimport ballerinax/rabbitmq;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final rabbitmq:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the RabbitMQ client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (rabbitmq:DEFAULT_HOST, 5671,\n            // To secure the client connection using TLS/SSL, the client needs to be configured with\n            // a certificate file of the server.\n            secureSocket = {\n                cert: \"../resource/path/to/public.crt\"\n            }\n        );\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Publishes the message using the `newClient` and the routing key named `OrderQueue`.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            routingKey: \"OrderQueue\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-client-secure-connection/rabbitmq_client_secure_connection.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/rabbitmq-client-secure-connection/rabbitmq_client_secure_connection.md",
    "content": "# RabbitMQ client - SSL/TLS\n\nThe `rabbitmq:Client` can be configured to connect to the server via SSL/TLS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the `rabbitmq:ConnectionConfiguration`. Use this to secure the communication between the client and the server.\n\n::: code rabbitmq_client_secure_connection.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_client_secure_connection.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out rabbitmq_client_secure_connection.client.out :::\n\n## Related links\n- [`rabbitmq:SecureSocket` - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#SecureSocket)\n- [RabbitMQ connection - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/rabbitmq-client-secure-connection/rabbitmq_client_secure_connection.metatags",
    "content": "description: This example demonstrates consuming messages from a RabbitMQ queue using a secured connection.\nkeywords: ballerina, ballerina by example, rabbitmq, ssl, tls, authentication, credentials\n"
  },
  {
    "path": "examples/rabbitmq-client-secure-connection/rabbitmq_client_secure_connection.server.out",
    "content": "$ bal run rabbitmq-client-secure-connection.bal\n"
  },
  {
    "path": "examples/rabbitmq-consumer/rabbitmq_consumer.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// The consumer service listens to the \"OrderQueue\" queue.\nservice \"OrderQueue\" on new rabbitmq:Listener(rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT) {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-consumer/rabbitmq_consumer.md",
    "content": "# RabbitMQ service - Consume message\n\nThe `rabbitmq:Service` listens to the given queue for incoming messages. When a publisher sends a message on a queue, any active service listening on that queue receives the message. A `rabbitmq:Listener` is created by passing the host and port of the RabbiMQ broker. A `rabbitmq:Service` attached to the listener is used to listen to a specific queue and consume incoming messages. The queue to listen to should be given as the service name or in the `queueName` field of the `rabbitmq:ServiceConfig`. Use it to listen to messages sent to a particular queue.\n\n::: code rabbitmq_consumer.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html). \n\nRun the service by executing the following command.\n\n::: out rabbitmq_consumer.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client](/learn/by-example/rabbitmq-producer/).\n\n## Related links\n- [`rabbitmq` package - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest)\n- [RabbitMQ subscribing - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#6-subscribing)\n"
  },
  {
    "path": "examples/rabbitmq-consumer/rabbitmq_consumer.metatags",
    "content": "description: This example demonstrates consuming messages from a RabbitMQ queue in an asynchronous manner.\nkeywords: ballerina, ballerina by example, rabbitmq, consumer, bbe, service, asynchronous\n"
  },
  {
    "path": "examples/rabbitmq-consumer/rabbitmq_consumer.out",
    "content": "$ bal run rabbitmq_consumer.bal\ntime = 2021-05-20T14:49:11.011+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-consumer-with-client-acknowledgement/rabbitmq_consumer_with_client_acknowledgement.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type StringMessage record {|\n    *rabbitmq:AnydataMessage;\n    string content;\n|};\n\n// The consumer service listens to the \"OrderQueue\" queue.\n// The `ackMode` is by default rabbitmq:AUTO_ACK where messages are acknowledged\n// immediately after consuming.\n@rabbitmq:ServiceConfig {\n    queueName: \"OrderQueue\",\n    autoAck: false\n}\nservice rabbitmq:Service on new rabbitmq:Listener(rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT) {\n\n    remote function onMessage(StringMessage message, rabbitmq:Caller caller) returns error? {\n        log:printInfo(\"Received message: \" + message.content);\n\n        // Positively acknowledges a single message.\n        check caller->basicAck();\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-consumer-with-client-acknowledgement/rabbitmq_consumer_with_client_acknowledgement.md",
    "content": "# RabbitMQ service - Consumer with acknowledgement\n\nThe `rabbitmq:Caller` allows manual acknowledgments for the consumed messages. A `rabbitmq:Listener` is created by passing the host and port of the RabbiMQ broker. A `rabbitmq:Service` attached to the `rabbitmq:Listener` can be used to listen to a specific subject and consume incoming messages. To enable manual acknowledgments, set the `autoAck` mode in `rabbitmq:ServiceConfig` to `false`. The `rabbitmq:Caller` can be used to acknowledge the message positively or negatively using the `basicAck` and `basicNack` functions. Use it to manually acknowledge the consumed messages.\n\n::: code rabbitmq_consumer_with_client_acknowledgement.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the service by executing the following command.\n\n::: out rabbitmq_consumer_with_client_acknowledgement.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client](/learn/by-example/rabbitmq-producer/).\n\n## Related links\n- [`rabbitmq:Caller` client object - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Caller)\n- [RabbitMQ client acknowledgements - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#8-client-acknowledgements)\n"
  },
  {
    "path": "examples/rabbitmq-consumer-with-client-acknowledgement/rabbitmq_consumer_with_client_acknowledgement.metatags",
    "content": "description: This example demonstrates manually acknowledging the messages consumed from a RabbitMQ queue.\nkeywords: ballerina, ballerina by example, rabbitmq, consumer, bbe, acknowledgment\n"
  },
  {
    "path": "examples/rabbitmq-consumer-with-client-acknowledgement/rabbitmq_consumer_with_client_acknowledgement.out",
    "content": "$ bal run rabbitmq_consumer_with_client_acknowledgement.bal\ntime = 2021-05-20T14:53:56.067+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-producer/rabbitmq_producer.bal",
    "content": "import ballerina/http;\nimport ballerinax/rabbitmq;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final rabbitmq:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the RabbitMQ client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        // Publishes the message using the `newClient` and the routing key named `OrderQueue`.\n        check self.orderClient->publishMessage({\n            content: newOrder,\n            routingKey: \"OrderQueue\"\n        });\n\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-producer/rabbitmq_producer.client.out",
    "content": "$ curl http://localhost:9092/orders -H \"Content-type:application/json\" -d \"{\\\"orderId\\\": 1, \\\"productName\\\": \\\"Sport shoe\\\", \\\"price\\\": 27.5, \\\"isValid\\\": true}\"\n"
  },
  {
    "path": "examples/rabbitmq-producer/rabbitmq_producer.md",
    "content": "# RabbitMQ client - Produce message\n\nThe `rabbitmq:Client` allows sending messages to a given pre-declared queue. A `rabbitmq:Client` is created by passing the host and port of the RabbitMQ broker. For more details on declaring the queue, see the `RabbitMQ client - Declare a queue` sample. The `publishMessage` method, which requires the queue name as the routing key and the message content is used to publish messages. Use it to publish messages that can be received by one or more consumers.\n\n::: code rabbitmq_producer.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n- Declare the queue as given in the [RabbitMQ client - Declare queue](/learn/by-example/rabbitmq-queue-declare/) example.\n- Run the RabbitMQ service given in the [RabbitMQ service - Consume message](/learn/by-example/rabbitmq-consumer/) example.\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_producer.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out rabbitmq_producer.client.out :::\n\n## Related links\n- [`rabbitmq:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Client)\n- [RabbitMQ publishing - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#5-publishing)\n"
  },
  {
    "path": "examples/rabbitmq-producer/rabbitmq_producer.metatags",
    "content": "description: This example demonstrates producing messages to a RabbitMQ queue.\nkeywords: ballerina, ballerina by example, rabbitmq, producer, bbe, client\n"
  },
  {
    "path": "examples/rabbitmq-producer/rabbitmq_producer.server.out",
    "content": "$ bal run rabbitmq_producer.bal\n"
  },
  {
    "path": "examples/rabbitmq-queue-declare/rabbitmq_queue_declare.bal",
    "content": "import ballerinax/rabbitmq;\n\npublic function main() returns error? {\n    // Creates a ballerina RabbitMQ client.\n    rabbitmq:Client newClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);\n\n    // Declares the queue, OrderQueue.\n    check newClient->queueDeclare(\"OrderQueue\");\n}\n"
  },
  {
    "path": "examples/rabbitmq-queue-declare/rabbitmq_queue_declare.md",
    "content": "# RabbitMQ client - Declare queue\n\nA RabbitMQ queue is a buffer that stores messages. The queue takes messages from the publisher and sends them to the consumer. A `rabbitmq:Client` is created with the host and port of the RabbitMQ broker. A queue with a specific name and custom configurations can be declared by using the `queueDeclare` method. To create a queue with a server-generated name, the `queueAutoGenerate` method can be used. Use this to declare the queue before publishing messages.\n\n::: code rabbitmq_queue_declare.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_queue_declare.out :::\n\n## Related links\n- [`rabbitmq:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Client)\n- [RabbitMQ exchanges and queues - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#3-exchanges-and-queues)\n"
  },
  {
    "path": "examples/rabbitmq-queue-declare/rabbitmq_queue_declare.metatags",
    "content": "description: This example demonstrates declaring a RabbitMQ queue.\nkeywords: ballerina, ballerina by example, rabbitmq, queue, bbe, client\n"
  },
  {
    "path": "examples/rabbitmq-queue-declare/rabbitmq_queue_declare.out",
    "content": "$ bal run rabbitmq_queue_declare.bal\n"
  },
  {
    "path": "examples/rabbitmq-service-basic-auth/rabbitmq_service_basic_auth.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener rabbitmq:Listener orderListener = new (rabbitmq:DEFAULT_HOST, 5671,\n    // Provide the credentials to secure the listener connections using username/password authentication.\n    // with the `rabbitmq:Credentials` record.\n    auth = {\n        username: \"alice\",\n        password: \"alice@123\"\n    }\n);\n\n// The consumer service listens to the `OrderQueue` queue.\nservice \"OrderQueue\" on orderListener {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-service-basic-auth/rabbitmq_service_basic_auth.md",
    "content": "# RabbitMQ service - Basic authentication\n\nThe RabbitMQ authentication allows securing the client communication with the server. After an application connects to RabbitMQ and before it can perform operations, it must authenticate (i.e., present and prove its identity). In this example, the underlying connection of the listener is secured with Basic Authentication. A secured `rabbitmq:Listener` is created by using the default host and port or custom configurations and by providing the authentication details using the `rabbitmq:Credentials` record. Use it to authenticate client connections using a username and password.\n\n::: code rabbitmq_service_basic_auth.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the service by executing the following command.\n\n::: out rabbitmq_service_basic_auth.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client - Basic authentication](/learn/by-example/rabbitmq-client-basic-auth/).\n\n## Related links\n- [`rabbitmq:Credentials` - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Credentials)\n- [RabbitMQ connection - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/rabbitmq-service-basic-auth/rabbitmq_service_basic_auth.metatags",
    "content": "description: This example demonstrates consuming messages from a RabbitMQ queue using a connection with basic authentication.\nkeywords: ballerina, ballerina by example, rabbitmq, ssl, tls, authentication, credentials\n"
  },
  {
    "path": "examples/rabbitmq-service-basic-auth/rabbitmq_service_basic_auth.out",
    "content": "$ bal run rabbitmq_service_basic_auth.bal\ntime = 2021-05-20T14:49:11.011+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-service-constraint-validation/rabbitmq_service_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type Order record {\n    int orderId;\n    // Add a constraint to allow only string values of length between 1 and 30.\n    @constraint:String {maxLength: 30, minLength: 1}\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\n// The consumer service listens to the \"OrderQueue\" queue.\nservice \"OrderQueue\" on new rabbitmq:Listener(rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT) {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n\n    // When an error occurs, `onError` gets invoked.\n    remote function onError(rabbitmq:AnydataMessage message, rabbitmq:Error err) {\n        if err is rabbitmq:PayloadValidationError {\n            log:printError(\"Payload validation failed\", err);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-service-constraint-validation/rabbitmq_service_constraint_validation.md",
    "content": "# RabbitMQ service - Constraint validation\n\nThe Ballerina constraint module allows you to add additional constraints to the message content. The constraints can be added to a given data type using different annotations. When a message with a constraint is received from the RabbitMQ server, it is validated internally. This validation happens soon after the successful data-binding of the message content before executing the `onMessage` remote method. If the validation fails, the `onError` remote method is invoked with the error type `nats:PayloadValidationError`. Use this to validate the message content as the application receives it, which allows you to guard against unnecessary remote method processing and malicious content.\n\n::: code rabbitmq_service_constraint_validation.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html). \n\nRun the service by executing the following command.\n\n::: out rabbitmq_service_constraint_validation.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client](/learn/by-example/rabbitmq-producer/) example with a valid product name (0 < length <= 30), then with an invalid product name and again with a valid product name.\n\n## Related links\n- [`rabbitmq:PayloadValidationError` error type - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#PayloadValidationError)\n- [`rabbitmq` package - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest)\n- [`constraint` package - API documentation](https://lib.ballerina.io/ballerina/constraint/latest)\n"
  },
  {
    "path": "examples/rabbitmq-service-constraint-validation/rabbitmq_service_constraint_validation.metatags",
    "content": "description: This example demonstrates validating a payload according to the constraints defined in the payload record.\nkeywords: ballerina, ballerina by example, bbe, rabbitmq, consumer, listener, service, constraint, validation\n"
  },
  {
    "path": "examples/rabbitmq-service-constraint-validation/rabbitmq_service_constraint_validation.out",
    "content": "$ bal run rabbitmq_service_constraint_validation.bal\ntime = 2022-12-05T08:08:36.426+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\ntime = 2022-12-05T08:08:57.313+05:30 level = ERROR module = \"\" message = \"Payload validation failed\" error = \"Validation failed for \\'$.productName:maxLength\\' constraint(s).\"\ntime = 2022-12-05T08:09:19.634+05:30 level = INFO module = \"\" message = \"Received valid order for Sport shoe\"\n"
  },
  {
    "path": "examples/rabbitmq-service-secure-connection/rabbitmq_service_secure_connection.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nlistener rabbitmq:Listener orderListener = new (rabbitmq:DEFAULT_HOST, 5671,\n    // To secure the client connection using TLS/SSL, the client needs to be configured with\n    // a certificate file of the server.\n    secureSocket = {\n        cert: \"../resource/path/to/public.crt\"\n    }\n);\n\n// The consumer service listens to the `OrderQueue` queue.\nservice \"OrderQueue\" on orderListener {\n\n    remote function onMessage(Order 'order) returns error? {\n        if 'order.isValid {\n            log:printInfo(string `Received valid order for ${'order.productName}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-service-secure-connection/rabbitmq_service_secure_connection.md",
    "content": "# RabbitMQ service - SSL/TLS\n\nThe `rabbitmq:Listener` can be configured to connect to the server via SSL/TLS by providing a certificate file. The certificate can be provided through the `secureSocket` field of the connection configuration. Use this to secure the communication between the client and the server.\n\n::: code rabbitmq_service_secure_connection.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the service by executing the following command.\n\n::: out rabbitmq_service_secure_connection.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client - SSL/TLS](/learn/by-example/rabbitmq-client-secure-connection/).\n\n## Related links\n- [`rabbitmq:SecureSocket` - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#SecureSocket)\n- [RabbitMQ connection - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#2-connection)\n"
  },
  {
    "path": "examples/rabbitmq-service-secure-connection/rabbitmq_service_secure_connection.metatags",
    "content": "description: This example demonstrates consuming messages from a RabbitMQ queue using a secured connection.\nkeywords: ballerina, ballerina by example, rabbitmq, ssl, tls, authentication, credentials\n"
  },
  {
    "path": "examples/rabbitmq-service-secure-connection/rabbitmq_service_secure_connection.out",
    "content": "$ bal run rabbitmq_service_secure_connection.bal\ntime = 2021-05-20T14:49:11.011+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-sync-consumer/rabbitmq_sync_consumer.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type Order record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\npublic function main() returns error? {\n    // Creates a ballerina RabbitMQ client.\n    rabbitmq:Client newClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);\n\n    // Consuming message from the routing key OrderQueue.\n    Order 'order = check newClient->consumePayload(\"OrderQueue\");\n    if 'order.isValid {\n        log:printInfo(string `Received valid order for ${'order.productName}`);\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-sync-consumer/rabbitmq_sync_consumer.md",
    "content": "# RabbitMQ client - Consume message\n\nThe `rabbitmq:Client` allows fetching individual messages one by one from the server. A `rabbitmq:Client` is created by passing the host and port of the RabbitMQ broker. To pull messages, use the `consumePayload` or `consumeMessage` method, which requires the queue name as the argument. Messages are fetched in the FIFO order. It is possible to use automatic or manual acknowledgments similar to consumer services. Use it to pull messages one by one from a queue in the RabbitMQ server.\n\n::: code rabbitmq_sync_consumer.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_sync_consumer.out :::\n\n>**Tip:** You can try out the above consumer via the [RabbitMQ client](/learn/by-example/rabbitmq-producer/).\n\n## Related links\n- [`rabbitmq:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Client)\n- [RabbitMQ pull API - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#7-retrieving-individual-messages)\n"
  },
  {
    "path": "examples/rabbitmq-sync-consumer/rabbitmq_sync_consumer.metatags",
    "content": "description: This example demonstrates consuming messages from a RabbitMQ queue synchronously.\nkeywords: ballerina, ballerina by example, rabbitmq, pull, consumer, client, bbe\n"
  },
  {
    "path": "examples/rabbitmq-sync-consumer/rabbitmq_sync_consumer.out",
    "content": "$ bal run rabbitmq_sync_consumer.bal\ntime = 2021-05-20T14:49:11.011+05:30 level = INFO module = \"\" message = \"Received message: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-transaction-consumer/rabbitmq_transaction_consumer.bal",
    "content": "import ballerina/log;\nimport ballerinax/rabbitmq;\n\npublic type StringMessage record {|\n    *rabbitmq:AnydataMessage;\n    string content;\n|};\n\n// The consumer service listens to the \"MyQueue\" queue.\n@rabbitmq:ServiceConfig {\n    queueName: \"OrderQueue\",\n    autoAck: false\n}\nservice on new rabbitmq:Listener(rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT) {\n\n    remote function onMessage(StringMessage message, rabbitmq:Caller caller) returns error? {\n        // Acknowledges a single message positively.\n        transaction {\n            log:printInfo(\"Received message: \" + message.content);\n\n            // Positively acknowledges a single message.\n            check caller->basicAck();\n            check commit;\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-transaction-consumer/rabbitmq_transaction_consumer.md",
    "content": "# RabbitMQ service - Transactional consumer\n\nThe `rabbitmq:Service` can become a transactional consumer by acknowledging messages within a Ballerina transaction block. A `rabbitmq:Listener` can be created by passing the host and port of the RabbitMQ broker. A `rabbitmq:Service` attached to the listener can be used to listen to a specific queue. The queue to listen to should be given as the service name or in the `queueName` field of the `rabbitmq:ServiceConfig`. The `rabbitmq:Caller`, which is passed as an argument in the `onMessage` remote method is used to acknowledge the message inside a transaction block. Use it to consume messages with ensured acknowledgment to the RabbitMQ server.\n\n::: code rabbitmq_transaction_consumer.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n\nRun the service by executing the following command.\n\n::: out rabbitmq_transaction_consumer.out :::\n\n>**Tip:** You can invoke the above service via the [RabbitMQ client - Transactional producer](/learn/by-example/rabbitmq-transaction-producer//).\n\n## Related links\n- [`rabbitmq` package - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest)\n- [RabbitMQ client acknowledgments - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#8-client-acknowledgements)\n"
  },
  {
    "path": "examples/rabbitmq-transaction-consumer/rabbitmq_transaction_consumer.metatags",
    "content": "description: This example demonstrates transactionally acknowledging messages consumed from a RabbitMQ queue.\nkeywords: ballerina, ballerina by example, rabbitmq, bbe, consumer, transaction\n"
  },
  {
    "path": "examples/rabbitmq-transaction-consumer/rabbitmq_transaction_consumer.out",
    "content": "$ bal run rabbitmq_transaction_consumer.bal\ntime = 2021-01-18 15:15:36,514 level = INFO  module = \"\" message = \"The message received: Hello from Ballerina\"\n"
  },
  {
    "path": "examples/rabbitmq-transaction-producer/rabbitmq_transaction_producer.bal",
    "content": "import ballerina/http;\nimport ballerinax/rabbitmq;\n\ntype Order readonly & record {\n    int orderId;\n    string productName;\n    decimal price;\n    boolean isValid;\n};\n\nservice / on new http:Listener(9092) {\n    private final rabbitmq:Client orderClient;\n\n    function init() returns error? {\n        // Initiate the RabbitMQ client at the start of the service. This will be used\n        // throughout the lifetime of the service.\n        self.orderClient = check new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);\n    }\n\n    resource function post orders(Order newOrder) returns http:Accepted|error {\n        transaction {\n            // Publishes the message using the `newClient` and the routing key named `OrderQueue`.\n            check self.orderClient->publishMessage({\n                content: newOrder,\n                routingKey: \"OrderQueue\"\n            });\n            check commit;\n        }\n        return http:ACCEPTED;\n    }\n}\n"
  },
  {
    "path": "examples/rabbitmq-transaction-producer/rabbitmq_transaction_producer.md",
    "content": "# RabbitMQ client - Transactional producer\n\nThe `rabbitmq:Client` can become a transactional producer by publishing messages within a Ballerina transaction block. Upon successful execution of the transaction block, the client will commit or roll back in the case of any error. A `rabbitmq:Client` can be created by passing the host and port of the RabbitMQ broker. To publish messages, the `publishMessage` method, which requires the message and queue name as arguments is used. Use it to publish messages to the RabbitMQ server with ensured delivery.\n\n::: code rabbitmq_transaction_producer.bal :::\n\n## Prerequisites\n- Start an instance of the [RabbitMQ server](https://www.rabbitmq.com/download.html).\n- Declare the queue as given in the [RabbitMQ client - Declare queue](/learn/by-example/rabbitmq-queue-declare/) example.\n- Run the RabbitMQ service given in the [RabbitMQ service - Transactional consumer](/learn/by-example/rabbitmq-transaction-consumer/) example.\n\nRun the client program by executing the following command.\n\n::: out rabbitmq_transaction_producer.out :::\n\n## Related links\n- [`rabbitmq:Client` client object - API documentation](https://lib.ballerina.io/ballerinax/rabbitmq/latest#Client)\n- [RabbitMQ publishing - Specification](https://github.com/ballerina-platform/module-ballerinax-rabbitmq/blob/master/docs/spec/spec.md#5-publishing)\n"
  },
  {
    "path": "examples/rabbitmq-transaction-producer/rabbitmq_transaction_producer.metatags",
    "content": "description: This example demonstrates transactionally producing messages to a RabbitMQ queue.\nkeywords: ballerina, ballerina by example, rabbitmq, producer, bbe, transaction\n"
  },
  {
    "path": "examples/rabbitmq-transaction-producer/rabbitmq_transaction_producer.out",
    "content": "$ bal run rabbitmq_transaction_producer.bal\n"
  },
  {
    "path": "examples/rag-ingestion-with-external-vector-store/rag_ingestion_with_external_vector_store.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\nimport ballerinax/ai.pinecone;\n\n// Configuration for Pinecone.\nconfigurable string pineconeServiceUrl = ?;\nconfigurable string pineconeApiKey = ?;\n\n// Define the vector store to use.\n// The example uses Pinecone. Alternatively, you can use other providers\n// or try out the in-memory vector store (`ai:InMemoryVectorStore`).\nfinal ai:VectorStore vectorStore = \n            check new pinecone:VectorStore(pineconeServiceUrl, pineconeApiKey);\n\n// Define the embedding provider to use.\n// The example uses the default embedding provider implementation\n// (with configuration added via a Ballerina VS Code command).\nfinal ai:EmbeddingProvider embeddingProvider = \n            check ai:getDefaultEmbeddingProvider();\n\n// Create the knowledge base with the vector store and embedding provider.\nfinal ai:KnowledgeBase knowledgeBase = \n            new ai:VectorKnowledgeBase(vectorStore, embeddingProvider);\n\npublic function main() returns error? {\n    // Use data loaders to load documents.\n    ai:DataLoader loader = check new ai:TextDataLoader(\"./leave_policy.pdf\");\n    ai:Document|ai:Document[] documents = check loader.load();\n\n    // Ingest the documents into the knowledge base. \n    // When `ai:Document`s are ingested, chunking is handled by the knowledge base.\n    // Alternatively, for finer control, you can use the required chunker\n    // (`ai:Chunker` implementations) to chunk documents and pass the chunks\n    // as the argument.\n    ai:Error? ingestionResult = knowledgeBase.ingest(documents);\n    if ingestionResult is () {\n        io:println(\"Ingestion successful\");\n    } else {\n        io:println(\"Ingestion failed: \", ingestionResult.message());\n    }\n}\n"
  },
  {
    "path": "examples/rag-ingestion-with-external-vector-store/rag_ingestion_with_external_vector_store.md",
    "content": "# Retrieval-augmented generation (RAG) ingestion\n\nBallerina has high-level, provider-agnostic APIs to ingest data for retrieval-augmented generation (RAG) workflows. These include abstractions such as `ai:DataLoader`, `ai:VectorStore`, `ai:EmbeddingProvider`, and `ai:KnowledgeBase`.\n\nThese abstractions enable you to load documents, convert them into semantically meaningful vector representations using embedding models, and index them into a vector database (e.g., Pinecone, Weaviate, etc.). The knowledge base (`ai: KnowledgeBase`) orchestrates this process.\n\nThis example demonstrates how to use `ai:TextDataLoader` to load documents, generate embeddings with a configured provider, and ingest them into a vector store.\n\n> Note: This example uses the default embedding provider implementation and Pinecone. To generate the configuration for the embedding provider, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` embedding provider implementation. Follow [`ballerinax/ai.pinecone` prerequisites](https://central.ballerina.io/ballerinax/ai.pinecone/latest#prerequisites) to extract Pinecone configuration. Alternatively, you can try out the in-memory vector store (`ai:InMemoryVectorStore`).\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code rag_ingestion_with_external_vector_store.bal :::\n\n::: out rag_ingestion_with_external_vector_store.out :::\n\n## Related links\n\n- [Sample policy document](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/rag-ingestion-with-external-vector-store/leave_policy.pdf)\n- [RAG query with external vector store example](/learn/by-example/rag-query-with-external-vector-store/)\n- [The `ballerinax/ai.milvus` module](https://central.ballerina.io/ballerinax/ai.milvus/latest)\n- [The `ballerinax/ai.pinecone` module](https://central.ballerina.io/ballerinax/ai.pinecone/latest)\n- [The `ballerinax/ai.pgvector` module](https://central.ballerina.io/ballerinax/ai.pgvector/latest)\n- [The `ballerinax/ai.weaviate` module](https://central.ballerina.io/ballerinax/ai.weaviate/latest)\n\n"
  },
  {
    "path": "examples/rag-ingestion-with-external-vector-store/rag_ingestion_with_external_vector_store.metatags",
    "content": "description: This BBE demonstrates how to do data ingestion for retrieval-augmented generation (RAG).\nkeywords: ballerina, ballerina by example, BBE, ai, llm, rag\n"
  },
  {
    "path": "examples/rag-ingestion-with-external-vector-store/rag_ingestion_with_external_vector_store.out",
    "content": "$ bal run rag_ingestion_with_external_vector_store.bal\nIngestion successful\n"
  },
  {
    "path": "examples/rag-query-with-external-vector-store/rag_query_with_external_vector_store.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\nimport ballerinax/ai.pinecone;\n\n// Configuration for Pinecone.\nconfigurable string pineconeServiceUrl = ?;\nconfigurable string pineconeApiKey = ?;\n\n// Define the vector store to use.\n// The example uses Pinecone. Alternatively, you can use other providers\n// or try out the in-memory vector store (`ai:InMemoryVectorStore`).\nfinal ai:VectorStore vectorStore = \n            check new pinecone:VectorStore(pineconeServiceUrl, pineconeApiKey);\n\n// Define the embedding provider to use.\n// The example uses the default embedding provider implementation\n// (with configuration added via a Ballerina VS Code command).\nfinal ai:EmbeddingProvider embeddingProvider = \n            check ai:getDefaultEmbeddingProvider();\n\n// Create the knowledge base with the vector store and embedding provider.\nfinal ai:KnowledgeBase knowledgeBase = \n            new ai:VectorKnowledgeBase(vectorStore, embeddingProvider);\n\n// Define the model provider to use.\n// The example uses the default model provider implementation\n// (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider modelProvider = check ai:getDefaultModelProvider();\n\npublic function main() returns error? {\n    string appealQuery = \n        \"What is the process for appealing a rejected leave request?\";\n\n    // Retrieve the relevant context (chunks) from the knowledge base.\n    ai:QueryMatch[] queryMatches = check knowledgeBase.retrieve(appealQuery, 10);\n    ai:Chunk[] context = from ai:QueryMatch queryMatch in queryMatches\n                            select queryMatch.chunk;\n\n    // Use the `generate` method, inserting the context and query to the prompt.\n    string answer = check modelProvider->generate(`Answer the query based on the \n\t    following context:\n\n\t    Context: ${context}\n\n\t    Query: ${appealQuery}\n\n\t    Base the answer only on the above context. If the answer is not\n\t    contained within the context, respond with \"I don't know\".`);\n    io:println(\"Query: \", appealQuery);\n    io:println(\"Answer: \", answer);\n\n    string carryForwardQuery = \n        \"How many annual leave days can a full-time employee carry forward to the next year?\";\n    \n    queryMatches = check knowledgeBase.retrieve(carryForwardQuery, 10);\n    context = from ai:QueryMatch queryMatch in queryMatches\n                            select queryMatch.chunk;\n\n    // The `augmentUserQuery` function augments the user query with the context using \n    // a generic prompt template.\n    ai:ChatUserMessage augmentedQuery = ai:augmentUserQuery(context, carryForwardQuery);\n\n    // Use the `chat` method with the `ai:ChatUserMessage` with the augmented query.\n    ai:ChatAssistantMessage assistantMessage = check modelProvider->chat(augmentedQuery);\n    \n    io:println(\"\\nQuery: \", carryForwardQuery);\n    io:println(\"Answer: \", assistantMessage.content);\n}\n"
  },
  {
    "path": "examples/rag-query-with-external-vector-store/rag_query_with_external_vector_store.md",
    "content": "# Retrieval-augmented generation (RAG) query\n\nRetrieval-augmented generation (RAG) is a technique that enhances capabilities of large language models by combining them with external knowledge sources to provide more accurate and contextually-relevant responses.\n\nBallerina has high-level, provider-agnostic APIs for retrieval-augmented generation (RAG) workflows. These include abstractions such as `ai:VectorStore`, `ai:EmbeddingProvider`, and `ai:KnowledgeBase`.\n\nThese abstractions enable you to query semantically similar content from vector databases (e.g., Pinecone, Weaviate, etc.) and use retrieved context in the request to the LLM to generate more accurate responses.\n\nThis example demonstrates how to query a knowledge base to retrieve relevant documents and use them with a language model to answer questions based on the retrieved context. \n\n> Note: You can follow the [RAG ingestion](/learn/by-example/rag-ingestion/) example to ingest data first.\n\n> Note: This example uses the default model provider and embedding provider implementations and Pinecone. To generate the configuration for the model and embedding providers, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` embedding provider implementation. Follow [`ballerinax/ai.pinecone` prerequisites](https://central.ballerina.io/ballerinax/ai.pinecone/latest#prerequisites) to extract Pinecone configuration. Alternatively, you can try out the in-memory vector store (`ai:InMemoryVectorStore`).\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code rag_query_with_external_vector_store.bal :::\n\n::: out rag_query_with_external_vector_store.out :::\n\n## Related links\n\n- [RAG ingestion example](/learn/by-example/rag-ingestion/)\n- [The `ballerinax/ai.milvus` module](https://central.ballerina.io/ballerinax/ai.milvus/latest)\n- [The `ballerinax/ai.pinecone` module](https://central.ballerina.io/ballerinax/ai.pinecone/latest)\n- [The `ballerinax/ai.pgvector` module](https://central.ballerina.io/ballerinax/ai.pgvector/latest)\n- [The `ballerinax/ai.weaviate` module](https://central.ballerina.io/ballerinax/ai.weaviate/latest)\n"
  },
  {
    "path": "examples/rag-query-with-external-vector-store/rag_query_with_external_vector_store.metatags",
    "content": "description: This BBE demonstrates how to do retrieval-augmented generation (RAG).\nkeywords: ballerina, ballerina by example, BBE, ai, llm, rag\n"
  },
  {
    "path": "examples/rag-query-with-external-vector-store/rag_query_with_external_vector_store.out",
    "content": "$ bal run rag_query_with_external_vector_store.bal\nQuery: What is the process for appealing a rejected leave request?\nAnswer: I don't know.\n\nQuery: How many annual leave days can a full-time employee carry forward to the next year?\nAnswer: A full-time employee can carry forward up to 5 unused annual leave days to the next year.\n"
  },
  {
    "path": "examples/rag-with-in-memory-vector-store/leave_policy.md",
    "content": "# 📝 Company Leave Policy\n\n**Effective Date:** January 1, 2025  \n**Last Updated:** September 24, 2025  \n**Applies to:** All full-time and part-time employees  \n\n---\n\n## 1. 🎯 Purpose\n\nThe purpose of this leave policy is to outline the types of leave available to employees and the procedures for requesting time off. We aim to provide a fair and transparent system that supports employee well-being while ensuring continuity of work.\n\n---\n\n## 2. 🕒 Types of Leave\n\n### 2.1. Annual Leave (Paid Time Off - PTO)\n\n- **Eligibility:** All full-time employees  \n- **Accrual:** 1.75 days per month (21 days per year)  \n- **Carry Forward:** Up to 5 unused days can be carried forward to the next calendar year  \n- **Usage:** Requires manager approval and minimum 3 days' notice\n\n### 2.2. Sick Leave\n\n- **Eligibility:** All employees  \n- **Entitlement:** 12 days per year (non-cumulative)  \n- **Documentation:** Medical certificate required for absences longer than 2 days  \n- **Notification:** Inform the manager within 24 hours of illness\n\n### 2.3. Casual Leave\n\n- **Entitlement:** 8 days per year  \n- **Usage:** For short-term personal reasons  \n- **Approval:** Prior approval required where possible\n\n### 2.4. Maternity / Paternity Leave\n\n- **Maternity Leave:** Up to 26 weeks (as per applicable law)  \n- **Paternity Leave:** 10 days  \n- **Notification:** At least 8 weeks' advance notice\n\n### 2.5. Bereavement Leave\n\n- **Entitlement:** Up to 5 working days  \n- **Eligibility:** Death of an immediate family member  \n- **Proof:** May require documentation\n\n### 2.6. Leave Without Pay (LWP)\n\n- **Eligibility:** On request, subject to manager and HR approval  \n- **Usage:** For personal emergencies or extended time off needs  \n- **Impact:** Does not affect job status, but may affect benefits depending on duration\n\n---\n\n## 3. 📅 Leave Request Procedure\n\n1. Submit leave request via the HR portal or email  \n2. Include:\n   - Type of leave\n   - Dates\n   - Reason (if required)  \n3. Manager reviews and approves/rejects  \n4. HR updates leave records\n\n---\n\n## 4. 🔁 Leave Encashment\n\n- **Encashment:** Allowed only at the end of the calendar year for up to 5 unused annual leave days  \n- **Eligibility:** Must have completed at least 12 months of continuous service\n\n---\n\n## 5. ❗ Important Notes\n\n- Unauthorized absence may lead to disciplinary action  \n- Holidays falling during leave period will not be counted as leave  \n- In case of resignation, encashment or adjustment of unused leaves will be as per final settlement\n\n---\n\n## 6. 📌 Contact\n\nFor any clarification, please contact:  \n📧 **hr@sample.com**  \n📞 **+1-SAM-PLE-LEAVE**\n\n---\n\n> *This document is for internal use only and subject to change by management without prior notice.*\n\n"
  },
  {
    "path": "examples/rag-with-in-memory-vector-store/rag_with_in_memory_vector_store.bal",
    "content": "import ballerina/ai;\nimport ballerina/io;\n\n// Define an in-memory vector store.\nfinal ai:VectorStore vectorStore = check new ai:InMemoryVectorStore();\n\n// Define the embedding provider to use.\n// The example uses the default embedding provider implementation\n// (with configuration added via a Ballerina VS Code command).\nfinal ai:EmbeddingProvider embeddingProvider = \n            check ai:getDefaultEmbeddingProvider();\n\n// Create the knowledge base with the vector store and embedding provider.\nfinal ai:KnowledgeBase knowledgeBase = \n            new ai:VectorKnowledgeBase(vectorStore, embeddingProvider);\n\n// Define the model provider to use.\n// The example uses the default model provider implementation\n// (with configuration added via a Ballerina VS Code command).\nfinal ai:ModelProvider modelProvider = check ai:getDefaultModelProvider();\n\npublic function main() returns error? {\n    // Ingestion process.\n    // Use data loaders to load documents.\n    ai:DataLoader loader = check new ai:TextDataLoader(\"./leave_policy.md\");\n    ai:Document|ai:Document[] documents = check loader.load();\n\n    // Ingest the documents into the knowledge base. \n    // When `ai:Document`s are ingested, chunking is handled by the knowledge base.\n    // Alternatively, for finer control, you can use the required chunker\n    // (`ai:Chunker` implementations) to chunk documents and pass the chunks\n    // as the argument.\n    check knowledgeBase.ingest(documents);\n    io:println(\"Ingestion successful\");\n\n    // Querying process.\n    string query = \n        \"How many annual leave days can a full-time employee carry forward to the next year?\";\n\n    ai:QueryMatch[] queryMatches = check knowledgeBase.retrieve(query, 10);\n    ai:Chunk[] context = from ai:QueryMatch queryMatch in queryMatches\n                            select queryMatch.chunk;\n\n    // The `augmentUserQuery` function augments the user query with the context using \n    // a generic prompt template.\n    ai:ChatUserMessage augmentedQuery = ai:augmentUserQuery(context, query);\n\n    // Use the `chat` method with the `ai:ChatUserMessage` with the augmented query.\n    ai:ChatAssistantMessage assistantMessage = check modelProvider->chat(augmentedQuery);\n    \n    io:println(\"\\nQuery: \", query);\n    io:println(\"Answer: \", assistantMessage.content);\n}\n"
  },
  {
    "path": "examples/rag-with-in-memory-vector-store/rag_with_in_memory_vector_store.md",
    "content": "# Retrieval-augmented generation (RAG) with an in-memory vector store\n\nBallerina has high-level, provider-agnostic APIs to ingest data for retrieval-augmented generation (RAG) workflows. These include abstractions such as `ai:DataLoader`, `ai:VectorStore`, `ai:EmbeddingProvider`, and `ai:KnowledgeBase`.\n\nThese abstractions enable you to load documents, convert them into semantically meaningful vector representations using embedding models, and index them into a vector database. Then at generation/querying, you can query semantically similar content from vector databases and use retrieved context in the request to the LLM to generate more accurate responses. The knowledge base (`ai: KnowledgeBase`) orchestrates this process.\n\nThis example demonstrates implementing RAG workflow using an in-memory vector store.\n\n> Note: This example uses the default embedding provider and model provider implementations. To generate the necessary configuration, open up the VS Code command palette (`Ctrl` + `Shift` + `P` or `command` + `shift` + `P`), and run the `Configure default WSO2 Model Provider` command to add your configuration to the `Config.toml` file. If not already logged in, log in to the Ballerina Copilot when prompted. Alternatively, to use your own keys, use the relevant `ballerinax/ai.<provider>` embedding provider implementation.\n\nFor more information on the underlying module, see the [`ballerina/ai` module](https://lib.ballerina.io/ballerina/ai/latest/).\n\n::: code rag_with_in_memory_vector_store.bal :::\n\n::: out rag_with_in_memory_vector_store.out :::\n\n## Related links\n\n- [Sample policy document](https://github.com/ballerina-platform/ballerina-distribution/tree/master/examples/rag-with-in-memory-vector-store/leave_policy.md)\n- [RAG ingestion with external vector store example](/learn/by-example/rag-ingestion-with-external-vector-store/)\n- [RAG query with external vector store example](/learn/by-example/rag-query-with-external-vector-store/)\n- [The `ballerinax/ai.milvus` module](https://central.ballerina.io/ballerinax/ai.milvus/latest)\n- [The `ballerinax/ai.pinecone` module](https://central.ballerina.io/ballerinax/ai.pinecone/latest)\n- [The `ballerinax/ai.pgvector` module](https://central.ballerina.io/ballerinax/ai.pgvector/latest)\n- [The `ballerinax/ai.weaviate` module](https://central.ballerina.io/ballerinax/ai.weaviate/latest)\n\n"
  },
  {
    "path": "examples/rag-with-in-memory-vector-store/rag_with_in_memory_vector_store.metatags",
    "content": "description: This BBE demonstrates how to do data ingestion for retrieval-augmented generation (RAG).\nkeywords: ballerina, ballerina by example, BBE, ai, llm, rag\n"
  },
  {
    "path": "examples/rag-with-in-memory-vector-store/rag_with_in_memory_vector_store.out",
    "content": "$ bal run rag_with_in_memory_vector_store.bal\nIngestion successful\n\nQuery: How many annual leave days can a full-time employee carry forward to the next year?\nAnswer: A full-time employee can carry forward up to 5 unused annual leave days to the next year.\n"
  },
  {
    "path": "examples/random-numbers/random_numbers.bal",
    "content": "import ballerina/io;\nimport ballerina/random;\n\npublic function main() returns error? {\n    // Generates a random decimal number between 0.0 and 1.0.\n    float randomDecimal = random:createDecimal();\n    io:println(\"Random decimal number: \", randomDecimal);\n\n    // Generates a random number between the given start(inclusive) and end(exclusive) values.\n    int randomInteger = check random:createIntInRange(1, 100);\n    io:println(\"Random integer number in range: \", randomInteger);\n}\n"
  },
  {
    "path": "examples/random-numbers/random_numbers.md",
    "content": "# Random numbers\n\nThe `random` library provides functions related to random number generation.\n\nFor more information on the underlying module, see the [`random` module](https://lib.ballerina.io/ballerina/random/latest/).\n\n::: code random_numbers.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out random_numbers.out :::"
  },
  {
    "path": "examples/random-numbers/random_numbers.metatags",
    "content": "description: BBE on how to to generate random numbers.\nkeywords: ballerina, ballerina by examples, bbe, random\n"
  },
  {
    "path": "examples/random-numbers/random_numbers.out",
    "content": "$ bal run random_numbers.bal\nRandom decimal number: 0.6146990788006506\nRandom integer number in range: 94\n"
  },
  {
    "path": "examples/raw-templates/raw_templates.bal",
    "content": "import ballerina/io;\n\nfunction col3() returns boolean {\n    return false;\n}\n\ntype MyCSVRawTemplate object {\n    *object:RawTemplate;\n    public (string[] & readonly) strings;\n    public [int, int, boolean] insertions;\n};\n\npublic function main() {\n    int col1 = 5;\n    int col2 = 10;\n\n    // Any value is allowed as an interpolation when defining a value of the `object:RawTemplate` type \n    // since it has `(any|error)[]` as the `insertions` type.\n    object:RawTemplate rawTemplate = `${col1}, fixed_string1,  ${col2}, ${col3()}, fixed_string3`;\n    io:println(rawTemplate.strings);\n    io:println(rawTemplate.insertions);\n\n    // With the custom `MyCSVRawTemplate ` raw template type, the compiler \n    // expects two integers followed by a boolean value as interpolations.\n    MyCSVRawTemplate myCSVRawTemplate = `fixed_string4, ${col1}, ${col2}, fixed_string_5, ${col3()}`;\n    io:println(myCSVRawTemplate.strings);\n    io:println(myCSVRawTemplate.insertions);\n}\n"
  },
  {
    "path": "examples/raw-templates/raw_templates.md",
    "content": "# Raw templates\n\nRaw template expressions are backtick templates without a tag (such as `string` or `xml`). This is a sequence of characters interleaved with interpolations within a pair of backticks (in the form `${expression}`). The result of evaluating such a raw template is an `object:RawTemplate` object that has two fields `(readonly & string[]) strings` and `(any|error)[] insertions`. The `strings` array will have string literals in the backtick string broken at interpolations and the `insertions` array will have the resultant values of evaluating each interpolation.\n\nIf you want to control the type of the strings or the interpolations more precisely, you can define an object type that includes the `object:RawTemplate` type and override the relevant field(s) with narrower types. Then, the compiler will statically validate the values against the expected type(s).\n\nAn important use case of custom raw templates is SQL parameterized queries.\n\n::: code raw_templates.bal :::\n\n::: out raw_templates.out :::\n\n## Related links\n- [String templates](https://ballerina.io/learn/by-example/string-templates/)\n- [RegExp type](https://ballerina.io/learn/by-example/regexp-type/)\n- [Object type inclusion](https://ballerina.io/learn/by-example/object-type-inclusion/)\n- [Database Access - Simple query](https://ballerina.io/learn/by-example/mysql-query-operation/)\n"
  },
  {
    "path": "examples/raw-templates/raw_templates.metatags",
    "content": "description: This BBE demonstrates raw templates in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, raw templates\n"
  },
  {
    "path": "examples/raw-templates/raw_templates.out",
    "content": "$ bal run\n[\"\",\", fixed_string1,  \",\", \",\", fixed_string3\"]\n[5,10,false]\n[\"fixed_string4, \",\", \",\", fixed_string_5, \",\"\"]\n[5,10,false]\n"
  },
  {
    "path": "examples/readonly-and-isolated/readonly_and_isolated.bal",
    "content": "import ballerina/io;\n\ntype Entry map<json>;\n\ntype RoMap readonly & map<Entry>;\n\nfinal RoMap m = loadMap();\n\nfunction loadMap() returns RoMap {\n    readonly & Entry entry1 = {\n        \"munich\": {latitude: \"48.1351N\", longitude: \"11.5820E\"},\n        \"berlin\": {latitude: \"52.5200N\", longitude: \"13.4050E\"}\n    };\n    readonly & Entry entry2 = {\n        \"bordeaux\": {latitude: \"44.8378N\", longitude: \"0.5792W\"},\n        \"paris\": {latitude: \"48.8566N\", longitude: \"2.3522E\"}\n    };\n    RoMap roMap = {\"germany\": entry1, \"france\": entry2};\n    return roMap;\n}\n\nisolated function lookup(string s) returns readonly & Entry? {\n    // Accesses `m` directly without locking.\n    return m[s];\n}\n\npublic function main() {\n    io:println(lookup(\"france\"));\n}\n"
  },
  {
    "path": "examples/readonly-and-isolated/readonly_and_isolated.md",
    "content": "# Readonly and isolated\n\n`isolated` functions can access `final` variables with `readonly` type without locking. It relies on the fact that immutability is deep. `isolated` for functions complements `readonly` for data.\n\n::: code readonly_and_isolated.bal :::\n\nExecuting the above code gives the output below.\n\n::: out readonly_and_isolated.out :::"
  },
  {
    "path": "examples/readonly-and-isolated/readonly_and_isolated.metatags",
    "content": "description: This BBE introduces readonly and isolated in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, readonly, isolated\n"
  },
  {
    "path": "examples/readonly-and-isolated/readonly_and_isolated.out",
    "content": "$ bal run readonly_and_isolated.bal\n{\"bordeaux\":{\"latitude\":\"44.8378N\",\"longitude\":\"0.5792W\"},\"paris\":{\"latitude\":\"48.8566N\",\"longitude\":\"2.3522E\"}}\n"
  },
  {
    "path": "examples/readonly-objects-and-classes/readonly_objects_and_classes.bal",
    "content": "import ballerina/io;\n\n// The `Timezone` is a `readonly` object type.\ntype TimeZone readonly & object {\n   function getOffset(decimal utc) returns decimal;\n};\n\nreadonly class FixedTimeZone {\n    // Include the `readonly` object type named `TypeZone` using object type inclusion.\n   *TimeZone;\n\n   // The `final decimal` field named offset is read-only because the `decimal` basic type is\n   // inherently immutable. \n   final decimal offset;\n\n   function init(decimal offset) {\n      self.offset = offset;\n   }\n\n   function getOffset(decimal utc) returns decimal {\n      return self.offset;\n   }\n}\n\npublic function main() {\n    // Create a new class object.\n    FixedTimeZone timeZone = new(+5.30);\n\n    io:println(timeZone is FixedTimeZone);\n    io:println(timeZone is readonly & FixedTimeZone);\n}\n"
  },
  {
    "path": "examples/readonly-objects-and-classes/readonly_objects_and_classes.md",
    "content": "# Readonly Objects and Classes\n\nAn object is `readonly` if all of its fields are `final` and are of types that are subtypes of the `readonly` type. Object `T` can be declared as readonly with `readonly & T`.\nA class that belongs to the `readonly` type can be declared by prefixing the `readonly` keyword in the class declaration.\n\n::: code readonly_objects_and_classes.bal :::\n\n::: out readonly_objects_and_classes.out :::"
  },
  {
    "path": "examples/readonly-objects-and-classes/readonly_objects_and_classes.metatags",
    "content": "description: This BBE introduces read-only objects and classes in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, readonly type, final, object, class\n"
  },
  {
    "path": "examples/readonly-objects-and-classes/readonly_objects_and_classes.out",
    "content": "$ bal run readonly_objects_and_classes.bal\ntrue\ntrue\n"
  },
  {
    "path": "examples/readonly-type/readonly_type.bal",
    "content": "import ballerina/io;\n\n// A `const` is immutable.\nconst s = \"Anne\";\n\ntype Row record {\n    // Both the field and its value are immutable.\n    readonly string k;\n    int value;\n};\n\ntable<Row> key(k) t = table [\n    {k: \"John\", value: 17}\n];\n\npublic function main() {\n    // Can safely use `s` as a key.\n    t.add({k: s, value: 18});\n    io:println(t);\n}\n"
  },
  {
    "path": "examples/readonly-type/readonly_type.md",
    "content": "# `readonly` type\n\nThe `readonly` type consists of values that are immutable. For structural type `T`, `T & readonly` means immutable `T`. `T & readonly` is a subtype of `T` and a subtype of `readonly`. Guaranteed that if declared type of a value is a subtype of `readonly`, then at runtime the value can never be mutated. It is enforced by runtime checks on the mutating structures. With `readonly` field, both the field and its value are immutable.\n\n::: code readonly_type.bal :::\n\nExecuting the above code gives the output below.\n\n::: out readonly_type.out :::"
  },
  {
    "path": "examples/readonly-type/readonly_type.metatags",
    "content": "description: This BBE introduces readonly type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, readonly type\n"
  },
  {
    "path": "examples/readonly-type/readonly_type.out",
    "content": "$ bal run readonly_type.bal\n[{\"k\":\"John\",\"value\":17},{\"k\":\"Anne\",\"value\":18}]\n"
  },
  {
    "path": "examples/receive-email-using-client/receive_email_using_client.bal",
    "content": "import ballerina/email;\nimport ballerina/log;\n\npublic function main() returns error? {\n    email:ImapClient imapClient = check new (\"imap.email.com\", \"reader@email.com\", \"pass456\");\n    do {\n        while true {\n            // Reads the first unseen email received by the POP3 server. \n            // `()` is returned when there are no new unseen emails. \n            email:Message? email = check imapClient->receiveMessage(timeout = 30);\n            if email is email:Message {\n                log:printInfo(\"Received an email\", subject = email.subject, body = email?.body);\n            }\n        }\n    } on fail var err {\n        log:printError(err.message(), stackTrace = err.stackTrace());\n        check imapClient->close();\n    }\n}\n"
  },
  {
    "path": "examples/receive-email-using-client/receive_email_using_client.md",
    "content": "# Email client - Receive email\n\nThe `email:ImapClient` can receive emails from an email server via IMAP protocol. An `email:ImapClient` can be created by providing the hostname, username, and password. Once connected, `receiveMessage` method is used to receive emails from the server. It is a blocking method with a timeout. When the email server supports both POP3 and IMAP, it is recommended to use the IMAP as it provides the ability to manage emails using multiple devices or email clients, while allowing access to emails that are already read. \n\n>**Note:** The Ballerina `email` module also provides an `email:PopClient` which can be used likewise. The only difference is that the `email:PopClient` uses POP3 protocol for communication. \n\n::: code receive_email_using_client.bal :::\n\n## Prerequisites\n- The email server should be up and running.\n\nRun the sample code by executing the following command.\n\n::: out receive_email_using_client.out :::\n\n## Related links\n- [`email:ImapClient` client object - API documentation](https://lib.ballerina.io/ballerina/email/latest#ImapClient)\n- [`email:PopClient` client object - API documentation](https://lib.ballerina.io/ballerina/email/latest#PopClient)\n- [IMAP client - Specification](https://ballerina.io/spec/email/#33-imap-client)\n- [POP3 client - Specification](https://ballerina.io/spec/email/#32-pop3-client)\n"
  },
  {
    "path": "examples/receive-email-using-client/receive_email_using_client.metatags",
    "content": "description: This is a BBE on receiving emails. It has the client functionality for receiving emails.\nkeywords: ballerina, ballerina by example, bbe, email, POP3, POP, IMAP\n"
  },
  {
    "path": "examples/receive-email-using-client/receive_email_using_client.out",
    "content": "$ bal run receive_email_using_client.bal\n"
  },
  {
    "path": "examples/receive-email-using-service/receive_email_using_service.bal",
    "content": "import ballerina/email;\nimport ballerina/log;\n\n// Creates the listener with the connection parameters and the protocol-related configuration. \nlistener email:ImapListener emailListener = new ({\n    host: \"imap.email.com\",\n    username: \"reader@email.com\",\n    password: \"pass456\"\n});\n\n// One or many services can listen to the email listener for the periodically-polled emails.\nservice \"observer\" on emailListener {\n\n    // When an email is successfully received, the `onMessage` method is called.\n    remote function onMessage(email:Message email) {\n        log:printInfo(\"Received an email\", subject = email.subject, content = email?.body);\n    }\n\n    // When an error occurs during the email poll operations, the `onError` method is called.\n    remote function onError(email:Error emailError) {\n        log:printError(emailError.message(), stackTrace = emailError.stackTrace());\n    }\n\n    // When the listener is closed, the `onClose` method is called.\n    remote function onClose(email:Error? closeError) {\n        if closeError is email:Error {\n            log:printInfo(closeError.message(), stackTrace = closeError.stackTrace());\n        }\n    }\n}\n"
  },
  {
    "path": "examples/receive-email-using-service/receive_email_using_service.md",
    "content": "# Email service - Receive email\n\nThe `email:Service` receives messages from an email server via IMAP using the `email:ImapListener`. An `email:ImapListener` can be initialized by providing the hostname, username, and password. Once connected, `onMessage` method is invoked whenever an email is read from the email server. If there is an error while reading the data from the server, `onError` method is invoked with relevant error details. When the email server supports both POP3 and IMAP, it is recommended to use the IMAP as it provides the ability to manage emails using multiple devices or email clients, while allowing access to emails that are already read. \n\n>**Note:** The Ballerina `email` module also provides an `email:PopListener` which can be used likewise. The only difference is that the `email:PopListener` uses POP3 protocol for communication. \n\n::: code receive_email_using_service.bal :::\n\n## Prerequisites\n- Email server should be up and running.\n\nRun the email service by executing the following command.\n\n::: out receive_email_using_service.out :::\n\n## Related links\n- [`email:ImapListener` listener object - API documentation](https://lib.ballerina.io/ballerina/email/latest#ImapListener)\n- [`email:PopListener` listener object - API documentation](https://lib.ballerina.io/ballerina/email/latest#PopListener)\n- [Email service - Specification](https://ballerina.io/spec/email/#4-service)\n"
  },
  {
    "path": "examples/receive-email-using-service/receive_email_using_service.metatags",
    "content": "description: This BBE is about receiving emails. It has a listener-based functionality for receiving emails.\nkeywords: ballerina, ballerina by example, bbe, email, POP3, POP, IMAP, listener\n"
  },
  {
    "path": "examples/receive-email-using-service/receive_email_using_service.out",
    "content": "$ bal run receive_email_using_listener.bal\n"
  },
  {
    "path": "examples/record-to-edi/bal_project.out",
    "content": "$ bal new record_to_edi\n$ cd record_to_edi\n$ bal add sorder\n"
  },
  {
    "path": "examples/record-to-edi/codegen_command.out",
    "content": "$ bal edi codegen -i resources/simple_order_schema.json -o modules/sorder/sorder.bal\n"
  },
  {
    "path": "examples/record-to-edi/output.out",
    "content": "$ bal run\nHDR*ORDER_200*HMart*17-05-2023~\nITM*A680*15~\nITM*A530*2~\nITM*A500*4~\n"
  },
  {
    "path": "examples/record-to-edi/package_structure.out",
    "content": "└── record_to_edi\n    ├── Ballerina.toml\n    ├── Dependencies.toml\n    ├── main.bal\n    ├── modules\n    │   └── sorder\n    │       ├── Module.md\n    │       ├── resources\n    │       ├── sorder.bal\n    │       └── tests\n    │           └── lib_test.bal\n    └── resources\n        └── simple_order_schema.json\n"
  },
  {
    "path": "examples/record-to-edi/record_to_edi.bal",
    "content": "import ballerina/io;\nimport record_to_edi.sorder;\n\npublic function main() returns error? {\n    sorder:SimpleOrder simpleOrder = \n        {header: {code: \"HDR\", orderId: \"ORDER_200\", organization: \"HMart\", date: \"17-05-2023\"}};\n    simpleOrder.items.push({code: \"ITM\", item: \"A680\", quantity: 15}); \n    simpleOrder.items.push({code: \"ITM\", item: \"A530\", quantity: 2}); \n    simpleOrder.items.push({code: \"ITM\", item: \"A500\", quantity: 4});\n    string ediText = check sorder:toEdiString(simpleOrder);\n    io:println(ediText);\n}\n"
  },
  {
    "path": "examples/record-to-edi/record_to_edi.md",
    "content": "# Record to EDI conversion\n\nSame EDI schema and generated code used in EDI to record conversion example can be used to convert Ballerina records of type SimpleOrder to EDI.\n\n::: code schema.json :::\n\nCreate a new Ballerina project named `record_to_edi` and create a module named `sorder` inside that project by using the below commands.\n\n::: code bal_project.out :::\n\nCreate a new folder named `resources` in the root of the project and copy the schema file into it. At this point, directory structure of the project would look like below:\n\n::: out package_structure.out :::\n\nGet the EDI tool from the Ballerina central using the below command:\n\n::: out tool_pull_command.out :::\n\nRun the below command from the project root directory to generate the Ballerina parser for the above schema.\n\n::: out codegen_command.out :::\n\n>Note that it is recommended to place generated code for each EDI schema in a separate module in order to avoid conflicts.\n\nWrite a Ballerina program by using generated methods and records to convert Ballerina records to EDI.\n\n::: code record_to_edi.bal :::\n\nRun the program using the command below:\n\n::: out output.out :::\n"
  },
  {
    "path": "examples/record-to-edi/record_to_edi.metatags",
    "content": "description: This BBE demonstrates how convert Ballerina records into EDI text based on an EDI schema.\nkeywords: ballerina, ballerina by example, bbe, edi, electronic data interchange, b2b, integration\n"
  },
  {
    "path": "examples/record-to-edi/schema.json",
    "content": "{\n    \"name\": \"SimpleOrder\",\n    \"delimiters\" : {\"segment\" : \"~\", \"field\" : \"*\", \"component\": \":\", \"repetition\": \"^\"},\n    \"segments\" : [\n        {\n            \"code\": \"HDR\",\n            \"tag\" : \"header\",\n            \"minOccurances\": 1,\n            \"fields\" : [{\"tag\": \"code\"}, {\"tag\" : \"orderId\", \"required\": true}, {\"tag\" : \"organization\"}, {\"tag\" : \"date\"}]\n        },\n        {\n            \"code\": \"ITM\",\n            \"tag\" : \"items\",\n            \"maxOccurances\" : -1,\n            \"fields\" : [{\"tag\": \"code\"}, {\"tag\" : \"item\", \"required\": true}, {\"tag\" : \"quantity\", \"required\": true, \"dataType\" : \"int\"}]\n        }\n    ]\n}\n"
  },
  {
    "path": "examples/record-to-edi/tool_pull_command.out",
    "content": "$ bal tool pull edi\n"
  },
  {
    "path": "examples/records/records.bal",
    "content": "import ballerina/io;\n\n// Defines a `closed record` type named `Student`. It only allows fields that are specified.\ntype Student record {|\n    string name;\n    int age;\n|};\n\n// Defines an `open record` type named `Employee`. It allows fields other than those specified.\ntype Employee record {\n    string name;\n    int age;\n};\n\npublic function main() {\n    // Creates an `open record` by specifying values for its fields.\n    record {string name; int age;} person = {\n        name: \"Harry\",\n        age: 12\n    };\n\n    // Creates a record using the `Student` type definition.\n    Student student = {\n        name: \"Harry\",\n        age: 12\n    };\n\n    // Creates a record using the `Employee` type definition with an additional `country` field.\n    Employee employee = {\n        name: \"Harry\",\n        age: 12,\n        \"country\": \"UK\"\n    };\n\n    // Accesses the `name` field in `employee`.\n    string name = employee.name;\n    io:println(name);\n\n    // The two `person` & `student` records are equal since they have the same set of fields \n    // and values.\n    io:println(person == student);\n\n    // Record equality returns `false` on the following two records as `employee` has \n    // an additional field called `country`.\n    io:println(person == employee);\n}\n"
  },
  {
    "path": "examples/records/records.md",
    "content": "# Records\n\nA `record` type is a collection of specific named fields where each field has a type for its value. A field `f` of a record value `r` can be accessed with `r.f`. Records are mutable and can be constructed using a syntax similar to a map.\n\nA `closed record` type only allows fields that are specified whereas, an `open record` type allows additional fields other than those specified. Typically, a `record` type is written using a type definition.\n\n::: code records.bal :::\n\n::: out records.out :::\n\n## Related links\n- [Open records](/learn/by-example/open-records/)\n- [Controlling openness](/learn/by-example/controlling-openness/)\n- [Default values for record fields](/learn/by-example/default-values-for-record-fields/)\n- [Maps](/learn/by-example/maps/)\n"
  },
  {
    "path": "examples/records/records.metatags",
    "content": "description: This BBE demonstrates how to define a record, access record fields, record type definition, and record equality.\nkeywords: ballerina, ballerina by example, bbe, records, record field, open record, closed record\n"
  },
  {
    "path": "examples/records/records.out",
    "content": "$ bal run records.bal\nHarry\ntrue\nfalse\n"
  },
  {
    "path": "examples/regexp-find-operations/regexp_find_operations.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.regexp;\n\npublic function main() returns error? {\n    string logContent = string `\n        2024-09-19 10:02:01 WARN  [UserLogin] - Failed login attempt for user: johndoe\n        2024-09-19 10:03:17 ERROR [Database] - Connection to database timed out\n        2024-09-19 10:04:05 WARN  [RequestHandler] - Response time exceeded threshold for /api/v1/users\n        2024-09-19 10:05:45 INFO  [Scheduler] - Scheduled task started: Data backup\n        2024-09-19 10:06:10 ERROR [Scheduler] - Failed to start data backup: Permission denied\n        2024-09-19 10:11:55 INFO  [Security] - Security scan completed, no issues found\n        2024-09-19 10:12:30 ERROR [RequestHandler] - 404 Not Found: /api/v1/products`;\n\n    // Regular expression to match error logs with three groups:\n    // 1. Timestamp (e.g., 2024-09-19 10:03:17).\n    // 2. Component (e.g., Database, Scheduler).\n    // 3. Log message (e.g., Connection to database timed out).\n    string:RegExp errorLogPattern = re `(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}) ERROR \\[(\\w+)\\]\\s-\\s(.*)`;\n\n    // Retrieve the first error log from `logContent`.\n    regexp:Span? firstErrorLog = errorLogPattern.find(logContent);\n    if firstErrorLog == () {\n        io:println(\"Failed to find a error log\");\n        return;\n    }\n    io:println(\"First error log: \", firstErrorLog.substring());\n\n    // Retrieve all error logs from the `logContent`.\n    regexp:Span[] allErrorLogs = errorLogPattern.findAll(logContent);\n    io:println(\"\\nAll error logs:\");\n    foreach regexp:Span errorLog in allErrorLogs {\n        io:println(errorLog.substring());\n    }\n\n    // Retrieve groups (timestamp, component, message) from the first error log.\n    regexp:Groups? firstErrorLogGroups = errorLogPattern.findGroups(logContent);\n    if firstErrorLogGroups == () {\n        io:println(\"Failed to find groups in first error log\");\n        return;\n    }\n    io:println(\"\\nGroups within first error log:\");\n    check printGroupsWithinLog(firstErrorLogGroups);\n\n    // Retrieve groups from all error logs.\n    regexp:Groups[] allErrorLogGroups = errorLogPattern.findAllGroups(logContent);\n    io:println(\"\\nGroups in all error logs\");\n    foreach regexp:Groups logGroup in allErrorLogGroups {\n        check printGroupsWithinLog(logGroup);\n    }\n}\n\nfunction printGroupsWithinLog(regexp:Groups logGroup) returns error? {\n    // The first element in the `logGroup` is the entire matched string.\n    // The subsequent elements in `logGroup` represent the captured groups \n    // (timestamp, component, message).\n    string timestamp = (check logGroup[1].ensureType(regexp:Span)).substring();\n    string component = (check logGroup[2].ensureType(regexp:Span)).substring();\n    string logMessage = (check logGroup[3].ensureType(regexp:Span)).substring();\n\n    io:println(\"Timestamp: \", timestamp);\n    io:println(\"Component: \", component);\n    io:println(\"Message: \", logMessage);\n}\n"
  },
  {
    "path": "examples/regexp-find-operations/regexp_find_operations.md",
    "content": "# RegExp find operations\n\nThe `RegExp` type provides a set of langlib functions to find patterns within strings. These functions enable efficient pattern matching, grouping, and extraction based on specific regular expressions.\n\n::: code regexp_find_operations.bal :::\n\n::: out regexp_find_operations.out :::\n\n## Related links\n- [RegExp type](/learn/by-example/regexp-type)\n- [RegExp API Docs](https://lib.ballerina.io/ballerina/lang.regexp)\n- [string API Docs](https://lib.ballerina.io/ballerina/lang.string)\n"
  },
  {
    "path": "examples/regexp-find-operations/regexp_find_operations.metatags",
    "content": "description: This BBE demonstrates how to use the regexp langlib functions relevant to regex find operations.\nkeywords: ballerina, ballerina by example, bbe, regexp, RegExp, regex, regular expressions, ballerina regex functions, regexp langlib functions, find, findAll, findGroups, findAllGroups\n"
  },
  {
    "path": "examples/regexp-find-operations/regexp_find_operations.out",
    "content": "$ bal run regexp_find_operations.bal\nFirst error log: 2024-09-19 10:03:17 ERROR [Database] - Connection to database timed out\n\nAll error logs:\n2024-09-19 10:03:17 ERROR [Database] - Connection to database timed out\n2024-09-19 10:06:10 ERROR [Scheduler] - Failed to start data backup: Permission denied\n2024-09-19 10:12:30 ERROR [RequestHandler] - 404 Not Found: /api/v1/products\n\nGroups within first error log:\nTimestamp: 2024-09-19 10:03:17\nComponent: Database\nMessage: Connection to database timed out\n\nGroups in all error logs\nTimestamp: 2024-09-19 10:03:17\nComponent: Database\nMessage: Connection to database timed out\nTimestamp: 2024-09-19 10:06:10\nComponent: Scheduler\nMessage: Failed to start data backup: Permission denied\nTimestamp: 2024-09-19 10:12:30\nComponent: RequestHandler\nMessage: 404 Not Found: /api/v1/products\n"
  },
  {
    "path": "examples/regexp-match-operations/regexp_match_operations.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.regexp;\n\npublic function main() returns error? {\n    string[] productCodes = [\"ELEC-1234\", \"FURN-5678\", \"CLOT-1111\", \"FOOD-3333\", \"BAR-123\"];\n\n    // Regular expression to match and validate product codes.\n    // Format: [PRODUCT_TYPE]-[UNIQUE_ID]\n    string:RegExp productCodePattern = re `^([A-Z]{4})-(\\d{4})$`;\n\n    foreach string productCode in productCodes {\n        // Check if the product code fully matches the expected format.\n        boolean isValidProductCode = productCodePattern.isFullMatch(productCode);\n        io:println(string `Product Code: ${productCode}, Valid: ${isValidProductCode}`);\n\n        // If the product code is invalid, skip further processing.\n        if !isValidProductCode {\n            continue;\n        }\n\n        // For a valid product code, extract the product type and unique ID from the match groups.\n        regexp:Groups? matchGroups = productCodePattern.fullMatchGroups(productCode);\n        if matchGroups is regexp:Groups {\n            // The first member in the `matchGroups` tuple is the entire matched string.\n            // The subsequent members represent the captured groups\n            // corresponding to product type and unique ID respectively.\n            io:println(\"Product Type: \",\n                    (check matchGroups[1].ensureType(regexp:Span)).substring());\n            io:println(\"Unique ID: \",\n                    (check matchGroups[2].ensureType(regexp:Span)).substring());\n        }\n    }\n\n    // Match product code from a specific starting index in the string.\n    regexp:Span? productCode = productCodePattern.matchAt(\n            \"Product code: FURN-5678, Product code: CLOT-1234\", 39);\n    if productCode is regexp:Span {\n        io:println(\"Matched product: \", productCode.substring());\n    }\n\n    // Regular expression to extract the time in the format `HH:MM` from a log string.\n    string:RegExp timePattern = re `([01][0-9]|2[0-3]):([0-5][0-9])`;\n\n    // Find groups of the matching string from a specified starting index.\n    regexp:Groups? timeMatchGroups = timePattern.matchGroupsAt(\n            \"Production time: 14:35, Production time: 16:15\", 41);\n    if timeMatchGroups is regexp:Groups {\n        string hour = (check timeMatchGroups[1].ensureType(regexp:Span)).substring();\n        string minutes = (check timeMatchGroups[2].ensureType(regexp:Span)).substring();\n        io:println(\"Production hour: \", hour);\n        io:println(\"Production minutes: \", minutes);\n    }\n}\n"
  },
  {
    "path": "examples/regexp-match-operations/regexp_match_operations.md",
    "content": "# RegExp match operations\n\nThe `RegExp` type supports a set of langlib functions to match patterns in strings and enable operations such as finding, validating, grouping, and extracting data based on regular expressions.\n\n::: code regexp_match_operations.bal :::\n\n::: out regexp_match_operations.out :::\n\n## Related links\n- [RegExp type](/learn/by-example/regexp-type)\n- [RegExp API Docs](https://lib.ballerina.io/ballerina/lang.regexp)\n- [string API Docs](https://lib.ballerina.io/ballerina/lang.string)\n"
  },
  {
    "path": "examples/regexp-match-operations/regexp_match_operations.metatags",
    "content": "description: This BBE demonstrates how to use the regexp langlib functions relevant to regex match operations.\nkeywords: ballerina, ballerina by example, bbe, regexp, RegExp, regex, regular expressions, ballerina regex functions, regexp langlib functions, fullMatchGroups, isFullMatch, matchAt, matchGroupsAt\n"
  },
  {
    "path": "examples/regexp-match-operations/regexp_match_operations.out",
    "content": "$ bal run regexp_match_operations.bal\nProduct Code: ELEC-1234, Valid: true\nProduct Type: ELEC\nUnique ID: 1234\nProduct Code: FURN-5678, Valid: true\nProduct Type: FURN\nUnique ID: 5678\nProduct Code: CLOT-1111, Valid: true\nProduct Type: CLOT\nUnique ID: 1111\nProduct Code: FOOD-3333, Valid: true\nProduct Type: FOOD\nUnique ID: 3333\nProduct Code: BAR-123, Valid: false\nMatched product: CLOT-1234\nProduction hour: 16\nProduction minutes: 15\n"
  },
  {
    "path": "examples/regexp-operations-overview/regexp_operations_overview.bal",
    "content": "import ballerina/lang.regexp;\nimport ballerina/io;\n\npublic function main() returns error? {\n\n    string data = \"bob@example.net,alice@example.com,charlie@example.org,david@example.xyz,invalid#@example.n%t\";\n\n    // Split the comma-separated email list.\n    string[] emails = re `,`.split(data);\n    io:println(emails);\n\n    // Define a RegExp pattern to match valid email addresses.\n    string:RegExp validEmailPattern = re `([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})`;\n\n    // Extract usernames and domains from valid email addresses.\n    string[] usernames = [];\n    string[] domains = [];\n    foreach string email in emails {\n        // Check if the email is valid.\n        if validEmailPattern.isFullMatch(email) { \n            // Extract the username and domain from the email.\n            regexp:Groups? emailGroups = validEmailPattern.findGroups(email);\n            if emailGroups is regexp:Groups {\n                // 0th element contains the entire match\n                usernames.push((<regexp:Span>emailGroups[1]).substring());\n                domains.push((<regexp:Span>emailGroups[2]).substring());\n            }\n        }\n    }\n\n    io:println(usernames);\n    io:println(domains);\n}\n"
  },
  {
    "path": "examples/regexp-operations-overview/regexp_operations_overview.md",
    "content": "# RegExp operations\n\nThe ``RegExp`` type supports a set of langlib functions to search and manipulate string values.\n\n::: code regexp_operations_overview.bal :::\n\n::: out regexp_operations_overview.out :::\n\n## Related links\n- [RegExp type](/learn/by-example/regexp-type)\n- [RegExp API Docs](https://lib.ballerina.io/ballerina/lang.regexp)\n- [string API Docs](https://lib.ballerina.io/ballerina/lang.string)"
  },
  {
    "path": "examples/regexp-operations-overview/regexp_operations_overview.metatags",
    "content": "description: This BBE demonstrates how to use langlib functions defined in the regexp langlib module.\nkeywords: ballerina, ballerina by example, bbe, regexp, RegExp, regex, regular expressions, ballerina regex functions, regexp langlib functions\n"
  },
  {
    "path": "examples/regexp-operations-overview/regexp_operations_overview.out",
    "content": "$ bal run regexp_operations_overview.bal\n[\"bob@example.net\",\"alice@example.com\",\"charlie@example.org\",\"david@example.xyz\",\"invalid#@example.n%t\"]\n[\"bob\",\"alice\",\"charlie\",\"david\"]\n[\"example.net\",\"example.com\",\"example.org\",\"example.xyz\"]\n"
  },
  {
    "path": "examples/regexp-replace-operations/regexp_replace_operations.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    string creditCardNumber = \"1234-5678-9876-5432\";\n    string:RegExp pattern = re `\\d{4}-\\d{4}-\\d{4}`;\n    // Replace the first occurrence of the credit card pattern with a masked representation.\n    string maskedCardNumber = pattern.replace(creditCardNumber, \"****-****-****\");\n    io:println(maskedCardNumber);\n\n    xml xmlString = \n            xml `<root><!--comment 1 --><e1>value1</e1><e2>value2</e2><!--comment 2-->></root>`;\n    \n    // Regular expression to match XML comments.\n    string:RegExp commentPattern = re `<!--.*?-->`;\n    // Replace all occurrences of XML comments with an empty string, effectively removing them.\n    string commentsRemovedXml = commentPattern.replaceAll(xmlString.toString(), \"\");\n    io:println(\"XML string with comments removed: \", commentsRemovedXml);\n}\n"
  },
  {
    "path": "examples/regexp-replace-operations/regexp_replace_operations.md",
    "content": "# RegExp replace operations\n\nThe `RegExp` type supports a set of langlib functions to replace parts of strings that match specific patterns.\n\n::: code regexp_replace_operations.bal :::\n\n::: out regexp_replace_operations.out :::\n\n## Related links\n- [RegExp type](/learn/by-example/regexp-type)\n- [RegExp API Docs](https://lib.ballerina.io/ballerina/lang.regexp)\n- [string API Docs](https://lib.ballerina.io/ballerina/lang.string)\n"
  },
  {
    "path": "examples/regexp-replace-operations/regexp_replace_operations.metatags",
    "content": "description: This BBE demonstrates how to use the regexp langlib functions relevant to regex replace operations.\nkeywords: ballerina, ballerina by example, bbe, regexp, RegExp, regex, regular expressions, ballerina regex functions, regexp langlib functions, replace, replaceAll\n"
  },
  {
    "path": "examples/regexp-replace-operations/regexp_replace_operations.out",
    "content": "$ bal run regexp_replace_operations.bal\n****-****-****-5432\nXML string with comments removed: <root><e1>value1</e1><e2>value2</e2>&gt;</root>\n"
  },
  {
    "path": "examples/regexp-type/regexp_type.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.regexp;\n\npublic function main() returns error? {\n    \n    // Declare a `RegExp` value using a regular expression literal.\n    regexp:RegExp alphanumericPattern = re `[a-zA-Z0-9]`;\n    // Matches any string that is a single alphanumeric character.\n    io:println(\"Pattern `[a-zA-Z0-9]` matches `a`: \", alphanumericPattern.isFullMatch(\"a\"));\n\n    // `string:RegExp` is an alias for `regexp:RegExp`.\n    string:RegExp alphanumericPattern2 = re `[a-zA-Z0-9]`;\n    io:println(\"Pattern `[a-zA-Z0-9]` matches `a1`: \", alphanumericPattern2.isFullMatch(\"a1\"));\n\n    // Construct a `RegExp` value from a string using the `fromString` langlib function.\n    string:RegExp pattern = check regexp:fromString(\"HELLO*\");\n    // Matches any string that starts with \"HELLO\" and ends with zero or more characters.\n    io:println(\"Pattern `HELLO*` matches `HELLO`: \", pattern.isFullMatch(\"HELLO\"));\n\n    // Matches any string that contains one or more consecutive \"a\" characters.\n    boolean result = re `a+`.isFullMatch(\"aaa\");\n    io:println(\"Pattern `a+` matches `aaa`: \", result);\n\n    // Interpolations can be used to construct the pattern dynamically.\n    string literal = \"xyz\";\n    string:RegExp pattern2 = re `abc|${literal}`;\n    // Matches any string that starts with \"abc\" or \"XYZ\".\n    io:println(\"Pattern `abc|${\\\"xyz\\\"}` matches `xyz`: \", pattern2.isFullMatch(\"xyz\"));\n\n    // The `RegExp` type supports Unicode general category patterns.\n    // Characters are matched based on their Unicode properties.\n    string:RegExp pattern3 = re `\\p{Ll}`;\n    io:println(\"Pattern `\\\\p{Ll}` matches `a`: \", \"a\".matches(pattern3));\n\n    // The `\\P` escape sequence is used to get the negation of the pattern.\n    // Matches every non-puncutation character.\n    string:RegExp pattern4 = re `\\P{P}`;\n    io:println(\"Pattern `\\\\p{P}` matches `0`: \", \"0\".matches(pattern4));\n\n    // The `RegExp` type supports matching characters according to the script using Unicode script patterns.\n    string:RegExp pattern5 = re `\\p{sc=Latin}`;\n    regexp:Span? findResult = pattern5.find(\"aεЛ\");\n    // The `find` function returns nil if no match is found. Since we know a \n    // match is found here, use the `ensureType` function to narrow the type down to `regexp:Span`.\n    regexp:Span latinValue = check findResult.ensureType();\n    io:println(\"Pattern `\\\\p{sc=Latin}` matches `aεЛ`: \", latinValue.substring());\n\n    // The `RegExp` type supports non-capturing groups to control the behavior of regular expression patterns.\n    // The `i` flag will ignore the case of the pattern.\n    string:RegExp pattern6 = re `(?i:BalleRINA)`;\n    io:println(\"Pattern `(?i:BalleRINA)` matches `Ballerina`: \", \"Ballerina\".matches(pattern6));\n}\n"
  },
  {
    "path": "examples/regexp-type/regexp_type.md",
    "content": "# RegExp type\n\n`RegExp` is a built-in type in Ballerina that represents a regular expression. Regular expressions are commonly used for tasks such as validating input, searching and replacing text, and parsing data.\n\nThe `RegExp` type is defined in the `lang.regexp` module, and can also be referenced using the type alias named the same in the `lang.string` module. The `RegExp` type conforms to a subset of the ECMAScript specification for regular expressions.\n\nA `RegExp` value can be created by using the regexp template expression or calling the [`fromString` method of the lang.regexp](https://lib.ballerina.io/ballerina/lang.regexp/latest#fromString) module. \n\n::: code regexp_type.bal :::\n\n::: out regexp_type.out :::\n\n## Related links\n- [Ballerina regular expression grammar](https://ballerina.io/spec/lang/master/#section_10.1)\n- [RegExp langlib functions overview](/learn/by-example/regexp-operations-overview)\n- [RegExp API Docs](https://lib.ballerina.io/ballerina/lang.regexp)\n- [string API Docs](https://lib.ballerina.io/ballerina/lang.string)\n"
  },
  {
    "path": "examples/regexp-type/regexp_type.metatags",
    "content": "description: This BBE demonstrates how to define a regular expression and the different patterns supported by the Ballerina RegExp type.\nkeywords: ballerina, ballerina by example, bbe, regex, regexp, regular expression\n"
  },
  {
    "path": "examples/regexp-type/regexp_type.out",
    "content": "$ bal run regexp_type.bal\nPattern `[a-zA-Z0-9]` matches `a`: true\nPattern `[a-zA-Z0-9]` matches `a1`: false\nPattern `HELLO*` matches `HELLO`: true\nPattern `a+` matches `aaa`: true\nPattern `abc|${\"xyz\"}` matches `xyz`: true\nPattern `\\p{Ll}` matches `a`: true\nPattern `\\p{P}` matches `0`: true\nPattern `\\p{sc=Latin}` matches `aεЛ`: a\nPattern `(?i:BalleRINA)` matches `Ballerina`: true\n"
  },
  {
    "path": "examples/resource/path/to/client-private.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCBXKLp9WJUuJko\nSfDn3HM2LWVxiHrP11me6D4X2AqoUiCZ1w976q1LuBlzWNhONYwJvHXewUuRmo0d\n4NRp2ma0qjdMN246XWyozpzPfJdvovfiT+V6HnSbMg82ZppfF3e85Cgrg6mSA7Wf\nfaaHr62SnexseZ9ioNCuRUrW2Zg208l99IItP4K4iGclQlyjs3S6drH7JJk3rv8B\nf76wmmoCEAhknOtGLq543dEUIjFgNdIy/GsSY52fiA4LSjUCv27kGn03nayqoZs3\nXHqM0qLdt9SPXbYe7l75j0o6Z9tyGFCKXY/zVwiLfRUqDIOfkN5YS4Ohit52Tj7q\noBmvEzD7AgMBAAECggEAXM/F4u23OummmQ1T1kaIMpqnaalt06jCGAywYBMUsmca\nFMYDyfg5lVXkjKl1p8crTeD1AHjWawTjskgYnkmf3ocxXXF3mFBnIUX7o7HURLg7\n+RcxoUgwiRiFaZZ7szX3JoLbfzzbcHNQ37kavccBVWwQsFMiU3Tlw+LbKwK6/row\nLYsQPx7gT4u7hViat4vQDTYcgyjvvFCiek4ndL6O9K49MxIMU678UXB6ia5iUevy\nvgEfcYkKQ5EQ38qS3ZwsubPvj4633jvAJRr/hJD8XINZC74kTXeV3BGH2LlpQOEq\nkWkOypwYNjnXtt1JO8+Iu6mEXKUoiIBPfGrJ3vDSQQKBgQDmYPc7kfYan/LHjJRv\niE2CwbC26yVA6+BEPQv9z7jChO9Q6cUbGvM8EEVNpC9nmFogkslzJhz55HP84QZL\nu3ptU+D96ncq6zkBqxBfRnZG++D36+XRXIwzz3h+g1Nwrl0y0MFbwlkMm3ZqJdd6\npZz1FZGd6zvQftW8m7jPSKHuswKBgQCPv6czFOZR6bI+qCQdaORpe9JGoAduOD+4\nYKl96s0eiAKhkGhFCrMd6GJwWRkpNcfwB+J9sMahORbfvwiYanI56h7Vi30DFPRb\nm1m8dLkr6z+8bxMxKJaMXIIjy3UDamgDr7QHInNUih2iGvtB8QqZ0aobsB2XIxZg\nqESTMcpYmQKBgHSwSqneraQgvgz7FLhFdtUzHDoacr0mfGqz7R37F99XDAyUy+SF\nywvyRdgkwGodjhEPqH/tnyGn6GP+6nxzknhL0xtppkCT8kT5C4rmmsQrknChCL/5\nu34GqUaTaDEb8FLrz/SVRRuQpvLvBey2dADjkuVFH//kLoig64P6iyLnAoGBAIlF\ng+2L78YZXVXoS1SqbjUtQUigWXgvzunLpQ/Rwb9+MsUGmgwUg6fz2s1eyGBKM3xM\ni0VsIsKjOezBCPxD6oDTyk4yvlbLE+7HE5KcBJikNmFD0RgIonu3e6+jA0MXweyD\nRW/qviflHRdInNgDzxPE3KVEMX26zAvRpGrMCWdBAoGAdQ5SvX+mAC3cKqoQ9Zal\nlSqWoyjfzP5EaVRG8dtoLxbznQGTTvtHXc65/MznX/L9qkWCS6Eb4HH5M3hFNY46\nLNIzGQLznE1odwv7H5B8c0/m3DrKTxbh8bYcrR1BW5/nKZNNW7k1O6OjEozvAajK\nJQdp3KBU9S8CmBjGrRpJ2qw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/resource/path/to/client-public.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEfP3e8zANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxDTALBgNVBAoT\nBFdTTzIxDTALBgNVBAsTBFdTTzIxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNzEw\nMjQwNTQ3NThaFw0zNzEwMTkwNTQ3NThaMGQxCzAJBgNVBAYTAlVTMQswCQYDVQQI\nEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzENMAsGA1UEChMEV1NPMjENMAsG\nA1UECxMEV1NPMjESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAgVyi6fViVLiZKEnw59xzNi1lcYh6z9dZnug+F9gKqFIg\nmdcPe+qtS7gZc1jYTjWMCbx13sFLkZqNHeDUadpmtKo3TDduOl1sqM6cz3yXb6L3\n4k/leh50mzIPNmaaXxd3vOQoK4OpkgO1n32mh6+tkp3sbHmfYqDQrkVK1tmYNtPJ\nffSCLT+CuIhnJUJco7N0unax+ySZN67/AX++sJpqAhAIZJzrRi6ueN3RFCIxYDXS\nMvxrEmOdn4gOC0o1Ar9u5Bp9N52sqqGbN1x6jNKi3bfUj122Hu5e+Y9KOmfbchhQ\nil2P81cIi30VKgyDn5DeWEuDoYredk4+6qAZrxMw+wIDAQABozEwLzAOBgNVHQ8B\nAf8EBAMCBaAwHQYDVR0OBBYEFNmtrQ36j6tUGhKrfW9qWWE7KFzMMA0GCSqGSIb3\nDQEBCwUAA4IBAQAv3yOwgbtOu76eJMl1BCcgTFgaMUBZoUjK9Un6HGjKEgYz/YWS\nZFlY/qH5rT01DWQevUZB626d5ZNdzSBZRlpsxbf9IE/ursNHwHx9ua6fB7yHUCzC\n1ZMp1lvBHABi7wcA+5nbV6zQ7HDmBXFhJfbgH1iVmA1KcvDeBPSJ/scRGasZ5q2W\n3IenDNrfPIUhD74tFiCiqNJO91qD/LO+++3XeZzfPh8NRKkiPX7dB8WJ3YNBuQAv\ngRWTISpSSXLmqMb+7MPQVgecsepZdk8CwkRLxh3RKPJMjigmCgyvkSaoDMKAYC3i\nYjfUTiJ57UeqoSl0IaOFJ0wfZRFh+UytlDZa\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/resource/path/to/encryptedPrivate.key",
    "content": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIE6jAcBgoqhkiG9w0BDAEEMA4ECJ1AVEOFT+s1AgIFDASCBMiHG70PvakbuVha\n9JBcXWzje1B30LItVdpiETbu5LNG3v0IIX7DmRQCBJxXkkCeZ3Bcw/A1cjkGIR0j\n6P1AyUAlZBU9+GcCF2BcpyaMOxNVQuHUZA9//fnlfO6KMTdIg9b/MutH++bLSoh9\nJkHivtgEQVEAu79NpTdKh9XklIWUBe5gU4OteBL0/feKgB6NFeYm7vNb8b486jSB\noXWC7l8Y5VoU4grhDT9dL1PQqLQvIRWTnB1BhUE9OquWrRRaGE7WeWABzzFhHB4X\nDdHABqsNE9qeEGHrUBKfjfg6+8GIEjjJcpJt9wGBi4yHbUaao7xueu0aA9nVVo75\n6PJOwcJqoPhwkDFpAYADLJTVxh8EqbaihSe3HVqjsF3au5nu338VbJu8VZ2rAgTv\nV2IxsV/BWrv8RIbt/EINz82uU0umbhpvUakMjZGD01NCvx6mshfKA3zIEac7apmc\n6wwoqh42sEHk3i7H/xQhuS32ACzRDwXzXYf2f8CZVrSk7Ajc4w4mwY5YylCmn+P5\nYK6fRCaJAN2J4CGvIut3LvjGX8pNuu9msFMrFjbITL/xeUzIrJoE1C9O2V1dQ5LU\nO4wVFGKHkFpBBzxxDQwRbYn66EbL4/dCwtIkj7kncz7Y+qYBi+Voe81RSL1mBtR/\nnOQPIHNOLSUvIPA2aj4ufcdSrbXapMfrTOiO+EUuBOGE6FncaGm3hfKnPa1C4fuZ\nyokvpEMNOUs5eJjSC0tcP+zibTkiMHy2vhvrI3xme6oIFG7Nvxi2MxcWolUNmXlk\nUVGyJJurL9QhKfjGSIuEZgJd7/PrDK0gzEQBMS/10BUPRe1pE+05GEOvJBbhw1Bt\n6b3LjbVtNnR/2/G3I9LlwRLac4IHlU/JMy58E3Uxim0/rJJ7uGGbXsxdwFS4968I\n/ekA1PcZgvNet60rMYxSXz6QPwYnvM94gFD6I5PgUhJJPeQZiw9kFLBqKsUjBrjY\njFAcTVW6sWEo1CMsUC94gwvHvpOLtPHjik/iPAfHXeGQ9baTaArMAJiQO+0h9O3Y\n0rXM8gEz4zAID3N4neVjjMda7C/2avAfJRoBxYAFMcuMNTta4mMmXOCs+M6x45GI\nw/KPAZbsRTcRWLjU5QguqP6eAxSghHITruW0HEqscT20K3cRWXXDEOr8ZqId90xY\nPQo5ZEvaJLGgxN4Q7CUPJJ1mKHruTmMm+UOxIuXRR2eaqsJDnLovmu4jGOSLVYV4\nFFJ7PxD+tx9b8WS8tckS/Pjm2PcUAJz3I6/DFc3iKwoeCXBIG/djwWfabRcoGb0U\nSq8tiqvCjT/LuubpQgKhkEnxWCBRR+Qns4quJJ2Kead/g8E19cUxolGPTW9jr2GF\n1XWuGytK0PqUOIMsuJkhWN3dErFmftcfmfhqFFulOvE7eWr+ZToyFESmNK+MNnAL\nmmZFOt7zTNwooQkzpVohLtKPwe3k71dhhsK3gQBoscKQFnMQSmKLM7c4A6HPcq20\nXFtRM30O5cSO2jLZ+sAcJS81uIrcPWWf8yY5lMZ1irHFri6jnwcv7Sbe3rqZJFer\n9ckVz4rq399UHOyujNT2gjIaFnEwmHfM0yaZ0dYG2JU/jXdbqsTLKsHSOZsrkkL5\n9BaHO8wfzVx/CnQfP6M=\n-----END ENCRYPTED PRIVATE KEY-----\n"
  },
  {
    "path": "examples/resource/path/to/private.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCBXKLp9WJUuJko\nSfDn3HM2LWVxiHrP11me6D4X2AqoUiCZ1w976q1LuBlzWNhONYwJvHXewUuRmo0d\n4NRp2ma0qjdMN246XWyozpzPfJdvovfiT+V6HnSbMg82ZppfF3e85Cgrg6mSA7Wf\nfaaHr62SnexseZ9ioNCuRUrW2Zg208l99IItP4K4iGclQlyjs3S6drH7JJk3rv8B\nf76wmmoCEAhknOtGLq543dEUIjFgNdIy/GsSY52fiA4LSjUCv27kGn03nayqoZs3\nXHqM0qLdt9SPXbYe7l75j0o6Z9tyGFCKXY/zVwiLfRUqDIOfkN5YS4Ohit52Tj7q\noBmvEzD7AgMBAAECggEAXM/F4u23OummmQ1T1kaIMpqnaalt06jCGAywYBMUsmca\nFMYDyfg5lVXkjKl1p8crTeD1AHjWawTjskgYnkmf3ocxXXF3mFBnIUX7o7HURLg7\n+RcxoUgwiRiFaZZ7szX3JoLbfzzbcHNQ37kavccBVWwQsFMiU3Tlw+LbKwK6/row\nLYsQPx7gT4u7hViat4vQDTYcgyjvvFCiek4ndL6O9K49MxIMU678UXB6ia5iUevy\nvgEfcYkKQ5EQ38qS3ZwsubPvj4633jvAJRr/hJD8XINZC74kTXeV3BGH2LlpQOEq\nkWkOypwYNjnXtt1JO8+Iu6mEXKUoiIBPfGrJ3vDSQQKBgQDmYPc7kfYan/LHjJRv\niE2CwbC26yVA6+BEPQv9z7jChO9Q6cUbGvM8EEVNpC9nmFogkslzJhz55HP84QZL\nu3ptU+D96ncq6zkBqxBfRnZG++D36+XRXIwzz3h+g1Nwrl0y0MFbwlkMm3ZqJdd6\npZz1FZGd6zvQftW8m7jPSKHuswKBgQCPv6czFOZR6bI+qCQdaORpe9JGoAduOD+4\nYKl96s0eiAKhkGhFCrMd6GJwWRkpNcfwB+J9sMahORbfvwiYanI56h7Vi30DFPRb\nm1m8dLkr6z+8bxMxKJaMXIIjy3UDamgDr7QHInNUih2iGvtB8QqZ0aobsB2XIxZg\nqESTMcpYmQKBgHSwSqneraQgvgz7FLhFdtUzHDoacr0mfGqz7R37F99XDAyUy+SF\nywvyRdgkwGodjhEPqH/tnyGn6GP+6nxzknhL0xtppkCT8kT5C4rmmsQrknChCL/5\nu34GqUaTaDEb8FLrz/SVRRuQpvLvBey2dADjkuVFH//kLoig64P6iyLnAoGBAIlF\ng+2L78YZXVXoS1SqbjUtQUigWXgvzunLpQ/Rwb9+MsUGmgwUg6fz2s1eyGBKM3xM\ni0VsIsKjOezBCPxD6oDTyk4yvlbLE+7HE5KcBJikNmFD0RgIonu3e6+jA0MXweyD\nRW/qviflHRdInNgDzxPE3KVEMX26zAvRpGrMCWdBAoGAdQ5SvX+mAC3cKqoQ9Zal\nlSqWoyjfzP5EaVRG8dtoLxbznQGTTvtHXc65/MznX/L9qkWCS6Eb4HH5M3hFNY46\nLNIzGQLznE1odwv7H5B8c0/m3DrKTxbh8bYcrR1BW5/nKZNNW7k1O6OjEozvAajK\nJQdp3KBU9S8CmBjGrRpJ2qw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/resource/path/to/public.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEfP3e8zANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxDTALBgNVBAoT\nBFdTTzIxDTALBgNVBAsTBFdTTzIxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNzEw\nMjQwNTQ3NThaFw0zNzEwMTkwNTQ3NThaMGQxCzAJBgNVBAYTAlVTMQswCQYDVQQI\nEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzENMAsGA1UEChMEV1NPMjENMAsG\nA1UECxMEV1NPMjESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAgVyi6fViVLiZKEnw59xzNi1lcYh6z9dZnug+F9gKqFIg\nmdcPe+qtS7gZc1jYTjWMCbx13sFLkZqNHeDUadpmtKo3TDduOl1sqM6cz3yXb6L3\n4k/leh50mzIPNmaaXxd3vOQoK4OpkgO1n32mh6+tkp3sbHmfYqDQrkVK1tmYNtPJ\nffSCLT+CuIhnJUJco7N0unax+ySZN67/AX++sJpqAhAIZJzrRi6ueN3RFCIxYDXS\nMvxrEmOdn4gOC0o1Ar9u5Bp9N52sqqGbN1x6jNKi3bfUj122Hu5e+Y9KOmfbchhQ\nil2P81cIi30VKgyDn5DeWEuDoYredk4+6qAZrxMw+wIDAQABozEwLzAOBgNVHQ8B\nAf8EBAMCBaAwHQYDVR0OBBYEFNmtrQ36j6tUGhKrfW9qWWE7KFzMMA0GCSqGSIb3\nDQEBCwUAA4IBAQAv3yOwgbtOu76eJMl1BCcgTFgaMUBZoUjK9Un6HGjKEgYz/YWS\nZFlY/qH5rT01DWQevUZB626d5ZNdzSBZRlpsxbf9IE/ursNHwHx9ua6fB7yHUCzC\n1ZMp1lvBHABi7wcA+5nbV6zQ7HDmBXFhJfbgH1iVmA1KcvDeBPSJ/scRGasZ5q2W\n3IenDNrfPIUhD74tFiCiqNJO91qD/LO+++3XeZzfPh8NRKkiPX7dB8WJ3YNBuQAv\ngRWTISpSSXLmqMb+7MPQVgecsepZdk8CwkRLxh3RKPJMjigmCgyvkSaoDMKAYC3i\nYjfUTiJ57UeqoSl0IaOFJ0wfZRFh+UytlDZa\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/resource/path/to/server-private.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCBXKLp9WJUuJko\nSfDn3HM2LWVxiHrP11me6D4X2AqoUiCZ1w976q1LuBlzWNhONYwJvHXewUuRmo0d\n4NRp2ma0qjdMN246XWyozpzPfJdvovfiT+V6HnSbMg82ZppfF3e85Cgrg6mSA7Wf\nfaaHr62SnexseZ9ioNCuRUrW2Zg208l99IItP4K4iGclQlyjs3S6drH7JJk3rv8B\nf76wmmoCEAhknOtGLq543dEUIjFgNdIy/GsSY52fiA4LSjUCv27kGn03nayqoZs3\nXHqM0qLdt9SPXbYe7l75j0o6Z9tyGFCKXY/zVwiLfRUqDIOfkN5YS4Ohit52Tj7q\noBmvEzD7AgMBAAECggEAXM/F4u23OummmQ1T1kaIMpqnaalt06jCGAywYBMUsmca\nFMYDyfg5lVXkjKl1p8crTeD1AHjWawTjskgYnkmf3ocxXXF3mFBnIUX7o7HURLg7\n+RcxoUgwiRiFaZZ7szX3JoLbfzzbcHNQ37kavccBVWwQsFMiU3Tlw+LbKwK6/row\nLYsQPx7gT4u7hViat4vQDTYcgyjvvFCiek4ndL6O9K49MxIMU678UXB6ia5iUevy\nvgEfcYkKQ5EQ38qS3ZwsubPvj4633jvAJRr/hJD8XINZC74kTXeV3BGH2LlpQOEq\nkWkOypwYNjnXtt1JO8+Iu6mEXKUoiIBPfGrJ3vDSQQKBgQDmYPc7kfYan/LHjJRv\niE2CwbC26yVA6+BEPQv9z7jChO9Q6cUbGvM8EEVNpC9nmFogkslzJhz55HP84QZL\nu3ptU+D96ncq6zkBqxBfRnZG++D36+XRXIwzz3h+g1Nwrl0y0MFbwlkMm3ZqJdd6\npZz1FZGd6zvQftW8m7jPSKHuswKBgQCPv6czFOZR6bI+qCQdaORpe9JGoAduOD+4\nYKl96s0eiAKhkGhFCrMd6GJwWRkpNcfwB+J9sMahORbfvwiYanI56h7Vi30DFPRb\nm1m8dLkr6z+8bxMxKJaMXIIjy3UDamgDr7QHInNUih2iGvtB8QqZ0aobsB2XIxZg\nqESTMcpYmQKBgHSwSqneraQgvgz7FLhFdtUzHDoacr0mfGqz7R37F99XDAyUy+SF\nywvyRdgkwGodjhEPqH/tnyGn6GP+6nxzknhL0xtppkCT8kT5C4rmmsQrknChCL/5\nu34GqUaTaDEb8FLrz/SVRRuQpvLvBey2dADjkuVFH//kLoig64P6iyLnAoGBAIlF\ng+2L78YZXVXoS1SqbjUtQUigWXgvzunLpQ/Rwb9+MsUGmgwUg6fz2s1eyGBKM3xM\ni0VsIsKjOezBCPxD6oDTyk4yvlbLE+7HE5KcBJikNmFD0RgIonu3e6+jA0MXweyD\nRW/qviflHRdInNgDzxPE3KVEMX26zAvRpGrMCWdBAoGAdQ5SvX+mAC3cKqoQ9Zal\nlSqWoyjfzP5EaVRG8dtoLxbznQGTTvtHXc65/MznX/L9qkWCS6Eb4HH5M3hFNY46\nLNIzGQLznE1odwv7H5B8c0/m3DrKTxbh8bYcrR1BW5/nKZNNW7k1O6OjEozvAajK\nJQdp3KBU9S8CmBjGrRpJ2qw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/resource/path/to/server-public.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEfP3e8zANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxDTALBgNVBAoT\nBFdTTzIxDTALBgNVBAsTBFdTTzIxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNzEw\nMjQwNTQ3NThaFw0zNzEwMTkwNTQ3NThaMGQxCzAJBgNVBAYTAlVTMQswCQYDVQQI\nEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzENMAsGA1UEChMEV1NPMjENMAsG\nA1UECxMEV1NPMjESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAgVyi6fViVLiZKEnw59xzNi1lcYh6z9dZnug+F9gKqFIg\nmdcPe+qtS7gZc1jYTjWMCbx13sFLkZqNHeDUadpmtKo3TDduOl1sqM6cz3yXb6L3\n4k/leh50mzIPNmaaXxd3vOQoK4OpkgO1n32mh6+tkp3sbHmfYqDQrkVK1tmYNtPJ\nffSCLT+CuIhnJUJco7N0unax+ySZN67/AX++sJpqAhAIZJzrRi6ueN3RFCIxYDXS\nMvxrEmOdn4gOC0o1Ar9u5Bp9N52sqqGbN1x6jNKi3bfUj122Hu5e+Y9KOmfbchhQ\nil2P81cIi30VKgyDn5DeWEuDoYredk4+6qAZrxMw+wIDAQABozEwLzAOBgNVHQ8B\nAf8EBAMCBaAwHQYDVR0OBBYEFNmtrQ36j6tUGhKrfW9qWWE7KFzMMA0GCSqGSIb3\nDQEBCwUAA4IBAQAv3yOwgbtOu76eJMl1BCcgTFgaMUBZoUjK9Un6HGjKEgYz/YWS\nZFlY/qH5rT01DWQevUZB626d5ZNdzSBZRlpsxbf9IE/ursNHwHx9ua6fB7yHUCzC\n1ZMp1lvBHABi7wcA+5nbV6zQ7HDmBXFhJfbgH1iVmA1KcvDeBPSJ/scRGasZ5q2W\n3IenDNrfPIUhD74tFiCiqNJO91qD/LO+++3XeZzfPh8NRKkiPX7dB8WJ3YNBuQAv\ngRWTISpSSXLmqMb+7MPQVgecsepZdk8CwkRLxh3RKPJMjigmCgyvkSaoDMKAYC3i\nYjfUTiJ57UeqoSl0IaOFJ0wfZRFh+UytlDZa\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/resource-method-typing/resource_method_typing.bal",
    "content": "import ballerina/http;\n\ntype Args record {|\n    decimal x;\n    decimal y;\n|};\n\ntype Response record {|\n    decimal result;\n|};\n\nlistener http:Listener ln = new (9090);\n\nservice /calc on ln {\n   // Resource method arguments can use user-defined types.\n   // Annotations can be used to refine the mapping between the Ballerina-declared\n   // type and wire format.\n   resource function post add(Args args) returns Response {\n      return {result: args.x + args.y};\n   }\n}\n"
  },
  {
    "path": "examples/resource-method-typing/resource_method_typing.client.out",
    "content": "$ curl http://localhost:9090/calc/add -H 'content-type: application/json' -d \"{\\\"x\\\": 1.0, \\\"y\\\": 2.0}\"\n{\"result\":3.0}\n"
  },
  {
    "path": "examples/resource-method-typing/resource_method_typing.md",
    "content": "# Resource method typing\n\nResource method arguments can use user-defined types. The listener will use introspection to map the protocol format (typically JSON) to a user-defined type using `cloneWithType`. The return value, which is a subtype of anydata will be mapped from the user-defined type to the protocol format typically JSON, using `toJson`.\n\nThe API description (e.g. OpenAPI) can be generated from the Ballerina service declaration. Annotations can be used to refine the mapping between the Ballerina-declared type and wire format.\n\n::: code resource_method_typing.bal :::\n\nRun the service using the `bal run` command.\n\n::: out resource_method_typing.server.out :::\n\nRun this cURL command to invoke the resource.\n\n::: out resource_method_typing.client.out :::\n\n## Related links\n- [Casting JSON to user-defined type](/learn/by-example/casting-json-to-user-defined-type/)\n- [JSON type](/learn/by-example/json-type/)\n- [Service data binding](/learn/by-example/http-service-data-binding/)\n- [http module](https://lib.ballerina.io/ballerina/http)\n"
  },
  {
    "path": "examples/resource-method-typing/resource_method_typing.metatags",
    "content": "description: This BBE demonstrates how to accept JSON in rest API, return JSON in rest API, payload binding, data binding, access payload.\nkeywords: ballerina, ballerina by example, bbe, resource, service, data binding, json, record, http\n"
  },
  {
    "path": "examples/resource-method-typing/resource_method_typing.server.out",
    "content": "$ bal run resource_method_typing.bal\n"
  },
  {
    "path": "examples/resource-methods/resource_methods.bal",
    "content": "import ballerina/http;\n\n// Service declaration specifies base path for the resource names. The base path is `/` in this example.\nservice / on new http:Listener(8080) {\n    // Resource method is associated with combination of accessor (`get`) and resource name (`hello`). \n    // Accessors are determined by the network protocol.\n    // In HTTP resources, function parameters come from query parameters.\n    resource function get hello(string name) returns string {\n        return \"Hello, \" + name;\n    }\n}\n"
  },
  {
    "path": "examples/resource-methods/resource_methods.client.out",
    "content": "$ curl \"localhost:8080/hello?name=Ballerina\"\nHello, Ballerina\n"
  },
  {
    "path": "examples/resource-methods/resource_methods.md",
    "content": "# Resource methods\n\n- Service objects use `remote` methods to expose services in procedural style: remote methods are named by verbs.\n- Service objects use `resource` methods to expose services in an RESTful style: resources are named by nouns. \n\nResources are motivated by HTTP, but are general enough also to work for GraphQL. `resource` methods are a network-oriented generalization of OO getter/setter concept.\n\n::: code resource_methods.bal :::\n\nRun the service using the `bal run` command.\n\n::: out resource_methods.server.out :::\n\nRun this cURL command to invoke the resource.\n\n::: out resource_methods.client.out :::"
  },
  {
    "path": "examples/resource-methods/resource_methods.metatags",
    "content": "description: This BBE introduces the resource concept in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, resources, resource methods, HTTP, GraphQL\n"
  },
  {
    "path": "examples/resource-methods/resource_methods.server.out",
    "content": "$ bal run resource_methods.bal\n"
  },
  {
    "path": "examples/resource-path-parameters/resource_path_parameters.bal",
    "content": "import ballerina/http;\n\nservice /demo on new http:Listener(8080) {\n    // Here is how you can make path segments as parameters.\n    resource function get greeting/hello/[string name]() returns string {\n        return \"Hello, \" + name;\n    }\n}\n"
  },
  {
    "path": "examples/resource-path-parameters/resource_path_parameters.client.out",
    "content": "$ curl \"localhost:8080/demo/greeting/hello/Ballerina\"\nHello, Ballerina\n"
  },
  {
    "path": "examples/resource-path-parameters/resource_path_parameters.md",
    "content": "# Resource path parameters\n\nPath segments can be treated as parameters in Ballerina.\n\n::: code resource_path_parameters.bal :::\n\nRun the service using the `bal run` command.\n\n::: out resource_path_parameters.server.out :::\n\nRun this cURL command to invoke the resource.\n\n::: out resource_path_parameters.client.out :::"
  },
  {
    "path": "examples/resource-path-parameters/resource_path_parameters.metatags",
    "content": "description: This BBE introduces how you can specify resource path parameters.\nkeywords:  ballerina, ballerina by example, bbe, path parameters, resources\n"
  },
  {
    "path": "examples/resource-path-parameters/resource_path_parameters.server.out",
    "content": "$ bal run resource_path_parameters.bal\n"
  },
  {
    "path": "examples/rest-arguments/rest_arguments.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\n// A function to print the sum of two or more integers.\nfunction sum(int first, int second, int... others) {\n    int sum = first + second;\n    foreach int othVal in others {\n        sum += othVal;\n    }\n    io:println(sum);\n}\n\n// A record with some HTTP client configuration values.\ntype Configuration record {|\n    string url;\n    decimal timeout;\n    http:HttpVersion httpVersion;\n|};\n\n// A function that initializes an HTTP client using some configuration.\nfunction initializeHttpClient(string url, decimal timeout, http:HttpVersion httpVersion) {\n    // Intialize the client just for demonstration.\n    http:Client|error cl = new (url, {timeout, httpVersion});\n    if cl is error {\n        io:println(\"Failed to initialize an HTTP client\", cl);\n        return;\n    }\n    io:println(\n        string `Initialized client with URL: ${url}, timeout: ${timeout}, HTTP version: ${httpVersion}`);\n}\n\npublic function main() {\n    // Call the `sum` function using an array of length 4 as a rest argument.\n    int[4] ints1 = [1, 2, 3, 4];\n    sum(...ints1);\n\n    // Since the `sum` function has two required parameters, when providing only a list rest \n    // argument, the length of the list should be guaranteed by the static type to be at\n    // least 2.\n    // Call the `sum` function using a tuple with at least two members.\n    [int, int, int...] ints2 = [5, 6];\n    sum(...ints2);\n\n    // A rest argument can be used along with positional arguments, \n    // providing only some of the arguments.\n    // Call the `sum` function with a rest argument after two positional arguments.\n    sum(5, 6, ...ints1);\n\n    // Call the `sum` function with a rest argument after one positonal argument.\n    // Note how the rest argument provides arguments for both a required parameter\n    // and the rest parameter. Since only one positional argument is provided, the list\n    // type of the expression used in the rest argument should guarantee the presence of \n    // at least one member in the list to provide an argument for the second required parameter.\n    [int, int...] ints3 = [5, 6, 7];\n    sum(4, ...ints3);\n\n    // Call the `initializeHttpClient` function using a record value in the rest argument\n    // providing values for all the parameters.\n    Configuration config1 = {httpVersion: http:HTTP_2_0, url: \"http://localhost:8080\", timeout: 60};\n    initializeHttpClient(...config1);\n\n    // Call the `initializeHttpClient` function using a positional argument and a rest argument with \n    // a record value. The positional argument provides the argument for the first parameter (`url`) and the \n    // rest argument provides values for the other two parameters. \n    record {|\n        decimal timeout;\n        http:HttpVersion httpVersion;\n    |} config2 = {httpVersion: http:HTTP_1_1, timeout: 15};\n    initializeHttpClient(\"http://localhost:8080\", ...config2);\n}\n"
  },
  {
    "path": "examples/rest-arguments/rest_arguments.md",
    "content": "# Rest arguments\n\nBallerina allows you to call functions with rest arguments, with an expression of a mapping or list type, spreading the members of the mapping or the list as individual arguments to the function.\n\nIf the type of the expression used in the rest argument is a list type, the rest argument is equivalent to specifying each member of the list value as a positional argument. If it is a mapping type, the rest argument is equivalent to specifying each field of the mapping value as a named argument, where the name and the value of the named argument come from the name and the value of the field. In either case, the static type of the expression must ensure that the equivalent positional and/or named arguments would be valid and that arguments are provided for all the required parameters.\n \n::: code rest_arguments.bal :::\n\n::: out rest_arguments.out :::\n\n## Related links\n- [Functions](/learn/by-example/functions/)\n- [Provide function arguments by name](/learn/by-example/provide-function-arguments-by-name/)\n- [Included record parameters](/learn/by-example/included-record-parameters/)\n- [Aggregation](/learn/by-example/aggregation/)\n"
  },
  {
    "path": "examples/rest-arguments/rest_arguments.metatags",
    "content": "description: This BBE demonstrates calling functions with rest arguments in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, rest arguments, functions, function definition, parameters\n"
  },
  {
    "path": "examples/rest-arguments/rest_arguments.out",
    "content": "$ bal run rest_arguments.bal\n10\n11\n21\n22\nInitialized client with URL: http://localhost:8080, timeout: 60, HTTP version: 2.0\nInitialized client with URL: http://localhost:8080, timeout: 15, HTTP version: 1.1\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-error-binding-pattern/rest_binding_pattern_in_error_binding_pattern.bal",
    "content": "import ballerina/io;\n\ntype SampleErrorData record {|\n    int code;\n    string reason;\n|};\n\ntype SampleError error<SampleErrorData>;\n\npublic function main() {\n    // The detail mapping can be destructured using a rest parameter.\n    // `details` is of type `map<string|boolean>` having the `code` and `reason` fields.\n    var error(message, ...details) = getSampleError();\n    io:println(\"Message: \", message);\n\n    map<int|string> detailsMap = details;\n    io:println(\"Details: \", detailsMap);\n\n    // Here, the `...filteredDetails` rest parameter contains only the detail fields\n    // that are not matched.\n    var error(_, code = code, ...filteredDetails) = getSampleError();\n    io:println(\"Code: \", code);\n    io:println(\"Filtered Details: \", filteredDetails);\n\n    map<int|string> moreDetails;\n\n    // The detail mapping can be destructured into a `map<int|string>` typed variable\n    // by using a rest parameter.\n    error(_, ...moreDetails) = getSampleError();\n    io:println(\"All Details: \", moreDetails);\n}\n\nfunction getSampleError() returns SampleError {\n    return error(\"Transaction Failure\", error(\"Database Error\"), code = 20,\n                            reason = \"deadlock condition\");\n}\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-error-binding-pattern/rest_binding_pattern_in_error_binding_pattern.md",
    "content": "# Rest binding pattern in error binding pattern\n\nYou can use the rest binding pattern (`...r`) to bind the detail mappings that are not explicitly bound in the error binding pattern. The type of the rest binding will be a `map` holding the fields that have not been matched.\n\n::: code rest_binding_pattern_in_error_binding_pattern.bal :::\n\n::: out rest_binding_pattern_in_error_binding_pattern.out :::\n\n## Related links\n- [Binding Patterns](/learn/by-example/binding-patterns/)\n- [Typed Binding Pattern](/learn/by-example/typed-binding-pattern/)\n- [Error Binding Pattern](/learn/by-example/error-binding-pattern/)\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-error-binding-pattern/rest_binding_pattern_in_error_binding_pattern.metatags",
    "content": "description: This BBE demonstrates the rest binding pattern in the error binding pattern, rest parameter in error binding, rest binding, error binding pattern, error typed binding, and error destructuring with binding patterns.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, rest binding, rest parameter, error binding pattern, error binding, error typed binding, error binding, error destructuring\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-error-binding-pattern/rest_binding_pattern_in_error_binding_pattern.out",
    "content": "$ bal run rest_binding_pattern_in_error_binding_pattern.bal\nMessage: Transaction Failure\nDetails: {\"code\":20,\"reason\":\"deadlock condition\"}\nCode: 20\nFiltered Details: {\"reason\":\"deadlock condition\"}\nAll Details: {\"code\":20,\"reason\":\"deadlock condition\"}\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-list-binding-pattern/rest_binding_pattern_in_list_binding_pattern.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n\n    float[4] [first, second, ...others] = getScores();\n\n    // The first two values returned by `getScores()` will be bound to the \n    // variables `first` and `second` which will be of `float` type.\n    io:println(first);\n    io:println(second);\n\n    // The rest of the values will be bound to `others`, which will be of `float[]` type.\n    io:println(others);\n}\n\nfunction getScores() returns float[4] {\n    return [1.2, 2.3, 3.4, 4.5];\n}\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-list-binding-pattern/rest_binding_pattern_in_list_binding_pattern.md",
    "content": "# Rest binding pattern in list binding pattern\n\nIf the number of binding patterns is less than the members in the list value, the rest binding pattern (`...r`) can be used to create a new list value consisting of the members that are not bound.\n\n::: code rest_binding_pattern_in_list_binding_pattern.bal :::\n\n::: out rest_binding_pattern_in_list_binding_pattern.out :::\n\n## Related links\n- [List binding pattern](/learn/by-example/list-binding-pattern/)\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Rest type in tuples](/learn/by-example/rest-type-in-tuples/)\n  "
  },
  {
    "path": "examples/rest-binding-pattern-in-list-binding-pattern/rest_binding_pattern_in_list_binding_pattern.metatags",
    "content": "description: This BBE introduces the use of rest binding pattern in a list.\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, rest binding pattern\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-list-binding-pattern/rest_binding_pattern_in_list_binding_pattern.out",
    "content": "$ bal run rest_binding_pattern_in_list_binding_pattern.bal\n1.2\n2.3\n[3.4,4.5]\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-mapping-binding-pattern/rest_binding_pattern_in_mapping_binding_pattern.bal",
    "content": "import ballerina/io;\n\ntype Person record {\n    int id;\n    string fname;\n    string lname;\n};\n\npublic function main() {\n    // The value of the `id` field is ignored using `_`.\n    // The value of the `fname` field is matched with the `firstName` variable.\n    // `...otherDetails` is a rest parameter. The remaining fields that have not been matched\n    // are matched with `...otherDetails`.\n    Person {id: _, fname: firstName, ...otherDetails} = getPerson();\n    io:println(firstName);\n\n    // The type of `otherDetails` is a `record` holding the remaining fields.\n    record {|string lname; anydata...;|} details = otherDetails;\n    io:println(details);\n\n    string fname;\n    record {|string lname; anydata...;|} otherInfo;\n\n    // The values of the fields in the destructed record are assigned to the variable references.\n    // The value of the `fname` field is assigned to the `fname` variable.\n    // The remaining field values that have not been matched are assigned to `...otherInfo`.\n    {fname, ...otherInfo} = getPerson();\n    io:println(fname);\n    io:println(otherInfo);\n}\n\nfunction getPerson() returns Person {\n    Person person = {id: 1001, fname: \"Anne\", lname: \"Frank\", \"age\": 24, \"country\": \"UK\"};\n    return person;\n}\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-mapping-binding-pattern/rest_binding_pattern_in_mapping_binding_pattern.md",
    "content": "# Rest binding pattern in mapping binding pattern\n\nYou can use the rest binding pattern (`...r`) to bind the fields that are not explicitly bound in the mapping binding pattern. The type of the rest binding will be a `record` holding the fields that have not been matched.\n\n::: code rest_binding_pattern_in_mapping_binding_pattern.bal :::\n\n::: out rest_binding_pattern_in_mapping_binding_pattern.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Mapping binding pattern](/learn/by-example/mapping-binding-pattern/)\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-mapping-binding-pattern/rest_binding_pattern_in_mapping_binding_pattern.metatags",
    "content": "description: This BBE demonstrates the rest binding pattern, rest binding pattern in mapping binding, rest binding pattern in record typed binding, record destructuring with binding patterns, and JSON destructuring.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, rest binding, mapping binding pattern, mapping binding, record typed binding, record binding, record destructuring, json destructuring\n"
  },
  {
    "path": "examples/rest-binding-pattern-in-mapping-binding-pattern/rest_binding_pattern_in_mapping_binding_pattern.out",
    "content": "$ bal rest_binding_pattern_in_mapping_binding_pattern.bal\nAnne\n{\"lname\":\"Frank\",\"age\":24,\"country\":\"UK\"}\nAnne\n{\"lname\":\"Frank\",\"id\":1001,\"age\":24,\"country\":\"UK\"}\n"
  },
  {
    "path": "examples/rest-parameters/rest_parameters.bal",
    "content": "import ballerina/io;\n\nfunction foo(int n, string... s) {\n    io:println(n);\n    io:println(s[0]);\n    io:println(s[1]);\n    io:println(s[2]);\n    io:println(s);\n    io:println(s is string[]);\n}\n\npublic function main() {\n    // The `s` parameter will be `[\"x\", \"y\", \"z\"]`.\n    foo(1, \"x\", \"y\", \"z\");\n}\n"
  },
  {
    "path": "examples/rest-parameters/rest_parameters.md",
    "content": "# Rest Parameters\n\nBallerina supports rest parameters. There can not be another parameter after a rest parameter. \nIf a function has a rest parameter, that will be initialized to a newly created list with the remaining arguments in the function.\nThe inherent type of this list is `T[]` in which `T` is the type of the rest parameter.\n\n::: code rest_parameters.bal :::\n\n::: out rest_parameters.out :::"
  },
  {
    "path": "examples/rest-parameters/rest_parameters.metatags",
    "content": "description: This BBE demonstrates rest parameters in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, rest parameters, rest params\n"
  },
  {
    "path": "examples/rest-parameters/rest_parameters.out",
    "content": "1\nx\ny\nz\n[\"x\",\"y\",\"z\"]\ntrue\n"
  },
  {
    "path": "examples/rest-type-in-tuples/rest_type_in_tuples.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // declare a tuple with zero or more `int` members after the first member of type `string`.\n    [string, int...] scoreList = [\"John\", 55, 43, 65, 65];\n    io:println(scoreList);\n\n    [string, int...] secondScoreList = [\"Amy\"];\n    io:println(secondScoreList);\n\n    // [T...] is equivalent to array T[].\n    [int...] scores = [];\n    io:println(scores);\n\n    scores = [23, 53];\n    io:println(scores);\n\n    // New members can be pushed to a tuple with rest type by using `array:push()` method\n    scores.push(43);\n    io:println(scores);\n}\n"
  },
  {
    "path": "examples/rest-type-in-tuples/rest_type_in_tuples.md",
    "content": "# Rest type in tuples\n\nA Tuple type descriptor can optionally contain a tuple rest descriptor. It can be described as `[R...]`. This implies that the tuple can contain zero or more members after the `nth` member where the type of those members are `R`. Rest type descriptor should be the last member type descriptor in the tuple. Tuples are not open by default.\n\n::: code rest_type_in_tuples.bal :::\n\n::: out rest_type_in_tuples.out :::\n\n## Related links\n- [Tuples](/learn/by-example/tuples)\n- [Arrays](/learn/by-example/arrays)\n- [Manipulating an array `(lang.array)`](https://lib.ballerina.io/ballerina/lang.array)\n- [Filler values of a list](/learn/by-example/filler-values-of-a-list)\n- [List sub typing](/learn/by-example/list-subtyping)\n- [List equality](/learn/by-example/list-equality)"
  },
  {
    "path": "examples/rest-type-in-tuples/rest_type_in_tuples.metatags",
    "content": "description: This BBE demonstrates how to create variable length tuple, create tuple with rest type descriptor.\nkeywords: ballerina, ballerina by example, bbe, rest type, tuple rest type, collection, length, size, list, rest, list binding pattern, push\n"
  },
  {
    "path": "examples/rest-type-in-tuples/rest_type_in_tuples.out",
    "content": "$ bal run rest_type_in_tuples.bal\n[\"John\",55,43,65,65]\n[\"Amy\"]\n[]\n[23,53]\n[23,53,43]\n"
  },
  {
    "path": "examples/retry-transaction-statement/retry_transaction_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // Short for `retry<DefaultRetryManager>(3)`.\n    // If any of the `doStage1` and `doStage2` returns `error:Retriable`, the program will retry execution\n    // until execution succeeds without an `error:Retriable` error.\n    // By default, it will retry 3 times with the `DefaultRetryManager`.\n    retry transaction {\n        check doStage1();\n        check doStage2();\n        check commit;\n    }\n\n    return;\n}\n\nfunction doStage1() returns error? {\n    io:println(\"Stage1 completed\");\n    return;\n}\n\nfunction doStage2() returns error? {\n    // Returns an `error:Retriable` error for retrying.\n    // To support custom errors, a custom implementation of the `RetryManager` is required.\n    return error 'error:Retriable(\"Stage2 failed\");\n}\n"
  },
  {
    "path": "examples/retry-transaction-statement/retry_transaction_statement.md",
    "content": "# Retry transaction statement\n\nTransactional errors are often transient: retrying will fix them. This works by creating a  RetryManager object `r`, before executing the transaction. If the block fails with error `e`, it calls `r.shouldRetry(e)`. If that returns `true`, then it executes the block again.\n\n`retry` has an optional type parameter giving class of `RetryManager` to create, and optional arguments to new `DefaultRetryManager` tries `n` times. `retry` can be used without `transaction`.\n\n::: code retry_transaction_statement.bal :::\n\n::: out retry_transaction_statement.out :::"
  },
  {
    "path": "examples/retry-transaction-statement/retry_transaction_statement.metatags",
    "content": "description: This BBE demonstrates retrying a transaction in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, retry, retry transaction, retry manager\n"
  },
  {
    "path": "examples/retry-transaction-statement/retry_transaction_statement.out",
    "content": "$ bal run retry_transaction_statement.bal\nStage1 completed\nStage1 completed\nStage1 completed\nStage1 completed\nerror: Stage2 failed\n"
  },
  {
    "path": "examples/rollback/rollback.bal",
    "content": "import ballerina/io;\n\n// Defines the `Update` record type.\ntype Update record {\n    int updateIndex;\n    int stockMnt;\n};\n\npublic function main() returns error? {\n    // Creates an array of `Update` records.\n    Update[] updates = [\n        {updateIndex: 0, stockMnt: 2000},\n        {updateIndex: 1, stockMnt: -1000},\n        {updateIndex: 2, stockMnt: 1500},\n        {updateIndex: 3, stockMnt: -1000},\n        {updateIndex: 4, stockMnt: -2000}\n    ];\n    // This transfer will be rolled back.\n    io:println(transfer(updates));\n\n    // Creates an array of employee salaries.\n    int[] salaryList = [100, 200, 300, 100];\n\n    // This salary increment will be rolled back.\n    check incrementSalary(salaryList);\n\n    int[] salaryList2 = [100, 200, 100, 100];\n\n    // This salary increment will be successful.\n    check incrementSalary(salaryList2);\n}\n\nfunction transfer(Update[] updates) returns error? {\n\n    transaction {\n        // Inside the transaction, call `doUpdate` on each `update` record.\n        foreach var u in updates {\n            // If an error is returned, the `transfer` function returns with\n            // that error and the transaction is rolled back.\n            check doUpdate(u);\n        }\n        // `commit` will not be called because of an implicit rollback.\n        check commit;\n    }\n    return;\n}\n\nfunction doUpdate(Update u) returns error? {\n    // If the stock amount is less than `-1500`, an error is returned.\n    if (u.stockMnt < -1500) {\n        return error(\"Not enough stocks: \", stockIndex = u.updateIndex);\n    }\n\n    return;\n}\n\nfunction incrementSalary(int[] salaryList) returns error? {\n    transaction {\n        foreach int index in 0 ..< salaryList.length() {\n            salaryList[index] += 100;\n        }\n\n        // If the new total salary exceeds `1000`, then, the rollback statement performs \n        // rollback on the transaction.\n        int salarySum = int:sum(...salaryList);\n        if (salarySum > 1000) {\n            io:println(\"Budget exceeded\");\n            rollback;\n        } else {\n            io:println(\"Salary increment successful\");\n            check commit;\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rollback/rollback.md",
    "content": "# Rollback\n\nIf there is a fail or panic in the execution of the block, then the transaction is rolled back. Transaction statement can also contain a rollback statement. Every possible exit from a transaction block must be either `commit`, `rollback`, fail exit (e.g., from `check`), or panic exit.\n\nRollback does not automatically restore Ballerina variables to values before the transaction.\n\n::: code rollback.bal :::\n\n::: out rollback.out :::"
  },
  {
    "path": "examples/rollback/rollback.metatags",
    "content": "description: This BBE demonstrates `rollback` operation in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, rollback, rollback transaction\n"
  },
  {
    "path": "examples/rollback/rollback.out",
    "content": "$ bal run rollback.bal\nerror(\"Not enough stocks: \",stockIndex=4)\nBudget exceeded\nSalary increment successful\n"
  },
  {
    "path": "examples/run-strands-safely-on-separate-threads/run_strands_safely_on_separate_threads.bal",
    "content": "import ballerina/io;\n\nfinal int[] & readonly intArr = [4, 2, 10, 8, 6];\n\nisolated function f1(int[] arr) returns int[] {\n    return arr.sort();\n}\n\nfunction f2(int[] arr) returns int[] {\n    return arr.sort();\n}\n\nisolated function f3() {\n    // An isolated `start` action is allowed in an isolated function.\n    // Here, the strand created by the `start` action will run on a separate thread.\n    future<int[]> _ = start f1([4, 2, 8, 6]);\n}\n\nisolated function f4() {\n    // A named worker is allowed in an isolated function.\n    // Here, the strand created by a named worker can run on a separate thread\n    // if the body of the worker satisfies the requirements for an isolated function.\n    worker A {\n        int[] _ = f1(intArr);\n    }\n}\n\nfunction f5() {\n    future<int[]> _ = start f1([4, 2, 8, 6]);\n}\n\nfunction f6() {\n    worker A {\n        int[] _ = f2(intArr);\n    }\n}\n\npublic function main() {\n    // `f2` is inferred to be isolated.\n    io:println(f2 is isolated function (int[]) returns int[]);\n    // `f5` is inferred to be isolated.\n    io:println(f5 is isolated function ());\n    // `f6` is inferred to be isolated.\n    io:println(f6 is isolated function ());\n}\n"
  },
  {
    "path": "examples/run-strands-safely-on-separate-threads/run_strands_safely_on_separate_threads.md",
    "content": "# Run strands safely on a separate thread based on isolation\n\nThe isolated feature in Ballerina supports identifying cases in which strands created by a start action, or a named worker can be run safely on separate threads.\n\nA `start` action is isolated if the function or method it calls has a type that is isolated and the expression for every argument is an isolated expression. The object whose method is called by the method call or remote method call is treated as an argument. An isolated `start` action is allowed in an isolated function and the strand created by the `start` action will run on a separate thread from the current thread.\n\nThe strand created by a named worker can run on a separate thread from the default worker if the body of the worker satisfies the requirements for an isolated function.\n\n::: code run_strands_safely_on_separate_threads.bal :::\n\n::: out run_strands_safely_on_separate_threads.out :::\n"
  },
  {
    "path": "examples/run-strands-safely-on-separate-threads/run_strands_safely_on_separate_threads.metatags",
    "content": "description: This BBE demonstrates how to run strands safely on a separate thread based on isolation.\nkeywords: ballerina, ballerina by example, bbe, inferring isolated, strand\n"
  },
  {
    "path": "examples/run-strands-safely-on-separate-threads/run_strands_safely_on_separate_threads.out",
    "content": "$ bal run_strands_safely_on_separate_threads.bal\ntrue\ntrue\ntrue\n"
  },
  {
    "path": "examples/security-crypto/security_crypto.bal",
    "content": "import ballerina/crypto;\nimport ballerina/io;\nimport ballerina/random;\n\nfunction hash() returns error? {\n    // Input value for hash operations.\n    string value = \"Hello Ballerina!\";\n    byte[] input = value.toBytes();\n\n    // Hashing input value using the MD5 hashing algorithm, and printing the hash value using the Hex encoding.\n    // For details, see https://lib.ballerina.io/ballerina/crypto/latest#hashMd5\n    byte[] output = crypto:hashMd5(input);\n    io:println(\"Hex encoded hash with MD5: \" + output.toBase16());\n\n    // Hashing the input value using the SHA1 hashing algorithm, and printing the hash value using the Base64 encoding.\n    output = crypto:hashSha1(input);\n    io:println(\"Base64 encoded hash with SHA1: \" + output.toBase64());\n\n    // Hashing the input value using the SHA256 hashing algorithm, and printing the hash value using the Hex encoding.\n    output = crypto:hashSha256(input);\n    io:println(\"Hex encoded hash with SHA256: \" + output.toBase16());\n\n    // Hashing the input value using the SHA384 hashing algorithm, and printing the hash value using the Base64 encoding.\n    output = crypto:hashSha384(input);\n    io:println(\"Base64 encoded hash with SHA384: \" + output.toBase64());\n\n    // Hashing the input value using the SHA512 hashing algorithm, and printing the hash value using the Hex encoding.\n    output = crypto:hashSha512(input);\n    io:println(\"Hex encoded hash with SHA512: \" + output.toBase16());\n\n    // The Hex-encoded CRC32B checksum generation for the input value.\n    io:println(\"CRC32B for text: \" + crypto:crc32b(input));\n}\n\nfunction hmac() returns error? {\n    // Input value for HMAC operations.\n    string value = \"Hello Ballerina!\";\n    byte[] input = value.toBytes();\n\n    // The key used for the HMAC generation.\n    string secret = \"somesecret\";\n    byte[] key = secret.toBytes();\n\n    // HMAC generation for the input value using the MD5 hashing algorithm, and printing the HMAC value using the Hex encoding.\n    byte[] output = check crypto:hmacMd5(input, key);\n    io:println(\"Hex encoded HMAC with MD5: \" + output.toBase16());\n\n    // HMAC generation for input the value using the SHA1 hashing algorithm, and printing the HMAC value using the Base64 encoding.\n    output = check crypto:hmacSha1(input, key);\n    io:println(\"Base64 encoded HMAC with SHA1: \" + output.toBase64());\n\n    // HMAC generation for the input value using the SHA256 hashing algorithm, and printing the HMAC value using the Hex encoding.\n    output = check crypto:hmacSha256(input, key);\n    io:println(\"Hex encoded HMAC with SHA256: \" + output.toBase16());\n\n    // HMAC generation for the input value using the SHA384 hashing algorithm, and printing the HMAC value using the Base64 encoding.\n    output = check crypto:hmacSha384(input, key);\n    io:println(\"Base64 encoded HMAC with SHA384: \" + output.toBase64());\n\n    // HMAC generation for the input value using the SHA512 hashing algorithm, and printing the HMAC value using the Hex encoding.\n    output = check crypto:hmacSha512(input, key);\n    io:println(\"Hex encoded HMAC with SHA512: \" + output.toBase16());\n}\n\nfunction decodePrivateKey() returns crypto:PrivateKey|error {\n    // Obtaining the reference to an RSA private key by a key file.\n    string keyFile = \"../resource/path/to/private.key\";\n    crypto:PrivateKey privateKey = check crypto:decodeRsaPrivateKeyFromKeyFile(keyFile);\n\n    // Obtaining the reference to an RSA private key by an encrypted key file.\n    string encryptedKeyFile = \"../resource/path/to/encryptedPrivate.key\";\n    privateKey = check crypto:decodeRsaPrivateKeyFromKeyFile(encryptedKeyFile, \"ballerina\");\n\n    // Obtaining the reference to an RSA private key stored within a PKCS#12 or PFX format archive file.\n    crypto:KeyStore keyStore = {\n        path: \"../resource/path/to/ballerinaKeystore.p12\",\n        password: \"ballerina\"\n    };\n    privateKey = check crypto:decodeRsaPrivateKeyFromKeyStore(keyStore, \"ballerina\", \"ballerina\");\n\n    return privateKey;\n}\n\nfunction decodePublicKey() returns crypto:PublicKey|error {\n    // Obtaining the reference to an RSA public key by a cert file.\n    string certFile = \"../resource/path/to/public.crt\";\n    crypto:PublicKey publicKey = check crypto:decodeRsaPublicKeyFromCertFile(certFile);\n\n    // Obtaining reference to a RSA public key stored within a PKCS#12 or PFX format archive file.\n    crypto:TrustStore trustStore = {\n        path: \"../resource/path/to/ballerinaTruststore.p12\",\n        password: \"ballerina\"\n    };\n    publicKey = check crypto:decodeRsaPublicKeyFromTrustStore(trustStore, \"ballerina\");\n\n    return publicKey;\n}\n\nfunction sign() returns error? {\n    // Input value for the `sign` operations.\n    string value = \"Hello Ballerina!\";\n    byte[] input = value.toBytes();\n\n    // Private and public keys for the `sign` and `verify` operations.\n    crypto:PrivateKey privateKey = check decodePrivateKey();\n    crypto:PublicKey publicKey = check decodePublicKey();\n\n    // Signing the input value using the RSA-MD5 signature algorithms, and printing the signature value using the Hex encoding.\n    byte[] output = check crypto:signRsaMd5(input, privateKey);\n    io:println(\"Hex encoded RSA-MD5 signature: \" + output.toBase16());\n\n    boolean verified = check crypto:verifyRsaMd5Signature(input, output, publicKey);\n    io:println(\"RSA-MD5 signature verified: \" + verified.toString());\n\n    // Signing the input value using the RSA-MD5 signature algorithms, and printing the signature value using the Base64 encoding.\n    output = check crypto:signRsaSha1(input, privateKey);\n    io:println(\"Base64 encoded RSA-SHA1 signature: \" + output.toBase64());\n\n    verified = check crypto:verifyRsaSha1Signature(input, output, publicKey);\n    io:println(\"RSA-SHA1 signature verified: \" + verified.toString());\n\n    // Signing the input value using the RSA-MD5 signature algorithms, and printing the signature value using the Hex encoding.\n    output = check crypto:signRsaSha256(input, privateKey);\n    io:println(\"Hex encoded RSA-SHA256 signature: \" + output.toBase16());\n\n    verified = check crypto:verifyRsaSha256Signature(input, output, publicKey);\n    io:println(\"RSA-SHA256 signature verified: \" + verified.toString());\n\n    // Signing the input value using the RSA-MD5 signature algorithms, and printing the signature value using the Base64 encoding.\n    output = check crypto:signRsaSha384(input, privateKey);\n    io:println(\"Base64 encoded RSA-SHA384 signature: \" + output.toBase64());\n\n    verified = check crypto:verifyRsaSha384Signature(input, output, publicKey);\n    io:println(\"RSA-SHA384 signature verified: \" + verified.toString());\n\n    // Signing the input value using the RSA-MD5 signature algorithms, and printing the signature value using the Hex encoding.\n    output = check crypto:signRsaSha512(input, privateKey);\n    io:println(\"Hex encoded RSA-SHA512 signature: \" + output.toBase16());\n\n    verified = check crypto:verifyRsaSha512Signature(input, output, publicKey);\n    io:println(\"RSA-SHA512 signature verified: \" + verified.toString());\n}\n\nfunction encrypt() returns error? {\n    // Input value for the `encrypt` operations.\n    string value = \"Hello Ballerina!\";\n    byte[] input = value.toBytes();\n\n    // Private and public keys for the `encrypt` and `decrypt` operations.\n    crypto:PrivateKey privateKey = check decodePrivateKey();\n    crypto:PublicKey publicKey = check decodePublicKey();\n\n    // Encrypts and decrypts an input value using the `RSA ECB PKCS1` padding.\n    byte[] output = check crypto:encryptRsaEcb(input, publicKey);\n    output = check crypto:decryptRsaEcb(output, privateKey);\n    io:println(\"RSA ECB PKCS1 decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `RSA ECB OAEPwithSHA512andMGF1` padding.\n    output = check crypto:encryptRsaEcb(input, publicKey, crypto:OAEPwithSHA512andMGF1);\n    output = check crypto:decryptRsaEcb(output, privateKey, crypto:OAEPwithSHA512andMGF1);\n    io:println(\"RSA ECB OAEPwithSHA512andMGF1 decrypted value: \" + check string:fromBytes(output));\n\n    // Randomly generates a 128 bit key for the AES encryption.\n    byte[16] aesKey = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n    foreach var i in 0 ... 15 {\n        aesKey[i] = <byte>(check random:createIntInRange(0, 255));\n    }\n\n    // Randomly generates a 128 bit IV for the AES encryption.\n    byte[16] iv = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n    foreach var i in 0 ... 15 {\n        iv[i] = <byte>(check random:createIntInRange(0, 255));\n    }\n\n    // Encrypts and decrypts an input value using the `AES CBC PKCS5` padding.\n    output = check crypto:encryptAesCbc(input, aesKey, iv);\n    output = check crypto:decryptAesCbc(output, aesKey, iv);\n    io:println(\"AES CBC PKCS5 decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `AES CBC` without padding.\n    output = check crypto:encryptAesCbc(input, aesKey, iv, crypto:NONE);\n    output = check crypto:decryptAesCbc(output, aesKey, iv, crypto:NONE);\n    io:println(\"AES CBC no padding decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `AES GCM PKCS5` padding.\n    output = check crypto:encryptAesGcm(input, aesKey, iv);\n    output = check crypto:decryptAesGcm(output, aesKey, iv);\n    io:println(\"AES GCM PKCS5 decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `AES GCM` without padding.\n    output = check crypto:encryptAesGcm(input, aesKey, iv, crypto:NONE);\n    output = check crypto:decryptAesGcm(output, aesKey, iv, crypto:NONE);\n    io:println(\"AES GCM no padding decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `AES ECB PKCS5 padding`.\n    output = check crypto:encryptAesEcb(input, aesKey);\n    output = check crypto:decryptAesEcb(output, aesKey);\n    io:println(\"AES ECB PKCS5 decrypted value: \" + check string:fromBytes(output));\n\n    // Encrypts and decrypts an input value using the `AES ECB` without padding.\n    output = check crypto:encryptAesEcb(input, aesKey, crypto:NONE);\n    output = check crypto:decryptAesEcb(output, aesKey, crypto:NONE);\n    io:println(\"AES ECB no padding decrypted value: \" + check string:fromBytes(output));\n}\n\npublic function main() returns error? {\n    check hash();\n    check hmac();\n    check sign();\n    check encrypt();\n}\n"
  },
  {
    "path": "examples/security-crypto/security_crypto.md",
    "content": "# Cryptographic operations\n\nThe `crypto` stdlib provides functions usable to perform different cryptographic operations such as hashing, HMAC generation, checksum generation, encryption, decryption, digitally signing data and  verifying digitally signed data.\n\nFor more information on the underlying module, see the [`crypto` module](https://lib.ballerina.io/ballerina/crypto/latest/).\n\n>**Tip:** You may need to change the certificate file path, private key file path, and trusted certificate file path in the code below.\n\n::: code security_crypto.bal :::\n\nRun the program by executing the command below.\n\n::: out security_crypto.out :::\n\n## Related links\n- [Binary data](/learn/by-example/binary-data/)"
  },
  {
    "path": "examples/security-crypto/security_crypto.metatags",
    "content": "description: BBE on how to perform different cryptographic operations in Ballerina such as hashing, HMAC generation, checksum generation, encryption, decryption, digitally signing data and verifying digitally signed data.\nkeywords: ballerina, ballerina by example, bbe, crypto, hash, hmac, sign, encrypt decrypt\n"
  },
  {
    "path": "examples/security-crypto/security_crypto.out",
    "content": "$ bal run security_crypto.bal\nHex encoded hash with MD5: 0605402ee16d8e96511a58ff105bc24a\nBase64 encoded hash with SHA1: /8fwbGIevBvv2Nl3gEL9DtWas+Q=\nHex encoded hash with SHA256: a984a643c350b17f0738bac0fef17f2cd91d91e04596351d0af\n    670c79adc12d5\nBase64 encoded hash with SHA384: lselzItgAZHQmqNbkf/s2aRjBSd93O3ayc0PB0Dxk6AEo1s4\n    4zyTz/Qp0FJO1n6b\nHex encoded hash with SHA512: a6f0770f1582f49396a97fbd5973ac22a3a578ac6a991786427\n    dfec17dbd984d8d6289771ac6f44176160a3dcd59f4a8c6b3ab97bef0caa5c67a3fac78c8e946\nCRC32B for text: db9230c5\nHex encoded HMAC with MD5: b69fa2cc698e0923a7eea9d8f2b156fe\nBase64 encoded HMAC with SHA1: AkWFajkb/gml703Zf4pPgxrjam4=\nHex encoded HMAC with SHA256: 13a3369b8ba326fd311d4500b06a5214a02ed2a033917108f6b\n    9af58b7ede381\nBase64 encoded HMAC with SHA384: 0AjKoWLhNPgdobGTPJs0PdkA0W9wkJtzUvXigzC1ZmXDJJsx\n    p4icks4JrPiwHGm6\nHex encoded HMAC with SHA512: 27588ad08e772a6bba5fca5f45cf467819c8de69a70a42be6fe\n    3eb09ceb3bfeb8b2976bda8ea5c10dcfa2294b12cb0b50b22a06309bada98af21857904a03205\nHex encoded RSA-MD5 signature: 2cfd121e4ff2409d1b2482ebbf37d0c035884d6d858e307e44\n    60b092d79cb20abb624a0dfae76b73b1fc85447be3060a36b318813f0115b1919e5efa7a7f9b1\n    173ec869f56fd9448d99770e1565db1c69a04fd0075fa0e33423a7e829a8b9c25a4dd2c68f3ee\n    e021c0c4ff27979750b395384e280afd87af5274c8d2d99ad4438d9bfc9b2c5a2814212ba29ce\n    6ff70cbe30a5c23f86b0330e143c4d8813ff10092cd313c6861706d37df5f4bb4e9fc72354975\n    ee1786cf24c79b9edfa909968f198c4da37464f3d214a68fb39956717e92d667bb5a9a7f5986b\n    a055d431813d4053a028873499f98c94fd6b5c6fd5aefad432669f957ab4ce9e91c5e77b36ec0\nRSA-MD5 signature verified: true\nBase64 encoded RSA-SHA1 signature: bYMHKKVkjbOUp9ly3AdW9/euxF94krkkF9SDk2FfbVEc0m\n    qpGIxVoZlPiFxszurZF1YPcqOSeOehDkaHXUMfQkTjBq7XlcePtkywy0fChqw8/SWqZR8nbYv97tt\n    8+MVTkymbm26syQLwYNLiGp/EsN6X+fJpkdakwHE+TrdE+rEFrNysGyAm1DWwc4c+l7MEmSYMUnh/\n    GWPY5r2knOOdDA3mr+XyrsxzFRWZgO7ebVvEQfq9XkRp8kdiGVgpLS5au0jKj3EpbCdS1prFgy3gr\n    kuSJTTUQCwgPo7WSjWbuehFGni7rbas8HIqNlyWF0qUyznJ3eqbUwZ95QqOoVWZoQ==\nRSA-SHA1 signature verified: true\nHex encoded RSA-SHA256 signature: 215c6ea96c9e82348430c6bb02e715560b4fbd3afcf24fb\n    eb41ff12d4d68a797d61c4d6f822807688e4dc604e212b3cc7ac563b3cbe4e5690e2aebaf4e3d\n    f35c19d4b0f7043f50501f390634303577053b029d495104c0e98bc887f0be744ef6f726f7192\n    01907ad4e86cef82eb030b60c384f7034a85159081e598e197bb8904a9123f39d190796dc7fd9\n    46157547c10523999b8fa956d4119dbfe3c1435911c0585cf3c537964516706772e87f2470557\n    40cc4867ac6b99d7bf699fce1b59956c7f55368c8c88c9d47e51ef120ed3f27c3e555691a6971\n    42c78cbd72c23b81b43fa5ab67164a35f8e8c6bf1da187d3feb866add13f1fb9576a2f7887535\n    311\nRSA-SHA256 signature verified: true\nBase64 encoded RSA-SHA384 signature: BjQ40dffGiRQ4zo1s+ld+zKhJL21RbO5sW3L2+4xmonU\n    t126u9D4/FZ2sM1QGGamj8btB9otiYmWr9sFm4fTs1EX6vrxcCGCAiDdkMxiRs7kShaz2x/BjJQ7c\n    Od9OY+amwo7DQ/FAk9mNOt4lFUpjc9WyEW9F1PEJRXZQvMmVabDu8lp/Fh02lmEquG15DT5qT0jRx\n    RJiS8CNa+97cMZdOmF2KeADfRbNJSz70mZ76MrsNxYIXYIiJzJBQod0efQr0Sr/HDn4JDVph9rpDM\n    3p8m94TyXvSOwxwxzZWRLEwB0ANdfDmbrW4bOpxfZZFmy1hltqNJQ9G0BcKOHsZDj6Q==\nRSA-SHA384 signature verified: true\nHex encoded RSA-SHA512 signature: 15428fdc7b26d18b1f3eae4569399ae6ebfd430c8f073bf\n    2fa77ebfe1ad5645640374ea4a4aeadd252af3a198e55e69ad2a910e28470d9b54748887de06a\n    5c3ed7ab12399a404359332553e051e8ae0f3ef741faa15a21ad17a9c235e5f91d567bcca0e5a\n    6117689dccada4a33ee897514f7a8a32f12dac0087f5dcbb094c93c792f672e1685618ac5d93a\n    a9d30f6d8e306145ef2d1b9cfdc04d6c61b43376089a78471e8e03d97ee3b57e1b734a23f4436\n    6a99234a0abeb1d36d01c474833b4c2beaf430dae06ab95a1c951645fb1e0a5e7b9eed44d40e3\n    5036f2cd2764df6cc04fe1248e1bb772a53c8201a974109333a318ce57930494d4cb5e41d0dc8\n    f1c\nRSA-SHA512 signature verified: true\nRSA ECB PKCS1 decrypted value: Hello Ballerina!\nRSA ECB OAEPwithSHA512andMGF1 decrypted value: Hello Ballerina!\nAES CBC PKCS5 decrypted value: Hello Ballerina!\nAES CBC no padding decrypted value: Hello Ballerina!\nAES GCM PKCS5 decrypted value: Hello Ballerina!\nAES GCM no padding decrypted value: Hello Ballerina!\nAES ECB PKCS5 decrypted value: Hello Ballerina!\nAES ECB no padding decrypted value: Hello Ballerina!\n"
  },
  {
    "path": "examples/security-crypto/tests/security_crypto_test.bal",
    "content": "import ballerina/test;\n\nstring[] outputs = [];\n\n// This is the mock function which will replace the real function\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any... val) {\n    outputs.push(val.reduce(function (any a, any b) returns string => a.toString() + b.toString(), \"\").toString());\n}\n\n@test:Config {}\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function\n    check main();\n    test:assertEquals(outputs.length(), 29);\n    test:assertEquals(outputs[0], \"Hex encoded hash with MD5: 0605402ee16d8e96511a58ff105bc24a\");\n    test:assertEquals(outputs[1], \"Base64 encoded hash with SHA1: /8fwbGIevBvv2Nl3gEL9DtWas+Q=\");\n    test:assertEquals(outputs[2], \"Hex encoded hash with SHA256: a984a643c350b17f0738bac0fef17f2cd91d91e04596351d0af\" +\n                                  \"670c79adc12d5\");\n    test:assertEquals(outputs[3], \"Base64 encoded hash with SHA384: lselzItgAZHQmqNbkf/s2aRjBSd93O3ayc0PB0Dxk6AEo1s4\" +\n                                  \"4zyTz/Qp0FJO1n6b\");\n    test:assertEquals(outputs[4], \"Hex encoded hash with SHA512: a6f0770f1582f49396a97fbd5973ac22a3a578ac6a991786427\" +\n                                  \"dfec17dbd984d8d6289771ac6f44176160a3dcd59f4a8c6b3ab97bef0caa5c67a3fac78c8e946\");\n    test:assertEquals(outputs[5], \"CRC32B for text: db9230c5\");\n    test:assertEquals(outputs[6], \"Hex encoded HMAC with MD5: b69fa2cc698e0923a7eea9d8f2b156fe\");\n    test:assertEquals(outputs[7], \"Base64 encoded HMAC with SHA1: AkWFajkb/gml703Zf4pPgxrjam4=\");\n    test:assertEquals(outputs[8], \"Hex encoded HMAC with SHA256: 13a3369b8ba326fd311d4500b06a5214a02ed2a033917108f6b\" +\n                                  \"9af58b7ede381\");\n    test:assertEquals(outputs[9], \"Base64 encoded HMAC with SHA384: 0AjKoWLhNPgdobGTPJs0PdkA0W9wkJtzUvXigzC1ZmXDJJsx\" +\n                                  \"p4icks4JrPiwHGm6\");\n    test:assertEquals(outputs[10], \"Hex encoded HMAC with SHA512: 27588ad08e772a6bba5fca5f45cf467819c8de69a70a42be6fe\" +\n                                  \"3eb09ceb3bfeb8b2976bda8ea5c10dcfa2294b12cb0b50b22a06309bada98af21857904a03205\");\n\n    test:assertEquals(outputs[11], \"Hex encoded RSA-MD5 signature: 2cfd121e4ff2409d1b2482ebbf37d0c035884d6d858e307e4\" +\n                                   \"460b092d79cb20abb624a0dfae76b73b1fc85447be3060a36b318813f0115b1919e5efa7a7f9b117\" +\n                                   \"3ec869f56fd9448d99770e1565db1c69a04fd0075fa0e33423a7e829a8b9c25a4dd2c68f3eee021c\" +\n                                   \"0c4ff27979750b395384e280afd87af5274c8d2d99ad4438d9bfc9b2c5a2814212ba29ce6ff70cbe\" +\n                                   \"30a5c23f86b0330e143c4d8813ff10092cd313c6861706d37df5f4bb4e9fc72354975ee1786cf24c\" +\n                                   \"79b9edfa909968f198c4da37464f3d214a68fb39956717e92d667bb5a9a7f5986ba055d431813d40\" +\n                                   \"53a028873499f98c94fd6b5c6fd5aefad432669f957ab4ce9e91c5e77b36ec0\");\n    test:assertEquals(outputs[12], \"RSA-MD5 signature verified: true\");\n    test:assertEquals(outputs[13], \"Base64 encoded RSA-SHA1 signature: bYMHKKVkjbOUp9ly3AdW9/euxF94krkkF9SDk2FfbVEc0\" +\n                                   \"mqpGIxVoZlPiFxszurZF1YPcqOSeOehDkaHXUMfQkTjBq7XlcePtkywy0fChqw8/SWqZR8nbYv97tt8+\" +\n                                   \"MVTkymbm26syQLwYNLiGp/EsN6X+fJpkdakwHE+TrdE+rEFrNysGyAm1DWwc4c+l7MEmSYMUnh/GWPY5\" +\n                                   \"r2knOOdDA3mr+XyrsxzFRWZgO7ebVvEQfq9XkRp8kdiGVgpLS5au0jKj3EpbCdS1prFgy3grkuSJTTUQ\" +\n                                   \"CwgPo7WSjWbuehFGni7rbas8HIqNlyWF0qUyznJ3eqbUwZ95QqOoVWZoQ==\");\n    test:assertEquals(outputs[14], \"RSA-SHA1 signature verified: true\");\n    test:assertEquals(outputs[15], \"Hex encoded RSA-SHA256 signature: 215c6ea96c9e82348430c6bb02e715560b4fbd3afcf24f\" +\n                                   \"beb41ff12d4d68a797d61c4d6f822807688e4dc604e212b3cc7ac563b3cbe4e5690e2aebaf4e3df3\" +\n                                   \"5c19d4b0f7043f50501f390634303577053b029d495104c0e98bc887f0be744ef6f726f719201907\" +\n                                   \"ad4e86cef82eb030b60c384f7034a85159081e598e197bb8904a9123f39d190796dc7fd946157547\" +\n                                   \"c10523999b8fa956d4119dbfe3c1435911c0585cf3c537964516706772e87f247055740cc4867ac6\" +\n                                   \"b99d7bf699fce1b59956c7f55368c8c88c9d47e51ef120ed3f27c3e555691a697142c78cbd72c23b\" +\n                                   \"81b43fa5ab67164a35f8e8c6bf1da187d3feb866add13f1fb9576a2f7887535311\");\n    test:assertEquals(outputs[16], \"RSA-SHA256 signature verified: true\");\n    test:assertEquals(outputs[17], \"Base64 encoded RSA-SHA384 signature: BjQ40dffGiRQ4zo1s+ld+zKhJL21RbO5sW3L2+4xmon\" +\n                                   \"Ut126u9D4/FZ2sM1QGGamj8btB9otiYmWr9sFm4fTs1EX6vrxcCGCAiDdkMxiRs7kShaz2x/BjJQ7cOd\" +\n                                   \"9OY+amwo7DQ/FAk9mNOt4lFUpjc9WyEW9F1PEJRXZQvMmVabDu8lp/Fh02lmEquG15DT5qT0jRxRJiS8\" +\n                                   \"CNa+97cMZdOmF2KeADfRbNJSz70mZ76MrsNxYIXYIiJzJBQod0efQr0Sr/HDn4JDVph9rpDM3p8m94Ty\" +\n                                   \"XvSOwxwxzZWRLEwB0ANdfDmbrW4bOpxfZZFmy1hltqNJQ9G0BcKOHsZDj6Q==\");\n    test:assertEquals(outputs[18], \"RSA-SHA384 signature verified: true\");\n    test:assertEquals(outputs[19], \"Hex encoded RSA-SHA512 signature: 15428fdc7b26d18b1f3eae4569399ae6ebfd430c8f073b\" +\n                                   \"f2fa77ebfe1ad5645640374ea4a4aeadd252af3a198e55e69ad2a910e28470d9b54748887de06a5c\" +\n                                   \"3ed7ab12399a404359332553e051e8ae0f3ef741faa15a21ad17a9c235e5f91d567bcca0e5a61176\" +\n                                   \"89dccada4a33ee897514f7a8a32f12dac0087f5dcbb094c93c792f672e1685618ac5d93aa9d30f6d\" +\n                                   \"8e306145ef2d1b9cfdc04d6c61b43376089a78471e8e03d97ee3b57e1b734a23f44366a99234a0ab\" +\n                                   \"eb1d36d01c474833b4c2beaf430dae06ab95a1c951645fb1e0a5e7b9eed44d40e35036f2cd2764df\" +\n                                   \"6cc04fe1248e1bb772a53c8201a974109333a318ce57930494d4cb5e41d0dc8f1c\");\n    test:assertEquals(outputs[20], \"RSA-SHA512 signature verified: true\");\n    test:assertEquals(outputs[21], \"RSA ECB PKCS1 decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[22], \"RSA ECB OAEPwithSHA512andMGF1 decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[23], \"AES CBC PKCS5 decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[24], \"AES CBC no padding decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[25], \"AES GCM PKCS5 decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[26], \"AES GCM no padding decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[27], \"AES ECB PKCS5 decrypted value: Hello Ballerina!\");\n    test:assertEquals(outputs[28], \"AES ECB no padding decrypted value: Hello Ballerina!\");\n}\n"
  },
  {
    "path": "examples/security-jwt-issue-validate/security_jwt_issue_validate.bal",
    "content": "import ballerina/io;\nimport ballerina/jwt;\n\npublic function main() returns error? {\n    // Defines the JWT issuer configurations with the private key file configurations, \n    // which are used to self-sign the JWT.\n    jwt:IssuerConfig issuerConfig = {\n        username: \"ballerina\",\n        issuer: \"wso2\",\n        audience: \"vEwzbcasJVQm1jVYHUHCjhxZ4tYa\",\n        keyId: \"NTAxZmMxNDMyZDg3MTU1ZGM0MzEzODJhZWI4NDNlZDU1OGFkNjFiMQ\",\n        expTime: 3600,\n        // Signature can be created using either the private key configurations or keystore configurations.\n        // For details, see https://lib.ballerina.io/ballerina/jwt/latest#IssuerSignatureConfig.\n        signatureConfig: {\n            config: {\n                keyFile: \"../resource/path/to/private.key\"\n            }\n        }\n    };\n\n    // Issues a JWT based on the provided header, payload, and private key.\n    string jwt = check jwt:issue(issuerConfig);\n    io:println(\"Issued JWT: \", jwt);\n\n    // Defines the JWT validator configurations with the public certificate file configurations, \n    // which are used to validate the signature of JWT.\n    jwt:ValidatorConfig validatorConfig = {\n        issuer: \"wso2\",\n        audience: \"vEwzbcasJVQm1jVYHUHCjhxZ4tYa\",\n        clockSkew: 60,\n        // Signature can be validated using the public certificate file, truststore configurations, or JWKS configurations.\n        // For detials, see https://lib.ballerina.io/ballerina/jwt/latest#ValidatorSignatureConfig.\n        signatureConfig: {\n            certFile: \"../resource/path/to/public.crt\"\n        }\n    };\n\n    // Validates the created JWT.\n    jwt:Payload payload = check jwt:validate(jwt, validatorConfig);\n    io:println(\"Validated JWT Payload: \", payload.toString());\n}\n"
  },
  {
    "path": "examples/security-jwt-issue-validate/security_jwt_issue_validate.md",
    "content": "# JWT issue/validate\n\nThis example demonstrates how to issue a self-signed JWT and validate a JWT.\n\nFor more information on the underlying module, see the [`jwt` module](https://lib.ballerina.io/ballerina/jwt/latest/).\n\n>**Tip:** You may need to change the certificate file path, private key file path, and trusted certificate file path in the code below.\n\n::: code security_jwt_issue_validate.bal :::\n\nRun the program by executing command below.\n\n::: out security_jwt_issue_validate.out :::\n"
  },
  {
    "path": "examples/security-jwt-issue-validate/security_jwt_issue_validate.metatags",
    "content": "description: BBE on how to issue and validate a JSON Web Token (JWT) in Ballerina.\nkeywords: ballerina, ballerina by example, jwt, jwt issuer, jwt validator\n"
  },
  {
    "path": "examples/security-jwt-issue-validate/security_jwt_issue_validate.out",
    "content": "$ bal run security_jwt_issue_validate.bal\nIssued JWT: eyJhbGciOiJSUzI1NiIsICJ0eXAiOiJKV1QiLCAia2lkIjoiTlRBeFptTXhORE15WkR\n            nM01UVTFaR00wTXpFek9ESmhaV0k0TkRObFpEVTFPR0ZrTmpGaU1RIn0.eyJpc3MiOi\n            JiYWxsZXJpbmEiLCAic3ViIjoiYWRtaW4iLCAiYXVkIjoidkV3emJjYXNKVlFtMWpWW\n            UhVSENqaHhaNHRZYSIsICJqdGkiOiI1NWEwYjc1NC04OTVmLTQyNzktODg0My1iNzQ1\n            ZTExYTU3ZTkiLCAiZXhwIjoxNjExMTI3MDIzLCAibmJmIjoxNjExMTIzNDIzLCAiaWF\n            0IjoxNjExMTIzNDIzfQ.DMJDjJEFiQN7d_2CXGfXX_UR8Fi7Witr3aVGm4K7amEm3xN\n            cbh1bZmKO2ir-oP2_ikoM1_ETO7i4E4LKJHNAEdhqj8YHyKpbszaEq5zouMOtdFcI7i\n            TS8LyYDnyLEQQ6sa9L9NoMz3xULeF8epk0eaN1vVA-ijndVkZlMjaXJNf9Bgzn2qJOd\n            sQ6F0GeC4WKEt-xcEY5C2_haEDotSOYhUzEqh6D1fRtrGy7GaH5gzx99n-xjn8NZbTD\n            F0VnD6c1kJPe25FiPz24l9KdaCE1i2WbuzEhZWMclHW5RcTXVkLLkjQ4DvxfE-riGmK\n            qPN1gatWViZQF_VGBK-G7rEhi9Q\nValidated JWT Payload: {\"iss\":\"ballerina\",\"sub\":\"admin\",\n                        \"aud\":\"vEwzbcasJVQm1jVYHUHCjhxZ4tYa\",\n                        \"jti\":\"55a0b754-895f-4279-8843-b745e11a57e9\",\n                        \"exp\":1611127023,\"nbf\":1611123423,\"iat\":1611123423}\n"
  },
  {
    "path": "examples/security-jwt-issue-validate/tests/security_jwt_issue_validate_test.bal",
    "content": "import ballerina/test;\n\nstring[] outputs = [];\n\n// This is the mock function which will replace the real function\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any... val) {\n    outputs.push(val.reduce(function (any a, any b) returns string => a.toString() + b.toString(), \"\").toString());\n}\n\n@test:Config {}\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invokes the main function.\n    check main();\n    test:assertEquals(outputs.length(), 2);\n    test:assertTrue(outputs[0].includes(\"Issued JWT: eyJhbGciOiJSUzI1NiIsICJ0eXAiOiJKV1QiLCAia2\" +\n        \"lkIjoiTlRBeFptTXhORE15WkRnM01UVTFaR00wTXpFek9ESmhaV0k0TkRObFpEVTFPR0ZrTmpGaU1RIn0.\"));\n    test:assertTrue(outputs[1].includes(\"Validated JWT Payload: {\\\"iss\\\":\\\"wso2\\\",\\\"sub\\\":\" +\n        \"\\\"ballerina\\\",\\\"aud\\\":\\\"vEwzbcasJVQm1jVYHUHCjhxZ4tYa\\\",\"));\n}\n"
  },
  {
    "path": "examples/send-email/send_email.bal",
    "content": "import ballerina/email;\n\npublic function main() returns error? {\n    // Creates an SMTP client with the connection parameters, host, username, and password. \n    // The default port number `465` is used over SSL with these configurations. `SmtpConfig` can \n    // be configured and passed to this client if the port or security is to be customized.\n    email:SmtpClient smtpClient = check new (\"smtp.email.com\", \"sender@email.com\" , \"pass123\");\n\n    // Defines the email that is required to be sent.\n    email:Message email = {\n        // \"TO\", \"CC\", and \"BCC\" addresses can be added as follows.\n        // Only the \"TO\" address is mandatory out of these three.\n        to: \"receiver1@email.com\",\n        cc: \"receiver2@email.com\",\n        bcc: \"receiver3@email.com\",\n        // Subject of the email is added as follows. This field is mandatory.\n        subject: \"Sample Email\",\n        // Body content (text) of the email is added as follows. This field is optional.\n        body: \"This is a sample email.\"\n    };\n\n    // Sends the email message with the client. The `send` method can be used instead if the \n    // email is required to be sent with mandatory and optional parameters instead of \n    // configuring an `email:Message` record.\n    check smtpClient->sendMessage(email);\n}\n"
  },
  {
    "path": "examples/send-email/send_email.md",
    "content": "# Email client - Send email\n\nThe `email:SmtpClient` connects to a given SMTP server to send emails. An `email:SmtpClient` is created by providing the hostname and required credentials.  Once connected, the `sendMessage` or the `send` methods are used to send emails. An `email:Message` record, which contains the required information about the email can be passed to the `sendMessage` method. If additional information is not required, the `send` method can be used only with mandatory parameters such as `to`, `from`, `subject`, and `body`.\n\n::: code send_email.bal :::\n\n## Prerequisites\n- SMTP server should be up and running.\n\nRun the SMTP client by executing the following command.\n\n::: out send_email.out :::\n\n## Related links\n- [`email:SmtpClient` client object - API documentation](https://lib.ballerina.io/ballerina/email/latest#SmtpClient)\n- [`email:Message` record - API documentation](https://lib.ballerina.io/ballerina/email/latest#Message)\n- [SMTP client - Specification](https://ballerina.io/spec/email/#31-smtp-client)\n"
  },
  {
    "path": "examples/send-email/send_email.metatags",
    "content": "description: This BBE is about sending emails.\nkeywords: ballerina, ballerina by example, bbe, email, SMTP\n"
  },
  {
    "path": "examples/send-email/send_email.out",
    "content": "$ bal run send_email.bal\n\n# Check the inbox to view the sent emails.\n"
  },
  {
    "path": "examples/sensitive-data-logging/sensitive_data_logging.bal",
    "content": "import ballerina/log;\n\n// Custom masking function\nisolated function maskString(string input) returns string {\n    if input.length() <= 2 {\n        return \"****\";\n    }\n    return input.substring(0, 1) + \"****\" + input.substring(input.length() - 1);\n}\n\n// User record with sensitive data annotations\ntype User record {\n    string id;\n    @log:Sensitive\n    string password;\n    @log:Sensitive {\n        strategy: {\n            replacement: \"****\"\n        }\n    }\n    string creditCard;\n    @log:Sensitive {\n        strategy: {\n            replacement: maskString\n        }\n    }\n    string ssn;\n    string name;\n};\n\npublic function main() returns error? {\n    // Create user with sensitive information\n    User user = {\n        id: \"U001\",\n        password: \"mypassword\",\n        creditCard: \"4111-1111-1111-1234\",\n        ssn: \"123-45-6789\",\n        name: \"John Doe\"\n    };\n\n    // Log user details - sensitive fields will be masked automatically\n    log:printInfo(\"User details\", user = user);\n}\n"
  },
  {
    "path": "examples/sensitive-data-logging/sensitive_data_logging.md",
    "content": "# Sensitive data logging\n\nThis example demonstrates how to mask sensitive data in log messages using the `@log:Sensitive` annotation. The Ballerina log module provides built-in capabilities to protect personally identifiable information (PII) and other sensitive data from being exposed in logs. By default, sensitive data masking is disabled and **must be enabled** in the configuration file.\n\n::: code Config.toml :::\n\nThere are three masking strategies available:\n1. **Exclude strategy (default)**: The sensitive field is completely excluded from log output.\n2. **Fixed replacement**: The sensitive field is replaced with a fixed string (e.g., \"****\").\n3. **Custom function replacement**: A custom function is used to mask the sensitive field.\n\n::: code sensitive_data_logging.bal :::\n\nRun the example:\n\n::: out sensitive_data_logging.out :::\n\n## Related links\n- [`log` module - Specification](https://ballerina.io/spec/log/#5-sensitive-data-masking)\n- [`log` module - API documentation](https://lib.ballerina.io/ballerina/log/latest)\n"
  },
  {
    "path": "examples/sensitive-data-logging/sensitive_data_logging.metatags",
    "content": "description: BBE on how to mask sensitive data in logs using @log:Sensitive annotation with different masking strategies.\nkeywords: ballerina, ballerina by examples, bbe, log, sensitive data, masking, exclude, replace, PII, security\n"
  },
  {
    "path": "examples/sensitive-data-logging/sensitive_data_logging.out",
    "content": "$ bal run sensitive_data_logging.bal\n\ntime=2025-10-07T15:32:20.226+05:30 level=INFO module=\"\" message=\"User details\" user={\"id\":\"U001\",\"creditCard\":\"****\",\"ssn\":\"1****9\",\"name\":\"John Doe\"}\n"
  },
  {
    "path": "examples/sequence-diagrams/sequence_diagrams.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\n\n// A function can be viewed as a sequence diagram.\n// The diagram has a lifeline (vertical line) for each worker (both named worker and function's default worker).\npublic function main() returns error? {\n    // The diagram also has a lifeline for each client object parameter or variable in \n    // the initialization section, representing the remote system to which the client object is sending messages.\n    http:Client cl = check new (\"https://run.mocky.io\");\n\n    // Each remote method call on a client object is represented as a horizontal line\n    // between the lifeline of the worker making the call and the remote system.\n    string payload = check cl->get(\"/v3/55cf043f-f5d4-4005-af3c-cce4a955afc7/\");\n\n    io:println(payload);\n    return;\n}\n"
  },
  {
    "path": "examples/sequence-diagrams/sequence_diagrams.md",
    "content": "# Sequence diagrams\n\nA function can be viewed as a sequence diagram as shown below.\n\n![Sequence diagrams](/learn/by-example/images/sequence-diagram.png \"Sequence Diagram\")\n\nThe diagram has a lifeline (vertical line) for each worker (both named worker and function's default worker). The diagram also has a lifeline for each client object parameter or variable in the initialization section, representing the remote system to which the client object is sending messages. Each remote method call on a client object is represented as a horizontal line between the lifeline of the worker making the call and the remote system.\n\n::: code sequence_diagrams.bal :::\n\n::: out sequence_diagrams.out :::"
  },
  {
    "path": "examples/sequence-diagrams/sequence_diagrams.metatags",
    "content": "description: This BBE demonstrates Ballerina's sequence diagrams\nkeywords: ballerina, ballerina by example, bbe, sequence diagram, diagram\n"
  },
  {
    "path": "examples/sequence-diagrams/sequence_diagrams.out",
    "content": "$ bal run sequence_diagrams.bal\nHello World\n"
  },
  {
    "path": "examples/service-declaration/service_declaration.bal",
    "content": "import ballerina/io;\nimport ballerina/udp;\n\n// You can combine a listener declaration with a service declaration as shown in this example.\nservice on new udp:Listener(8080) {\n    remote function onDatagram(readonly & udp:Datagram dg) {\n        io:println(\"bytes received: \", dg.data.length());\n    }\n}\n"
  },
  {
    "path": "examples/service-declaration/service_declaration.client.out",
    "content": "$ nc -u localhost 8080\nHello, Ballerina\n"
  },
  {
    "path": "examples/service-declaration/service_declaration.md",
    "content": "# Service declaration\n\nA service represents a collection of remotely accessible methods attached to a particular listener. A service declaration is syntactic sugar for creating services in Ballerina.  A service declaration gets desugared into several things including creating a listener object, registering it with the module, creating a service object, attaching the service object to the listener object, etc,.\n\nThe type of the listener determines required type of remote methods.\n\n::: code service_declaration.bal :::\n\nRun the service using the `bal run` command.\n\n::: out service_declaration.server.out :::\n\nUse the following Netcat (or nc) command to send packets to the service.\n\n::: out service_declaration.client.out :::"
  },
  {
    "path": "examples/service-declaration/service_declaration.metatags",
    "content": "description: This BBE demonstrates how to write a service in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, service, UDP, service declaration, providing services\n"
  },
  {
    "path": "examples/service-declaration/service_declaration.server.out",
    "content": "$ bal run service_declaration.bal\nbytes received: 17\n"
  },
  {
    "path": "examples/sftp-client-receive-file/sftp_client_receive_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates the client with the connection parameters, host, username, and\n    // password. An error is returned in a failure. The default port number\n    // `22` for SSH is used with these configurations.\n    ftp:Client fileClient = check new ({\n        protocol: ftp:SFTP,\n        host: \"sftp.example.com\",\n        port: 22,\n        auth: {\n            credentials: {\n                username: \"user1\",\n                password: \"pass456\"\n            },\n            // Private key file location and its password (if encrypted) is\n            // given corresponding to the SSH key file used in the SFTP client.\n            privateKey: {\n                path: \"../resource/path/to/private.key\",\n                password: \"keyPass123\"\n            }\n        }\n    });\n\n    // Reads a file from a FTP server for a given file path. In error cases,\n    // an error is returned.\n    stream<byte[] & readonly, io:Error?> fileStream = check fileClient->get(\"/server/logFile.txt\");\n\n    // Write the content to a file.\n    check io:fileWriteBlocksFromStream(\"./local/newLogFile.txt\", fileStream);\n\n    // Closes the file stream to finish the `get` operation.\n    check fileStream.close();\n}\n"
  },
  {
    "path": "examples/sftp-client-receive-file/sftp_client_receive_file.md",
    "content": "# SFTP client - Receive file\n\nThe `ftp:Client` connects to a given SFTP server, and then sends and receives files as byte streams. An `ftp:Client` with SFTP protocol is created by giving the protocol, host-name and required credentials and the private key. Once connected, `get` method is used to read files as byte streams from the SFTP server. Use this to transfer files from a remote file system to a local file system.\n\n::: code sftp_client_receive_file.bal :::\n\n## Prerequisites\n- Start a [SFTP server](https://hub.docker.com/r/atmoz/sftp/) instance.\n- Run the SFTP client given in the [SFTP client - Send file](/learn/by-example/sftp-client-send-file) example to put a file in the SFTP server.\n\nRun the program by executing the following command. The newly-added file will appear in the local directory.\n\n::: out sftp_client_receive_file.out :::\n\n## Related links\n- [`ftp:Client->get` method  - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Client#get)\n- [SFTP client - Specification](/spec/ftp/#322-secure-client)\n"
  },
  {
    "path": "examples/sftp-client-receive-file/sftp_client_receive_file.metatags",
    "content": "description: This example demonstrates getting file content from a remote SFTP server.\nkeywords: ballerina, ballerina by example, bbe, SFTP, FTP security\n"
  },
  {
    "path": "examples/sftp-client-receive-file/sftp_client_receive_file.out",
    "content": "$ bal run sftp_client.bal\n"
  },
  {
    "path": "examples/sftp-client-send-file/sftp_client_send_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates the client with the connection parameters, host, username, and\n    // password. An error is returned in a failure. The default port number\n    // `22` for SSH is used with these configurations.\n    ftp:Client fileClient = check new ({\n        protocol: ftp:SFTP,\n        host: \"sftp.example.com\",\n        port: 22,\n        auth: {\n            credentials: {\n                username: \"user1\",\n                password: \"pass456\"\n            },\n            // Private key file location and its password (if encrypted) is\n            // given corresponding to the SSH key file used in the SFTP client.\n            privateKey: {\n                path: \"../resource/path/to/private.key\",\n                password: \"keyPass123\"\n            }\n        }\n    });\n\n    // Add a new file to the given file location. In error cases,\n    // an error is returned. The local file is provided as a stream of\n    // `io:Block` in which 1024 is the block size.\n    stream<io:Block, io:Error?> fileStream\n        = check io:fileReadBlocksAsStream(\"./local/logFile.txt\", 1024);\n    check fileClient->put(\"/server/logFile.txt\", fileStream);\n    check fileStream.close();\n}\n"
  },
  {
    "path": "examples/sftp-client-send-file/sftp_client_send_file.md",
    "content": "# SFTP client - Send file\n\nThe `ftp:Client` connects to a given SFTP server, and then sends and receives files as byte streams. A `ftp:Client` with SFTP protocol is created by giving the protocol, host-name, required credentials and the private key. Once connected, `put` method is used to write files as byte streams to the SFTP server. Use this to transfer files from a local file system to a remote file system.\n\n::: code sftp_client_send_file.bal :::\n\n## Prerequisites\n- Start a [SFTP server](https://hub.docker.com/r/atmoz/sftp/) instance.\n\nRun the program by executing the following command. The newly-added file will appear in the SFTP server.\n\n::: out sftp_client_send_file.out :::\n\n## Related links\n- [`ftp:Client->put` method  - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Client#put)\n- [SFTP client - Specification](/spec/ftp/#322-secure-client)\n"
  },
  {
    "path": "examples/sftp-client-send-file/sftp_client_send_file.metatags",
    "content": "description: This example demonstrates putting file content on a remote SFTP server.\nkeywords: ballerina, ballerina by example, bbe, SFTP, FTP security\n"
  },
  {
    "path": "examples/sftp-client-send-file/sftp_client_send_file.out",
    "content": "$ bal run sftp_client.bal\n"
  },
  {
    "path": "examples/sftp-service-receive-file/sftp_service_receive_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\n// Creates the listener with the connection parameters and the protocol-related\n// configuration. The listener listens to the files\n// with the given file name pattern located in the specified path.\nlistener ftp:Listener fileListener = new ({\n    protocol: ftp:SFTP,\n    host: \"sftp.example.com\",\n    auth: {\n        credentials: {\n            username: \"user1\",\n            password: \"pass456\"\n        },\n        privateKey: {\n            path: \"../resource/path/to/private.key\",\n            password: \"keyPass123\"\n        }\n    },\n    port: 22,\n    path: \"/home/in\",\n    fileNamePattern: \"(.*).txt\"\n});\n\n// One or many services can listen to the SFTP listener for the\n// periodically-polled file related events.\nservice on fileListener {\n\n    // When a file event is successfully received, the `onFileChange` method is called.\n    remote function onFileChange(ftp:WatchEvent & readonly event, ftp:Caller caller) returns error? {\n        // `addedFiles` contains the paths of the newly-added files/directories\n        // after the last polling was called.\n        foreach ftp:FileInfo addedFile in event.addedFiles {\n            // Get the newly added file from the SFTP server as a `byte[]` stream.\n            stream<byte[] & readonly, io:Error?> fileStream = check caller->get(addedFile.pathDecoded);\n\n            // Write the content to a file.\n            check io:fileWriteBlocksFromStream(string `./local/${addedFile.name}`, fileStream);\n            check fileStream.close();\n        }\n    }\n}\n"
  },
  {
    "path": "examples/sftp-service-receive-file/sftp_service_receive_file.md",
    "content": "# SFTP service - Receive file\n\nThe `ftp:Service` connects to a given SFTP server via the `ftp:Listener`. A `ftp:Listener` with SFTP protocol is created by providing the protocol, host-name, required credentials, and the private key. Once connected, service starts receiving events every time a file is deleted or added to the server. To take action for these events `ftp:Caller` is used. The `ftp:Caller` can be specified as a parameter of `onFileChange` remote method. The `ftp:Caller` allows interacting with the server via `get`, `append`, `delete`, etc remote methods. Use this to listen to file changes occurring in a remote file system and take action for those changes.\n\n::: code sftp_service_receive_file.bal :::\n\n## Prerequisites\n- Start a [SFTP server](https://hub.docker.com/r/atmoz/sftp/) instance.\n\nRun the program by executing the following command. Each newly added file in the SFTP server will be saved in the local file system.\n\n::: out sftp_service_receive_file.out :::\n\n>**Tip:** Run the SFTP client given in the [SFTP client - Send file](/learn/by-example/sftp-client-send-file) example to put a file in the SFTP server.\n\n## Related links\n- [`ftp:Listener` client object - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Listener)\n- [SFTP service - Specification](/spec/ftp/#422-secure-listener)\n"
  },
  {
    "path": "examples/sftp-service-receive-file/sftp_service_receive_file.metatags",
    "content": "description: This example demonstrates receiving file/directory changes that occur in a remote SFTP server and using an ftp:Caller to read the contents of the newly added files.\nkeywords: ballerina, ballerina by example, bbe, SFTP, remote file, listener, FTP security\n"
  },
  {
    "path": "examples/sftp-service-receive-file/sftp_service_receive_file.out",
    "content": "$ bal run sftp_service_read.bal\n"
  },
  {
    "path": "examples/sftp-service-send-file/sftp_service_send_file.bal",
    "content": "import ballerina/ftp;\nimport ballerina/io;\n\n// Creates the listener with the connection parameters and the protocol-related\n// configuration. The listener listens to the files\n// with the given file name pattern located in the specified path.\nlistener ftp:Listener fileListener = new ({\n    protocol: ftp:SFTP,\n    host: \"sftp.example.com\",\n    auth: {\n        credentials: {\n            username: \"user1\",\n            password: \"pass456\"\n        },\n        privateKey: {\n            path: \"../resource/path/to/private.key\",\n            password: \"keyPass123\"\n        }\n    },\n    port: 22,\n    path: \"/home/in\",\n    fileNamePattern: \"(.*).txt\"\n});\n\n// One or many services can listen to the SFTP listener for the\n// periodically-polled file related events.\nservice on fileListener {\n\n    // When a file event is successfully received, the `onFileChange` method is called.\n    remote function onFileChange(ftp:WatchEvent event, ftp:Caller caller) returns error? {\n        // `addedFiles` contains the paths of the newly-added files/directories\n        // after the last polling was called.\n        foreach ftp:FileInfo addedFile in event.addedFiles {\n            // The `ftp:Caller` can be used to append another file to the added files in the server.\n            stream<io:Block, io:Error?> fileStream = check io:fileReadBlocksAsStream(\"./local/appendFile.txt\", 7);\n            check caller->append(addedFile.pathDecoded, fileStream);\n            check fileStream.close();\n        }\n    }\n}\n"
  },
  {
    "path": "examples/sftp-service-send-file/sftp_service_send_file.md",
    "content": "# SFTP service - Send file\n\nThe `ftp:Service` connects to a given SFTP server via the `ftp:Listener`. Once connected, service starts receiving events every time a file is deleted or added to the server. To take action for these events `ftp:Caller` is used. The `ftp:Caller` can be specified as a parameter of `onFileChange` remote method. The `ftp:Caller` allows interacting with the server via `get`, `append`, `delete`, etc remote methods. Use this to listen to file changes occurring in a remote file system and take action for those changes.\n\n::: code sftp_service_send_file.bal :::\n\n## Prerequisites\n- Start a [SFTP server](https://hub.docker.com/r/atmoz/sftp/) instance.\n\nRun the program by executing the following command. Each newly added file in the SFTP server will be appended with the content in the appending file.\n\n::: out sftp_service_send_file.out :::\n\n>**Tip:** Run the SFTP client given in the [SFTP client - Send file](/learn/by-example/sftp-client-send-file) example to put a file in the SFTP server.\n\n## Related links\n- [`ftp:Caller` client object - API documentation](https://lib.ballerina.io/ballerina/ftp/latest#Caller)\n- [`ftp:Caller` functions - Specification](/spec/ftp/#52-functions)\n"
  },
  {
    "path": "examples/sftp-service-send-file/sftp_service_send_file.metatags",
    "content": "description: This example demonstrates receiving file/directory changes that occur in a remote SFTP server and using an ftp:Caller to append a file to the newly added files.\nkeywords: ballerina, ballerina by example, bbe, SFTP, remote file, listener, FTP security\n"
  },
  {
    "path": "examples/sftp-service-send-file/sftp_service_send_file.out",
    "content": "$ bal run sftp_service_read_write.bal\n"
  },
  {
    "path": "examples/single-use-of-typed-binding/single_use_of_typed_binding.bal",
    "content": "import ballerina/io;\n\ntype Person record {\n    int id;\n    string fname;\n    string lname;\n};\n\npublic function main() {\n    // A typed list binding followed by `=` in which the values of the list members are bound to\n    // the `name` and `age` variables in the binding.\n    [string, int] [name, age] = getPersonInfo();\n    io:println(name, \" \", age);\n\n    // The same can be written using `var`.\n    var [personName, personAge] = getPersonInfo();\n    io:println(personName, \" \", personAge);\n\n    // Other binding patterns can also be used as such.\n    // Here, a typed mapping binding is followed by `=` in which the values of the record fields\n    // are bound to the `id`, `fname`, and `lname` variables of the binding.\n    Person {id, fname, lname} = getPerson();\n    io:println(id, \" \", fname, \" \", lname);\n}\n\nfunction getPersonInfo() returns [string, int] {\n    return [\"John\", 30];\n}\n\nfunction getPerson() returns Person {\n    return {id: 1001, fname: \"Anne\", lname: \"Frank\"};\n}\n"
  },
  {
    "path": "examples/single-use-of-typed-binding/single_use_of_typed_binding.md",
    "content": "# Single use of typed binding patterns\n\nThe single use of typed binding patterns is usually followed by an `=` operator.\n\n::: code single_use_of_typed_binding.bal :::\n\n::: out single_use_of_typed_binding.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Single use with on fail clause](/learn/by-example/single-use-with-on-fail-clause/)\n- [Iterative use of typed binding patterns](/learn/by-example/iterative-use-of-typed-binding/)\n"
  },
  {
    "path": "examples/single-use-of-typed-binding/single_use_of_typed_binding.metatags",
    "content": "description: This BBE demonstrates the single use of typed binding patterns, single use of list binding, single use of mapping binding, single use of error binding, typed binding followed by `=`, list binding followed by `=`, mapping binding followed by `=`, and error binding followed by `=`.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, typed binding, single use, list binding, mapping binding, error binding\n"
  },
  {
    "path": "examples/single-use-of-typed-binding/single_use_of_typed_binding.out",
    "content": "$ bal run single_use_of_typed_binding.bal\nJohn 30\nJohn 30\n1001 Anne Frank\n"
  },
  {
    "path": "examples/single-use-with-on-fail-clause/single_use_with_on_fail_clause.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n   do {\n       _ = check int:fromString(\"Hello\");\n       // A typed capture binding pattern is used with an `on fail` clause.\n       // It matches the associated error value in the clause and binds the value\n       // to the `err` variable.\n   } on fail error err {\n       io:println(err.message());\n   }\n}\n"
  },
  {
    "path": "examples/single-use-with-on-fail-clause/single_use_with_on_fail_clause.md",
    "content": "# Single use of typed binding patterns with `on fail` clause\n\nThe only exception where the single use is not followed by an `=` operator is when it is used with an `on fail` clause.\n\n::: code single_use_with_on_fail_clause.bal :::\n\n::: out single_use_with_on_fail_clause.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Typed binding pattern](/learn/by-example/typed-binding-pattern/)\n- [Single use of typed binding patterns](/learn/by-example/single-use-of-typed-binding/)\n- [Iterative use of typed binding patterns](/learn/by-example/iterative-use-of-typed-binding/)\n"
  },
  {
    "path": "examples/single-use-with-on-fail-clause/single_use_with_on_fail_clause.metatags",
    "content": "description: This BBE demonstrates the single use of typed binding patterns, single use of typed binding with the `on fail` clause, and use of capture binding with the `on fail` clause.\nkeywords: ballerina, ballerina by example, bbe, binding pattern, typed binding, single use, on fail\n"
  },
  {
    "path": "examples/single-use-with-on-fail-clause/single_use_with_on_fail_clause.out",
    "content": "$ bal run single_use_with_on_fail_clause.bal\n{ballerina/lang.int}NumberParsingError\n"
  },
  {
    "path": "examples/singleton-types/singleton_types.bal",
    "content": "import ballerina/io;\n\n// The `SwitchStatus` type is a union type of two singleton types\n// defined using string literals, which are simple constant expressions.\ntype SwitchStatus \"on\"|\"off\";\n\n// The `shouldToggleSwitch` function has two parameters of the `SwitchStatus` type,\n// restricting the arguments to be either \"on\" or \"off\". Trying to pass as an argument \n// a value that cannot be guaranteed to be either \"on\" or \"off\"  will result\n// in a compile-time error.\nfunction shouldToggleSwitch(SwitchStatus currentStatus, SwitchStatus newStatus) \n        returns boolean {\n    return currentStatus != newStatus;\n}\n\n// The type of the `STATUS_OFF` constant is the singleton type containing only \n// the \"off\" value.\nconst STATUS_OFF = \"off\";\n\n// The type of the `DEFAULT_CONFIG` constant is the singleton type containing only \n// an immutable mapping value with exactly two fields: a `name` field with the value \n// \"default\" and a `status` field with the value \"off\".\nconst DEFAULT_CONFIG = {\n    name: \"default\",\n    status: STATUS_OFF\n};\n\npublic function main() {\n    // The `shouldToggleSwitch` function can be called only with \"on\" or \"off\" as arguments.\n    boolean b1 = shouldToggleSwitch(\"on\", \"off\");\n    io:println(b1);\n\n    // The type of `arg1` is the singleton type containing only the \"off\" value.\n    \"off\" arg1 = \"off\";\n\n    // A constant can be used as a singleton type.\n    // The type of `arg2` is also the singleton type containing only the \"off\" value.\n    // On the left-hand side, `STATUS_OFF` is used as a type.\n    // On the right-hand side, `STATUS_OFF` is used as a value.\n    STATUS_OFF arg2 = STATUS_OFF;\n\n    boolean b2 = shouldToggleSwitch(arg1, arg2);\n    io:println(b2);\n\n    // An immutable mapping value that has exactly the same fields as the\n    // `DEFAULT_CONFIG` constant.\n    map<json> & readonly mv1 = {\n        name: \"default\",\n        status: \"off\"\n    };\n\n    // An immutable mapping value that is not the same as the `DEFAULT_CONFIG`\n    // value since it has \"on\" as the value for the `status` field.\n    map<json> & readonly mv2 = {\n        name: \"default\",\n        status: \"on\"\n    };\n\n    // The `DEFAULT_CONFIG` constant is used as a type in the `is` check.\n    // Since it is a singleton type, the `is` check will evaluate to true\n    // only for an immutable value that has exactly the same fields.\n    io:println(mv1 is DEFAULT_CONFIG);\n    io:println(mv2 is DEFAULT_CONFIG);\n}\n"
  },
  {
    "path": "examples/singleton-types/singleton_types.md",
    "content": "# Singleton types\n\nA singleton type is a type that contains exactly one value. A singleton type is described using a compile-time constant expression. \n\nWhen the simple constant expression is a variable reference to a structured value, the value will be an immutable value. Therefore, a mutable value will not belong to any singleton type.\n\nUnions of singletons enable the definition of more refined types, constraining the value space to include exactly the allowed values, and thereby, removing the need for explicit validation.\n\nThe type of a constant is a singleton type and a constant can be used as a singleton type. Enumerations are shorthand for unions of\nstring constants, and therefore, the members of an enumeration can also be used as singleton types.\n\n::: code singleton_types.bal :::\n\n::: out singleton_types.out :::\n\n## Related links\n- [Constants](/learn/by-example/const-and-final/)\n- [Enumerations](/learn/by-example/enumerations/)\n- [Immutability](/learn/by-example/immutability/)\n"
  },
  {
    "path": "examples/singleton-types/singleton_types.metatags",
    "content": "description: This BBE demonstrates singleton types in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, singletons, singleton types\n"
  },
  {
    "path": "examples/singleton-types/singleton_types.out",
    "content": "$ bal run singleton_types.bal\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "examples/soap-client-security-inbound-security-config/soap_client_security_inbound_security_config.bal",
    "content": "import ballerina/soap.soap12;\nimport ballerina/crypto;\n\npublic function main() returns error? {\n    crypto:KeyStore keyStore = {\n        path: \"/path/to/keyStore.p12\",\n        password: \"keyStorePassword\"\n    };\n    crypto:KeyStore decryptionKeyStore = {\n        path: \"/path/to/keyStore.p12\",\n        password: \"keyStorePassword\"\n    };\n\n    soap12:Client soapClient = check new (\"http://soap-endpoint.com?wsdl\",\n        {\n            inboundSecurity: {\n                signatureKeystore: keyStore,\n                decryptKeystore: decryptionKeyStore\n            }\n        }\n    );\n    xml body = xml `<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\n                        <soap:Body></soap:Body>\n                    </soap:Envelope>`;\n\n    check soapClient->sendOnly(body);\n}\n"
  },
  {
    "path": "examples/soap-client-security-inbound-security-config/soap_client_security_inbound_security_config.md",
    "content": "# SOAP client security - Inbound security configuration\n\nThe `soap` client can be configured to apply inbound security settings when a request is made. These configurations include various web service security policies such as `Username Token`, `Timestamp Token`, `X509 Token`, `Symmetric Binding`, `Asymmetric Binding`, and `Transport Binding`. These configurations can be implemented individually or in combination with one another. After applying the security configuration, the required security tags will be included under the `<soap:Header>` tag within the SOAP envelope.\n\n::: code soap_client_security_inbound_security_config.bal :::\n\nRun the program by executing the following command.\n\n::: out soap_client_security_inbound_security_config.out :::\n\n## Related links\n\n- [`soap` module - API documentation](https://central.ballerina.io/ballerina/soap/)\n- [SOAP client security inbound security configuration - Specification](/spec/soap/#321-inbound-security-configurations)\n"
  },
  {
    "path": "examples/soap-client-security-inbound-security-config/soap_client_security_inbound_security_config.metatags",
    "content": "description: This example demonstrates applying inbound security configurations for SOAP envelopes when the request is made.\nkeywords: ballerina, ballerina by example, soap, client, security, inbound security\n"
  },
  {
    "path": "examples/soap-client-security-inbound-security-config/soap_client_security_inbound_security_config.out",
    "content": "$ bal run soap_client_security_inbound_security_config.bal\n"
  },
  {
    "path": "examples/soap-client-security-outbound-security-config/soap_client_security_outbound_security_config.bal",
    "content": "import ballerina/crypto;\nimport ballerina/soap.soap12;\n\npublic function main() returns error? {\n    crypto:KeyStore keyStore = {\n        path: \"/path/to/keyStore.p12\",\n        password: \"keyStorePassword\"\n    };\n    crypto:KeyStore decryptionKeyStore = {\n        path: \"/path/to/decryptionKeyStore.p12\",\n        password: \"keyStorePassword\"\n    };\n\n    soap12:Client soapClient = check new (\"http://soap-endpoint.com?wsdl\",\n        {\n            outboundSecurity: {\n                signatureConfig: {\n                    keystore: keyStore,\n                    privateKeyAlias: \"private-key-alias\",\n                    privateKeyPassword: \"private-key-password\"\n                },\n                encryptionConfig: {\n                    keystore: decryptionKeyStore,\n                    publicKeyAlias: \"public-key-alias\"\n                }\n            }\n        }\n    );\n    xml body = xml `<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\n                        <soap:Body></soap:Body>\n                    </soap:Envelope>`;\n    check soapClient->sendOnly(body);\n}\n"
  },
  {
    "path": "examples/soap-client-security-outbound-security-config/soap_client_security_outbound_security_config.md",
    "content": "# SOAP client security - Outbound security configuration\n\nThe `soap` client can be configured to apply outbound security configurations for decrypting the data in the SOAP response, and verifying the digital signature for security validation. The configurations can be set by passing `soap:OutboundSecurityConfig` to the `outboundSecurity` field of the client.\n\n::: code soap_client_security_outbound_security_config.bal :::\n\nRun the program by executing the following command.\n\n::: out soap_client_security_outbound_security_config.out :::\n\n## Related links\n\n- [`soap` module - API documentation](https://central.ballerina.io/ballerina/soap/)\n- [SOAP client security outbound security configuration - Specification](/spec/soap/#322-outbound-security-configurations)\n"
  },
  {
    "path": "examples/soap-client-security-outbound-security-config/soap_client_security_outbound_security_config.metatags",
    "content": "description: This example demonstrates applying outbound security configurations to decrypt and verify signatures in SOAP responses.\nkeywords: ballerina, ballerina by example, soap, client, security, outbound security\n"
  },
  {
    "path": "examples/soap-client-security-outbound-security-config/soap_client_security_outbound_security_config.out",
    "content": "$ bal run soap_client_security_outbound_security_config.bal\n"
  },
  {
    "path": "examples/soap-client-security-ssl-tsl/soap_client_security_ssl_tls.bal",
    "content": "import ballerina/soap.soap12;\n\npublic function main() returns error? {\n    soap12:Client soapClient = check new (\"https://soap-endpoint.com?wsdl\",\n        {\n            httpConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        }\n    );\n\n    xml body = xml `<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">\n                        <soap:Body></soap:Body>\n                    </soap:Envelope>`;\n    check soapClient->sendOnly(body);\n}\n"
  },
  {
    "path": "examples/soap-client-security-ssl-tsl/soap_client_security_ssl_tls.md",
    "content": "# SOAP client security - SSL/TLS\n\nThe `soap` client can be configured to apply HTTP security configurations using the `httpConfig` parameter. SSL certificate can be applied using the `secureSocket` field to establish an HTTPS connection between the client and the server. The SOAP client supports all client security configurations supported by the HTTP client.\n\n::: code soap_client_security_ssl_tls.bal :::\n\nRun the program by executing the following command.\n\n::: out soap_client_security_ssl_tls.out :::\n\n## Related links\n\n- [`soap` module - API documentation](https://central.ballerina.io/ballerina/soap/)\n- [HTTP client security - Specification](https://ballerina.io/spec/http/#2411-security)\n- [`soap` - Specification](/spec/soap)\n"
  },
  {
    "path": "examples/soap-client-security-ssl-tsl/soap_client_security_ssl_tls.metatags",
    "content": "description: This example demonstrates applying HTTP security configurations for a Ballerina SOAP client.\nkeywords: ballerina, ballerina by example, soap, http, client, security, ssl, tls\n"
  },
  {
    "path": "examples/soap-client-security-ssl-tsl/soap_client_security_ssl_tls.out",
    "content": "$ bal run soap_client_security_ssl_tls.bal\n"
  },
  {
    "path": "examples/soap-client-send-receive/soap_client_send_receive.bal",
    "content": "import ballerina/io;\nimport ballerina/soap.soap12;\n\nxmlns \"http://tempuri.org/\" as quer;\n\npublic function main() returns error? {\n    int additionA = 37;\n    int additionB = 73;\n\n    // The SOAP 1.2 client connects to a live SOAP endpoint \n    // that executes basic arithmetic operations\n    soap12:Client soapClient = check new (\"http://www.dneonline.com/calculator.asmx?WSDL\");\n\n    // The SOAP envelope is constructed including necessary numerical values \n    // for the addition operation.\n    xml body = xml `<soap:Envelope\n                        xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"\n                        soap:encodingStyle=\"http://www.w3.org/2003/05/soap-encoding\">\n                        <soap:Body>\n                        <quer:Add xmlns:quer=\"http://tempuri.org/\">\n                            <quer:intA>${additionA}</quer:intA>\n                            <quer:intB>${additionB}</quer:intB>\n                        </quer:Add>\n                        </soap:Body>\n                    </soap:Envelope>`;\n\n    // `sendOnly()` fires and forgets a request.\n    check soapClient->sendOnly(body, \"http://tempuri.org/Add\");\n\n    // `sendReceive()` sends a request to a SOAP endpoint\n    // and receives the response in `xml` or `mime:Entity[]` format.\n    xml response = check soapClient->sendReceive(body, \"http://tempuri.org/Add\");\n    xml result = response/**/<quer:AddResult>/*;\n    io:println(string `Sum: ${additionA} + ${additionB} = `, result);\n}\n"
  },
  {
    "path": "examples/soap-client-send-receive/soap_client_send_receive.md",
    "content": "# SOAP client - Send/Receive\n\nThe `soap` module provides APIs to connect to a SOAP endpoint that supports SOAP 1.1 or 1.2 versions. Users can specify the version when importing the `soap` module. The `sendReceive()` API will send a request to a SOAP endpoint and bind the response to one of the `xml` or `mime:Entity[]` data types determined by the user. The `sendOnly()` API will fire and forget a SOAP request.\n\n::: code soap_client_send_receive.bal :::\n\nRun the program by executing the following command.\n\n::: out soap_client_send_receive.out :::\n\n## Related links\n\n- [`soap` module - API documentation](https://central.ballerina.io/ballerina/soap/)\n- [`soap` Client - Specification](/spec/soap/#21-client)\n"
  },
  {
    "path": "examples/soap-client-send-receive/soap_client_send_receive.metatags",
    "content": "description: This example demonstrates connecting and interacting with a SOAP endpoint via a Ballerina SOAP client.\nkeywords: ballerina, ballerina by example, soap, client\n"
  },
  {
    "path": "examples/soap-client-send-receive/soap_client_send_receive.out",
    "content": "$ bal run soap_client_send_receive.bal\nSum: 37 + 73 = 110\n"
  },
  {
    "path": "examples/sort-iterable-objects/sort_iterable_objects.bal",
    "content": "import ballerina/io;\n\ntype Employee record {\n    string firstName;\n    string lastName;\n    decimal salary;\n};\n\npublic function main() {\n    Employee[] employees = [\n        {firstName: \"Jones\", lastName: \"Welsh\", salary: 1000.00},\n        {firstName: \"Anne\", lastName: \"Frank\", salary: 5000.00},\n        {firstName: \"Rocky\", lastName: \"Irving\", salary: 6000.00},\n        {firstName: \"Anne\", lastName: \"Perera\", salary: 3000.00},\n        {firstName: \"Jermaine\", lastName: \"Perera\", salary: 4000.00},\n        {firstName: \"Rocky\", lastName: \"Puckett\", salary: 6000.00},\n        {firstName: \"Jermaine\", lastName: \"Kent\", salary: 4000.00}\n    ];\n\n    Employee[] sorted = from var e in employees\n                        // The `order by` clause sorts the output items based on the given \n                        // `order-key` and the `order-direction`.\n                        // The `order-key` must be an ordered type.\n                        // The `order-direction` is `ascending` if not specified explicitly.\n                        order by e.firstName ascending, e.lastName descending\n                        select e;\n\n    foreach Employee e in sorted {\n        io:println(e.firstName, \" \", e.lastName);\n    }\n}\n"
  },
  {
    "path": "examples/sort-iterable-objects/sort_iterable_objects.md",
    "content": "# Sort iterable objects\n\nThe `order by` clause in the query expression can be used to sort the elements in a collection. Ordering works consistently with the `<`, `<=`, `>`, `>=` operators. Some comparisons involving `()` and float `NaN` are considered unordered. Therefore, if these unordered types are encountered in the query, they will be returned as the last elements of the ordered collection.\n\nThe syntax to write an `order by` clause is `order by expression orderDirection`. The order direction can be `ascending` or `descending`.\n\n::: code sort_iterable_objects.bal :::\n\n::: out sort_iterable_objects.out :::\n\n## Related links\n- [Query expressions](/learn/by-example/query-expressions)\n- [Let clause in query expression](/learn/by-example/let-clause)\n- [Limit clause in query expression](/learn/by-example/limit-clause)\n- [Joining iterable objects using query](/learn/by-example/joining-iterable-objects)\n- [Querying tables](/learn/by-example/querying-tables)\n- [Create maps with query expression](/learn/by-example/create-maps-with-query)\n- [Create tables with query expression](/learn/by-example/create-tables-with-query)\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [On conflict clause in query expression](/learn/by-example/on-conflict-clause)\n- [Nested query expressions](/learn/by-example/nested-query-expressions)\n"
  },
  {
    "path": "examples/sort-iterable-objects/sort_iterable_objects.metatags",
    "content": "description: This BBE demonstrates ordering in Ballerina, sorting iterable objects, sorting a table, and sorting a list, result, or a collection.\nkeywords: ballerina, ballerina by example, bbe, order by clause, query, query expression, order, sort, ascending, descending, collection\n"
  },
  {
    "path": "examples/sort-iterable-objects/sort_iterable_objects.out",
    "content": "$ bal run sort_iterable_objects.bal\nAnne Perera\nAnne Frank\nJermaine Perera\nJermaine Kent\nJones Welsh\nRocky Puckett\nRocky Irving\n"
  },
  {
    "path": "examples/start-service-from-service-class-definition/start_service_from_service_class_definition.bal",
    "content": "import ballerina/http;\nimport ballerina/lang.runtime;\n\npublic type Album readonly & record {|\n    string title;\n    string artist;\n|};\n\n// The listener object is attached to the `albumService`.\n// It receives inputs from the specified port 9090 and invokes the remote methods.\nhttp:Listener httpListener = check new (9090);\n\npublic service class Service {\n    *http:Service;\n\n    table<Album> key(title) albums = table [\n            {title: \"Blue Train\", artist: \"John Coltrane\"},\n            {title: \"Jeru\", artist: \"Gerry Mulligan\"}\n        ];\n\n    resource function get albums() returns Album[] {\n        return self.albums.toArray();\n    }\n\n    resource function post albums(Album album) {\n        self.albums.add(album);\n    }\n}\n\npublic function main() returns error? {\n    // Create an HTTP service.\n    http:Service albumService = new Service();\n    // Attach the service to the listener along with the resource path.\n    check httpListener.attach(albumService);\n    // Start the listener.\n    check httpListener.'start();\n    // Register the listener dynamically.\n    runtime:registerListener(httpListener);\n}\n"
  },
  {
    "path": "examples/start-service-from-service-class-definition/start_service_from_service_class_definition.client.out",
    "content": "$ curl http://localhost:9090/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}]\n\n$ curl http://localhost:9090/albums -H \"Content-type:application/json\" -d \"{\\\"title\\\": \\\"Sarah Vaughan and Clifford Brown\\\", \\\"artist\\\": \\\"Sarah Vaughan\\\"}\" \n$ curl http://localhost:9090/albums\n[{\"title\":\"Blue Train\", \"artist\":\"John Coltrane\"}, {\"title\":\"Jeru\", \"artist\":\"Gerry Mulligan\"}, {\"title\":\"Sarah Vaughan and Clifford Brown\", \"artist\":\"Sarah Vaughan\"}]\n"
  },
  {
    "path": "examples/start-service-from-service-class-definition/start_service_from_service_class_definition.md",
    "content": "# Start service from service class definition\n\nThe `service` keyword is used with the class definition to define a service class. A service object can be constructed from a service class. A service object supports network interaction with a remote system that is originated by the remote system. They are a special kind of object that contain `remote` and `resource` methods in addition to regular methods.\n\nThe `Listener` object receives network input and makes calls to remote methods of attached service objects. \nThe example below demonstrates how to start the service from its class definition.\n\n::: code start_service_from_service_class_definition.bal :::\n\nRun the service as follows.\n\n::: out start_service_from_service_class_definition.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal.\n\n::: out start_service_from_service_class_definition.client.out :::\n\n## Related links\n- [Dynamic listener](/learn/by-example/dynamic-listener/)\n- [Object type inclusion](/learn/by-example/object-type-inclusion/)\n- [Client class](/learn/by-example/client-class/)\n"
  },
  {
    "path": "examples/start-service-from-service-class-definition/start_service_from_service_class_definition.metatags",
    "content": "description: This BBE demonstrates creating a listener object, starting a service from the service class definition, and attaching a listener to a service object in Ballerina. \nkeywords: ballerina, ballerina by example, bbe, service class, listener, runtime, object type inclusion\n"
  },
  {
    "path": "examples/start-service-from-service-class-definition/start_service_from_service_class_definition.server.out",
    "content": "$ bal run start_service_from_service_class_definition.bal\n"
  },
  {
    "path": "examples/stop-handler/stop_handler.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/lang.runtime;\n\nstring[] fruitBasket = [\"Apple\", \"Orange\"];\n\nfunction init() {\n    io:println(\"initial items in fruit basket: \" + fruitBasket.toString());\n\n    // Registers a function that will be called during the graceful shutdown.\n    runtime:onGracefulStop(clearBasket);\n}\n\npublic function clearBasket() returns error? {\n    // Remove all elements from the array.\n    fruitBasket.removeAll();\n    io:println(\"after removing all fruit items: \" + fruitBasket.toString());\n}\n\nservice / on new http:Listener(9090) {\n    \n    resource function post addToBasket(@http:Payload string fruit) \n            returns string[] {\n\n        // Add an element to the array.\n        fruitBasket.push(fruit);\n        io:println(\"after adding a fruit item: \" + fruitBasket.toString());\n        return fruitBasket;\n    }\n}\n"
  },
  {
    "path": "examples/stop-handler/stop_handler.client.out",
    "content": "$ curl http://localhost:9090/addToBasket -d 'Guava'\n[\"Apple\", \"Orange\", \"Guava\"]\n"
  },
  {
    "path": "examples/stop-handler/stop_handler.md",
    "content": "# `StopHandler`\n\nA `StopHandler` is a function that is registered at runtime with a module and invoked during graceful shutdown.\nThis example demonstrates how to register a `StopHandler` that will be executed at the end of the program.\n\n::: code stop_handler.bal :::\n\nNavigate to the directory that contains the 'stop_handler.bal' file, and run the 'bal run' command.\n\n::: out stop_handler.server.out :::\n\nInvoke the service by executing the following cURL command in a new terminal to add a fruit item.\n\n::: out stop_handler.client.out :::\n"
  },
  {
    "path": "examples/stop-handler/stop_handler.metatags",
    "content": "description: Registering a function that will be executed during the graceful shutdown.\nkeywords: ballerina, ballerina by example, stop handler, bbe, service\n"
  },
  {
    "path": "examples/stop-handler/stop_handler.server.out",
    "content": "$ bal run stop_handler.bal\ninitial items in fruit basket: [\"Apple\",\"Orange\"]\n\n# Invoke the service using cURL command as mentioned below in a new terminal.\nafter adding a fruit item: [\"Apple\",\"Orange\",\"Guava\"]\n\n# Send the interrupt signal SIGINT (Ctrl+C) to terminate the current process.\nafter removing all fruit items: []\n"
  },
  {
    "path": "examples/strands/strands.bal",
    "content": "import ballerina/io;\n\nfunction userSpeakerService(string userName) {\n    string messagePrefix = userName + \" speaking : \";\n    foreach int i in 0...9 {\n       io:println(messagePrefix, i);\n    }\n}\n\npublic function main() {\n\n    io:println(\"In function worker\");\n\n    // By default, named workers are multitasked cooperatively, not preemptively.\n    // Each named worker has a strand (a logical thread of control) and\n    // the execution switches between strands only at specific `yield` points.\n    worker A {\n        io:println(\"In worker A\");\n        userSpeakerService(\"Worker A\");\n        io:println(\"Worker A end\");\n    }\n\n    worker B {\n        io:println(\"In worker B\");\n        future<()> _ = start userSpeakerService(\"Worker B\");\n        io:println(\"Worker B end\");\n    }\n\n    // Explicitly wait for named workers to complete.\n    // This guarantees that the Ballerina program will not terminate till \n    // the workers have completed their execution.\n    wait A;\n    wait B;\n}\n"
  },
  {
    "path": "examples/strands/strands.md",
    "content": "# Strands\n\nBy default, named workers are multitasked cooperatively, not preemptively. Each named worker has a \"strand\" (logical thread of control) and execution switches between strands only at specific \"yield\" points such as doing a wait or when a library function invokes a system call that would block.\n\n::: code strands.bal :::\n\n::: out strands.out :::"
  },
  {
    "path": "examples/strands/strands.metatags",
    "content": "description: This BBE demonstrates Ballerina strands\nkeywords: ballerina, ballerina by example, bbe, strands, concurrency\n"
  },
  {
    "path": "examples/strands/strands.out",
    "content": "$ bal run strands.bal\nIn function worker\nIn worker B\nWorker B end\nIn worker A\nWorker A speaking : 0\nWorker A speaking : 1\nWorker B speaking : 0\nWorker A speaking : 2\nWorker A speaking : 3\nWorker A speaking : 4\nWorker B speaking : 1\nWorker A speaking : 5\nWorker B speaking : 2\nWorker B speaking : 3\nWorker A speaking : 6\nWorker B speaking : 4\nWorker A speaking : 7\nWorker B speaking : 5\nWorker A speaking : 8\nWorker B speaking : 6\nWorker A speaking : 9\nWorker B speaking : 7\nWorker A end\nWorker B speaking : 8\nWorker B speaking : 9\n"
  },
  {
    "path": "examples/stream-type/stream_type.bal",
    "content": "import ballerina/io;\n\n// Defines a class called `EvenNumberGenerator`, which implements the `next()` method.\n// This will be invoked when the `next()` method of the stream gets invoked.\nclass EvenNumberGenerator {\n    int i = 0;\n    public isolated function next() returns record {|int value;|}|error? {\n        self.i += 2;\n        return {value: self.i};\n    }\n}\n\npublic function main() {\n    EvenNumberGenerator evenGen = new ();\n\n    // Creates a `stream` passing an `EvenNumberGenerator` object to the `stream` constructor.\n    stream<int, error?> evenNumberStream = new (evenGen);\n\n    var evenNumber = evenNumberStream.next();\n\n    if (evenNumber !is error?) {\n        io:println(\"Retrieved even number: \", evenNumber.value);\n    }\n}\n"
  },
  {
    "path": "examples/stream-type/stream_type.md",
    "content": "# Stream type\n\nA stream represents a sequence of values that are generated as needed. The end of a stream is indicated with a termination value, which is error or nil. The type `stream<T,E>` is a stream of which the members of the sequence are of the type `T`, and the termination value is type `E`. `stream<T>` means `stream<T,()>`.\n\nThe stream type is a separate basic type, However like an object, it can be initialized with a `new` expression by passing an object, which implements the `next() returns record{| T value; |}|C` method where `C` is either `()`, `error` or `error?`.\n\n::: code stream_type.bal :::\n\n::: out stream_type.out :::\n\n## Related links\n- [Create streams with query expression](/learn/by-example/create-streams-with-query)\n- [Querying with streams](/learn/by-example/querying-with-streams)\n"
  },
  {
    "path": "examples/stream-type/stream_type.metatags",
    "content": "description: This BBE demonstrates the `stream` type in Ballerina, creating a stream of values, loading values lazily, and saving resources by loading values when needed.\nkeywords: ballerina, ballerina by example, bbe, stream type, streams, lazy, value, next\n"
  },
  {
    "path": "examples/stream-type/stream_type.out",
    "content": "$ bal run stream_type.bal\nRetrieved even number: 2\n"
  },
  {
    "path": "examples/string-templates/string_templates.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    string word = \"world\";\n    string s0 = string `Hello, ${word}!`;\n    io:println(s0);\n\n    // Use interpolations to use escape characters.\n    // Note how the first `\\n` is treated as is.\n    string s1 = string `line one \\n rest of line 1 ${\"\\n\"} second line`;\n    io:println(s1);\n\n    // Use interpolations to add the ` and  $ characters.\n    string s2 = string `Backtick: ${\"`\"} Dollar: ${\"$\"}`;\n    io:println(s2);\n\n    // A string template expression can be written on multiple lines by breaking at interpolations.\n    string s3 = string `T_1 is ${\n                1}, T_2 is ${1 +\n                2} and T_3 is ${1 + 2 + 3\n                }`;\n    io:println(s3);\n\n    // If there are no interpolations to break at a required point, you can introduce an interpolation with an empty\n    // string.\n    string s4 = string `prefix ${\n                \"\"}middle ${\"\"\n                }suffix`;\n    io:println(s4);\n}\n"
  },
  {
    "path": "examples/string-templates/string_templates.md",
    "content": "# String templates\n\nA string template is a template expression that can be used to create a string literal. It consists of the `string` tag and a sequence of characters interleaved with interpolations (in the form `${expression}`). Each interpolation must be a subtype of `boolean|int|float|decimal|string`. Every character not a part of the interpolation is interpreted as is to form a sequence of string literals broken at interpolations. This means if you want to add any escape characters you must add them as interpolations (for example `${\"\\n\"}`). Every interpolation is converted to a string using the `toString` lang lib function and concatenated with the other string literals to form a single string literal.\n\n::: code string_templates.bal :::\n\n::: out string_templates.out :::\n"
  },
  {
    "path": "examples/string-templates/string_templates.metatags",
    "content": "description: This BBE demonstrates string templates in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, string templates\n"
  },
  {
    "path": "examples/string-templates/string_templates.out",
    "content": "$ bal run string_templates.bal\nHello, world!\nline one \\n rest of line 1 \n second line\nBacktick: ` Dollar: $\nT_1 is 1, T_2 is 3 and T_3 is 6\nprefix middle suffix\n"
  },
  {
    "path": "examples/strings/strings.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // String literals use double quotes. You can use usual C escapes such as `\\t \\n`.\n    // Numeric escapes specify Unicode code point using one or more hex digits `\\u{H}`.\n    string grin = \"\\u{1F600}\";\n\n    // String concatenation uses `+` operator.\n    string greeting = \"Hello\" + grin;\n    io:println(greeting);\n\n    // `greeting[1]` accesses character at index 1 (zero-based).\n    io:println(greeting[1]);\n}\n"
  },
  {
    "path": "examples/strings/strings.md",
    "content": "# Strings\n\nThe `string` type represents immutable sequence of zero or more Unicode characters.  There is no separate character type: a character is represented by a `string` of length 1.\n\nTwo `string` values are `==` if both sequences have the same characters. You can use `<`, `<=`, `>`, and `>=` operators on `string` values and they work by comparing code points. Unpaired surrogates are not allowed.\n\n::: code strings.bal :::\n\n::: out strings.out :::"
  },
  {
    "path": "examples/strings/strings.metatags",
    "content": "description: This BBE introduces the string type in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, string, unicode, utf-8, char\n"
  },
  {
    "path": "examples/strings/strings.out",
    "content": "$ bal run strings.bal\nHello😀\ne\n"
  },
  {
    "path": "examples/structural-typing/structural_typing.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // 1 belongs to `int`.\n    io:println(1 is int);\n    // [10, 20, 30] belongs to `int[]`.\n    io:println([10, 20, 30] is int[]);\n}\n"
  },
  {
    "path": "examples/structural-typing/structural_typing.md",
    "content": "# Structural typing\n\nTyping in Ballerina is structural: a type describes a set of values. Ballerina has semantic subtyping: subtype means subset. Universe of values is partitioned into basic types. Each value belongs to exactly one basic type. You can think of each value as being tagged with its basic type.\n\nThere is a complexity in making structural typing work with mutation. \n\n- Immutable basic types (so far): `nil`, `boolean`, `int`, `float`, `string` \n- Mutable basic types (so far): `array`, `map`, and `record`\n\n::: code structural_typing.bal :::\n\n::: out structural_typing.out :::"
  },
  {
    "path": "examples/structural-typing/structural_typing.metatags",
    "content": "description: This BBE demonstrates structural typing in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, structural typing, types\n"
  },
  {
    "path": "examples/structural-typing/structural_typing.out",
    "content": "$ bal run structural_typing.bal\ntrue\ntrue\n"
  },
  {
    "path": "examples/structured-keys/structured_keys.bal",
    "content": "import ballerina/io;\n\ntype Employee record {\n    readonly record {\n        string first;\n        string last;\n    } name;\n    int salary;\n};\n\npublic function main() {\n    //In the key field, the `name` is of the `record` type.\n    table<Employee> key(name) t = table [\n            {name: {first: \"John\", last: \"Smith\"}, salary: 100},\n            {name: {first: \"Fred\", last: \"Bloggs\"}, salary: 200}\n        ];\n\n    Employee? e = t[{first: \"Fred\", last: \"Bloggs\"}];\n    io:println(e);\n\n    record {|string first; string last;|} n = {first: \"Sam\", last: \"Smith\"};\n    // Make the key immutable using `cloneReadOnly()`.\n    t.add({name: n.cloneReadOnly(), salary: 23});\n    io:println(t);\n}\n"
  },
  {
    "path": "examples/structured-keys/structured_keys.md",
    "content": "# Structured keys\n\nKey fields can be structured types as long as they belong to any subtype of plain data. Plain data is a simple value, a sequence value, or a structured value where all members are plain data. The value of the key field must be immutable. The initializer of the read-only field will be constructed as immutable. When using `add`/`put`, `cloneReadOnly()` can be used to create an immutable value.\n\n::: code structured_keys.bal :::\n\n::: out structured_keys.out :::\n\n## Related links\n- [Table](/learn/by-example/table-syntax/)\n- [Multiple key fields](/learn/by-example/multiple-key-fields/)\n- [Records](/learn/by-example/records/)\n"
  },
  {
    "path": "examples/structured-keys/structured_keys.metatags",
    "content": "description: This BBE demonstrates how to set a record as key in table, create record key table, make immutable clone.\nkeywords: ballerina, ballerina by example, bbe, structured keys, keys, table, map\n"
  },
  {
    "path": "examples/structured-keys/structured_keys.out",
    "content": "$ bal run structured_keys.bal\n{\"name\":{\"first\":\"Fred\",\"last\":\"Bloggs\"},\"salary\":200}\n[{\"name\":{\"first\":\"John\",\"last\":\"Smith\"},\"salary\":100},{\"name\":{\"first\":\"Fred\",\"last\":\"Bloggs\"},\"salary\":200},{\"name\":{\"first\":\"Sam\",\"last\":\"Smith\"},\"salary\":23}]\n"
  },
  {
    "path": "examples/synchronize-message-passing/synchronize_message_passing.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    worker A {\n        int msg = 10;\n\n        // Send a message synchronously to the `B` worker.\n        // The 'A' worker will wait until 'B' receives the message.\n        error? res = msg ->> B;\n        io:println(res ?: \"Transmission to B is successful\");\n\n        // This transmission will not happen because the previous tranmission returns an error`.\n        res = \"Hello\" ->> B;\n        io:println(res ?: \"Transmission to B is successful\");\n    }\n\n    worker B returns error? {\n        int value;\n\n        value = <- A;\n        io:println(string `Received ${value} from the A worker.`);\n\n        if value == 10 {\n            return error(\"Error in the B worker.\");\n        }\n\n        string text = <- A;\n        io:println(string `Received ${text} from the A worker.`);\n    }\n}\n"
  },
  {
    "path": "examples/synchronize-message-passing/synchronize_message_passing.md",
    "content": "# Synchronize message passing\n\nUse `->> W` to send a message synchronously to the `W` worker. These messages should be of the `anydata` type. Unlike asynchronous send, synchronous send will wait until the message is delivered. If the transmission fails with an `error` or a `panic`, then, the error will be propagated to the waiting strand. Otherwise, it will return `nil`.\n\n::: code synchronize_message_passing.bal :::\n\n::: out synchronize_message_passing.out :::\n"
  },
  {
    "path": "examples/synchronize-message-passing/synchronize_message_passing.metatags",
    "content": "description: This BBE demonstrates how the `sync send` action can be used for concurrency in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, sync send, concurrency, worker\n"
  },
  {
    "path": "examples/synchronize-message-passing/synchronize_message_passing.out",
    "content": "$ bal run sync_send.bal\nReceived 10 from the A worker.\nTransmission to B is successful\nerror(\"Error in the B worker.\")\n"
  },
  {
    "path": "examples/table/table.bal",
    "content": "import ballerina/io;\n \ntype Employee record {|\n   \t// The key must be read-only.\n   \treadonly string name;\n   \tint salary;\n|};\n \npublic function main() {\n   \t// Creates a `table` with members of the `Employee` type in which each\n   \t// member is uniquely identified using their `name` field.\n   \ttable<Employee> key(name) employees = table [\n   \t    { name: \"John\", salary: 100 },\n   \t    { name: \"Jane\", salary: 200 }\n   \t];\n\t\n   \t// Since the key is already available, the `put` method updates the entry with the new `salary`.\n   \t// If the key is not available, `put` will function the same as `add`.\n   \temployees.put({name: \"John\", salary: 320});\n   \tio:println(employees);\n\t\n   \t// As the key is not available, the `add` method appends the new entry.\n   \t// If the key is available, the operation results in a panic.\n   \temployees.add({name: \"Sam\", salary: 150});\n   \tio:println(employees);\n\t\n   \t// Retrieves the `Employee` member with `\"Fred\"` as the value of the key.\n   \tEmployee? e = employees[\"Fred\"];\n   \tio:println(e is ());\n\t\n   \t// Iterates over the rows of `employees` in the specified order.\n   \tforeach Employee employee in employees {\n   \t    employee.salary += 102;\n   \t}\n   \t_ = employees.remove(\"John\");\n\t\n   \tio:println(employees);\n}\n"
  },
  {
    "path": "examples/table/table.md",
    "content": "# Table\n\nThe table constructor expression looks like an array constructor. The `add` and `put` langlib functions can be used to update a table. The `put` method will update the table if there is an entry with a given key or add a new entry otherwise, while the `add` method will panic if there is an entry with the given key. The `foreach` statement will iterate over a table's rows in their order. Use `t[k]` to access a row using its key.\n\n::: code table.bal :::\n\n::: out table.out :::\n\n## Related links\n- [Maps](/learn/by-example/maps/)\n- [Structured keys](/learn/by-example/structured-keys/)\n- [Multiple key fields](/learn/by-example/multiple-key-fields/)\n- [Control openness](/learn/by-example/controlling-openness/)"
  },
  {
    "path": "examples/table/table.metatags",
    "content": "description: This BBE demonstrates how to create a table, create a table with a key, add entries to a table, update entries in a table, iterate over a table, get entries from a table, and create a table without a key in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, table syntax, table, map, key\n"
  },
  {
    "path": "examples/table/table.out",
    "content": "$ bal run table.bal\n[{\"name\":\"John\",\"salary\":320},{\"name\":\"Jane\",\"salary\":200}]\n[{\"name\":\"John\",\"salary\":320},{\"name\":\"Jane\",\"salary\":200},{\"name\":\"Sam\",\"salary\":150}]\ntrue\n[{\"name\":\"Jane\",\"salary\":302},{\"name\":\"Sam\",\"salary\":252}]\n"
  },
  {
    "path": "examples/table-types/table_types.bal",
    "content": "import ballerina/io;\n \ntype Employee record {|\n   \treadonly string name;\n   \tint salary;\n|};\n \npublic function main() {\n   \t// Creates a `table` with members of the `Employee` type in which each\n   \t// member is uniquely identified using their `name` field.\n   \ttable<Employee> key(name) t1 = table [\n   \t    { name: \"John\", salary: 100 },\n   \t    { name: \"Jane\", salary: 200 }\n   \t];\n   \tio:println(t1);\n\t\n   \t// A table can be declared without a key.\n   \ttable<Employee> t2 = table [\n   \t    { name: \"John\", salary: 100 },\n   \t    { name: \"Jane\", salary: 200 }\n   \t];\n   \tio:println(t2);\n\t\n   \t// A table can also be declared with a type parameter as the key type.\n   \ttable<Employee> key<string> t3 = table key(name) [\n   \t    { name: \"John\", salary: 100 },\n   \t    { name: \"Jane\", salary: 200 }\n   \t];\n   \tio:println(t3);\n}\n"
  },
  {
    "path": "examples/table-types/table_types.md",
    "content": "# Table types\n\nA `table` is a collection of records in which each record represents a row of the `table`. Each row of the `table` is uniquely identified by a key. This key must be immutable and each row’s key is stored in its fields.\nCompared to maps,\n- the key is part of the value rather than being separate.\n- the type of the key is not restricted to string.\n- the order of the members is preserved.\n\n::: code table_types.bal :::\n\n::: out table_types.out :::\n\n## Related links\n- [Table](/learn/by-example/table/)\n- [Structured keys](/learn/by-example/structured-keys/)\n- [Multiple key fields](/learn/by-example/multiple-key-fields/)"
  },
  {
    "path": "examples/table-types/table_types.metatags",
    "content": "description: This BBE demonstrates how to create a table with a key, create a table without a key, and create a table with a key as a type-descriptor in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, table, map, key\n"
  },
  {
    "path": "examples/table-types/table_types.out",
    "content": "$ bal run table_types.bal\n[{\"name\":\"John\",\"salary\":100},{\"name\":\"Jane\",\"salary\":200}]\n[{\"name\":\"John\",\"salary\":100},{\"name\":\"Jane\",\"salary\":200}]\n[{\"name\":\"John\",\"salary\":100},{\"name\":\"Jane\",\"salary\":200}]\n"
  },
  {
    "path": "examples/task-frequency-job-execution/task_frequency_job_execution.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.runtime;\nimport ballerina/task;\n\n// Creates a job to be executed by the scheduler.\nclass Job {\n\n    *task:Job;\n    int i = 1;\n\n    // Executes this function when the scheduled trigger fires.\n    public function execute() {\n        self.i += 1;\n        io:println(\"MyCounter: \", self.i);\n    }\n\n    isolated function init(int i) {\n        self.i = i;\n    }\n}\n\npublic function main() returns error? {\n\n    // Schedules the task to execute the job every second.\n    task:JobId id = check task:scheduleJobRecurByFrequency(new Job(0), 1);\n\n    // Waits for nine seconds.\n    runtime:sleep(9);\n\n    // Unschedules the job.\n    check task:unscheduleJob(id);\n}\n"
  },
  {
    "path": "examples/task-frequency-job-execution/task_frequency_job_execution.md",
    "content": "# Schedule job recurrence by frequency\n\nThe `task` library provides an API to schedule Ballerina jobs periodically.\n\nFor more information on the underlying module, see the [`task` module](https://lib.ballerina.io/ballerina/task/latest/).\n\n::: code task_frequency_job_execution.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out task_frequency_job_execution.out :::"
  },
  {
    "path": "examples/task-frequency-job-execution/task_frequency_job_execution.metatags",
    "content": "description: BBE on how to schedule the frequency job execution in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, task, job, scheduler\n"
  },
  {
    "path": "examples/task-frequency-job-execution/task_frequency_job_execution.out",
    "content": "$ bal run task_frequency_job_execution.bal\nMyCounter: 1\nMyCounter: 2\nMyCounter: 3\nMyCounter: 4\nMyCounter: 5\nMyCounter: 6\nMyCounter: 7\nMyCounter: 8\nMyCounter: 9\nMyCounter: 10\n"
  },
  {
    "path": "examples/task-one-time-job-execution/task_one_time_job_execution.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.runtime;\nimport ballerina/task;\nimport ballerina/time;\n\n// Creates a job to be executed by the scheduler.\nclass Job {\n\n    *task:Job;\n    int i = 1;\n\n    // Executes this function when the scheduled trigger fires.\n    public function execute() {\n        self.i += 1;\n        io:println(\"MyCounter: \", self.i);\n    }\n\n    isolated function init(int i) {\n        self.i = i;\n    }\n}\n\npublic function main() returns error? {\n    // Gets the current time.\n    time:Utc currentUtc = time:utcNow();\n    // Increases the time by three seconds to get the specified time for scheduling the job.\n    time:Utc newTime = time:utcAddSeconds(currentUtc, 3);\n    // Gets the `time:Civil` for the given time.\n    time:Civil time = time:utcToCivil(newTime);\n\n    // Schedules the one-time job at the specified time.\n    _ = check task:scheduleOneTimeJob(new Job(0), time);\n\n    // Waits for five seconds.\n    runtime:sleep(5);\n}\n"
  },
  {
    "path": "examples/task-one-time-job-execution/task_one_time_job_execution.md",
    "content": "# Schedule one time job\n\nThe `task` library provides an API to schedule Ballerina jobs at a specific time.\n\nFor more information on the underlying module, see the [`task` module](https://lib.ballerina.io/ballerina/task/latest/).\n\n::: code task_one_time_job_execution.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out task_one_time_job_execution.out :::"
  },
  {
    "path": "examples/task-one-time-job-execution/task_one_time_job_execution.metatags",
    "content": "description: BBE on how to schedule a one-time job execution in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, task, job, scheduler\n"
  },
  {
    "path": "examples/task-one-time-job-execution/task_one_time_job_execution.out",
    "content": "$ bal run task_one_time_job_execution.bal\nMyCounter: 1\n"
  },
  {
    "path": "examples/tcp-client/tcp_client.bal",
    "content": "import ballerina/io;\nimport ballerina/tcp;\n\npublic function main() returns error? {\n\n    // Create a new TCP client by providing the `remoteHost` and `remotePort`.\n    // Optionally, you can provide the interface that the socket needs to bind \n    // and the timeout in seconds, which specifies the read timeout value.\n    // tcp:Client client = check new (\"localhost\", 3000, localHost = \"localhost\", timeout = 5);\n    tcp:Client socketClient = check new (\"localhost\", 9090);\n\n    // Send the desired content to the server.\n    check socketClient->writeBytes(\"Hello Ballerina\".toBytes());\n\n    // Read the response from the server.\n    readonly & byte[] receivedData = check socketClient->readBytes();\n    io:println(\"Received: \", string:fromBytes(receivedData));\n\n    // Close the connection between the server and the client.\n    check socketClient->close();\n}\n"
  },
  {
    "path": "examples/tcp-client/tcp_client.md",
    "content": "# TCP client - Send/Receive bytes\n\nThe `tcp:Client` connects to a given TCP server socket, and then sends and receives byte streams. A `tcp:Client` is created by giving the IP and port number. Once connected, `writeBytes` and `readBytes` synchronous methods are used to send and receive byte streams. Since, they are synchronous methods often used in two different strands. Use this to interact with TCP servers or implement high level protocols based on TCP.\n\n::: code tcp_client.bal :::\n\n## Prerequisites\n- Run the TCP service given in the [Send/Receive bytes](/learn/by-example/tcp-listener/) example.\n\nRun the client program by executing the command below.\n\n::: out tcp_client.out :::\n\n## Related links\n- [`tcp:Client` client object - API documentation](https://lib.ballerina.io/ballerina/tcp/latest#Client)\n- [TCP Client - Specification](/spec/tcp/#4-client)\n- [Binary data](/learn/by-example/binary-data/)\n"
  },
  {
    "path": "examples/tcp-client/tcp_client.metatags",
    "content": "description: This Ballerina sample demonstrates how the TCP client interacts with the TCP listener service.\nkeywords: ballerina, ballerina by example, bbe, socket, tcp\n"
  },
  {
    "path": "examples/tcp-client/tcp_client.out",
    "content": "$ bal run tcp_client.bal\nReceived: Hello Ballerina\n"
  },
  {
    "path": "examples/tcp-client-ssl-tls/tcp_client_ssl_tls.bal",
    "content": "import ballerina/tcp;\n\npublic function main() returns error? {\n    // A TCP client can be configured to communicate through SSL/TLS as well.\n    // To secure a client using SSL/TLS, the client needs to be configured with\n    // a certificate file of the listener.\n    // The `tcp:ClientSecureSocket` record provides the\n    // SSL-related configurations of the client.\n    tcp:Client securedClientEP = check new (\"localhost\", 9090,\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check securedClientEP->writeBytes(\"Hello, World!\".toBytes());\n    check securedClientEP->close();\n}\n"
  },
  {
    "path": "examples/tcp-client-ssl-tls/tcp_client_ssl_tls.md",
    "content": "# TCP client - SSL/TLS \n\nThe `tcp:Client` secured with SSL/TLS connects to a given SSL/TLS-secured TCP server socket, and then sends and receives byte streams. A `tcp:Client` secured with SSL/TLS is created by additionally giving `secureSocket` configurations which require the server's certificate as the `cert`. Once connected, `writeBytes` and `readBytes` synchronous methods are used to send and receive byte streams over an encrypted TLS connection. Use this to interact with TCP servers or implement high-level protocols based on TLS-encrypted secured TCP connection.\n\n::: code tcp_client_ssl_tls.bal :::\n\n## Prerequisites\n- Run the TCP service given in the [SSL/TLS](/learn/by-example/tcp-service-ssl-tls/) example.\n\nRun the client program by executing the command below.\n\n::: out tcp_client_ssl_tls.out :::\n\n## Related links\n- [`tcp` module - API documentation](https://lib.ballerina.io/ballerina/tcp/latest)\n- [TCP SSL/TLS - Specification](/spec/tcp/#512-configuring-tls-in-client-side)\n\n"
  },
  {
    "path": "examples/tcp-client-ssl-tls/tcp_client_ssl_tls.metatags",
    "content": "description: BBE on how to secure TCP client with SSL.\nkeywords: ballerina, ballerina by example, bbe, ssl, tls, tcp client\n"
  },
  {
    "path": "examples/tcp-client-ssl-tls/tcp_client_ssl_tls.out",
    "content": "$ bal run tcp_client_ssl_tls.bal\n"
  },
  {
    "path": "examples/tcp-listener/tcp_listener.bal",
    "content": "import ballerina/io;\nimport ballerina/log;\nimport ballerina/tcp;\n\n// Bind the service to the port. \nservice on new tcp:Listener(9090) {\n\n    // This remote method is invoked when the new client connects to the server.\n    remote function onConnect(tcp:Caller caller) returns tcp:ConnectionService {\n        io:println(\"Client connected to echo server: \", caller.remotePort);\n        return new EchoService();\n    }\n}\n\nservice class EchoService {\n    *tcp:ConnectionService;\n\n    // This remote method is invoked once the content is received from the client.\n    remote function onBytes(tcp:Caller caller, readonly & byte[] data) returns tcp:Error? {\n        io:println(\"Echo: \", string:fromBytes(data));\n        // Echoes back the data to the client from which the data is received.\n        check caller->writeBytes(data);\n    }\n\n    // This remote method is invoked in an erroneous situation,\n    // which occurs during the execution of the `onConnect` or `onBytes` method.\n    remote function onError(tcp:Error err) {\n        log:printError(\"An error occurred\", 'error = err);\n    }\n\n    // This remote method is invoked when the connection is closed.\n    remote function onClose() {\n        io:println(\"Client left\");\n    }\n}\n"
  },
  {
    "path": "examples/tcp-listener/tcp_listener.md",
    "content": "# TCP service - Send/Receive bytes\n\nThe `tcp:Service` allows opening up a TCP socket via a `tcp:Listener`. A `tcp:Listener` is created by giving the port number, to which `tcp:Service` is attached. The listener accepts and serves connections from TCP clients. The `onBytes` remote method is invoked once the content is received from the client. The `onError` and `onClose` remote methods get invoked in an erroneous situation and when the connection is closed respectively. Use a TCP service to establish connections and communicate over TCP protocol or implement high level protocols based on TCP. \n\n::: code tcp_listener.bal :::\n\nRun the service by executing the command below.\n\n::: out tcp_listener.out :::\n\n>**Tip:** You can invoke the above service via the [TCP client](/learn/by-example/tcp-client/).\n\n## Related links\n- [`tcp` module - API documentation](https://lib.ballerina.io/ballerina/tcp/latest)\n- [TCP service  - Specification](/spec/tcp/#3-service-types)\n"
  },
  {
    "path": "examples/tcp-listener/tcp_listener.metatags",
    "content": "description: This Ballerina sample demonstrates how the TCP  listener service interacts with the TCP client.\nkeywords: ballerina, ballerina by example, bbe, socket, tcp\n"
  },
  {
    "path": "examples/tcp-listener/tcp_listener.out",
    "content": "$ bal run tcp_listener.bal\nClient connected to echoServer: 48735\nEcho: Hello Ballerina\nClient left\n"
  },
  {
    "path": "examples/tcp-service-ssl-tls/tcp_service_ssl_tls.bal",
    "content": "import ballerina/io;\nimport ballerina/tcp;\n\n// An TCP listener can be configured to communicate through SSL/TLS as well.\n// To secure a listener using SSL/TLS, the listener needs to be configured with\n// a certificate file and a private key file for the listener.\n// The `tcp:ListenerSecureSocket` record provides the\n// SSL-related listener configurations of the listener.\nlistener tcp:Listener securedEP = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\nservice \"tcp\" on securedEP {\n\n     remote function onConnect(tcp:Caller caller) returns tcp:ConnectionService {\n        io:println(\"Client connected on server port: \", caller.remotePort);\n        return new EchoService();\n    }\n}\n\nservice class EchoService {\n    *tcp:ConnectionService;\n\n    remote function onBytes(readonly & byte[] data) returns byte[] {\n        io:println(\"Received message: \", string:fromBytes(data));\n        return data;\n    }\n}\n"
  },
  {
    "path": "examples/tcp-service-ssl-tls/tcp_service_ssl_tls.md",
    "content": "# TCP service - SSL/TLS \n\nThe `tcp:Listener` configured with allows you to expose a connection secured with one-way SSL/TLS. A `tcp:Listener` secured with SSL/TLS is created by providing the `secureSocket` configurations which require the server's certificate as the `certFile` and the server's private key as the `keyFile`. Use this to interact with TCP clients or implement high-level protocols based on TLS-encrypted secured TCP connection.\n\n::: code tcp_service_ssl_tls.bal :::\n\nRun the service by executing the command below.\n\n::: out tcp_service_ssl_tls.out :::\n\n>**Tip:** You can invoke the above service via the [TCP SSL/TLS client](/learn/by-example/tcp-client-ssl-tls/).\n\n## Related links\n- [`tcp` module - API documentation](https://lib.ballerina.io/ballerina/tcp/latest)\n- [TCP SSL/TLS - Specification](/spec/tcp/#511-configuring-tls-in-server-side)\n"
  },
  {
    "path": "examples/tcp-service-ssl-tls/tcp_service_ssl_tls.metatags",
    "content": "description: BBE on how to secure TCP listener with SSL.\nkeywords: ballerina, ballerina by example, bbe, ssl, tls, tcp listener\n"
  },
  {
    "path": "examples/tcp-service-ssl-tls/tcp_service_ssl_tls.out",
    "content": "$ bal run tcp_service_ssl_tls.bal\nClient connected on server port: 5639\nReceived message: Hello, World!\n"
  },
  {
    "path": "examples/temp-files-directories/temp_files_directories.bal",
    "content": "import ballerina/file;\nimport ballerina/io;\n\npublic function main() returns error? {\n\n    // Creates a temporary directory in the default `tmp` directory of the OS.\n    string tmpDir = check file:createTempDir();\n    io:println(\"Absolute path of the tmp directory: \", tmpDir);\n\n    // Creates a temporary file in the default `tmp` directory of the OS.\n    string tmpResult = check file:createTemp();\n    io:println(\"Absolute path of the tmp file: \", tmpResult);\n\n    // Creates a temporary file in a specific directory.\n    string tmp2Result = check file:createTemp(dir = tmpDir);\n    io:println(\"Absolute path of the tmp file: \", tmp2Result);\n}\n"
  },
  {
    "path": "examples/temp-files-directories/temp_files_directories.md",
    "content": "# Temp files and directories\n\nThe `file` provides APIs to perform temp file and directory operations.\n\nFor more information on the underlying module, see the [`file` module](https://lib.ballerina.io/ballerina/file/latest/).\n\n::: code temp_files_directories.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out temp_files_directories.out :::"
  },
  {
    "path": "examples/temp-files-directories/temp_files_directories.metatags",
    "content": "description: This BBE shows how to perform file-system operations in Ballerina.\nkeywords: ballerina, ballerina by examples, BBE, file, path, temp\n"
  },
  {
    "path": "examples/temp-files-directories/temp_files_directories.out",
    "content": "$ bal run temp_files_directories.bal\nAbsolute path of the tmp directory: /var/folders/f2/1s2f2mzd30ldl_fzxk4_gq3c0000gn/T/90eb0a6f-200a-454d-9285-f3264a71cd80\nAbsolute path of the tmp file: /var/folders/f2/1s2f2mzd30ldl_fzxk4_gq3c0000gn/T/9b0ce907-51cd-4f6b-98f0-d99566e3870d\nAbsolute path of the tmp file: /var/folders/f2/1s2f2mzd30ldl_fzxk4_gq3c0000gn/T/90eb0a6f-200a-454d-9285-f3264a71cd80/14c45332-37df-44d1-b24b-3dbcb7c7404c\n"
  },
  {
    "path": "examples/testerina-assertions/testerina_assertions.bal",
    "content": "import ballerina/test;\n\n@test:Config { }\nfunction testAssertEquals() {\n    json a = {name:\"John Doe\", age:25, address:{city:\"Colombo\", \n    country:\"Sri Lanka\"}};\n    json b = {name:\"John Doe\", age:25, address:{city:\"Colombo\", \n    country:\"Sri Lanka\"}};\n    // Asserts two values for value equality using `assertEquals`.\n    test:assertEquals(a, b, msg = \"JSON values are not equal\");\n}\n\n@test:Config { }\nfunction testAssertNotEquals() {\n    string s1 = \"abc\";\n    string s2 = \"def\";\n    // Asserts two values for value inequality using `assertNotEquals`.\n    test:assertNotEquals(s1, s2, msg = \"String values are equal\");\n}\n\n@test:Config { }\nfunction testAssertTrue() {\n    boolean value = true;\n    // Asserts if the provided value is `true`.\n    test:assertTrue(value, msg = \"AssertTrue failed\");\n}\n\n@test:Config { }\nfunction testAssertFalse() {\n    boolean value = false;\n    // Asserts if the provided value is `false`.\n    test:assertFalse(value, msg = \"AssertFalse failed\");\n}\n\n@test:Config { }\nfunction testAssertFail() {\n    boolean flag = true;\n    if (flag) {\n        return;\n    }\n    // Intentionally, throws an `AssertionError`.\n    test:assertFail(msg = \"AssertFailed\");\n}\n\nclass Person {\n    public string name = \"\";\n    public int age = 0;\n    public Person? parent = ();\n    private string email = \"default@abc.com\";\n    string address = \"No 20, Palm grove\";\n}\n\n@test:Config { }\nfunction testAssertExactEquals() {\n    Person person1 = new;\n    Person person2 = person1;\n    // Compares the values for exact equality i.e. whether both refer to the same entity.\n    test:assertExactEquals(person1, person2,\n        msg = \"Objects are not exactly equal\");\n}\n\n@test:Config { }\nfunction testAssertNotExactEquals() {\n    Person person1 = new;\n    Person person2 = new;\n    // Compares the values for the negation of exact equality.\n    test:assertNotExactEquals(person1, person2,\n        msg = \"Objects are exactly equal\");\n}\n"
  },
  {
    "path": "examples/testerina-assertions/testerina_assertions.md",
    "content": "# Assertions\n\nTesterina has in-built assertions that enable you to assert an outcome against an expected outcome. This example illustrates how to use different assertions.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/write-tests/#use-assertions) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_assertions.bal :::\n\n::: out testerina_assertions.out :::\n"
  },
  {
    "path": "examples/testerina-assertions/testerina_assertions.metatags",
    "content": "description: BBE on how to use assertions for unit testing.\nkeywords: ballerina, programming language, testing, assertion\n"
  },
  {
    "path": "examples/testerina-assertions/testerina_assertions.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n    ballerinatest/test_module:0.1.0\n\n                [pass] testAssertEquals\n                [pass] testAssertExactEquals\n                [pass] testAssertFail\n                [pass] testAssertFalse\n                [pass] testAssertNotEquals\n                [pass] testAssertNotExactEquals\n                [pass] testAssertTrue\n\n                7 passing\n                0 failing\n                0 skipped\n\n"
  },
  {
    "path": "examples/testerina-before-and-after-each/testerina_before_and_after_each.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// The `BeforeEach` function is executed before each test function.\n@test:BeforeEach\nfunction beforeEachFunc() {\n    io:println(\"I'm the before each function!\");\n}\n\n// The `AfterEach` function is executed after each test function.\n@test:AfterEach\nfunction afterEachFunc() {\n    io:println(\"I'm the after each function!\");\n}\n\n// A test function.\n@test:Config { }\nfunction testFunction1() {\n    io:println(\"I'm in test function 1!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// Another test function.\n@test:Config { }\nfunction testFunction2() {\n    io:println(\"I'm in test function 2!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n"
  },
  {
    "path": "examples/testerina-before-and-after-each/testerina_before_and_after_each.md",
    "content": "# Before and after each\n\nThe function specified with the `BeforeEach` annotation is executed before every test and the function specified with the `AfterEach` annotation is executed after every test within the test suite. This can be used for repeatedly initializing and tearing down test level aspects before every test function.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/execute-tests/#understand-the-test-execution-behavior) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_before_and_after_each.bal :::\n\n::: out testerina_before_and_after_each.out :::\n"
  },
  {
    "path": "examples/testerina-before-and-after-each/testerina_before_and_after_each.metatags",
    "content": "description: BBE on how to use before and after each test configurations.\nkeywords: ballerina, programming language, testing, before each test, after each test\n"
  },
  {
    "path": "examples/testerina-before-and-after-each/testerina_before_and_after_each.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n        ballerinatest/test_module:0.1.0\nI'm the before each function!\nI'm in test function 1!\nI'm the after each function!\nI'm the before each function!\nI'm in test function 2!\nI'm the after each function!\n\n                [pass] testFunction1\n                [pass] testFunction2\n\n                2 passing\n                0 failing\n                0 skipped\n\n"
  },
  {
    "path": "examples/testerina-before-and-after-groups/testerina_before_and_after_groups.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// Executed before the first test function of the group `g1`.\n@test:BeforeGroups { value:[\"g1\"] }\nfunction beforeGroupsFunc() {\n    io:println(\"I'm the before groups function!\");\n}\n\n// Executed after the last test function of the group `g1`.\n@test:AfterGroups { value:[\"g1\"] }\nfunction afterGroupsFunc() {\n    io:println(\"I'm the after groups function!\");\n}\n\n// A test function belonging to the group `g1`.\n@test:Config { groups: [\"g1\"]}\nfunction testFunction1() {\n    io:println(\"I'm in test function 1!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// Another test function.\n@test:Config {}\nfunction testFunction2() {\n    io:println(\"I'm in test function 2!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n"
  },
  {
    "path": "examples/testerina-before-and-after-groups/testerina_before_and_after_groups.md",
    "content": "# Before and after groups\n\nThe function specified with the `BeforeGroups` annotation is executed once before all the tests belonging to the specified group is executed and the function specified with the `AfterGroups` annotation is executed once after all the tests belonging to the specified group is executed.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/execute-tests/#understand-the-test-execution-behavior) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_before_and_after_groups.bal :::\n\n::: out testerina_before_and_after_groups.out :::\n"
  },
  {
    "path": "examples/testerina-before-and-after-groups/testerina_before_and_after_groups.metatags",
    "content": "description: BBE on how to use before and after groups configurations.\nkeywords: ballerina, programming language, testing, before groups, after groups\n"
  },
  {
    "path": "examples/testerina-before-and-after-groups/testerina_before_and_after_groups.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n        ballerinatest/test_module:0.1.0\nI'm the before groups function!\nI'm in test function 1!\nI'm the after groups function!\nI'm in test function 2!\n\n\t[pass] testFunction1\n\t[pass] testFunction2\n\n\t2 passing\n\t0 failing\n\t0 skipped\n"
  },
  {
    "path": "examples/testerina-before-and-after-suite/testerina_before_and_after_suite.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// Executed before all the test functions in the module.\n@test:BeforeSuite\nfunction beforeSuit() {\n    io:println(\"I'm the before suite function!\");\n}\n\n// A Test function.\n@test:Config { }\nfunction testFunction1() {\n    io:println(\"I'm in test function 1!\");\n    test:assertTrue(true, msg = \"Failed\");\n}\n\n// A Test function.\n@test:Config { }\nfunction testFunction2() {\n    io:println(\"I'm in test function 2!\");\n    test:assertTrue(true, msg = \"Failed\");\n}\n\n// Executed after all the test functions in the module.\n@test:AfterSuite { }\nfunction afterSuite() {\n    io:println(\"I'm the after suite function!\");\n}\n"
  },
  {
    "path": "examples/testerina-before-and-after-suite/testerina_before_and_after_suite.md",
    "content": "# Before and after suite\n\nThe `BeforeSuite` annotation allows you to execute a function before executing a test suite. Similarly, the `AfterSuite` annotation can be used to execute a function after a test suite.\n\nA module is considered as a suite in the Test framework. These annotations can be used to set up prerequisites and post actions for a test suite.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/execute-tests/#understand-the-test-execution-behavior) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_before_and_after_suite.bal :::\n\n::: out testerina_before_and_after_suite.out :::\n"
  },
  {
    "path": "examples/testerina-before-and-after-suite/testerina_before_and_after_suite.metatags",
    "content": "description: BBE on how to use before and after suite configurations.\nkeywords: ballerina, programming language, testing, before suite, after suite\n"
  },
  {
    "path": "examples/testerina-before-and-after-suite/testerina_before_and_after_suite.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n        ballerinatest/test_module:0.1.0\nI'm the before suite function!\nI'm in test function 1!\nI'm in test function 2!\nI'm the after suite function!\n\n                [pass] testFunction1\n                [pass] testFunction2\n\n                2 passing\n                0 failing\n                0 skipped\n"
  },
  {
    "path": "examples/testerina-before-and-after-test/testerina_before_and_after_test.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// Executed before the `testFunction` function.\nfunction beforeFunc() {\n    io:println(\"I'm the before function!\");\n}\n\n// The Test function.\n// The `before` and `after` attributes are used to define the functions\n// that need to be executed before and after this test function.\n@test:Config {\n    before: beforeFunc,\n    after: afterFunc\n}\nfunction testFunction() {\n    io:println(\"I'm in test function!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// Executed after the `testFunction` function.\nfunction afterFunc() {\n    io:println(\"I'm the after function!\");\n}\n"
  },
  {
    "path": "examples/testerina-before-and-after-test/testerina_before_and_after_test.md",
    "content": "# Before and after test\n\nThe `before` attribute allows you to execute a function before a test function. Similarly, the `after` attribute can be used to execute a function after a test function.\n\nThese annotations can be used to set up the prerequisites and post actions for a test case.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/execute-tests/#understand-the-test-execution-behavior) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_before_and_after_test.bal :::\n\n::: out testerina_before_and_after_test.out :::\n"
  },
  {
    "path": "examples/testerina-before-and-after-test/testerina_before_and_after_test.metatags",
    "content": "description: BBE on how to use before and after test configurations.\nkeywords: ballerina, programming language, testing, before test, after test\n"
  },
  {
    "path": "examples/testerina-before-and-after-test/testerina_before_and_after_test.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n    ballerinatest/test_module:0.1.0\nI'm the before function!\nI'm in test function!\nI'm the after function!\n\n        [pass] testFunction\n\n        1 passing\n        0 failing\n        0 skipped\n"
  },
  {
    "path": "examples/testerina-data-driven-tests/testerina_data_driven_tests.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// The `dataProvider` attribute is used to specify a data-provider function for the test.\n@test:Config {\n    dataProvider: stringDataProvider\n}\n// Data is passed to the function as function parameters.\nfunction testAddingValues(string fValue, string sValue, string result) returns error? {\n    int value1 = check 'int:fromString(fValue);\n    int value2 = check 'int:fromString(sValue);\n    int result1 = check 'int:fromString(result);\n    io:println(\"Input : [\" + fValue + \",\" + sValue + \",\" + result + \"]\");\n    test:assertEquals(value1 + value2, result1, msg = \"Incorrect Sum\");\n}\n\n// The data provider function, which returns a `string` value-set in array format.\nfunction stringDataProvider() returns (string[][]) {\n    return [[\"1\", \"2\", \"3\"], [\"10\", \"20\", \"30\"], [\"5\", \"6\", \"11\"]];\n}\n\n@test:Config {\n    dataProvider: mapDataProvider\n}\nfunction mapDataProviderTest(int value1, int value2, string fruit) returns error? {\n    io:println(\"Input : [\" + value1.toBalString() + \",\" + value2.toBalString() + \",\" + fruit + \"]\");\n    test:assertEquals(value1, value2, msg = \"The provided values are not equal\");\n    test:assertEquals(fruit.length(), 6);\n}\n\n// The data provider function, which returns a  data set as a map of tuples.\nfunction mapDataProvider() returns map<[int, int, string]>|error {\n    map<[int, int, string]> dataSet = {\n        \"banana\": [10, 10, \"banana\"],\n        \"cherry\": [5, 5, \"cherry\"]\n    };\n    return dataSet;\n}\n"
  },
  {
    "path": "examples/testerina-data-driven-tests/testerina_data_driven_tests.md",
    "content": "# Data-driven tests\n\nThe Ballerina Test framework provides in-built support for data-driven tests. You can specify a function that returns a set of data values as a data-provider to a test function.\n\nThe test execution will iterate the same test function over the provided dataset.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/define-data-driven-tests/) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_data_driven_tests.bal :::\n\n::: out testerina_data_driven_tests.out :::\n"
  },
  {
    "path": "examples/testerina-data-driven-tests/testerina_data_driven_tests.metadata",
    "content": "description: BBE on how to setup data-providers for data-driven tests.\nkeywords: ballerina, programming language, testing, data-driven tests, data-provider\n"
  },
  {
    "path": "examples/testerina-data-driven-tests/testerina_data_driven_tests.out",
    "content": "$ bal test test_module\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n        ballerinatest/test_module:0.1.0\nInput : [10,10,banana]\nInput : [5,5,cherry]\nInput : [1,2,3]\nInput : [10,20,30]\nInput : [5,6,11]\n\n        [pass] mapDataProviderTest#banana\n        [pass] mapDataProviderTest#cherry\n        [pass] testAddingValues#0\n        [pass] testAddingValues#1\n        [pass] testAddingValues#2\n\n        5 passing\n        0 failing\n        0 skipped\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_disable_groups.out",
    "content": "$ bal test --disable-groups g2 testerina_group_tests.bal\n\nCompiling source\n    testerina_group_tests.bal\n\nRunning tests\n\n    testerina_group_tests.bal\nI'm in test belonging to group g1!\nI'm the ungrouped test\n\n        [pass] testFunction1\n        [pass] testFunction3\n\n        2 passing\n        0 failing\n        0 skipped\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_tests.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// Belongs to the test group `g1`.\n@test:Config { groups: [\"g1\"] }\nfunction testFunction1() {\n    io:println(\"I'm in test belonging to group g1!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// Belongs to the test groups `g1` and `g2`.\n@test:Config { groups: [\"g1\", \"g2\"] }\nfunction testFunction2() {\n    io:println(\"I'm in test belonging to groups g1 and g2!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// Does not belong to any test group.\n@test:Config { }\nfunction testFunction3() {\n    io:println(\"I'm the ungrouped test\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_tests.md",
    "content": "# Group tests\n\nYou can tag your test cases with a single group name or multiple group names (one or more). This allows you to control the execution of selected tests.\n\nIn order to execute tests belonging to a selected test group, you can name the  test groups that are to be executed when you run the tests.\n\nLikewise, you can exclude executing the selected test groups as well.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/define-test-groups/) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_group_tests.bal :::\n\nRun the tests belonging to the `g1` and `g2` groups.\n\n::: out testerina_group_tests_groups_g1_g2.out :::\n\nRun the tests belonging to the `g1` group.\n\n::: out testerina_group_tests_groups_g1.out :::\n\nRun all tests other than the tests belonging to the `g2` group.\n\n::: out testerina_group_disable_groups.out :::\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_tests.metadata",
    "content": "description: BBE on how to group test cases.\nkeywords: ballerina, programming language, testing, grouping tests\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_tests_groups_g1.out",
    "content": "$ bal test --groups g1 testerina_group_tests.bal\n\nCompiling source\n    testerina_group_tests.bal\n\nRunning tests\n\n    testerina_group_tests.bal\nI'm in test belonging to group g1!\nI'm in test belonging to groups g1 and g2!\n\n        [pass] testFunction1\n        [pass] testFunction2\n\n        2 passing\n        0 failing\n        0 skipped\n"
  },
  {
    "path": "examples/testerina-group-tests/testerina_group_tests_groups_g1_g2.out",
    "content": "$ bal test --groups g1,g2 testerina_group_tests.bal\n\nCompiling source\n    testerina_group_tests.bal\n\nRunning tests\n\n    testerina_group_tests.bal\nI'm in test belonging to group g1!\nI'm in test belonging to groups g1 and g2!\n\n        [pass] testFunction1\n        [pass] testFunction2\n\n        2 passing\n        0 failing\n        0 skipped\n"
  },
  {
    "path": "examples/testerina-guarantee-test-execution-order/testerina_guarantee_test_execution_order.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\n// This test function depends on the `testFunction3`.\n@test:Config { \n    dependsOn: [testFunction3] }\nfunction testFunction1() {\n    io:println(\"I'm in test function 1!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// This test function depends on the `testFunction1`.\n@test:Config { dependsOn: [testFunction1] }\nfunction testFunction2() {\n    io:println(\"I'm in test function 2!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n\n// This will be executed without depending on other functions.\n// However, since other functions depend on this function, it will be executed first.\n@test:Config { }\nfunction testFunction3() {\n    io:println(\"I'm in test function 3!\");\n    test:assertTrue(true, msg = \"Failed!\");\n}\n"
  },
  {
    "path": "examples/testerina-guarantee-test-execution-order/testerina_guarantee_test_execution_order.md",
    "content": "# Guarantee test execution order\n\nThe `dependsOn` attribute can be used to define a list of functions that the test function depends on. These functions will be executed before the execution of that test.\n\nThis allows you to ensure that the tests are being executed in the expected order.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/test-a-simple-function/) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_guarantee_test_execution_order.bal :::\n\n::: out testerina_guarantee_test_execution_order.out :::\n"
  },
  {
    "path": "examples/testerina-guarantee-test-execution-order/testerina_guarantee_test_execution_order.metadata",
    "content": "description: BBE on how to setup a test execution order when unit testing.\nkeywords: ballerina, programming language, testing, execution order\n"
  },
  {
    "path": "examples/testerina-guarantee-test-execution-order/testerina_guarantee_test_execution_order.out",
    "content": "$ bal test test_module\n\nCompiling source\n        ballerinatest/test_module:0.1.0\n\nRunning tests\n    ballerinatest/test_module:0.1.0\nI'm in test function 3!\nI'm in test function 1!\nI'm in test function 2!\n\n                [pass] testFunction3\n                [pass] testFunction1\n                [pass] testFunction2\n\n                3 passing\n                0 failing\n                0 skipped\n"
  },
  {
    "path": "examples/testerina-mocking-functions/testerina_mocking_functions.md",
    "content": "# Function mocking\n\nMock functions allow you to hide the real function implementation and engage your own definition when running tests. This allows you to isolate your tests from the other modules and functions.\n\nFunction mocks can be stubbed with return values or with another user-defined function, which has the same signature as the original function.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/mocking/#mock-functions) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_mocking_functions_main.bal :::\n\n::: code testerina_mocking_functions_test.bal :::\n\n::: out testerina_mocking_functions_test.out :::\n"
  },
  {
    "path": "examples/testerina-mocking-functions/testerina_mocking_functions.metatags",
    "content": "description: BBE on how to mock functions for unit testing.\nkeywords: ballerina, programming language, testing, mocking\n"
  },
  {
    "path": "examples/testerina-mocking-functions/testerina_mocking_functions_main.bal",
    "content": "// Calls the `intAdd` function and returns the result.\npublic function addValues(int a, int b) returns int {\n    return intAdd(a, b);\n}\n\n// Adds two integers and returns the result.\npublic function intAdd(int a, int b) returns int {\n    return (a + b);\n}\n"
  },
  {
    "path": "examples/testerina-mocking-functions/testerina_mocking_functions_test.bal",
    "content": "// This demonstrates different ways to mock functions.\nimport ballerina/test;\nimport ballerina/io;\n\n// Creates a `MockFunction` for stubbing calls to\n// the `intAdd` function of the same module.\n@test:Mock { functionName: \"intAdd\" }\ntest:MockFunction intAddMockFn = new();\n\n@test:Config {}\nfunction testReturn() {\n    // Stubs the calls to return a specific value.\n    test:when(intAddMockFn).thenReturn(20);\n    // Stubs the calls to return a specific value when\n    // specific arguments are provided.\n    test:when(intAddMockFn).withArguments(0, 0).thenReturn(-1);\n\n    test:assertEquals(intAdd(10, 6), 20, msg = \"function mocking failed\");\n    test:assertEquals(intAdd(0, 0), -1,\n            msg = \"function mocking with arguments failed\");\n}\n\n// Creates a `MockFunction` that should replace the\n// imported `io:println` function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction printlnMockFn = new();\n\nint tally = 0;\n\n// This has a function signature similar to the `io:println` function.\npublic function mockPrint(any|error... val) {\n    tally = tally + 1;\n}\n\n@test:Config {}\nfunction testCall() {\n    // Stubs the calls to the `io:println` function\n    // to invoke the `mockPrint` function instead.\n    test:when(printlnMockFn).call(\"mockPrint\");\n\n    io:println(\"Testing 1\");\n    io:println(\"Testing 2\");\n    io:println(\"Testing 3\");\n\n    test:assertEquals(tally, 3);\n}\n"
  },
  {
    "path": "examples/testerina-mocking-functions/testerina_mocking_functions_test.out",
    "content": "$ bal test bbe_mocking\n\nCompiling source\n        ballerinatest/bbe_mocking:0.1.0\n\nRunning Tests\n\n        bbe_mocking\n\n                [pass] testCall\n                [pass] testReturn\n\n                2 passing\n                0 failing\n                0 skipped\n"
  },
  {
    "path": "examples/testerina-mocking-objects/testerina_mocking_objects.md",
    "content": "# Object mocking\n\nObject mocking enables controlling the values of member variables and the behavior of the member functions of an object. Mocking of objects can be done in two ways. \n\n1. Creating a test double - providing an equivalent mock object in place of the real\n2. Stubbing the member function or member variable - stubbing the behavior of functions and values of variables\n3. Creating a test double is suitable when a single mock function/object can be used throughout all tests whereas stubbing is ideal when defining different behaviors for different test cases is required.\n\nFor more information, see [Testing Ballerina Code](https://ballerina.io/learn/test-ballerina-code/mocking/#mock-objects) and the [`test` module](https://lib.ballerina.io/ballerina/test/latest/).\n\n::: code testerina_mocking_objects_main.bal :::\n\n::: code testerina_mocking_objects_test.bal :::\n\n::: out testerina_mocking_objects_test.out :::\n"
  },
  {
    "path": "examples/testerina-mocking-objects/testerina_mocking_objects.metatags",
    "content": "description: BBE on how to mock objects for unit testing.\nkeywords: ballerina, programming language, testing, mocking\n"
  },
  {
    "path": "examples/testerina-mocking-objects/testerina_mocking_objects_main.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/email;\n\n// Sample client that you can use for member access.\npublic client class ExampleClient {\n    public string id;\n\n    public function init(string id) {\n        self.id = id;\n    }\n}\n\n// Client objects are defined globally to be able to replace in the test files.\nhttp:Client clientEndpoint = check new(\"http://postman-echo.com\");\nemail:SmtpClient smtpClient = check new(\"localhost\", \"admin\", \"admin\");\nExampleClient exampleClient = new(\"originalId\");\n\n// Performs two `GET` requests to the specified\n// endpoint and returns the response.\nfunction performGet() returns @tainted http:Response {\n    io:println(\"Executing the 1st GET request\");\n    http:Response response = <http:Response> \n    checkpanic clientEndpoint -> get(\"/headers\");\n    io:println(\"Status code: \", response.statusCode.toString());\n\n    if (response.statusCode == 200) {\n        io:println(\"Executing the 2nd GET request\");\n        response = <http:Response> checkpanic\n        clientEndpoint -> get(\"/get?test=123\",\n            {\"Sample-Name\": \"http-client-connector\"});\n        io:println(\"Status code: \", response.statusCode.toString());\n    }\n    return response;\n}\n\n// Sends an email to the specified email addresses\n// and returns an error if found.\nfunction sendNotification(string[] emailIds) returns error? {\n    email:Message msg = {\n        'from: \"builder@abc.com\",\n        subject: \"Error Alert ...\",\n        to: emailIds,\n        body: \"\"\n    };\n    return smtpClient -> sendMessage(msg);\n}\n"
  },
  {
    "path": "examples/testerina-mocking-objects/testerina_mocking_objects_test.bal",
    "content": "// This demonstrates different ways to mock a client object.\nimport ballerina/test;\nimport ballerina/http;\nimport ballerina/email;\n\n// The test double of the `http:Client` object with the\n// implementation of the required functions.\npublic client class MockHttpClient {\n    remote isolated function get(@untainted string path,\n    map<string|string[]>? headers = (),\n    http:TargetType targetType = http:Response) returns\n    http:Response | anydata | http:ClientError {\n        http:Response response = new;\n        response.statusCode = 500;\n        return response;\n    }\n}\n\n@test:Config { }\nfunction testTestDouble() {\n    // Creates and assigns the defined test-double.\n    clientEndpoint = test:mock(http:Client, new MockHttpClient());\n    http:Response res = performGet();\n    test:assertEquals(res.statusCode, 500);\n}\n\n@test:Config { }\nfunction testReturn() {\n    // Creates and assigns a default mock object,\n    // which subsequently needs to be stubbed.\n    clientEndpoint = test:mock(http:Client);\n    // Stubs the `get` function to return the specified HTTP response.\n    test:prepare(clientEndpoint).when(\"get\").thenReturn(new http:Response());\n    http:Response res = performGet();\n    test:assertEquals(res.statusCode, 200);\n}\n\n@test:Config { }\nfunction testReturnSequence() {\n    http:Response mockResponse = new;\n    mockResponse.statusCode = 404;\n\n    clientEndpoint = test:mock(http:Client);\n    // Stubs the `get` function to return the specified HTTP response\n    // for each call (i.e., The first call will return the status code `200`\n    // and the second call will return the status code `404`).\n    test:prepare(clientEndpoint).when(\"get\").thenReturnSequence(\n        new http:Response(), mockResponse);\n    http:Response res = performGet();\n    test:assertEquals(res.statusCode, 404);\n}\n\n@test:Config { }\nfunction testReturnWithArgs() {\n    http:Response mockResponse = new;\n    mockResponse.statusCode = 404;\n    clientEndpoint = test:mock(http:Client);\n    // This stubs the `get` function to return the specified HTTP response when the specified\n    // argument is passed.\n    test:prepare(clientEndpoint).when(\"get\").\n    withArguments(\"/headers\").thenReturn(mockResponse);\n    // The object and record types should be denoted by the `test:ANY` constant.\n    test:prepare(clientEndpoint).when(\"get\").withArguments(\"/get?test=123\")\n        .thenReturn(mockResponse);\n    http:Response res = performGet();\n    test:assertEquals(res.statusCode, 404);\n}\n\n@test:Config { }\nfunction testSendNotification() {\n    smtpClient = test:mock(email:SmtpClient);\n    // Stubs the `send` method of the `mockSmtpClient` to do nothing.\n    // This is used for functions with an optional or no return type.\n    test:prepare(smtpClient).when(\"sendMessage\").doNothing();\n    string[] emailIds = [\"user1@test.com\", \"user2@test.com\"];\n    error? err = sendNotification(emailIds);\n    test:assertEquals(err, ());\n}\n\n@test:Config {}\nfunction testMemberVariable() {\n    string mockId = \"test\";\n    lock {\n        exampleClient = test:mock(ExampleClient);\n        // Stubs the value of the `id` to return the specified string.\n        test:prepare(exampleClient).getMember(\"id\").thenReturn(mockId);\n        test:assertEquals(exampleClient.id, mockId);\n    }\n}\n"
  },
  {
    "path": "examples/testerina-mocking-objects/testerina_mocking_objects_test.out",
    "content": "$ bal test bbe_mocking\nCompiling source\n        ballerinatest/bbe_mocking:0.1.0\n\nRunning Tests\n\n        bbe_mocking\nExecuting the 1st GET request\nStatus code: 200\nExecuting the 2nd GET request\nStatus code: 200\nExecuting the 1st GET request\nStatus code: 200\nExecuting the 2nd GET request\nStatus code: 404\nExecuting the 1st GET request\nStatus code: 404\nExecuting the 1st GET request\nStatus code: 500\n\n                [pass] testMemberVariable\n                [pass] testReturn\n                [pass] testReturnSequence\n                [pass] testReturnWithArgs\n                [pass] testSendNotification\n                [pass] testTestDouble\n\n                6 passing\n                0 failing\n                0 skipped\n"
  },
  {
    "path": "examples/time-formatting-and-parsing/tests/time_formatting_and_parsing_test.bal",
    "content": "import ballerina/io;\nimport ballerina/test;\n\nstring[] outputs = [];\nint counter = 0;\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new ();\n\npublic function mockPrint(io:Printable... s) {\n    string outstr = \"\";\n    foreach io:Printable str in s {\n        outstr = outstr + new PrintableClassImpl(str).toString();\n    }\n    outputs[counter] = outstr;\n    counter += 1;\n}\n\n// From ballerina/io module to mock io:println() with raw templates\nclass PrintableClassImpl {\n    io:Printable printable;\n\n    public isolated function init(io:Printable printable) {\n        self.printable = printable;\n    }\n    public isolated function toString() returns string {\n        io:Printable printable = self.printable;\n        if printable is io:PrintableRawTemplate {\n            return new PrintableRawTemplateImpl(printable).toString();\n        } else if printable is error {\n            return printable.toString();\n        } else {\n            return printable.toString();\n        }\n    }\n}\n\nclass PrintableRawTemplateImpl {\n    *object:RawTemplate;\n    public io:Printable[] insertions;\n\n    public isolated function init(io:PrintableRawTemplate printableRawTemplate) {\n        self.strings = printableRawTemplate.strings;\n        self.insertions = printableRawTemplate.insertions;\n    }\n    public isolated function toString() returns string {\n        io:Printable[] templeteInsertions = self.insertions;\n        string[] templeteStrings = self.strings;\n        string templatedString = templeteStrings[0];\n        foreach int i in 1 ..< (templeteStrings.length()) {\n            io:Printable templateInsert = templeteInsertions[i - 1];\n            if (templateInsert is io:PrintableRawTemplate) {\n                templatedString += new PrintableRawTemplateImpl(templateInsert).toString() + templeteStrings[i];\n            } else if (templateInsert is error) {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            } else {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            }\n        }\n        return templatedString;\n    }\n}\n\n@test:Config {}\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function\n    check main();\n    test:assertEquals(outputs[0], \"UTC value: [1196676930,0.12]\");\n    test:assertEquals(outputs[1], \"UTC string representation: 2007-12-03T10:15:30.120Z\");\n\n    test:assertEquals(outputs[2], \n    \"Converted civil value: {\\\"utcOffset\\\":{\\\"hours\\\":5,\\\"minutes\\\":30},\\\"timeAbbrev\\\":\\\"Asia/Colombo\\\",\\\"dayOfWeek\\\":1,\\\"year\\\":2021,\\\"month\\\":4,\\\"day\\\":12,\\\"hour\\\":23,\\\"minute\\\":20,\\\"second\\\":50.52}\");\n    test:assertEquals(outputs[3], \"Civil string representation: 2021-04-12T23:20:50.520+05:30\");\n    test:assertEquals(outputs[4], \"Email formatted string: Mon, 3 Dec 2007 10:15:30 Z\");\n\n    test:assertEquals(outputs[5], \n    \"Civil record of the email string: {\\\"utcOffset\\\":{\\\"hours\\\":-8,\\\"minutes\\\":0},\\\"timeAbbrev\\\":\\\"America/Los_Angeles\\\",\\\"dayOfWeek\\\":3,\\\"year\\\":2021,\\\"month\\\":3,\\\"day\\\":10,\\\"hour\\\":19,\\\"minute\\\":51,\\\"second\\\":55}\");\n    test:assertEquals(outputs[6], \"Email string of the civil record: Wed, 10 Mar 2021 19:51:55 -0800\");\n}\n"
  },
  {
    "path": "examples/time-formatting-and-parsing/time_formatting_and_parsing.bal",
    "content": "import ballerina/io;\nimport ballerina/time;\n\npublic function main() returns error? {\n    // Converts a given RFC 3339 timestamp\n    // (e.g. `2007-12-03T10:15:30.12Z`) string to a `time:Utc` value.\n    time:Utc utc = check time:utcFromString(\"2007-12-03T10:15:30.120Z\");\n    io:println(\"UTC value: \" + utc.toString());\n\n    // Converts a given `time:Utc` to a RFC 3339 timestamp\n    // (e.g. `2007-12-03T10:15:30.00Z`) string.\n    string utcString = time:utcToString(utc);\n    io:println(`UTC string representation: ${utcString}`);\n\n    // Converts a given RFC 3339 timestamp(e.g. `2007-12-03T10:15:30.00Z`)\n    // to a `time:Civil` record.\n    time:Civil civil1 = check\n    time:civilFromString(\"2021-04-12T23:20:50.520+05:30[Asia/Colombo]\");\n    io:println(\"Converted civil value: \" + civil1.toString());\n\n    // Converts a given `time:Civil` value to a RFC 3339\n    // (e.g. `2021-04-12T23:20:50.520+05:30`) formatted string.\n    string civilString = check time:civilToString(civil1);\n    io:println(`Civil string representation: ${civilString}`);\n\n    // Converts a given UTC to an RFC 5322 formatted string\n    // (e.g `Mon, 3 Dec 2007 10:15:30 GMT`).\n    string emailFormattedString = time:utcToEmailString(utc, \"Z\");\n    io:println(`Email formatted string: ${emailFormattedString}`);\n\n    // Converts a given RFC 5322 formatted string\n    // (e.g `Mon, 3 Dec 2007 10:15:30 GMT`) to a `time:Civil` record.\n    time:Civil civil2 = check\n    time:civilFromEmailString(\"Wed, 10 Mar 2021 19:51:55 -0800 (PST)\");\n    io:println(`Civil record of the email string: ${civil2.toString()}`);\n\n    // Converts a given `time:Civil` record to an RFC 5322 formatted string\n    // (e.g `Mon, 3 Dec 2007 10:15:30 GMT`).\n    string emailString = check\n    time:civilToEmailString(civil2, time:PREFER_ZONE_OFFSET);\n    io:println(`Email string of the civil record: ${emailString}`);\n}\n"
  },
  {
    "path": "examples/time-formatting-and-parsing/time_formatting_and_parsing.md",
    "content": "# Time formatting/parsing\n\nThe Ballerina `time` library contains APIs to convert UTC and local time to different string representations (RFC 5322 and RFC 3339) vice versa.\n\nFor more information on the underlying module, see the [`time` module](https://lib.ballerina.io/ballerina/time/latest/).\n\n::: code time_formatting_and_parsing.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out time_formatting_and_parsing.out :::"
  },
  {
    "path": "examples/time-formatting-and-parsing/time_formatting_and_parsing.metatags",
    "content": "description: BBE on how to format and parse UTC and Civil values to different RFC formats.\nkeywords: ballerina, ballerina by examples, bbe, time, utc, rfc3339, rfc5322\n"
  },
  {
    "path": "examples/time-formatting-and-parsing/time_formatting_and_parsing.out",
    "content": "$ bal run time_formatting_and_parsing.bal\nUTC value: [1196676930,0.12]\nUTC string representation: 2007-12-03T10:15:30.120Z\nConverted civil value: {\"utcOffset\":{\"hours\":5,\"minutes\":30},\"timeAbbrev\":\"Asia/Colombo\",\"dayOfWeek\":1,\"year\":2021,\"month\":4,\"day\":12,\"hour\":23,\"minute\":20,\"second\":50.52}\nCivil string representation: 2021-04-12T23:20:50.520+05:30\nEmail formatted string: Mon, 3 Dec 2007 10:15:30 Z\nCivil record of the email string: {\"utcOffset\":{\"hours\":-8,\"minutes\":0},\"timeAbbrev\":\"America/Los_Angeles\",\"dayOfWeek\":3,\"year\":2021,\"month\":3,\"day\":10,\"hour\":19,\"minute\":51,\"second\":55}\nEmail string of the civil record: Wed, 10 Mar 2021 19:51:55 -0800\n"
  },
  {
    "path": "examples/time-utc/tests/time_utc_test.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.'string as langstring;\nimport ballerina/test;\n\nstring[] outputs = [];\nint counter = 0;\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new ();\n\npublic function mockPrint(io:Printable... s) {\n    string outstr = \"\";\n    foreach io:Printable str in s {\n        outstr = outstr + new PrintableClassImpl(str).toString();\n    }\n    outputs[counter] = outstr;\n    counter += 1;\n}\n\n// From ballerina/io module to mock io:println() with raw templates\nclass PrintableClassImpl {\n    io:Printable printable;\n\n    public isolated function init(io:Printable printable) {\n        self.printable = printable;\n    }\n    public isolated function toString() returns string {\n        io:Printable printable = self.printable;\n        if printable is io:PrintableRawTemplate {\n            return new PrintableRawTemplateImpl(printable).toString();\n        } else if printable is error {\n            return printable.toString();\n        } else {\n            return printable.toString();\n        }\n    }\n}\n\nclass PrintableRawTemplateImpl {\n    *object:RawTemplate;\n    public io:Printable[] insertions;\n\n    public isolated function init(io:PrintableRawTemplate printableRawTemplate) {\n        self.strings = printableRawTemplate.strings;\n        self.insertions = printableRawTemplate.insertions;\n    }\n    public isolated function toString() returns string {\n        io:Printable[] templeteInsertions = self.insertions;\n        string[] templeteStrings = self.strings;\n        string templatedString = templeteStrings[0];\n        foreach int i in 1 ..< (templeteStrings.length()) {\n            io:Printable templateInsert = templeteInsertions[i - 1];\n            if (templateInsert is io:PrintableRawTemplate) {\n                templatedString += new PrintableRawTemplateImpl(templateInsert).toString() + templeteStrings[i];\n            } else if (templateInsert is error) {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            } else {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            }\n        }\n        return templatedString;\n    }\n}\n\n@test:Config {}\nfunction testFunc() {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function\n    main();\n    test:assertTrue(langstring:includes(outputs[0], \"Number of seconds from the epoch: \"));\n    test:assertTrue(langstring:includes(outputs[1], \"Nanoseconds fraction: \"));\n}\n"
  },
  {
    "path": "examples/time-utc/time_utc.bal",
    "content": "import ballerina/io;\nimport ballerina/time;\n\npublic function main() {\n    // Gets the current instant of the system clock (seconds from the epoch of\n    // 1970-01-01T00:00:00). The returned `time:Utc` value represents seconds\n    // from the epoch with nanoseconds precision.\n    // The `time:Utc` is a tuple with `[int, decimal]`. The first member of the\n    // tuple represents the number of seconds from the epoch. The second\n    // member represents the rest of the nanoseconds from the epoch as a\n    // fraction.\n    time:Utc currentUtc = time:utcNow();\n    io:println(`Number of seconds from the epoch: ${currentUtc[0]}s`);\n    io:println(`Nanoseconds fraction: ${currentUtc[1]}s`);\n}\n"
  },
  {
    "path": "examples/time-utc/time_utc.md",
    "content": "# UTC time\n\nThe Ballerina `time` library contains an API to obtain the current time from the epoch `1970-01-01T00:00:00`.\n\nFor more information on the underlying module, see the [`time` module](https://lib.ballerina.io/ballerina/time/latest/).\n\n::: code time_utc.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out time_utc.out :::"
  },
  {
    "path": "examples/time-utc/time_utc.metatags",
    "content": "description: BBE on how to get the current timestamp in seconds.\nkeywords: ballerina, ballerina by examples, bbe, time, current, epoch, utc\n"
  },
  {
    "path": "examples/time-utc/time_utc.out",
    "content": "$ bal run time_utc.bal\nNumber of seconds from the epoch: 1621839972s\nNanoseconds fraction: 0.005413000s\n"
  },
  {
    "path": "examples/time-utc-and-civil/tests/time_utc_and_civil_test.bal",
    "content": "import ballerina/io;\nimport ballerina/lang.'string as langstring;\nimport ballerina/test;\n\nstring[] outputs = [];\nint counter = 0;\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new ();\n\npublic function mockPrint(io:Printable... s) {\n    string outstr = \"\";\n    foreach io:Printable str in s {\n        outstr = outstr + new PrintableClassImpl(str).toString();\n    }\n    outputs[counter] = outstr;\n    counter += 1;\n}\n\n// From ballerina/io module to mock io:println() with raw templates\nclass PrintableClassImpl {\n    io:Printable printable;\n\n    public isolated function init(io:Printable printable) {\n        self.printable = printable;\n    }\n    public isolated function toString() returns string {\n        io:Printable printable = self.printable;\n        if printable is io:PrintableRawTemplate {\n            return new PrintableRawTemplateImpl(printable).toString();\n        } else if printable is error {\n            return printable.toString();\n        } else {\n            return printable.toString();\n        }\n    }\n}\n\nclass PrintableRawTemplateImpl {\n    *object:RawTemplate;\n    public io:Printable[] insertions;\n\n    public isolated function init(io:PrintableRawTemplate printableRawTemplate) {\n        self.strings = printableRawTemplate.strings;\n        self.insertions = printableRawTemplate.insertions;\n    }\n    public isolated function toString() returns string {\n        io:Printable[] templeteInsertions = self.insertions;\n        string[] templeteStrings = self.strings;\n        string templatedString = templeteStrings[0];\n        foreach int i in 1 ..< (templeteStrings.length()) {\n            io:Printable templateInsert = templeteInsertions[i - 1];\n            if (templateInsert is io:PrintableRawTemplate) {\n                templatedString += new PrintableRawTemplateImpl(templateInsert).toString() + templeteStrings[i];\n            } else if (templateInsert is error) {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            } else {\n                templatedString += templateInsert.toString() + templeteStrings[i];\n            }\n        }\n        return templatedString;\n    }\n}\n\n@test:Config {}\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function\n    check main();\n    test:assertTrue(langstring:includes(outputs[0], \"Civil record: {\\\"timeAbbrev\\\":\\\"Z\\\",\"));\n    test:assertEquals(outputs[1], \"UTC value of the civil record: [1618269650,0.52]\");\n}\n"
  },
  {
    "path": "examples/time-utc-and-civil/time_utc_and_civil.bal",
    "content": "import ballerina/io;\nimport ballerina/time;\n\npublic function main() returns error? {\n    // Gets the current instant of the system clock (seconds from the epoch of\n    // 1970-01-01T00:00:00). The returned `time:Utc` value represents seconds\n    // from the epoch with nanoseconds precision.\n    time:Utc utc1 = time:utcNow();\n    // Converts a given `time:Utc` value to a `time:Civil` value.\n    time:Civil civil1 = time:utcToCivil(utc1);\n    io:println(`Civil record: ${civil1.toString()}`);\n\n    // Converts a given `time:Civil` value to a `time:Utc` value.\n    // Note that, since `time:Civil` is used to represent localized time,\n    // it is mandatory to have the `utcOffset` field to be specified in the\n    // given `time:Civil` value.\n    time:Civil civil2 = {\n        year: 2021,\n        month: 4,\n        day: 13,\n        hour: 4,\n        minute: 50,\n        second: 50.52,\n        timeAbbrev: \"Asia/Colombo\",\n        utcOffset: {hours: 5, minutes: 30, seconds: 0d}\n    };\n    time:Utc utc2 = check time:utcFromCivil(civil2);\n    io:println(`UTC value of the civil record: ${utc2.toString()}`);\n}\n"
  },
  {
    "path": "examples/time-utc-and-civil/time_utc_and_civil.md",
    "content": "# Time with zone offset\n\nThe Ballerina `time` library contains APIs to convert UTC to local time and vice versa.\n\nFor more information on the underlying module, see the [`time` module](https://lib.ballerina.io/ballerina/time/latest/).\n\n::: code time_utc_and_civil.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out time_utc_and_civil.out :::"
  },
  {
    "path": "examples/time-utc-and-civil/time_utc_and_civil.metatags",
    "content": "description: BBE on how to convert a given UTC time to a civil record vice versa.\nkeywords: ballerina, ballerina by examples, bbe, time, utc, civil\n"
  },
  {
    "path": "examples/time-utc-and-civil/time_utc_and_civil.out",
    "content": "$ bal run time_utc_and_civil.bal\nCivil record: {\"timeAbbrev\":\"Z\",\"dayOfWeek\":1,\"year\":2021,\"month\":5,\"day\":24,\"hour\":7,\"minute\":7,\"second\":15.757818}\nUTC value of the civil record: [1618269650,0.52]\n"
  },
  {
    "path": "examples/time-zone/time_zone.bal",
    "content": "import ballerina/io;\nimport ballerina/time;\n\npublic function main() returns error? {\n    // Event recorded in UTC (2022-01-29 22:48:00).\n    time:Utc eventUtcTime = check time:utcFromString(\"2022-01-29T22:48:00Z\");\n    io:println(\"Event time in UTC: \", eventUtcTime);\n\n    // Load the system's default time zone.\n    time:Zone systemZone = check new time:TimeZone();\n    // Convert UTC event time to the system's local time.\n    time:Civil eventInSystemZone = systemZone.utcToCivil(eventUtcTime);\n    io:println(\"Event time in system's local time: \" + eventInSystemZone.toString());\n\n    // Print the event time in 'Europe/London' time zone.\n    printZoneTimeFromUtc(eventUtcTime, \"Europe/London\");\n\n    // Print the event time in 'Asia/Tokyo' time zone.\n    printZoneTimeFromUtc(eventUtcTime, \"Asia/Tokyo\");\n}\n\nfunction printZoneTimeFromUtc(time:Utc utcTime, string zoneId) {\n    time:Zone? zone = time:getZone(zoneId);\n    if zone is time:Zone {\n        time:Civil timeInZone = zone.utcToCivil(utcTime);\n        io:println(string `Event time in ${zoneId} time zone: ${timeInZone.toString()}`);\n    } else {\n        io:println(string `Failed to load the '${zoneId}' time zone.`);\n    }\n}\n"
  },
  {
    "path": "examples/time-zone/time_zone.md",
    "content": "# Time Zone\n\nThe Ballerina `time` library provides APIs for managing and converting time across different time zones. It supports loading system time zone, retrieving specific time zones based on the time zone ID, and enables seamless conversion between UTC and local times across different regions.\n\nFor more information on the underlying module, see the [`time` module](https://lib.ballerina.io/ballerina/time/latest/).\n\n::: code time_zone.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out time_zone.out :::"
  },
  {
    "path": "examples/time-zone/time_zone.metatags",
    "content": "description: BBE on how to use time zone APIs in Ballerina.\nkeywords: ballerina, ballerina by examples, bbe, time, zone, utc, zoneId\n"
  },
  {
    "path": "examples/time-zone/time_zone.out",
    "content": "$ bal run time_zone.bal\nEvent time in UTC: [1643496480,0]\nEvent time in system's local time: {\"timeAbbrev\":\"Asia/Colombo\",\"dayOfWeek\":0,\"year\":2022,\"month\":1,\"day\":30,\"hour\":4,\"minute\":18,\"second\":0}\nEvent time in Europe/London time zone: {\"timeAbbrev\":\"Europe/London\",\"dayOfWeek\":6,\"year\":2022,\"month\":1,\"day\":29,\"hour\":22,\"minute\":48,\"second\":0}\nEvent time in Asia/Tokyo time zone: {\"timeAbbrev\":\"Asia/Tokyo\",\"dayOfWeek\":0,\"year\":2022,\"month\":1,\"day\":30,\"hour\":7,\"minute\":48,\"second\":0}\n"
  },
  {
    "path": "examples/tracing/tests/tracing_test.bal",
    "content": "import ballerina/test;\nimport ballerina/http;\n\n@test:Config { }\nfunction testFunc() {\n    // Invoking the service\n    http:Client httpEndpoint = new (\"http://localhost:9234\");\n\n    string response1 = \"Hello, World!\";\n\n    // Send a GET request to the specified endpoint\n    http:Response|error response = httpEndpoint->get(\"/hello/sayHello\");\n    if response is http:Response {\n        var res = response.getTextPayload();\n        if res is error {\n            test:assertFail(msg = \"Failed to call the endpoint:\");\n        } else {\n            test:assertEquals(res, response1);\n        }\n    } else {\n        test:assertFail(msg = \"Failed to call the endpoint:\");\n    }\n}\n"
  },
  {
    "path": "examples/tracing/tracing.bal",
    "content": "import ballerina/http;\nimport ballerina/log;\nimport ballerina/observe;\nimport ballerina/lang.runtime;\nimport ballerinax/jaeger as _;\n\n// Simple `Hello` HTTP Service\nservice /hello on new http:Listener(9234) {\n\n    // Resource functions are invoked with the HTTP caller and the\n    // incoming request as arguments.\n    resource function get sayHello(http:Caller caller, http:Request req)\n            returns error? {\n        http:Response res = new;\n\n        //Start a child span attaching to the generated system span.\n        int spanId = check observe:startSpan(\"MyFirstLogicSpan\");\n\n        //Start a new root span without attaching to the system span.\n        int rootParentSpanId = observe:startRootSpan(\"MyRootParentSpan\");\n        // Some actual logic will go here, and for example, we have introduced some delay with the sleep.\n        runtime:sleep(1);\n        //Start a new child span for the `MyRootParentSpan` span.\n        int childSpanId = check observe:startSpan(\"MyRootChildSpan\", (),\n                                                            rootParentSpanId);\n        // Some actual logic will go here, and for example, we have introduced some delay with the sleep.\n        runtime:sleep(1);\n        //Finish the `MyRootChildSpan` span.\n        error? result = observe:finishSpan(childSpanId);\n        if (result is error) {\n            log:printError(\"Error in finishing span\", 'error = result);\n        }\n        // Some actual logic will go here, and for example, we have introduced some delay with the sleep.\n        runtime:sleep(1);\n        //Finish the `MyRootParentSpan` span.\n        result = observe:finishSpan(rootParentSpanId);\n        if (result is error) {\n            log:printError(\"Error in finishing span\", 'error = result);\n        }\n\n        //Some actual logic will go here, and for example, we have introduced some delay with the sleep.\n        runtime:sleep(1);\n\n        //Finish the created child `MyFirstLogicSpan` span, which was attached to the system trace.\n        result = observe:finishSpan(spanId);\n        if (result is error) {\n            log:printError(\"Error in finishing span\", 'error = result);\n        }\n        //Use a util method to set a string payload.\n        res.setPayload(\"Hello, World!\");\n\n        //Send the response back to the caller.\n        result = caller->respond(res);\n\n        if (result is error) {\n            log:printError(\"Error sending response\", 'error = result);\n        }\n\n        return ();\n    }\n}\n"
  },
  {
    "path": "examples/tracing/tracing.client.out",
    "content": "$ curl http://localhost:9234/hello/sayHello\nHello, World!\n"
  },
  {
    "path": "examples/tracing/tracing.md",
    "content": "# Distributed tracing\n\nBallerina supports Observability out of the box, and Tracing is one of the three important aspects of observability. To observe Ballerina code, the `--observability-included` build time flag should be given along with the `Config.toml` file when starting the service. The `Config.toml` file contains the required runtime configurations related to observability.\n\nYou can trace the code blocks and measure the time incurred during the actual runtime execution. Also, you can choose to hook the measurement with the default trace created or can create a completely new trace.\n\n>**Info:** For more information about configs and observing applications, see [Observe Ballerina programs](/learn/observe-ballerina-programs/).\n\n::: code tracing.bal :::\n\nInvoke the service using cURL and access [Jaeger UI](http://localhost:16686).\n\n::: out tracing.client.out :::\n\nJaeger is the default tracing tool used in Ballerina. To start the Jaeger, execute the command below.\n\nTo start the service, navigate to the directory that contains the\n`.bal` file, and execute the `bal run` command below with the `--observability-included` build time flag and the `Config.toml` runtime configuration file.\n\n::: out tracing.server.out :::\n"
  },
  {
    "path": "examples/tracing/tracing.metatags",
    "content": "description: BBE on how to use the default Tracing Observability feature in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, observability, tracing, opentracing\n"
  },
  {
    "path": "examples/tracing/tracing.server.out",
    "content": "$ docker run -d -p 13133:13133 -p 16686:16686 -p 55680:55680 jaegertracing/opentelemetry-all-in-one\n$ BAL_CONFIG_FILES=Config.toml bal run --observability-included tracing.bal\nballerina: started publishing traces to Jaeger on localhost:55680\n"
  },
  {
    "path": "examples/transaction-statement/transaction_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // The transaction statement begins a new transaction and executes a block.\n    transaction {\n        doStage1();\n        doStage2();\n\n        // Commit of a transaction must be done explicitly using commit.\n        // A commit must be lexically within a transaction statement and may return an error;\n        check commit;\n\n    }\n    return;\n}\n\nfunction doStage1() {\n    io:println(\"Stage1 completed\");\n}\n\nfunction doStage2() {\n    io:println(\"Stage2 completed\");\n}\n"
  },
  {
    "path": "examples/transaction-statement/transaction_statement.md",
    "content": "# Transaction statement\n\nBallerina provides support for interacting with a transaction manager. Compile-time guarantees that transactions are bracketed with begin and `commit` or `rollback`.\n\nThe region in the middle is typed as being a transactional context. Ballerina does not have a transactional memory and includes a transaction manager. The current transaction is a part of the execution context of a strand.\n\n::: code transaction_statement.bal :::\n\n::: out transaction_statement.out :::"
  },
  {
    "path": "examples/transaction-statement/transaction_statement.metatags",
    "content": "description: This BBE introduces transaction statement in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, transactions, transaction, commit\n"
  },
  {
    "path": "examples/transaction-statement/transaction_statement.out",
    "content": "$ bal run transaction_statement.bal\nStage1 completed\nStage2 completed\n"
  },
  {
    "path": "examples/transactional-named-workers/transactional_named_workers.bal",
    "content": "import ballerina/io;\n\ntype Update record {\n    int updateIndex;\n    int stockMnt;\n};\n\npublic function main() returns error? {\n    Update newUpdate = {\n        updateIndex: 132,\n        stockMnt: 3500\n    };\n    transaction {\n        check exec(newUpdate);\n        check commit;\n    }\n}\n\n// A `transactional` function can only be called from a `transactional` context\ntransactional function exec(Update u) returns error? {\n    // A `transactional` named worker starts a transaction branch in the current transaction.\n    transactional worker A {\n        bar();\n    }\n}\n\ntransactional function bar() {\n    io:println(\"bar() invoked\");\n}\n"
  },
  {
    "path": "examples/transactional-named-workers/transactional_named_workers.md",
    "content": "# Transactional named workers\n\nA named worker within a transactional function can be declared as `transactional`. This will start a new transaction branch for the named worker, as with a distributed transaction.\n\n::: code transactional_named_workers.bal :::\n\n::: out transactional_named_workers.out :::"
  },
  {
    "path": "examples/transactional-named-workers/transactional_named_workers.metatags",
    "content": "description: This BBE introduces the transactional named workers in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, workers, transactions, transactional workers, transactional named workers\n"
  },
  {
    "path": "examples/transactional-named-workers/transactional_named_workers.out",
    "content": "$ bal run transactional_named_workers.bal\nbar() invoked\n"
  },
  {
    "path": "examples/transactional-qualifier/transactional_qualifier.bal",
    "content": "import ballerina/io;\n\ntype Update record {\n    int updateIndex;\n    int stockMnt;\n};\n\npublic function main() returns error? {\n    Update updates = {updateIndex: 0, stockMnt: 100};\n    transaction {\n        check doUpdate(updates);\n        check commit;\n    }\n    return;\n}\n\n// Called within the transaction statement.\ntransactional function doUpdate(Update u) returns error? {\n    // Calls `foo()` non-transactional function.\n    foo(u);\n    // Calls `bar()` transactional function.\n    bar(u);\n    return;\n}\n\nfunction foo(Update u) {\n    if transactional {\n        // This is in the transactional context.\n        bar(u);\n    }\n}\n\ntransactional function bar(Update u) {\n    io:println(\"Calling from a transactional context\");\n}\n"
  },
  {
    "path": "examples/transactional-qualifier/transactional_qualifier.md",
    "content": "# Transactional qualifier\n\nAt compile-time, regions of code are typed as being a transactional context. Ballerina guarantees that, whenever that region is executed, there will be a current transaction.\n\nA function with a `transactional` qualifier can only be called from a transactional context; function  body will be a transactional context. `transactional` is also a boolean expression that tests at runtime whether there is a current transaction: used in a condition results in a transactional context.\n\n::: code transactional_qualifier.bal :::\n\n::: out transactional_qualifier.out :::"
  },
  {
    "path": "examples/transactional-qualifier/transactional_qualifier.metatags",
    "content": "description: This BBE introduces the transactional qualifier in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, transactional, transactional qualifier\n"
  },
  {
    "path": "examples/transactional-qualifier/transactional_qualifier.out",
    "content": "$ bal run transactional_qualifier.bal\nCalling from a transactional context\nCalling from a transactional context\n"
  },
  {
    "path": "examples/transform-csv-records-to-custom-types/transform_csv_records_to_custom_types.bal",
    "content": "import ballerina/data.csv;\nimport ballerina/io;\n\n// Represents the details of an employee.\ntype Employee record {|\n    int empId;\n    string empName;\n    string department;\n    decimal salary;\n|};\n\n// Represents the salary details of an employee.\ntype EmployeeSalary record {|\n    // This annotation is used to map the `empId` field in the source CSV record \n    // to the `id` field in the target record.\n    @csv:Name {\n        value: \"empId\"\n    }\n    int id;\n    decimal salary;\n|};\n\npublic function main() returns error? {\n    Employee[] employees = [\n        {empId: 1, empName: \"John\", department: \"Engineering\", salary: 1000.0},\n        {empId: 2, empName: \"Doe\", department: \"HR\", salary: 2000.0},\n        {empId: 3, empName: \"Jane\", department: \"Finance\", salary: 3000.0}\n    ];\n\n    // Transform the `employees` array into an array of `EmployeeSalary` records.\n    // Only the fields specified in the `EmployeeSalary` type (`id` and `salary`) \n    // are included in the values in the resulting array.\n    EmployeeSalary[] employeeSalaries = check csv:transform(employees);\n    io:println(employeeSalaries);\n\n    // Transform the `employees` array into an array of `anydata` arrays.\n    anydata[][] employeesArray = check csv:transform(employees);\n    io:println(employeesArray);\n}\n"
  },
  {
    "path": "examples/transform-csv-records-to-custom-types/transform_csv_records_to_custom_types.md",
    "content": "# Transform CSV records to custom types\n\nBallerina supports transforming CSV records into various data structures, such as custom records or arrays. It allows users to map CSV records to target types by specifying only the required fields.\n\n::: code transform_csv_records_to_custom_types.bal :::\n\n::: out transform_csv_records_to_custom_types.out :::\n"
  },
  {
    "path": "examples/transform-csv-records-to-custom-types/transform_csv_records_to_custom_types.metatags",
    "content": "description: This BBE demonstrates the transformation of CSV records into Ballerina arrays, both with and without data projection.\nkeywords: ballerina, ballerina by example, bbe, csv, csv records, record, record array, transform, csv data module, data.csv, data projection\n"
  },
  {
    "path": "examples/transform-csv-records-to-custom-types/transform_csv_records_to_custom_types.out",
    "content": "$ bal run transform_csv_records_to_custom_types.bal\n[{\"id\":1,\"salary\":1000.0},{\"id\":2,\"salary\":2000.0},{\"id\":3,\"salary\":3000.0}]\n[[1,\"John\",\"Engineering\",1000.0],[2,\"Doe\",\"HR\",2000.0],[3,\"Jane\",\"Finance\",3000.0]]\n"
  },
  {
    "path": "examples/trap-expression/trap_expression.bal",
    "content": "import ballerina/io;\n\nfunction hereBeDragons() returns int {\n    // Trigger a panic deep within the call stack. \n    alwaysPanic();\n}\n\n// Return type `never` indicate that this function will never return normally. I.e., it will always panic.\nfunction alwaysPanic() returns never {\n    panic error(\"deep down in the code\");\n}\n\npublic function main() {\n    // Division by 0 triggers a panic. \n    int|error result = trap 1 / 0;\n    if result is error {\n        io:println(\"Error: \", result);\n    }\n    // Calling the `hereBeDragons` function triggers a panic deep within the call stack, which is trapped here.\n    int|error result2 = trap hereBeDragons();\n    if result2 is error {\n        io:println(\"Error: \", result2);\n    }\n    // This will trigger a panic which is not trapped. Thus it will terminate the program.\n    int result3 = hereBeDragons();\n    io:println(\"Result: \", result3);\n}\n"
  },
  {
    "path": "examples/trap-expression/trap_expression.md",
    "content": "# Trap expression\n\nIf you have an expression such as a function call that can potentially trigger a panic you can use a `trap` expression to prevent further unwinding of the stack. Then if the evaluation of the expression triggers a panic you will get the `error` value associated with the panic. Otherwise, you will get the result of the expression.\n\n::: code trap_expression.bal :::\n\n::: out trap_expression.out :::\n\n+ [Panics](https://ballerina.io/learn/by-example/panics/)\n"
  },
  {
    "path": "examples/trap-expression/trap_expression.metatags",
    "content": "description: This BBE demonstrates how the trap expression is used in Ballerina to handle panics\nkeywords:  ballerina, ballerina by example, bbe, error, panic, trap\n"
  },
  {
    "path": "examples/trap-expression/trap_expression.out",
    "content": "$ bal run trap_expression.bal\nError: error(\"{ballerina}DivisionByZero\",message=\" / by zero\")\nError: error(\"deep down in the code\")\nerror: deep down in the code\n\tat trap_expression:alwaysPanic(trap_expression.bal:10)\n\t   trap_expression:hereBeDragons(trap_expression.bal:5)\n\t   trap_expression:main(trap_expression.bal:25)\n"
  },
  {
    "path": "examples/tuples/tuples.bal",
    "content": "import ballerina/io;\n \npublic function main() {\n    // Declare a tuple of length 3 where the type of each members are `string`, `int`, `boolean` respectively.\n    [string, int, boolean] person = [\"Mike\", 24, false];\n    io:println(person);\n \n    // Tuple with member type descriptors of same type is equivalent to array with a length.\n    // This is equivalent to `int[3]``.\n    [int, int, int] numbers = [1, 2, 3];\n    io:println(numbers);\n \n    // Members of a tuple can be accessed using member access expression.\n    int age = person[1];\n    io:println(age);\n \n    // Members of a tuple can be updated using member access expression in LHS of a assignment\n    person[1] = 25;\n    io:println(person);\n \n    int length = person.length();\n    // `array:length()` method can be used to get the length of a tuple\n    io:println(length);\n \n    // Tuples can be used to return multiple values from a function.\n    var personDetails = getPersonDetails();\n    io:println(personDetails);\n}\n \nfunction getPersonDetails() returns [int, boolean] {\n    return [30, true];\n}\n"
  },
  {
    "path": "examples/tuples/tuples.md",
    "content": "# Tuples\n\nThe tuple type is another structured type which creates a list of values like arrays. The main difference between the arrays and the tuples is that an array has only one type applicable to every member of its list. In contrast, in a tuple type, you can individually specify the types for each member. Tuples are most suitable for describing lists with multiple types. Tuples can be used to return multiple values from a function.\n\nTuple type can be declared as a comma separated list of types inside a square bracket `[ ]`.\n\n::: code tuples.bal :::\n\n::: out tuples.out :::\n\n## Related links\n- [Arrays](/learn/by-example/arrays)\n- [Manipulating an array `(lang.array)`](https://lib.ballerina.io/ballerina/lang.array)\n- [Filler values of a list](/learn/by-example/filler-values-of-a-list)\n- [List sub typing](/learn/by-example/list-subtyping)\n- [List equality](/learn/by-example/list-equality)\n"
  },
  {
    "path": "examples/tuples/tuples.metatags",
    "content": "description: This BBE demonstrates how to create a tuple, create a collection, create list with different member types, returning multiple values from a function, Accessing a tuple, Updating a tuple.\nkeywords: ballerina, ballerina by example, bbe, tuples, collection, size, list, multiple, tuple type, access\n\n"
  },
  {
    "path": "examples/tuples/tuples.out",
    "content": "$ bal run tuples.bal\n[\"Mike\",24,false]\n[1,2,3]\n24\n[\"Mike\",25,false]\n3\n[30,true]\n"
  },
  {
    "path": "examples/type-definitions/type_definitions.bal",
    "content": "import ballerina/io;\n\n// Defines a type named `MapArray`.\ntype MapArray map<string>[];\n\npublic function main() {\n    // Creates a `MapArray` value.\n    // `arr` has elements which are of `map<string>` type.\n    MapArray arr = [\n        {\"x\": \"foo\"},\n        {\"y\": \"bar\"}\n    ];\n\n    io:println(arr[0]);\n}\n"
  },
  {
    "path": "examples/type-definitions/type_definitions.md",
    "content": "# Type definitions\n\nA type definition gives a name for a type. The name is just an alias for the type.\n\n::: code type_definitions.bal :::\n\n::: out type_definitions.out :::"
  },
  {
    "path": "examples/type-definitions/type_definitions.metatags",
    "content": "description: This BBE demonstrates type definitions in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, type definition\n"
  },
  {
    "path": "examples/type-definitions/type_definitions.out",
    "content": "$ bal run type_definitions.bal\n{\"x\":\"foo\"}\n"
  },
  {
    "path": "examples/type-inclusion-for-records/type_inclusion_for_records.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    string name;\n    int age;\n|};\n\ntype Student record {|\n    int studentId;\n    string code;\n|};\n\n// The `PartTimeStudent` record has all the fields of `Person` and `Student`.\ntype PartTimeStudent record {|\n    *Person;\n    *Student;\n    // Overrides the `code` field in `Student`.\n    string:Char code;\n|};\n\npublic function main() {\n    PartTimeStudent student = {\n        name: \"Anne\",\n        age: 23,\n        studentId: 1001,\n        code: \"A\"\n    };\n    io:println(student);\n}\n"
  },
  {
    "path": "examples/type-inclusion-for-records/type_inclusion_for_records.md",
    "content": "# Type inclusion for records\n\nType inclusion enables you to create a record by combining fields of other records. You can include the record type `T` in the record type descriptor of another record by using the `*T` notation. This is effectively the same as copying the fields of the included records into the including record.\n\n::: code type_inclusion_for_records.bal :::\n\n::: out type_inclusion_for_records.out :::\n\n## Related links\n- [Records](/learn/by-example/records/)\n- [Open Records](/learn/by-example/open-records/)\n- [Default values for record fields](/learn/by-example/default-values-for-record-fields/)\n"
  },
  {
    "path": "examples/type-inclusion-for-records/type_inclusion_for_records.metatags",
    "content": "description: This BBE demonstrates type inclusion for records, record type inclusion, and including fields of a record.\nkeywords: ballerina, ballerina by example, bbe, record, record type, record field, inclusion, record inclusion\n"
  },
  {
    "path": "examples/type-inclusion-for-records/type_inclusion_for_records.out",
    "content": "$ bal run type_inclusion_for_records.bal\n{\"code\":\"A\",\"name\":\"Anne\",\"age\":23,\"studentId\":1001}\n"
  },
  {
    "path": "examples/type-inference/type_inference.bal",
    "content": "import ballerina/io;\n\n// `var` says that the type of the variable is from the type of expression, which is used to initialize it.\nvar x = \"str\";\n\nfunction printLines(string[] sv) {\n    // Type inference with a `foreach` statement.\n    foreach var s in sv {\n        io:println(s);\n    }\n\n}\n\npublic function main() {\n    string[] s = [x, x];\n    printLines(s);\n\n    // Infers `x`'s type as `MyClass`.\n    var x = new MyClass();\n    MyClass _ = x;\n\n    // Infers the class for `new` as `MyClass`.\n    MyClass _ = new;\n\n}\n\nclass MyClass {\n    function foo() {\n\n    }\n}\n"
  },
  {
    "path": "examples/type-inference/type_inference.md",
    "content": "# Type inference \n\nType inference is local and restricted to a single expression. Overuse of type inference can make the code harder to understand.\n\n::: code type_inference.bal :::\n\n::: out type_inference.out :::"
  },
  {
    "path": "examples/type-inference/type_inference.metatags",
    "content": "description: This BBE demonstrates type inference in Ballerina. \nkeywords:  ballerina, ballerina by example, bbe, var,\n"
  },
  {
    "path": "examples/type-inference/type_inference.out",
    "content": "$ bal run type_inference.bal\nstr\nstr\n"
  },
  {
    "path": "examples/typed-binding-pattern/typed_binding_pattern.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n\n    // The type of variable `name` will be `string` and `age` will be `int`.\n    [string, int] [name, age] = getDetails();\n    io:println(name);\n    io:println(age);\n\n    // The type of variable `profession` will be inferred from the expression `Software Engineer`.\n    var profession = \"Software Engineer\";\n    io:println(profession);\n\n    // In the following capture binding pattern, the value `Hello World` gets \n    // matched to the type `string`, resulting in a successful match and\n    // causing the value to be assigned to the variable `greeting`.\n    string greeting = \"Hello World\";\n    io:println(greeting);\n\n    // The inferred type of the following capture binding pattern will be `int|error`.\n    var response = check int:fromString(\"404\");\n    io:println(response);\n}\n\nfunction getDetails() returns [string, int] {\n    return [\"John\", 30];\n}\n"
  },
  {
    "path": "examples/typed-binding-pattern/typed_binding_pattern.md",
    "content": "# Typed binding pattern\n\nA typed binding pattern is a combination of a type and a binding pattern. It is used to create the variables occurring in the binding pattern. Use of `var` as the type means that the type is inferred. The two ways in which a typed binding pattern can be used are single use and iterative use.\n\n::: code typed_binding_pattern.bal :::\n\n::: out typed_binding_pattern.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)\n- [Single use of typed binding patterns](/learn/by-example/single-use-of-typed-binding/)\n- [Iterative use of typed binding patterns](/learn/by-example/iterative-use-of-typed-binding/)"
  },
  {
    "path": "examples/typed-binding-pattern/typed_binding_pattern.metatags",
    "content": "description: This BBE demostrates the use of a typed binding pattern and a capture binding pattern\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, typed binding pattern, capture binding pattern\n"
  },
  {
    "path": "examples/typed-binding-pattern/typed_binding_pattern.out",
    "content": "$ bal run typed_binding_pattern.bal\nJohn\n30\nSoftware Engineer\nHello World\n404\n"
  },
  {
    "path": "examples/typedesc-type/typedesc_type.bal",
    "content": "import ballerina/io;\n\ntype R record {\n    int x;\n    int y;\n};\n\n// `t` is a `typedesc` representing a record type and type `R`, which is a record is\n// assigned to it.\ntypedesc<record {}> t = R;\n\npublic function main() {\n    R r = {x: 1, y: 2};\n    any v = r;\n\n    // The `typeof` operator gets the dynamic type of a value and dynamic types for mutable\n    // structures are inherent types.\n    // It is retrieving the `typedesc` value of `v` and `t`, which are then compared.\n    io:println(typeof v === t);\n}\n"
  },
  {
    "path": "examples/typedesc-type/typedesc_type.md",
    "content": "# `typedesc` Type\n\nThe `typedesc` type is a built-in type that represents a type descriptor and is immutable (a subtype of read-only). It has a type parameter that describes the types that are described by the type descriptors that belong to that type descriptor. A `typedesc` value belongs to the `typedesc<T>` type if the type descriptor describes a type that is a subtype of `T`.\n\n::: code typedesc_type.bal :::\n\n::: out typedesc_type.out :::\n"
  },
  {
    "path": "examples/typedesc-type/typedesc_type.metatags",
    "content": "description: This BBE demonstrates the typedesc type in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, typedesc type\n"
  },
  {
    "path": "examples/typedesc-type/typedesc_type.out",
    "content": "$ bal run typedesc_type.bal\ntrue\n"
  },
  {
    "path": "examples/udp-client/udp_client.bal",
    "content": "import ballerina/io;\nimport ballerina/udp;\n\npublic function main() returns error? {\n    // Creates a new connectionless UDP client.\n    // Optionally, you can provide the address that the socket needs to bind\n    // and the timeout in seconds, which specifies the read timeout value.\n    // E.g.: `udp:Client client = new (localHost = \"localhost\", timeout = 5);`\n    udp:Client socketClient = check new;\n\n    udp:Datagram datagram = {\n        remoteHost: \"localhost\",\n        remotePort: 9090,\n        data: \"Hello Ballerina echo\".toBytes()\n    };\n\n    // Sends the data to the remote host.\n    // The parameter is a Datagram record, which contains the `remoteHost`,\n    // `remotePort`, and the `data` to be sent.\n    check socketClient->sendDatagram(datagram);\n    io:println(\"Datagram was sent to the remote host.\");\n\n    // Waits until the data is received from the remote host.\n    readonly & udp:Datagram result = check socketClient->receiveDatagram();\n    io:println(\"Received: \", string:fromBytes(result.data));\n\n    // Closes the client and releases the bound port.\n    check socketClient->close();\n}\n"
  },
  {
    "path": "examples/udp-client/udp_client.md",
    "content": "# UDP client - Send/Receive datagram\n\nThe `udp:Client` sends and receives datagrams. A `udp:Client` is created by optionally giving the address that the socket needs to bind and the timeout in seconds, which specifies the read timeout value. Once connected, `sendDatagram` and `receiveDatagram` synchronous methods are used to send and receive datagrams. Since they are synchronous methods often used in two different strands. Use this to interact with UDP servers or implement low latency connections for time-critical transmissions where data loss is acceptable. \n\n::: code udp_client.bal :::\n\n## Prerequisites\n- Run the UDP service given in the [Send/Receive datagram](/learn/by-example/udp-listener/) example.\n\nRun the client program by executing the command below.\n\n::: out udp_client.out :::\n\n## Related links\n- [`udp:Client` client object - API documentation](https://lib.ballerina.io/ballerina/udp/latest#Client)\n- [UDP Client - Specification](/spec/udp/#3-client)\n"
  },
  {
    "path": "examples/udp-client/udp_client.metatags",
    "content": "description: This Ballerina sample demonstrates how to send data to a remote UDP server.\nkeywords: ballerina, ballerina by example, bbe, socket, udp\n"
  },
  {
    "path": "examples/udp-client/udp_client.out",
    "content": "$ bal run udp_client.bal\nDatagram was sent to the remote host.\nReceived: Hello Ballerina echo\n"
  },
  {
    "path": "examples/udp-connect-client/udp_connect_client.bal",
    "content": "// This is the connection oriented client implementation of the UDP socket.\nimport ballerina/io;\nimport ballerina/udp;\n\npublic function main() returns error? {\n    // Creates a new connection-oriented UDP client by providing the\n    // `remoteHost` and the `remotePort`.\n    // Optionally, you can provide the interface that the socket needs to bind\n    // and the timeout in seconds, which specifies the read timeout value.\n    // E.g.: `udp:ConnectClient socketClient = new (\"www.ballerina.com\", 80,\n    // localHost = \"localhost\", timeout = 5);`\n    udp:ConnectClient socketClient = check new (\"localhost\", 9090);\n\n    // Sends the data to the connected remote host.\n    // The parameter is a `byte[]`, which contains the data to be sent.\n    check socketClient->writeBytes(\"Hello Ballerina echo\".toBytes());\n    io:println(\"Data was sent to the remote host.\");\n\n    // Waits until the data is received from the connected host.\n    readonly & byte[] result = check socketClient->readBytes();\n    io:println(\"Received: \", string:fromBytes(result));\n\n    // Closes the client and releases the bound port.\n    check socketClient->close();\n}\n"
  },
  {
    "path": "examples/udp-connect-client/udp_connect_client.md",
    "content": "# UDP client - Send/Receive datagram with connection\n\nThe `udp:ConnectClient` connects to a UDP socket, and then sends and receives datagrams. When connected, data may not be received from or sent to any other address. A `udp:ConnectClient` is created by giving the `remoteHost` and `remotePort`. Once connected, `writeBytes` and `readBytes` synchronous methods are used to send and receive byte streams. Since they are synchronous methods often used in two different strands. The client remains connected until it is explicitly disconnected or until it is closed. Use this to interact with UDP servers or implement low latency connections for time-critical transmissions where data loss is acceptable.\n\n::: code udp_connect_client.bal :::\n\n## Prerequisites\n- Run the UDP service given in the [Send/Receive datagram](/learn/by-example/udp-listener/) example.\n\nRun the client program by executing the command below.\n\n::: out udp_connect_client.out :::\n\n## Related links\n- [`udp:Client` client object - API documentation](https://lib.ballerina.io/ballerina/udp/latest#Client)\n- [UDP Client - Specification](/spec/udp/#3-client)\n"
  },
  {
    "path": "examples/udp-connect-client/udp_connect_client.metatags",
    "content": "description: This Ballerina sample demonstrates how to send data to a connected server.\nkeywords: ballerina, ballerina by example, bbe, socket, udp\n"
  },
  {
    "path": "examples/udp-connect-client/udp_connect_client.out",
    "content": "$ bal run udp_connect_client.bal\nData was sent to the remote host.\nReceived: Hello Ballerina echo\n"
  },
  {
    "path": "examples/udp-listener/udp_listener.bal",
    "content": "import ballerina/io;\nimport ballerina/udp;\n\n// Binds the service to the port.\n// Optionally, you can provide the `remoteHost` and `remotePort` to configure the listener\n// as a connected listener, which only reads and writes to the configured remote host.\n// E.g.: `udp:Listener(8080, remoteHost = \"www.remote-clinet.com\", remotePort = 9090)`\nservice on new udp:Listener(9090) {\n\n    // This remote method is invoked once the content is received from the\n    // client. You may replace the `onBytes` method with `onDatagram`, which\n    // reads the data as `readonly & udp:Datagram`.\n    remote function onDatagram(readonly & udp:Datagram datagram) returns udp:Datagram {\n        io:println(\"Received by listener: \", string:fromBytes(datagram.data));\n        // Echoes back the data to the same client.\n        // This is similar to calling `caller->sendDatagram(datagram);`.\n        return datagram;\n    }\n}\n"
  },
  {
    "path": "examples/udp-listener/udp_listener.md",
    "content": "# UDP service - Send/Receive datagram\n\nThe `udp:Service` allows opening up a UDP socket via a `udp:Listener`. A `udp:Listener` is created by giving the port number, to which `udp:Service` is attached. The listener accepts and serves connections from UDP clients. The `onDatagram` remote method is invoked once the content is received from the client. Use a UDP service to establish connections and communicate over UDP protocol or implement low latency connections for time-critical transmissions where data loss is acceptable.\n\n::: code udp_listener.bal :::\n\nRun the service by executing the command below.\n\n::: out udp_listener.out :::\n\n>**Tip:** You can invoke the above service via the [UDP client](/learn/by-example/udp-client/).\n\n## Related links\n- [`udp` module - API documentation](https://lib.ballerina.io/ballerina/udp/latest)\n- [UDP service - Specification](/spec/udp/#4-service)\n"
  },
  {
    "path": "examples/udp-listener/udp_listener.metatags",
    "content": "description: This Ballerina sample demonstrates read an reply to UDP clients using the UDP Listener.\nkeywords: ballerina, ballerina by example, bbe, socket, udp\n"
  },
  {
    "path": "examples/udp-listener/udp_listener.out",
    "content": "$ bal run udp_listener.bal\nReceived by listener: Hello Ballerina echo\n"
  },
  {
    "path": "examples/unary-operators/unary_operators.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    int a = 10;\n\n    // Negate the value of `a`.\n    int negatedInt = -a;\n    io:println(negatedInt);\n    \n    // Invert the bits of `a`.\n    int bitwiseInvertedInt = ~a;\n    io:println(bitwiseInvertedInt);\n\n    int:Signed8 b = 127;\n\n    // Negate the value of `b`.\n    int negatedSigned8Int = -b;\n    io:println(negatedSigned8Int);\n\n    float c = -10.5;\n\n    // Negate the value of `c`.\n    float negatedFloat = -c;\n    io:println(negatedFloat);\n    \n    // Using the `+` operator returns the value of its operand expression.\n    float unchangedFloat = +c;\n    io:println(unchangedFloat);\n\n    boolean d = true;\n\n    // Invert the boolean value of `d`.\n    boolean negatedBoolean = !d;\n    io:println(negatedBoolean);\n}\n"
  },
  {
    "path": "examples/unary-operators/unary_operators.md",
    "content": "# Unary operators\n\nBallerina supports unary operators that perform operations on a single operand. The unary `-` operator negates the value of a numeric type by changing its sign. The unary `+` operator returns the value of its numeric operand. The `~` operator inverts the bits of an integer, flipping each 0 to 1 and each 1 to 0.\n\nFor boolean values, the `!` operator inverts the boolean value, changing `true` to `false` and `false` to `true`.\n\n::: code unary_operators.bal :::\n\n::: out unary_operators.out :::\n"
  },
  {
    "path": "examples/unary-operators/unary_operators.metatags",
    "content": "description: This BBE introduces unary operators in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, operators, unary operators, bitwise operators, int, float, boolean, +, -, ~, !\n"
  },
  {
    "path": "examples/unary-operators/unary_operators.out",
    "content": "$ bal run unary_operators.bal\n-10\n-11\n-127\n10.5\n-10.5\nfalse\n"
  },
  {
    "path": "examples/unions/unions.bal",
    "content": "import ballerina/io;\n\ntype StructuredName record {\n    string firstName;\n    string lastName;\n};\n\n// A `Name` type value can be either a `StructuredName` or a `string`.\ntype Name StructuredName|string;\n\npublic function main() {\n    // `name1` is a `StructuredName`.\n    Name name1 = {\n        firstName: \"Rowan\",\n        lastName: \"Atkinson\"\n    };\n    // `name2` is a `string`.\n    Name name2 = \"Leslie Banks\";\n\n    io:println(nameToString(name1));\n    io:println(nameToString(name2));\n\n    map<string|()> grades1 = {\n        math: \"80\",\n        physics: (),\n        chemistry: \"76\"\n    };\n    // Parsing a map with grade values that are either the string\n    // representation of an integer or nil results in a map of\n    // just the non-nil grades as integers.\n    map<int>|error parseGrades1 = parseGrades(grades1);\n    io:println(parseGrades1);\n\n    map<string> grades2 = {\n        math: \"80\",\n        physics: \"N/A\",\n        chemistry: \"76\"\n    };\n    // Attempting to parse a map with string values that\n    // are not the string representation of a number results\n    // in the function terminating early, returning the error.\n    map<int>|error parseGrades2 = parseGrades(grades2);\n    io:println(parseGrades2);\n}\n\nfunction nameToString(Name nm) returns string {\n    // Checks whether `nm` belongs to `string` type.\n    if nm is string {\n        // The type of `nm` is narrowed to `string` here.\n        // Therefore, you can directly return `nm` from this\n        // function that specifies `string` as the return type.\n        return nm;\n    } else {\n        // The type of `nm` is narrowed to `StructuredName` here.\n        // Therefore, you can directly access fields defined in\n        // the `StructuredName` record.\n        return nm.firstName + \" \" + nm.lastName;\n    }\n}\n\nfunction parseGrades(map<string|()> grades) returns map<int>|error {\n    map<int> parsedGrades = {};\n\n    foreach [string, string|()] [subject, grade] in grades.entries() {\n        // If the `grade` value is `()`, continue on to the next entry.\n        if grade is () {\n            continue;\n        }\n\n        // The type of `grade` is narrowed to `string` here\n        // since we won't reach here if the value is `()`, due\n        // to the `continue` statement above.\n        // Therefore, we can directly use `grade` where a `string`\n        // value is expected.\n        int|error parsedGrade = int:fromString(grade);\n\n        // If the `parsedGrade` value is an error value, terminate the\n        // execution of this function and return the error value.\n        if parsedGrade is error {\n            return parsedGrade;\n        }\n\n        // Since we return the error from the function if `parsedGrade` is `error`,\n        // the type of `parsedGrade` is narrowed to `int` here,\n        // allowing it to be used as an `int`-typed variable when adding\n        // the value to a map of integers.\n        parsedGrades[subject] = parsedGrade;\n    }\n\n    return parsedGrades;\n}\n"
  },
  {
    "path": "examples/unions/unions.md",
    "content": "# Unions\n\n`T1|T2` is the union of the sets described by `T1` and `T2`. `T?` is completely equivalent to `T|()`. Unions are untagged. The `is` operator tests whether a value belongs to a specific type. \n\nThe `is` operator in the condition causes the declared type to be narrowed.\n\n::: code unions.bal :::\n\n::: out unions.out :::"
  },
  {
    "path": "examples/unions/unions.metatags",
    "content": "description: This BBE demonstrates unions in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, unions\n"
  },
  {
    "path": "examples/unions/unions.out",
    "content": "$ bal run unions.bal\nRowan Atkinson\nLeslie Banks\n{\"math\":80,\"chemistry\":76}\nerror(\"{ballerina/lang.int}NumberParsingError\",message=\"'string' value 'N/A' cannot be converted to 'int'\")\n"
  },
  {
    "path": "examples/url-encode-decode/tests/url_encode_decode_test.bal",
    "content": "import ballerina/test;\n\nstring[] outputs = [];\n\n// This is the mock function, which will replace the real function.\n@test:Mock {\n    moduleName: \"ballerina/io\",\n    functionName: \"println\"\n}\ntest:MockFunction mock_printLn = new();\n\npublic function mockPrint(any... val) {\n    outputs.push(val.reduce(function (any a, any b) returns string => a.toString() + b.toString(), \"\").toString());\n}\n\n@test:Config { }\nfunction testFunc() returns error? {\n    test:when(mock_printLn).call(\"mockPrint\");\n\n    // Invoking the main function\n    check main();\n    test:assertEquals(outputs.length(), 2);\n    test:assertTrue(outputs[0].includes(\"URL encoded value: data%3Dvalue\"));\n    test:assertTrue(outputs[1].includes(\"URL decoded value: data=value\"));\n}\n"
  },
  {
    "path": "examples/url-encode-decode/url_encode_decode.bal",
    "content": "import ballerina/io;\nimport ballerina/url;\n\npublic function main() returns error? {\n    string value1 = \"data=value\";\n    // Encoding a URL component into a string.\n    string encoded = check url:encode(value1, \"UTF-8\");\n    io:println(\"URL encoded value: \", encoded);\n\n    string value2 = \"data%3Dvalue\";\n    // Decoding an encoded URL component into a string.\n    string decoded = check url:decode(value2, \"UTF-8\");\n    io:println(\"URL decoded value: \", decoded);\n}\n"
  },
  {
    "path": "examples/url-encode-decode/url_encode_decode.md",
    "content": "# URL encode/decode operations\n\nBallerina URL API supports encoding/decoding a URL or part of a URL.\n\nFor more information on the underlying module, see the [`url` module](https://lib.ballerina.io/ballerina/url/latest/).\n\n::: code url_encode_decode.bal :::\n\nTo run this sample, place the source code in a file named `url_encode_decode.bal` and use the `bal run` command.\n\n::: out url_encode_decode.out :::"
  },
  {
    "path": "examples/url-encode-decode/url_encode_decode.metatags",
    "content": "description: BBE on how to perform encoding/decoding a URL or part of a URL.\nkeywords: ballerina, ballerina by example, url encoding, url decoding\n"
  },
  {
    "path": "examples/url-encode-decode/url_encode_decode.out",
    "content": "$ bal run url_encode_decode.bal\nURL encoded value: data%3Dvalue\nURL decoded value: data=value\n"
  },
  {
    "path": "examples/uuid-generation/uuid_generation.bal",
    "content": "import ballerina/io;\nimport ballerina/uuid;\n\npublic function main() returns error? {\n    // Generates a UUID of type 1 as a string.\n    string uuid1String = uuid:createType1AsString();\n    io:println(\"UUID of type 1 as a string: \", uuid1String);\n\n    // Generates a UUID of type 1 as a UUID record.\n    uuid:Uuid uuid1Record = check uuid:createType1AsRecord();\n    io:println(\"UUID of type 1 as a record: \", uuid1Record);\n\n    // Generates a UUID of type 3 as a string.\n    string uuid3String = check uuid:createType3AsString(\n    uuid:NAME_SPACE_DNS, \"ballerina.io\");\n    io:println(\"UUID of type 3 as a string: \", uuid3String);\n\n    // Generates a UUID of type 3 as a record.\n    uuid:Uuid uuid3Record = check uuid:createType3AsRecord(\n    uuid:NAME_SPACE_DNS, \"ballerina.io\");\n    io:println(\"UUID of type 3 as a record: \", uuid3Record);\n\n    // Generates a UUID of type 4 as a string.\n    string uuid4String = uuid:createType4AsString();\n    io:println(\"UUID of type 4 as a string: \", uuid4String);\n\n    // Generates a UUID of type 4 as a UUID record.\n    uuid:Uuid uuid4Record = check uuid:createType4AsRecord();\n    io:println(\"UUID of type 4 as a record: \", uuid4Record);\n\n    // Generates a UUID of type 5 as a string.\n    string uuid5String = check uuid:createType5AsString(\n                                    uuid:NAME_SPACE_DNS, \"ballerina.io\");\n    io:println(\"UUID of type 5 as a string: \", uuid5String);\n\n    // Generates a UUID of type 5 as a record.\n    uuid:Uuid uuid5Record = check uuid:createType5AsRecord(\n                                       uuid:NAME_SPACE_DNS, \"ballerina.io\");\n    io:println(\"UUID of type 5 as a record: \", uuid5Record);\n\n    // Generates a nil UUID as a string.\n    string nilUuidString = uuid:nilAsString();\n    io:println(\"Nil UUID as a string: \", nilUuidString);\n\n    // Generates a nil UUID as a UUID record.\n    uuid:Uuid nilUuidRecord = uuid:nilAsRecord();\n    io:println(\"Nil UUID as a record: \", nilUuidRecord);\n}\n"
  },
  {
    "path": "examples/uuid-generation/uuid_generation.md",
    "content": "# Generate UUID\n\nThe `uuid` library provides functions related to UUIDs (Universal Unique Identifiers).\n\nFor more information on the underlying module, see the [`uuid` module](https://lib.ballerina.io/ballerina/uuid/latest/).\n\n::: code uuid_generation.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out uuid_generation.out :::"
  },
  {
    "path": "examples/uuid-generation/uuid_generation.metatags",
    "content": "description: BBE on how to to generate different types of UUIDs.\nkeywords: ballerina, ballerina by examples, bbe, uuid, type\n"
  },
  {
    "path": "examples/uuid-generation/uuid_generation.out",
    "content": "$ bal run uuid_generation.bal\nUUID of type 1 as a string: 01eb3f05-fbf8-1b92-8711-dc6a5719bb63\nUUID of type 1 as a record: {\"timeLow\":32194310,\"timeMid\":7997,\"timeHiAndVersion\":5524,\"clockSeqHiAndReserved\":170,\"clockSeqLo\":116,\"node\":82490221220318}\nUUID of type 3 as a string: cea5c405-7d11-3fbb-bdfb-9b68497be28b\nUUID of type 3 as a record: {\"timeLow\":3466970117,\"timeMid\":32017,\"timeHiAndVersion\":16315,\"clockSeqHiAndReserved\":189,\"clockSeqLo\":251,\"node\":170872211759755}\nUUID of type 4 as a string: 73e0d74e-8a4a-40ce-b1d9-b5b522533852\nUUID of type 4 as a record: {\"timeLow\":2795821625,\"timeMid\":5327,\"timeHiAndVersion\":20251,\"clockSeqHiAndReserved\":161,\"clockSeqLo\":71,\"node\":59752348973988}\nUUID of type 5 as a string: 08aab8bc-c69e-5ea8-8a52-dbb645c67fb5\nUUID of type 5 as a record: {\"timeLow\":145406140,\"timeMid\":50846,\"timeHiAndVersion\":24232,\"clockSeqHiAndReserved\":138,\"clockSeqLo\":82,\"node\":241575901167541}\nNil UUID as a string: 00000000-0000-0000-0000-000000000000\nNil UUID as a record: {\"timeLow\":0,\"timeMid\":0,\"timeHiAndVersion\":0,\"clockSeqHiAndReserved\":0,\"clockSeqLo\":0,\"node\":0}\n"
  },
  {
    "path": "examples/uuid-operations/uuid_operations.bal",
    "content": "import ballerina/io;\nimport ballerina/uuid;\n\npublic function main() returns error? {\n    // Tests a string to see if it is a valid UUID.\n    boolean valid = uuid:validate(\"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID validated: \", valid.toString());\n\n    // Detects the RFC version of a UUID.\n    uuid:Version v = check uuid:getVersion(\n                                \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID version: \", v.toString());\n\n    // Converts a UUID string to an array of bytes.\n    byte[] uuidBytes1 = check uuid:toBytes(\n                                  \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID bytes: \", uuidBytes1);\n\n    // Converts a UUID string to a UUID record.\n    uuid:Uuid uuidRecord1 = check uuid:toRecord(\n                            \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID record: \", uuidRecord1);\n\n    uuid:Uuid uuidRecord = {\n        timeLow: 1133987422,\n        timeMid: 13817,\n        timeHiAndVersion: 4587,\n        clockSeqHiAndReserved: 173,\n        clockSeqLo: 193,\n        node: 2485377957890\n    };\n    // Converts a UUID record to a UUID string.\n    string uuidString1 = check uuid:toString(uuidRecord);\n    io:println(\"UUID string: \", uuidString1);\n\n    // Converts a UUID record to an array of bytes.\n    byte[] uuidBytes2 = check uuid:toBytes(uuidRecord);\n    io:println(\"UUID bytes: \", uuidBytes2);\n\n    // Converts a UUID bytes array to a UUID string.\n    string uuidString2 = check uuid:toString(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID string: \", uuidString2);\n\n    // Converts a UUID bytes array to a UUID record.\n    uuid:Uuid uuidRecord2 = check uuid:toRecord(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID record: \", uuidRecord2);\n}\n"
  },
  {
    "path": "examples/uuid-operations/uuid_operations.md",
    "content": "# UUID operations\n\nThe `uuid` library provides functions related to UUIDs (Universal Unique Identifiers).\n\nFor more information on the underlying module, see the [`uuid` module](https://lib.ballerina.io/ballerina/uuid/latest/).\n\n::: code uuid_operations.bal :::\n\nTo run this sample use the `bal run` command.\n\n::: out uuid_operations.out :::"
  },
  {
    "path": "examples/uuid-operations/uuid_operations.metatags",
    "content": "description: BBE on how to to perform operations on UUIDs.\nkeywords: ballerina, ballerina by examples, bbe, uuid, version, validation, string, record, bytes\n"
  },
  {
    "path": "examples/uuid-operations/uuid_operations.out",
    "content": "$ bal run uuid_operations.bal\nUUID validated: true\nUUID version: V1\nUUID bytes: [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]\nUUID record: {\"timeLow\":1133987422,\"timeMid\":13817,\"timeHiAndVersion\":4587,\"clockSeqHiAndReserved\":173,\"clockSeqLo\":193,\"node\":2485377957890}\nUUID string: 4397465e-35f9-11eb-adc1-0242ac120002\nUUID bytes: [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]\nUUID string: 4397465e-35f9-11eb-adc1-0242ac120002\nUUID record: {\"timeLow\":1133987422,\"timeMid\":13817,\"timeHiAndVersion\":4587,\"clockSeqHiAndReserved\":173,\"clockSeqLo\":193,\"node\":2485377957890}\n"
  },
  {
    "path": "examples/variables-and-types/variables_and_types.bal",
    "content": "import ballerina/io;\n\n// Modules and functions can declare variables. You can see both in this example.\n// Here we declare a variable `greeting` of type `string` and initialize it to `\"Hello\"`.\nstring greeting = \"Hello\";\n\npublic function main() {\n    // Assignments are statements not expressions.\n    string name = \"Ballerina\";\n\n    io:println(greeting, \" \", name);\n}\n"
  },
  {
    "path": "examples/variables-and-types/variables_and_types.md",
    "content": "# Variables and types\n\nA variable has a type, which constrains what values the variable can hold. There is a built-in set of named types, including `int`, `float`, `boolean`, `string`.\n\n::: code variables_and_types.bal :::\n\n::: out variables_and_types.out :::"
  },
  {
    "path": "examples/variables-and-types/variables_and_types.metatags",
    "content": "description: This BBE introduces variables and types in Ballerina.\nkeywords:  ballerina, ballerina by example, bbe, variables, types, type system"
  },
  {
    "path": "examples/variables-and-types/variables_and_types.out",
    "content": "$ bal run variables_and_types.bal\nHello Ballerina\n"
  },
  {
    "path": "examples/visibility-of-object-fields-and-methods/visibility_of_object_fields_and_methods.bal",
    "content": "import ballerina/io;\n\nclass Engineer {\n    // The `public` field is accessible outside the module as well.\n    public string name;\n\n    // The `private` field is only accessible within the class.\n    private decimal salary;\n\n    // The `init` method initializes the object.\n    function init(string name) {\n        self.name = name;\n        self.salary = 0;\n    }\n\n    // The default method is only accessible within the module.\n    function getName() returns string {\n        return self.name;\n    }\n\n    // The `private` method is only accessible within the class definition.\n    private function addBonus(decimal salary) returns decimal {\n        return salary + 100;\n    }\n\n    // The `public` method is accessible outside the module as well.\n    public function getSalary() returns decimal {\n        return self.addBonus(self.salary);\n    }\n\n    public function setSalary(decimal salary) {\n        self.salary = salary;\n    }\n}\n\npublic function main() {\n    // Arguments to `new` are passed as arguments to `init`.\n    Engineer engineer = new Engineer(\"Alice\");\n    engineer.setSalary(1000);\n\n    io:println(engineer.name);\n    io:println(engineer.getName());\n    io:println(engineer.getSalary());\n}\n"
  },
  {
    "path": "examples/visibility-of-object-fields-and-methods/visibility_of_object_fields_and_methods.md",
    "content": "# Visibility of object fields and methods\n\nThe visibility of each field and method of an object in Ballerina can be set to `private`, `public`, or default (without a visibility qualifier).\n\n- If the visibility is set to `private`, the field or method is only accessible within the `class` definition.\n- If the visibility is set to `public`, the field or method is accessible outside the module as well.\n- If the visibility is set to default (no visibility qualifier), the field or method is only accessible within the module.\n\nAttempting to access a private field or method from outside the class definition will result in a compile-time error.\n\n::: code visibility_of_object_fields_and_methods.bal :::\n\n::: out visibility_of_object_fields_and_methods.out :::\n\n## Related links\n- [Object](/learn/by-example/object/)\n- [Defining classes](/learn/by-example/defining-classes/)\n- [Object value from class definition](/learn/by-example/object-value-from-class-definition/)\n"
  },
  {
    "path": "examples/visibility-of-object-fields-and-methods/visibility_of_object_fields_and_methods.metatags",
    "content": "description: This BBE demonstrates an access modifier in the class definition, modifying the visibility of object fields and methods, invoking methods and fields, and defining a class in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, class, object, access modifier, visibility\n"
  },
  {
    "path": "examples/visibility-of-object-fields-and-methods/visibility_of_object_fields_and_methods.out",
    "content": "$ bal run visibility_of_object_fields_and_methods.bal\nAlice\nAlice\n1100\n"
  },
  {
    "path": "examples/waiting-for-workers/waiting_for_workers.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    io:println(\"Initializing\");\n\n    worker A {\n        io:println(\"In worker A\");\n    }\n\n    io:println(\"In function worker\");\n\n    // A worker (function or named) can use `wait` to wait for a named worker.\n    wait A;\n\n    io:println(\"After wait A\");\n}\n"
  },
  {
    "path": "examples/waiting-for-workers/waiting_for_workers.md",
    "content": "# Waiting for workers\n\nNamed workers can continue to execute after the function's default worker terminates and the function returns. \n\nA worker (function or named) can use `wait` to wait for a named worker.\n\n::: code waiting_for_workers.bal :::\n\n::: out waiting_for_workers.out :::"
  },
  {
    "path": "examples/waiting-for-workers/waiting_for_workers.metatags",
    "content": "description: This BBE demonstrates waiting for workers\nkeywords: ballerina, ballerina by example, bbe, worker, wait\n"
  },
  {
    "path": "examples/waiting-for-workers/waiting_for_workers.out",
    "content": "$ bal run waiting_for_workers.bal\nInitializing\nIn function worker\nIn worker A\nAfter wait A\n"
  },
  {
    "path": "examples/websocket-basic-sample/tests/websocket_basic_sample_test.bal",
    "content": "import ballerina/test;\nimport ballerina/websocket;\n\nstring msg = \"hey\";\n\n@test:Config {}\nfunction testText() returns websocket:Error? {\n    websocket:Client wsClient = check new(\"ws://localhost:9090/chat\");\n    check wsClient->writeMessage(msg);\n    string serviceReply = check wsClient->readMessage();\n    test:assertEquals(serviceReply, \"Hello!, How are you?\");\n    check wsClient->close();\n}\n\n"
  },
  {
    "path": "examples/websocket-basic-sample/websocket_basic_sample.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\nservice /chat on new websocket:Listener(9090) {\n\n    resource function get .() returns websocket:Service {\n        // Accept the WebSocket upgrade by returning a `websocket:Service`.\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    // This `remote method` is triggered when a new message is received\n    // from a client. It accepts `anydata` as the function argument. The received data \n    // will be converted to the data type stated as the function argument.\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        io:println(chatMessage);\n        check caller->writeMessage(\"Hello!, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-basic-sample/websocket_basic_sample.md",
    "content": "# WebSocket service - Send/Receive message\n\nThe `websocket:Service` allows opening up a port via a `websocket:Listener`. A `websocket:Listener` is created by giving the port number, to which `websocket:Service` is attached. The listener accepts and serves connections from WebSocket clients. The `onMessage` remote method receives incoming WebSocket messages. There are a few other remote methods to receive other types of WebSocket messages. The `onOpen` remote method is dispatched as soon as the WebSocket handshake is completed and the connection is established, `onPing` and `onPong` remote methods are dispatched upon receiving ping and pong messages respectively, `onIdleTimeout` remote method is dispatched when the idle timeout is reached, `onClose` is dispatched when a close frame with a `statusCode` and a `reason` is received and finally the `onError` is dispatched when an error occurs in the WebSocket connection. Use this service to implement user applications where you need to establish two-way communication over the WebSocket protocol.\n\n::: code websocket_basic_sample.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_basic_sample.out :::\n\n>**Tip:** You can invoke the above service via the [WebSocket client](/learn/by-example/websocket-client/).\n\n## Related links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket service - Specification](/spec/websocket/#3-service-types)\n"
  },
  {
    "path": "examples/websocket-basic-sample/websocket_basic_sample.metatags",
    "content": "description: This BBE demonstrates the basic functions of a WebSocket server.\nkeywords: ballerina, ballerina by example, bbe, websocket, basic sample, server\n"
  },
  {
    "path": "examples/websocket-basic-sample/websocket_basic_sample.out",
    "content": "$ bal run websocket_basic_sample.bal\n"
  },
  {
    "path": "examples/websocket-binary-client/websocket_binary_client.md",
    "content": "# Handle binary messages with client\n\nThe WebSocket client can be used to connect to and interact with a WebSocket server in a Synchronous manner.This example demonstrates how to read and write binary messages using ballerina websocket client.\n\nFor more information on the underlying module, see the [`websocket` module](https://lib.ballerina.io/ballerina/websocket/latest/).\n\n::: code ./examples/websocket-binary-client/websocket_binary_client.bal :::\n\n::: out ./examples/websocket-binary-client/websocket_binary_client.out :::"
  },
  {
    "path": "examples/websocket-client/websocket_client.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Create a new WebSocket client.\n    websocket:Client chatClient = check new (\"ws://localhost:9090/chat\");\n\n    // Write a message to the server using `writeMessage`.\n    // This function accepts `anydata`. If the given type is a `byte[]`, the message will be sent as\n    // binary frames and the rest of the data types will be sent as text frames.\n    check chatClient->writeMessage(\"Hello John!\");\n\n    // Read a message sent from the server using `readMessage`.\n    // The contextually-expected data type is inferred from the LHS variable type. The received data\n    // will be converted to that particular data type.\n    string message = check chatClient->readMessage();\n    io:println(message);\n}\n"
  },
  {
    "path": "examples/websocket-client/websocket_client.md",
    "content": "# WebSocket client - Send/Receive message\n\nThe `websocket:Client` connects to a given WebSocket server, and then sends and receives WebSocket frames. A `websocket:Client` is created by giving the URL of the server. Once connected, `writeMessage` and `readMessage` synchronous methods are used to send and receive messages. Since they are synchronous methods often used in two different strands. Use this to interact with WebSocket servers or implement user applications based on WebSocket.\n\n::: code websocket_client.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Send/Receive message](/learn/by-example/websocket-basic-sample/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client.out :::\n\n## Related links\n- [`websocket:Client` client object - API documentation](https://lib.ballerina.io/ballerina/websocket/latest#Client)\n- [WebSocket Client - Specification](/spec/websocket/#4-client)\n"
  },
  {
    "path": "examples/websocket-client/websocket_client.metatags",
    "content": "description: This BBE demonstrates how a WebSocket client can be used to connect to and interact with a WebSocket server using Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, sync, client\n"
  },
  {
    "path": "examples/websocket-client/websocket_client.out",
    "content": "$ bal run websocket_text_client.bal\nHello!, How are you?\n"
  },
  {
    "path": "examples/websocket-client-basic-auth/websocket_client_basic_auth.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the Basic authentication secured APIs.\n    // The client is enriched with the `Authorization: Basic <token>` header by\n    // passing the `websocket:CredentialsConfig` for the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            username: \"ldclakmal\",\n            password: \"ldclakmal@123\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-basic-auth/websocket_client_basic_auth.md",
    "content": "# WebSocket client - Basic authentication\n\nThe `websocket:Client` can connect to a service that is secured with basic authentication by adding the `Authorization: Basic <token>` header to the initial HTTP request. The username and password for basic authentication can be specified in the `auth` field of the client configuration. \n\n::: code websocket_client_basic_auth.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Basic authentication file user store](/learn/by-example/websocket-service-basic-auth-file-user-store/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_basic_auth.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-basic-auth/websocket_client_basic_auth.metatags",
    "content": "description: BBE on how to secure WebSocket client with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, basic auth\n"
  },
  {
    "path": "examples/websocket-client-basic-auth/websocket_client_basic_auth.out",
    "content": "$ bal run websocket_client_basic_auth.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-bearer-token-auth/websocket_client_bearer_token_auth.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:BearerTokenConfig` for the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            token: \"56ede317-4511-44b4-8579-a08f094ee8c5\"\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-bearer-token-auth/websocket_client_bearer_token_auth.md",
    "content": "# WebSocket client - Bearer token authentication\n\nThe `websocket:Client` can connect to a service that is secured with bearer token authentication by adding the `Authorization: Bearer <token>` header to the initial HTTP request. The bearer token can be specified in the `auth` field of the client configuration.\n\n::: code websocket_client_bearer_token_auth.bal :::\n\nRun the client program by executing the command below.\n\n::: out websocket_client_bearer_token_auth.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-bearer-token-auth/websocket_client_bearer_token_auth.metatags",
    "content": "description: BBE on how to secure WebSocket client with Bearer token auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, jwt auth\n"
  },
  {
    "path": "examples/websocket-client-bearer-token-auth/websocket_client_bearer_token_auth.out",
    "content": "$ bal run websocket_client_bearer_token_auth.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-mutual-ssl/websocket_client_mutual_ssl.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // A WebSocket client can be configured to initiate new connections that are\n    // secured via mutual SSL.\n    // The `websocket:ClientSecureSocket` record provides the SSL-related configurations.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        secureSocket = {\n            key: {\n                certFile: \"../resource/path/to/public.crt\",\n                keyFile: \"../resource/path/to/private.key\"\n            },\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-mutual-ssl/websocket_client_mutual_ssl.md",
    "content": "# WebSocket client - Mutual SSL\n\nThe `websocket:Client` allows you to open up a connection secured with mutual SSL (mTLS), which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. A `websocket:Client` secured with mutual SSL is created by providing the `secureSocket` configurations which require the client's public certificate as the `certFile`, the client's private key as the `keyFile`, and the server's certificate as the `cert`. Use this to interact with mTLS-encrypted WebSocket servers.\n\n::: code websocket_client_mutual_ssl.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Mutual SSL](/learn/by-example/websocket-service-mutual-ssl/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_mutual_ssl.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket SSL/TLS - Specification](/spec/websocket/#5-securing-the-websocket-connections)\n\n"
  },
  {
    "path": "examples/websocket-client-mutual-ssl/websocket_client_mutual_ssl.metatags",
    "content": "description: BBE on how to secure WebSocket client with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, websocket, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/websocket-client-mutual-ssl/websocket_client_mutual_ssl.out",
    "content": "$ bal run websocket_client_mutual_ssl.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-oauth2-client-cred-grant-type/websocket_client_oauth2_client_cred_grant_type.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the OAuth2 secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:OAuth2ClientCredentialsGrantConfig` for the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-oauth2-client-cred-grant-type/websocket_client_oauth2_client_cred_grant_type.md",
    "content": "# WebSocket client - OAuth2 client credentials grant type\n\nThe `websocket:Client` can connect to a service that is secured with the OAuth2 client credentials grant type by adding the `Authorization: Bearer <token>` header to the initial HTTP request. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n::: code websocket_client_oauth2_client_cred_grant_type.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [OAuth2](/learn/by-example/websocket-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_oauth2_client_cred_grant_type.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-oauth2-client-cred-grant-type/websocket_client_oauth2_client_cred_grant_type.metatags",
    "content": "description: BBE on how to secure WebSocket client with OAuth2 client credentials grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, oauth2, client credentials grant type\n"
  },
  {
    "path": "examples/websocket-client-oauth2-client-cred-grant-type/websocket_client_oauth2_client_cred_grant_type.out",
    "content": "$ bal run websocket_client_oauth2_client_credentials_grant_type.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-oauth2-jwt-bearer-grant-type/websocket_client_oauth2_jwt_bearer_grant_type.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the OAuth2 secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:OAuth2JwtBearerGrantConfig` for the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/foo/bar\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            assertion: \"eyJhbGciOiJFUzI1NiIsImtpZCI6Ij[...omitted for brevity...]\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-oauth2-jwt-bearer-grant-type/websocket_client_oauth2_jwt_bearer_grant_type.md",
    "content": "# WebSocket client - OAuth2 JWT bearer grant type\n\nThe `websocket:Client` can connect to a service that is secured with the OAuth2 JWT bearer grant type by adding the `Authorization: Bearer <token>` header to the initial HTTP request. The required configurations for this grant type can be specified in the `auth` field of the client configuration.\n\n::: code websocket_client_oauth2_jwt_bearer_grant_type.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [OAuth2](/learn/by-example/websocket-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_oauth2_jwt_bearer_grant_type.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-oauth2-jwt-bearer-grant-type/websocket_client_oauth2_jwt_bearer_grant_type.metatags",
    "content": "description: BBE on how to secure WebSocket client with OAuth2 JWT bearer grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, oauth2, jwt bearer grant type\n"
  },
  {
    "path": "examples/websocket-client-oauth2-jwt-bearer-grant-type/websocket_client_oauth2_jwt_bearer_grant_type.out",
    "content": "$ bal run websocket_client_oauth2_jwt_bearer_grant_type.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-oauth2-password-grant-type/websocket_client_oauth2_password_grant_type.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\nimport ballerina/oauth2;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the OAuth2 secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:OAuth2PasswordGrantConfig` to the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            tokenUrl: \"https://localhost:9445/oauth2/token\",\n            username: \"admin\",\n            password: \"admin\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            refreshConfig: oauth2:INFER_REFRESH_CONFIG,\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-oauth2-password-grant-type/websocket_client_oauth2_password_grant_type.md",
    "content": "# WebSocket client - OAuth2 password grant type\n\nThe `websocket:Client` can connect to a service that is secured with the OAuth2 password grant type by adding the `Authorization: Bearer <token>` header to the initial HTTP request. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this grant type when you need to exchange the user's credentials for an access token.\n\n::: code websocket_client_oauth2_password_grant_type.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [OAuth2](/learn/by-example/websocket-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_oauth2_password_grant_type.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-oauth2-password-grant-type/websocket_client_oauth2_password_grant_type.metatags",
    "content": "description: BBE on how to secure WebSocket client with OAuth2 password grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, oauth2, password grant type\n"
  },
  {
    "path": "examples/websocket-client-oauth2-password-grant-type/websocket_client_oauth2_password_grant_type.out",
    "content": "$ bal run websocket_client_oauth2_password_grant_type.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-oauth2-refresh-token-grant-type/websocket_client_oauth2_refresh_token_grant_type.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the OAuth2 secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:OAuth2RefreshTokenGrantConfig` for the `auth` configuration of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            refreshUrl: \"https://localhost:9445/oauth2/token\",\n            refreshToken: \"24f19603-8565-4b5f-a036-88a945e1f272\",\n            clientId: \"FlfJYKBD2c925h4lkycqNZlC2l4a\",\n            clientSecret: \"PJz0UhTJMrHOo68QQNpvnqAY_3Aa\",\n            scopes: \"admin\",\n            clientConfig: {\n                secureSocket: {\n                    cert: \"../resource/path/to/public.crt\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-oauth2-refresh-token-grant-type/websocket_client_oauth2_refresh_token_grant_type.md",
    "content": "# WebSocket client - OAuth2 refresh token grant type\n\nThe `websocket:Client` can connect to a service that is secured with the OAuth2 refresh token grant type by adding the `Authorization: Bearer <token>` header to the initial HTTP request. The required configurations for this grant type can be specified in the `auth` field of the client configuration. Use this to retrieve an access token automatically when it is expired.\n\n::: code websocket_client_oauth2_refresh_token_grant_type.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [OAuth2](/learn/by-example/websocket-service-oauth2/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_oauth2_refresh_token_grant_type.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-oauth2-refresh-token-grant-type/websocket_client_oauth2_refresh_token_grant_type.metatags",
    "content": "description: BBE on how to secure WebSocket client with OAuth2 refresh token grant type in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, oauth2, refresh token grant type\n"
  },
  {
    "path": "examples/websocket-client-oauth2-refresh-token-grant-type/websocket_client_oauth2_refresh_token_grant_type.out",
    "content": "$ bal run websocket_client_oauth2_refresh_token_grant_type.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-payload-constraint-validation/websocket_client_payload_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerina/io;\nimport ballerina/websocket;\n\n// Add a constraint for the maximum length.\n@constraint:String {\n    maxLength: 20\n}\npublic type Chat string;\n\npublic function main() returns error? {\n    websocket:Client chatClient = check new (\"ws://localhost:9090/chat\");\n    check chatClient->writeMessage(\"Hello John!\");\n    // Run `readMessage()` in a loop in a separate strand to continuously read messages.\n    Chat message = check chatClient->readMessage();\n    io:println(message);\n}\n"
  },
  {
    "path": "examples/websocket-client-payload-constraint-validation/websocket_client_payload_constraint_validation.md",
    "content": "# WebSocket client - Payload constraint validation\n\nThe Ballerina constraint package allows you to add additional constraints to the received payload. Through client payload constraint validation, the payload can be validated according to the defined constraints. The constraint validation happens along with the data binding step in the `readMessage` remote method. Constraints can be added to a given data type using different annotations. If the validation fails, a `PayloadBindingError` will be returned with the validation details. Use this to validate the receiving payload, which allows you to guard against unnecessary processing and malicious payloads.\n\n::: code websocket_client_payload_constraint_validation.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Send/Receive message](/learn/by-example/websocket-basic-sample/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_payload_constraint_validation.out :::\n\n## Related links\n- [`websocket:Client` client object - API documentation](https://lib.ballerina.io/ballerina/websocket/latest#Client)\n- [WebSocket Client - Specification](/spec/websocket/#4-client)\n- [Constraint BBE](/learn/by-example/constraint-validations/)\n"
  },
  {
    "path": "examples/websocket-client-payload-constraint-validation/websocket_client_payload_constraint_validation.metatags",
    "content": "description: BBE demonstrates the constraint validation capability of the WebSocket client.\nkeywords: ballerina, ballerina by example, bbe, websocket, data binding, client, constraint, validation\n"
  },
  {
    "path": "examples/websocket-client-payload-constraint-validation/websocket_client_payload_constraint_validation.out",
    "content": "$ bal run websocket_client_payload_constraint_validation.bal\nHello!, How are you?\n"
  },
  {
    "path": "examples/websocket-client-self-signed-jwt-auth/websocket_client_self_signed_jwt_auth.bal",
    "content": "import ballerina/io;\nimport ballerina/websocket;\n\npublic function main() returns error? {\n    // Defines the WebSocket client to call the JWT authentication secured APIs.\n    // The client is enriched with the `Authorization: Bearer <token>` header by\n    // passing the `websocket:JwtIssuerConfig` for the `auth` configuration of the\n    // client. A self-signed JWT is issued before the request is sent.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        auth = {\n            username: \"ballerina\",\n            issuer: \"wso2\",\n            audience: [\"ballerina\", \"ballerina.org\", \"ballerina.io\"],\n            keyId: \"5a0b754-895f-4279-8843-b745e11a57e9\",\n            jwtId: \"JlbmMiOiJBMTI4Q0JDLUhTMjU2In\",\n            customClaims: { \"scp\": \"admin\" },\n            expTime: 3600,\n            signatureConfig: {\n                config: {\n                    keyFile: \"../resource/path/to/private.key\"\n                }\n            }\n        },\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-self-signed-jwt-auth/websocket_client_self_signed_jwt_auth.md",
    "content": "# WebSocket client - Self signed JWT authentication\n\nThe `websocket:Client` can connect to a service that is secured with self-signed JWT by adding the `Authorization: Bearer <token>` header by passing the `websocket:JwtIssuerConfig` to the `auth` configuration of the client. A self-signed JWT is issued before the request is sent.\n\n::: code websocket_client_self_signed_jwt_auth.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [JWT authentication](/learn/by-example/websocket-service-jwt-auth/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_self_signed_jwt_auth.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-client-self-signed-jwt-auth/websocket_client_self_signed_jwt_auth.metatags",
    "content": "description: BBE on how to secure WebSocket client with self-signed JWT Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, jwt auth\n"
  },
  {
    "path": "examples/websocket-client-self-signed-jwt-auth/websocket_client_self_signed_jwt_auth.out",
    "content": "$ bal run websocket_client_self_signed_jwt_auth.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-client-ssl-tls/websocket_client_ssl_tls.bal",
    "content": "import ballerina/websocket;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // A WebSocket client can be configured to communicate through WSS as well.\n    // To secure a client using TLS/SSL, the client needs to be configured with\n    // a certificate file of the listener.\n    // The `websocket:ClientSecureSocket` record provides the SSL-related configurations of the client.\n    websocket:Client chatClient = check new (\"wss://localhost:9090/chat\",\n        secureSocket = {\n            cert: \"../resource/path/to/public.crt\"\n        }\n    );\n    check chatClient->writeMessage(\"Hello, John!\");\n    string chatMessage = check chatClient->readMessage();\n    io:println(chatMessage);\n}\n"
  },
  {
    "path": "examples/websocket-client-ssl-tls/websocket_client_ssl_tls.md",
    "content": "# WebSocket client - SSL/TLS\n\nThe `websocket:Client` secured with SSL/TLS connects to a given SSL/TLS-secured WebSocket server (WSS). A `websocket:Client` secured with SSL/TLS is created by providing the `secureSocket` configurations which require the server's public certificate as the `cert`. Use this to interact with TLS-encrypted WebSocket servers.\n\n::: code websocket_client_ssl_tls.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [SSL/TLS](/learn/by-example/websocket-service-ssl-tls/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_client_ssl_tls.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket SSL/TLS - Specification](/spec/websocket/#5-securing-the-websocket-connections)\n"
  },
  {
    "path": "examples/websocket-client-ssl-tls/websocket_client_ssl_tls.metatags",
    "content": "description: BBE on how to secure WebSocket client with SSL.\nkeywords: ballerina, ballerina by example, bbe, websocket, wss, ssl, tls\n"
  },
  {
    "path": "examples/websocket-client-ssl-tls/websocket_client_ssl_tls.out",
    "content": "$ bal run http_client_ssl_tls.bal\nHello, How are you?\n"
  },
  {
    "path": "examples/websocket-query-parameter/websocket_query_parameter.bal",
    "content": "import ballerina/websocket;\n\nservice /chat on new websocket:Listener(9090) {\n\n    // The `userName` parameter in the resource method is treated as a query parameter,\n    // which is extracted from the request URI. For example, invoking this service with\n    // the URI `ws://localhost:9090/chat?userName=John` passes `John` as the value\n    // to the `userName` parameter defined in the resource method.\n    resource function get .(string userName) returns websocket:Service {\n        return new ChatService(userName);\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n    private final string userName;\n\n    function init(string userName) {\n        self.userName = userName;\n    }\n\n    remote function onOpen(websocket:Caller caller) returns error? {\n        check caller->writeMessage(string `Welcome ${self.userName}!`);\n    }\n}\n"
  },
  {
    "path": "examples/websocket-query-parameter/websocket_query_parameter.md",
    "content": "# WebSocket service - Query parameter\n\nThe parameter in the `get` resource method represents the query segment of the request URL. The parameter name should match the query key, and its value is mapped at runtime by extracting it from the URL. Supported types for query parameters include `string`, `int`, `float`, `boolean`, and `decimal`. Query parameter types can be nilable (e.g., `string? bar`). When a request contains query segments, retrieving them as resource arguments is simpler and highly recommended. Alternatively, the `http:Request` object can be used as the parameter of the `get` resource method, which also exposes methods to retrieve query parameters as well.\n\n::: code websocket_query_parameter.bal :::\n\nRun the service as follows.\n\n::: out websocket_query_parameter.server.out :::\n\n>**Tip:** You can invoke the above service via the [WebSocket client](/learn/by-example/websocket-client/).\n\n\n## Related links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket service - Specification](/spec/websocket/#31-upgrade-service)"
  },
  {
    "path": "examples/websocket-query-parameter/websocket_query_parameter.metatags",
    "content": "description: This example is on how to extract the query parameters from websocket URL.\nkeywords: ballerina, ballerina by example, bbe, websocket service, query parameter\n"
  },
  {
    "path": "examples/websocket-query-parameter/websocket_query_parameter.server.out",
    "content": "$ bal run websocket_query_parameter.bal\n"
  },
  {
    "path": "examples/websocket-retry-client/websocket_retry_client.bal",
    "content": "import ballerina/websocket;\n\npublic function main() returns error? {\n    websocket:Client chatRetryClient = check new (\"ws://localhost:9090/chat\", {\n        // Set the maximum retry count to 5 so that it will try 5 times with the interval of\n        // 5 second in between the retry attempts.\n        retryConfig: {\n            maxCount: 5,\n            interval: 5\n        }\n    });\n    check chatRetryClient->writeMessage(\"Hey Sam!\");\n}\n"
  },
  {
    "path": "examples/websocket-retry-client/websocket_retry_client.md",
    "content": "# WebSocket client - Retry\n\nThe `websocket:Client` with enabled `retry` automatically tries to reconnect to the given backend. The client only retries when there is a connection error at the handshake phase or if an abnormal closure with the status code(1006) is received once the connection is upgraded to a WebSocket connection. The connection closures with mutual acknowledgments will not be retried. If the maximum reconnect attempt is reached, it stops the connection. A `websocket:Client` that retries upon failures is created by providing the `retry` configurations to the client. Use this to re-establish the connection, in cases like the WebSocket client lost the connection due to some transient failure such as a momentary loss of network connectivity or a temporary unavailability of a service.\n\n::: code websocket_retry_client.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Send/Receive message](/learn/by-example/websocket-basic-sample/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_retry_client.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n"
  },
  {
    "path": "examples/websocket-retry-client/websocket_retry_client.metatags",
    "content": "description: BBE on how transient failures can be handled using the WebSocket client. When it comes to WebSocket, the key attribute is maintaining a live connection. This BBE shows how the WebSocket client can be made resilient with its reconnect feature.\nkeywords: ballerina, ballerina by example, bbe, websocket, ws, retry\n"
  },
  {
    "path": "examples/websocket-retry-client/websocket_retry_client.out",
    "content": "$ bal run websocket_retry_client.bal\n\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-file-user-store/websocket_service_basic_auth_file_user_store.bal",
    "content": "import ballerina/websocket;\n\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with Basic authentication and can be authorized optionally.\n// Using Basic authentication with the file user store can be enabled by setting the\n// `websocket:FileUserStoreConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type\n// configurations for `scopes` field.\n@websocket:ServiceConfig {\n    auth: [\n        {\n            fileUserStoreConfig: {},\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-file-user-store/websocket_service_basic_auth_file_user_store.md",
    "content": "# WebSocket service - Basic authentication file user store\n\nThe `websocket:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header in the initial HTTP request against the provided configurations in the `Config.toml` file. The file stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the default values for the `fileUserStoreConfig` field and add the `Config.toml` file next to the service file. To engage authorization, set scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `401 Unauthorized` response is sent to the client when the authentication fails and a `403 Forbidden` response is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on user stores.\n\n::: code websocket_service_basic_auth_file_user_store.bal :::\n\n>**Info:** As a prerequisite to running the service, populate the `Config.toml` file correctly with the user information as shown below.\n\n::: code Config.toml :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_basic_auth_file_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [Basic authentication client](/learn/by-example/websocket-client-basic-auth).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)"
  },
  {
    "path": "examples/websocket-service-basic-auth-file-user-store/websocket_service_basic_auth_file_user_store.metatags",
    "content": "description: BBE on how to secure WebSocket service with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, basic auth\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-file-user-store/websocket_service_basic_auth_file_user_store.server.out",
    "content": "$ bal run websocket_service_basic_auth_file_user_store.bal\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-ldap-user-store/websocket_service_basic_auth_ldap_user_store.bal",
    "content": "import ballerina/websocket;\n\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with Basic authentication and can be authorized optionally.\n// Basic authentication using the LDAP user store can be enabled by setting\n// the `websocket:LdapUserStoreConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type\n// configurations for `scopes` field.\n@websocket:ServiceConfig {\n    auth: [\n        {\n            ldapUserStoreConfig: {\n                domainName: \"avix.lk\",\n                connectionUrl: \"ldap://localhost:389\",\n                connectionName: \"cn=admin,dc=avix,dc=lk\",\n                connectionPassword: \"avix123\",\n                userSearchBase: \"ou=Users,dc=avix,dc=lk\",\n                userEntryObjectClass: \"inetOrgPerson\",\n                userNameAttribute: \"uid\",\n                userNameSearchFilter: \"(&(objectClass=inetOrgPerson)(uid=?))\",\n                userNameListFilter: \"(objectClass=inetOrgPerson)\",\n                groupSearchBase: [\"ou=Groups,dc=avix,dc=lk\"],\n                groupEntryObjectClass: \"groupOfNames\",\n                groupNameAttribute: \"cn\",\n                groupNameSearchFilter: \"(&(objectClass=groupOfNames)(cn=?))\",\n                groupNameListFilter: \"(objectClass=groupOfNames)\",\n                membershipAttribute: \"member\",\n                userRolesCacheEnabled: true,\n                connectionPoolingEnabled: false,\n                connectionTimeout: 5,\n                readTimeout: 60\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-ldap-user-store/websocket_service_basic_auth_ldap_user_store.md",
    "content": "# WebSocket service - Basic authentication LDAP user store\n\nThe `websocket:Service` can be secured with basic authentication and additionally, scopes can be added to enforce authorization. It validates the basic authentication token sent in the `Authorization` header with the LDAP server. This server stores the usernames and passwords for the authentication and the scopes for the authorization. To engage authentication, set the LDAP related configurations to the `ldapUserStoreConfig` field. To engage authorization, set scopes to the `scopes` field. Both configurations must be given as part of the service configuration.\n\nA `401 Unauthorized` response is sent to the client when the authentication fails, and a `403 Forbidden` response is sent to the client when the authorization fails. Use this to authenticate and authorize requests based on LDAP user stores. \n\n::: code websocket_service_basic_auth_ldap_user_store.bal :::\n\n## Prerequisites\n- Run the LDAP server.\n\nRun the service by executing the command below.\n\n::: out websocket_service_basic_auth_ldap_user_store.server.out :::\n\n>**Tip:** You can invoke the above service via the [Basic authentication client](/learn/by-example/websocket-client-basic-auth).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`auth` module - API documentation](https://lib.ballerina.io/ballerina/auth/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-ldap-user-store/websocket_service_basic_auth_ldap_user_store.metatags",
    "content": "description: BBE on how to secure WebSocket service with Basic Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, basic auth\n"
  },
  {
    "path": "examples/websocket-service-basic-auth-ldap-user-store/websocket_service_basic_auth_ldap_user_store.server.out",
    "content": "$ bal run websocket_service_basic_auth_ldap_user_store.bal\n"
  },
  {
    "path": "examples/websocket-service-error-handling/websocket_service_error_handling.bal",
    "content": "import ballerina/http;\nimport ballerina/io;\nimport ballerina/websocket;\n\nservice /chat on new websocket:Listener(9090) {\n\n    resource function get .(@http:Header string origin) returns websocket:Service|error {\n        if origin != \"http://localhost:9090\" {\n            // Cancel the handshake by returning an error.\n            return error (\"Origin not allowed\");\n        }\n        // Accept the WebSocket upgrade by returning a `websocket:Service`.\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        io:println(chatMessage);\n        // If an error occurs, the error is returned from the `onMessage`. It is printed on the\n        // server terminal along with the stack trace.\n        check caller->writeMessage(\"Hello!, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-error-handling/websocket_service_error_handling.md",
    "content": "# WebSocket service - Error handling\n\nThe Ballerina `websocket` module allows returning errors from the `get` resource and remote methods. The initial WebSocket upgrade service can do various validations. For instance, origin checking and canceling the WebSocket handshake by returning an `error` from the get resource if the validation fails. In this case, it results in a `400 Bad Request` HTTP response, which is the default response. If the returned error is a `websocket:AuthzError`, or a `websocket:AuthnError`, `403 Forbidden` and `401 Unauthorized` HTTP responses are returned respectively. Once the connection is upgraded to a WebSocket connection, if an error is returned from a remote method in the `websocket:Service`, the error is printed on the server terminal along with the stack-trace and it continues to receive messages. Use `do/fail` block to catch and handle the error when needed.\n \n::: code websocket_service_error_handling.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_error_handling.out :::\n\n>**Tip:** You can invoke the above service via the [WebSocket client](/learn/by-example/websocket-client/).\n\n## Related links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket service - Specification](/spec/websocket/#3-service-types)\n- [Check semantics - Example](/learn/by-example/check-semantics/)\n"
  },
  {
    "path": "examples/websocket-service-error-handling/websocket_service_error_handling.metatags",
    "content": "description: This BBE demonstrates error handling in WebSocket services.\nkeywords: ballerina, ballerina by example, bbe, websocket, service, error handling\n"
  },
  {
    "path": "examples/websocket-service-error-handling/websocket_service_error_handling.out",
    "content": "$ bal run websocket_service_error_handling.bal\nerror: error occurred\n        at ChatService:onMessage(websocket_service_error_handling.bal:22)\n"
  },
  {
    "path": "examples/websocket-service-jwt-auth/websocket_service_jwt_auth.bal",
    "content": "import ballerina/websocket;\n\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with JWT authentication and can be authorized\n// optionally. JWT authentication can be enabled by setting the `websocket:JwtValidatorConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type\n// configurations for `scopes` field.\n@websocket:ServiceConfig {\n    auth: [\n        {\n            jwtValidatorConfig: {\n                issuer: \"wso2\",\n                audience: \"ballerina\",\n                signatureConfig: {\n                    certFile: \"../resource/path/to/public.crt\"\n                },\n                scopeKey: \"scp\"\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-jwt-auth/websocket_service_jwt_auth.md",
    "content": "# WebSocket service - JWT authentication\n\nThe `websocket:Service` and resource method can be secured with JWT and additionally, scopes can be added to enforce authorization. It validates the JWT sent in the `Authorization` header against the provided configurations. Ballerina uses the concept of scopes for authorization. The scope can be included in the JWT using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service/resource are compared against the scope included in the JWT for at least one match between the two sets.\n\n::: code websocket_service_jwt_auth.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_jwt_auth.server.out :::\n\n>**Tip:** You can invoke the above service via the [self-signed JWT authentication client](/learn/by-example/websocket-client-self-signed-jwt-auth).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`jwt` module - API documentation](https://lib.ballerina.io/ballerina/jwt/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)"
  },
  {
    "path": "examples/websocket-service-jwt-auth/websocket_service_jwt_auth.metatags",
    "content": "description: BBE on how to secure WebSocket service with JWT Auth in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, jwt auth\n"
  },
  {
    "path": "examples/websocket-service-jwt-auth/websocket_service_jwt_auth.server.out",
    "content": "$ bal run websocket_service_jwt_auth.bal\n"
  },
  {
    "path": "examples/websocket-service-mutual-ssl/websocket_service_mutual_ssl.bal",
    "content": "import ballerina/http;\nimport ballerina/websocket;\n\n// A WebSocket listener can be configured to accept new connections that are\n// secured via mutual SSL.\n// The `websocket:ListenerSecureSocket` record provides the SSL-related listener configurations.\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        },\n        // Enables mutual SSL.\n        mutualSsl: {\n            verifyClient: http:REQUIRE,\n            cert: \"../resource/path/to/public.crt\"\n        }\n    }\n);\n\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-mutual-ssl/websocket_service_mutual_ssl.md",
    "content": "# WebSocket service - Mutual SSL\n\nA `websocket:Listener` with enabled mutual SSL (mTLS) allows you to expose a connection secured with mutual SSL, which is a certificate-based authentication process in which two parties (the client and server) authenticate each other by verifying the digital certificates. It ensures that both parties are assured of each other's identity. A `websocket:Listener` secured with mutual SSL is created by providing the `secureSocket` configurations which require the word `require` as the `verifyClient`, the server's public certificate as the `certFile`, server's private key as the `keyFile` and the client's certificate as the `cert`. Use this to secure the WebSocket connection over mutual SSL.\n\n::: code websocket_service_mutual_ssl.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_mutual_ssl.server.out :::\n\n>**Tip:** You can invoke the above service via the [Mutual SSL/TLS client](/learn/by-example/websocket-client-mutual-ssl/).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket SSL/TLS - Specification](/spec/websocket/#5-securing-the-websocket-connections)\n\n"
  },
  {
    "path": "examples/websocket-service-mutual-ssl/websocket_service_mutual_ssl.metatags",
    "content": "description: BBE on how to secure WebSocket listener with mutual SSL.\nkeywords: ballerina, ballerina by example, bbe, websocket, mutual ssl, ssl protocols, ciphers\n"
  },
  {
    "path": "examples/websocket-service-mutual-ssl/websocket_service_mutual_ssl.server.out",
    "content": "$ bal run websocket_service_mutual_ssl.bal\n"
  },
  {
    "path": "examples/websocket-service-oauth2/websocket_service_oauth2.bal",
    "content": "import ballerina/websocket;\n\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\n// The service can be secured with OAuth2 and by enforcing authorization\n// optionally. It can be enabled by setting the `websocket:OAuth2IntrospectionConfig` configurations.\n// Authorization is based on scopes. A scope maps to one or more groups.\n// Authorization can be enabled by setting the `string|string[]` type configurations for `scopes` field.\n@websocket:ServiceConfig {\n    auth: [\n        {\n            oauth2IntrospectionConfig: {\n                url: \"https://localhost:9445/oauth2/introspect\",\n                tokenTypeHint: \"access_token\",\n                scopeKey: \"scp\",\n                clientConfig: {\n                    customHeaders: {\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"},\n                    secureSocket: {\n                        cert: \"../resource/path/to/public.crt\"\n                    }\n                }\n            },\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-oauth2/websocket_service_oauth2.md",
    "content": "# WebSocket service - OAuth2\n\nThe `websocket:Service` and resource method can be secured with OAuth2 and additionally, scopes can be added to enforce fine-grained authorization. It validates the OAuth2 token sent in the `Authorization` header against the provided configurations. This calls the configured introspection endpoint to validate. Ballerina uses the concept of scopes for authorization.  The scope can be included in the introspection response using a custom claim attribute. That custom claim attribute also can be configured as the `scopeKey`. In the authorization phase, the scopes of the service/resource are compared against the scope included in the introspection response for at least one match between the two sets.\n\n::: code websocket_service_oauth2.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_oauth2.server.out :::\n\n>**Tip:** You can invoke the above service via the [OAuth2 JWT Bearer grant type client](/learn/by-example/websocket-client-oauth2-jwt-bearer-grant-type).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [`oauth2` module - API documentation](https://lib.ballerina.io/ballerina/oauth2/latest/)\n- [WebSocket authentication - Specification](/spec/websocket/#52-authentication-and-authorization)\n"
  },
  {
    "path": "examples/websocket-service-oauth2/websocket_service_oauth2.metatags",
    "content": "description: BBE on how to secure WebSocket service with OAuth2 in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, websocket, auth, oauth2, introspection\n"
  },
  {
    "path": "examples/websocket-service-oauth2/websocket_service_oauth2.server.out",
    "content": "$ bal run websocket_service_oauth2.bal\n"
  },
  {
    "path": "examples/websocket-service-payload-constraint-validation/websocket_service_payload_constraint_validation.bal",
    "content": "import ballerina/constraint;\nimport ballerina/io;\nimport ballerina/websocket;\n\n// Add a constraint for the maximum length.\n@constraint:String {\n    maxLength: 20\n}\npublic type Chat string;\n\nservice /chat on new websocket:Listener(9090) {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, Chat chatMessage) returns error? {\n        io:println(chatMessage);\n        check caller->writeMessage(\"Hello!, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-payload-constraint-validation/websocket_service_payload_constraint_validation.md",
    "content": "# WebSocket service - Payload constraint validation\n\nThe Ballerina constraint package allows you to add additional constraints to the received payload. Through service payload constraint validation, the payload can be validated according to the defined constraints. The constraint validation happens along with the data binding step in the remote method signature parameter. Constraints can be added to a given data type using different annotations. If the validation fails, the `onError` remote method is dispatched with the validation error details. Use this to validate the receiving payload, which allows you to guard against unnecessary processing and malicious payloads.\n\n::: code websocket_service_payload_constraint_validation.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_payload_constraint_validation.out :::\n\n>**Tip:** You can invoke the above service via the [WebSocket client](/learn/by-example/websocket-client/).\n\n## Related links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket service - Specification](/spec/websocket/#3-service-types)\n- [Constraint BBE](/learn/by-example/constraint-validations/)\n"
  },
  {
    "path": "examples/websocket-service-payload-constraint-validation/websocket_service_payload_constraint_validation.metatags",
    "content": "description: BBE demonstrates the constraint validation capability of the WebSocket client.\nkeywords: ballerina, ballerina by example, bbe, websocket, data binding, client, constraint, validation\n"
  },
  {
    "path": "examples/websocket-service-payload-constraint-validation/websocket_service_payload_constraint_validation.out",
    "content": "$ bal run websocket_client_payload_constraint_validation.bal\nHello!, How are you?\n"
  },
  {
    "path": "examples/websocket-service-ssl-tls/websocket_service_ssl_tls.bal",
    "content": "import ballerina/websocket;\n\n// A WebSocket listener can be configured to communicate through WSS as well.\n// To secure a listener using SSL/TLS, the listener needs to be configured with\n// a certificate file and a private key file for the listener.\n// The `websocket:ListenerSecureSocket` record\n// provides the SSL-related listener configurations of the listener.\nlistener websocket:Listener chatListener = new (9090,\n    secureSocket = {\n        key: {\n            certFile: \"../resource/path/to/public.crt\",\n            keyFile: \"../resource/path/to/private.key\"\n        }\n    }\n);\n\nservice /chat on chatListener {\n\n    resource function get .() returns websocket:Service {\n        return new ChatService();\n    }\n}\n\nservice class ChatService {\n    *websocket:Service;\n\n    remote function onMessage(websocket:Caller caller, string chatMessage) returns error? {\n        check caller->writeMessage(\"Hello, How are you?\");\n    }\n}\n"
  },
  {
    "path": "examples/websocket-service-ssl-tls/websocket_service_ssl_tls.md",
    "content": "# WebSocket service - SSL/TLS\n\nThe `websocket:Listener` configured with SSL/TLS allows you to expose a connection secured with one-way SSL/TLS. A `websocket:Listener` secured with TLS/SSL is created by providing the `secureSocket` configurations which require the server's public certificate as the `certFile` and the server's private key as the `keyFile`. Use this to expose a WSS connection.\n\n::: code websocket_service_ssl_tls.bal :::\n\nRun the service by executing the command below.\n\n::: out websocket_service_ssl_tls.server.out :::\n\n>**Tip:** You can invoke the above service via the [SSL/TLS client](/learn/by-example/websocket-client-ssl-tls/).\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n- [WebSocket SSL/TLS - Specification](/spec/websocket/#5-securing-the-websocket-connections)"
  },
  {
    "path": "examples/websocket-service-ssl-tls/websocket_service_ssl_tls.metatags",
    "content": "description: BBE on how to secure WebSocket listener with SSL.\nkeywords: ballerina, ballerina by example, bbe, websocket, wss, ssl, tls\n"
  },
  {
    "path": "examples/websocket-service-ssl-tls/websocket_service_ssl_tls.server.out",
    "content": "$ bal run websocket_service_ssl_tls.bal\n"
  },
  {
    "path": "examples/websocket-text-client/websocket_text_client.md",
    "content": "# Handle text messages with client\n\nThe WebSocket client can be used to connect to and interact with a WebSocket server in a Synchronous manner. This example demonstrates how to read and write text messages using ballerina websocket client.\n\nFor more information on the underlying module, see the [`websocket` module](https://lib.ballerina.io/ballerina/websocket/latest/).\n\n::: code ./examples/websocket-text-client/websocket_text_client.bal :::\n\n::: out ./examples/websocket-text-client/websocket_text_client.out :::"
  },
  {
    "path": "examples/websocket-timeout-client/websocket_timeout_client.bal",
    "content": "import ballerina/websocket;\n\npublic function main() returns error? {\n    // Set the handshake timeout for 5 seconds.\n    websocket:Client chatClient = check new (\"ws://localhost:9090/chat\", handShakeTimeout = 5);\n    check chatClient->writeMessage(\"Hello John!\");\n}\n"
  },
  {
    "path": "examples/websocket-timeout-client/websocket_timeout_client.md",
    "content": "# WebSocket client - Timeout\n\nThe `websocket:Client` configured with timeouts can gracefully handle timeouts that happen in the running applications. Handshake timeout is the time (in seconds) that a connection waits to get the response of the WebSocket handshake. If the timeout exceeds, then, the connection is terminated with a `HandshakeTimedOut` error. If the configuration value `< 0`, then the value sets to the default value(300). Apart from the `handShakeTimeout`, the WebSocket client also has `readTimeout` and `writeTimeout` configurations to configure idle time to wait to receive a message and to write a message respectively. To enable handshake timeout, provide the `handShakeTimeout` configuration to the client. Use the handshake timeout to gracefully handle response delays that could occur due to network problems or problems in the back end.\n\n::: code websocket_timeout_client.bal :::\n\n## Prerequisites\n- Run the WebSocket service given in the [Send/Receive message](/learn/by-example/websocket-basic-sample/) example.\n\nRun the client program by executing the command below.\n\n::: out websocket_timeout_client.out :::\n\n## Related Links\n- [`websocket` module - API documentation](https://lib.ballerina.io/ballerina/websocket/latest)\n"
  },
  {
    "path": "examples/websocket-timeout-client/websocket_timeout_client.metatags",
    "content": "description: BBE on how to use a timeout in Ballerina WebSocket client.\nkeywords: ballerina, ballerina by example, bbe, websocket, ws, timeout\n"
  },
  {
    "path": "examples/websocket-timeout-client/websocket_timeout_client.out",
    "content": "$ bal run websocket_timeout_client.bal\n"
  },
  {
    "path": "examples/websub-webhook-sample/websub_webhook_sample.bal",
    "content": "// The Ballerina WebSub Subscriber service, which could be used as a WebHook Listener for GitHub.\nimport ballerina/io;\nimport ballerina/websub;\n\n// Annotation-based configurations specifying the subscription parameters.\n@websub:SubscriberServiceConfig {\n    target: [\n        \"https://api.github.com/hub\", \n        \"https://github.com/<YOUR_ORGANIZATION>/<REPOSITORY>/events/push.json\"\n    ],\n    secret: \"<YOUR_SECRET_KEY>\",\n    httpConfig: {\n        auth: {\n            token: \"<YOUR_AUTH_TOKEN>\"\n        }\n    }\n}\nservice on new websub:Listener(9090) {\n    // Defines the remote method that accepts the event notification request for the WebHook.\n    remote function onEventNotification(websub:ContentDistributionMessage event) returns error? {\n        json retrievedContent = check event.content.ensureType();\n        if retrievedContent.zen is string {\n            int hookId = check retrievedContent.hook_id;\n            io:println(string `PingEvent received for webhook [${hookId}]`);\n            int senderId = check retrievedContent.sender.id;\n            io:println(string `Event sender [${senderId}]`);\n        } else if retrievedContent.ref is string {\n            string repositoryName = check retrievedContent.repository.name;\n            io:println(string `PushEvent received for [${repositoryName}]`);\n            string lastUpdatedTime = check retrievedContent.repository.updated_at;\n            io:println(string `Last updated at ${lastUpdatedTime}`);\n        }\n    }\n}\n"
  },
  {
    "path": "examples/websub-webhook-sample/websub_webhook_sample.md",
    "content": "# WebSub service - Consume github events\n\nGitHub webhooks provide the capability to receive notifications based on the events in a GitHub repository. The Ballerina `websub` module can be used to define websub-compliant webhooks which are used to receive notifications from any websub-compliant `hub` implementation. Specify the GitHub pubsubhub API URL and the relevant event URL as the `target` parameter in `@websub:SubscriberServiceConfig` annotation. Start the `websub:SubscriberService` to receive event notifications.\n\n::: code websub_webhook_sample.bal :::\n\n## Prerequisites\n- Internet connectivity to connect to github API.\n- An active github repository to receive relevant events. \n\nRun the subscriber service by executing the following command.\n\n::: out websub_webhook_sample.out :::\n\n## Related links\n- [`websub` module - API documentation](https://lib.ballerina.io/ballerina/websub/latest/)\n- [Websub subscriber service - Specification](https://ballerina.io/spec/websub/#22-subscriber-service)\n"
  },
  {
    "path": "examples/websub-webhook-sample/websub_webhook_sample.metatags",
    "content": "description: This BBE demonstrates how a WebSub Subscriber service could be registered as a WebHook Service for GitHub.\nkeywords: ballerina, ballerina by example, bbe, websub, subscriber\n"
  },
  {
    "path": "examples/websub-webhook-sample/websub_webhook_sample.out",
    "content": "$ bal run websub_webhook_sample.bal\ntime = 2022-01-24T17:48:07.207+05:30 level = WARN module = ballerina/websub message = \"HTTPS is recommended but using HTTP\"\nPingEvent received for webhook [287075824]\nEvent sender [77491511]\nPushEvent received for [Hello-World]\nLast updated at 2021-03-15T15:43:01Z\n"
  },
  {
    "path": "examples/while-statement/while_statement.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n\n    // Loop through a list\n    string[] names = [\"Bob\", \"Jo\", \"Ann\", \"Tom\"];\n    int i = 0;\n    while i < names.length() {\n        io:println(names[i]);\n        i += 1;\n    }\n}\n"
  },
  {
    "path": "examples/while-statement/while_statement.md",
    "content": "# While statement\n\nThe `while` statement can be used to repeat a block of statements until a boolean condition is true. The parentheses `( )` around the boolean expression are not required. However, it is required to enclose the statement block using curly braces `{ }`.\n\n::: code while_statement.bal :::\n\n::: out while_statement.out :::\n\n## Related links\n- [Break statement](/learn/by-example/break-statement/)\n- [Continue statement](/learn/by-example/continue-statement/)\n- [Foreach statement](/learn/by-example/foreach-statement/)\n"
  },
  {
    "path": "examples/while-statement/while_statement.metatags",
    "content": "description: This BBE demonstrates how to use the `while` statement to loop through a list in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, while, loop, repeat, iterate\n"
  },
  {
    "path": "examples/while-statement/while_statement.out",
    "content": "$ bal run while_statement.bal\nBob\nJo\nAnn\nTom\n"
  },
  {
    "path": "examples/wildcard-binding-pattern/wildcard_binding_pattern.bal",
    "content": "public function main() {\n    // Since the basic type of the value returned by `getInt()` is `int`\n    // which belongs to `any` type, this will not cause an assignment.\n    int _ = getInt();\n\n    // The type of the wildcard binding pattern is  derived as `any`\n    // since it results in a successful match.\n    _ = 3;\n}\n\nfunction getInt() returns int {\n    return 0;\n}\n\n"
  },
  {
    "path": "examples/wildcard-binding-pattern/wildcard_binding_pattern.md",
    "content": "# Wildcard binding pattern\n\nA wildcard binding pattern which is denoted by the `_` symbol, matches a value if the value belongs to type `any`. As long as the basic type of the value is not an `error`, it does not cause any assignment to be made to the variable. It is useful for ignoring values such as the return value of a function or values in a list.\n\n::: code wildcard_binding_pattern.bal :::\n\n::: out wildcard_binding_pattern.out :::\n\n## Related links\n- [Binding patterns](/learn/by-example/binding-patterns/)"
  },
  {
    "path": "examples/wildcard-binding-pattern/wildcard_binding_pattern.metatags",
    "content": "description: This BBE introduces unused variables, ignoring the return value of a function and matching a value belonging to type any\nkeywords:  ballerina, ballerina by example, bbe, binding pattern, wildcard binding pattern\n"
  },
  {
    "path": "examples/wildcard-binding-pattern/wildcard_binding_pattern.out",
    "content": "$ bal run wildcard_binding_pattern.bal\n"
  },
  {
    "path": "examples/xml-access/xml_access.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    xml x1 = xml `<name>Sherlock Holmes</name>\n                  <details>\n                    <author>Sir Arthur Conan Doyle</author>\n                    <language>English</language>\n                  </details>`;\n\n    // `x[i]` or `x.get(i)` gives the `i`-th item.\n    io:println(x1[0]);\n\n    // `x.id` accesses a required attribute named `id`: the result is an `error` if there is no such\n    // attribute or if `x` is not a singleton.\n    xml x2 = xml `<para id=\"greeting\">Hello</para>`;\n    string id = check x2.id;\n    io:println(id);\n\n    // `x?.id` accesses an optional attribute named `id`: the result is `()` if there is no such\n    // attribute.\n    string? name = check x2?.name;\n\n    // The following nil check returns true since the attribute `name` does not exist in the `x2`.\n    io:println(name is ());\n\n}\n"
  },
  {
    "path": "examples/xml-access/xml_access.md",
    "content": "# XML access\n\nIt is possible to access elements in XML.\n\n- `x[i]` gives the `i`-th item (empty sequence if none).\n\n- `x.id` accesses the required attribute named `id`: the result is an error if there is no such attribute or if `x` is not a singleton.\n\n- `x?.id` accesses an optional attribute named `id`: the result is `()` if there is no such attribute. \n\nThe `lang.xml` langlib provides the other operations.\n\n::: code xml_access.bal :::\n\n::: out xml_access.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML operations](/learn/by-example/xml-operations/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-access/xml_access.metatags",
    "content": "description: This BBE demonstrates how to get an item in XML, access an attribute in XML, and access XML optional attributes in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml data model, xml, get element\n"
  },
  {
    "path": "examples/xml-access/xml_access.out",
    "content": "$ bal run xml_access.bal\n<name>Sherlock Holmes</name>\ngreeting\ntrue\n"
  },
  {
    "path": "examples/xml-data-model/xml_data_model.bal",
    "content": "import ballerina/io;\n\npublic function main() returns error? {\n    // An XML element. There can be only one root element.\n    xml x1 = xml `<book>The Lost World</book>`;\n    io:println(x1);\n\n    // An XML processing instruction.\n    xml x2 = xml `<?target data?>`;\n    io:println(x2);\n\n    // An XML comment.\n    xml x3 = xml `<!--I am a comment-->`;\n    io:println(x3);\n\n    // An XML text.\n    xml x4 = xml `Hello, world!`;\n    io:println(x4);\n\n    // `xml:createText` can be used to convert a string to `xmlText`.\n    string hello = \"Hello\";\n    string world = \"World\";\n    xml:Text xmlString = xml:createText(hello + \" \" + world);\n    io:println(xmlString);\n\n    // Creates an XML value.\n    xml xmlValue = xml `<name>Sherlock Holmes</name>\n                        <details>\n                          <author>Sir Arthur Conan Doyle</author>\n                          <language>English</language>\n                        </details>`;\n\n    // `x[i]` or `x.get(i)` gives the `i`-th item.\n    io:println(xmlValue[0]);\n\n    // `x.id` accesses a required attribute named `id`. The result is an `error` if there is no such\n    // attribute or if `x` is not a singleton.\n    xml xmlHello = xml `<para id=\"greeting\">Hello</para>`;\n    string id = check xmlHello.id;\n    io:println(id);\n\n    // `x?.id` accesses an optional attribute named `id`. The result is `()` if there is no such\n    // attribute.\n    string? name = check xmlHello?.name;\n    io:println(name);\n\n    xml xmlItems = xml\n        `<items>\n            <!--Contents-->\n            <book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n            <book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <pen><kind>marker</kind><color>blue</color></pen>\n        </items>`;\n\n    // `x.<items>` - retrieves every element in `x` named `items`.\n    xml items = xmlItems.<items>;\n    io:println(items);\n\n}\n"
  },
  {
    "path": "examples/xml-data-model/xml_data_model.md",
    "content": "# XML data model\n\nAn `xml` value is a sequence representing the parsed content of an XML element. An `xml` value has four kinds of items.\n\n- The element, processing instruction, and comment singletons correspond directly to the items in the XML information set\n- The text item corresponds to one or more character information items\n\nAn XML document is an `xml` sequence with only one `element` and no `text`. An `element` item is mutable and consists of:\n\n- `name`: type `string`\n- `attributes`: type `map<string>`\n- `children`: type `xml`\n\nA `text` item is immutable.\n\n- it has no identity: `==` is the same as `===`\n- consecutive `text` items never occur in an `xml` value: they are always merged\n\n::: code xml_data_model.bal :::\n\n::: out xml_data_model.out :::\n\n## Related links\n- [XML operations](/learn/by-example/xml-operations/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-data-model/xml_data_model.metatags",
    "content": "description: This BBE demonstrates how to define XML elements, XML processing instructions, XML comments, XML text, convert string to XML, create XML value, get the items, access the XML attributes, and retrieve elements in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml data model, xml\n"
  },
  {
    "path": "examples/xml-data-model/xml_data_model.out",
    "content": "$ bal run xml_data_model.bal\n<book>The Lost World</book>\n<?target data?>\n<!--I am a comment-->\nHello, world!\nHello World\n<name>Sherlock Holmes</name>\ngreeting\n\n<items>\n            <!--Contents-->\n            <book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n            <book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <pen><kind>marker</kind><color>blue</color></pen>\n        </items>\n"
  },
  {
    "path": "examples/xml-from-json-conversion/xml_from_json_conversion.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\npublic function main() returns error? {\n    // Creates a JSON value.\n    json jsonValue = {\"Store\": {\n            \"@id\": \"AST\",\n            \"name\": \"Anne\",\n            \"address\": {\n                \"street\": \"Main\",\n                \"city\": \"94\"\n            },\n            \"codes\": [\"4\", \"8\"]\n        }};\n    // Converts the JSON value to XML using a default `attributePrefix` (i.e., the `@` character).\n    xml xmlValue = check xmldata:fromJson(jsonValue);\n    io:println(xmlValue);\n}\n"
  },
  {
    "path": "examples/xml-from-json-conversion/xml_from_json_conversion.md",
    "content": "# JSON to XML conversion\n\nThe `data.xmldata` library provides an API to perform conversions from JSON to XML.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_from_json_conversion.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out xml_from_json_conversion.out :::"
  },
  {
    "path": "examples/xml-from-json-conversion/xml_from_json_conversion.metatags",
    "content": "description: This BBE demonstrates the conversion from JSON to XML in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, json, xml\n"
  },
  {
    "path": "examples/xml-from-json-conversion/xml_from_json_conversion.out",
    "content": "$ bal run xml_from_json_conversion.bal\n<Store id=\"AST\"><name>Anne</name><address><street>Main</street><city>94</city></address><codes>4</codes><codes>8</codes></Store>\n"
  },
  {
    "path": "examples/xml-from-record-conversion/xml_from_record_conversion.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\n// Defines a record type with annotations.\n@xmldata:Namespace {\n    prefix: \"ns\",\n    uri: \"http://sdf.com\"\n}\ntype Invoice record {\n    int id;\n    Item[] items;\n    @xmldata:Attribute\n    string 'xmlns = \"example.com\";\n    @xmldata:Attribute\n    string status?;\n};\n\n@xmldata:Namespace {\n    uri: \"http://example1.com\"\n}\ntype Item record {\n    string itemCode;\n    int count;\n};\n\npublic function main() returns error? {\n    // Creates an `Invoice` record.\n    Invoice data = {\n        id: 1,\n        items: [\n            {itemCode: \"223345\", count: 1},\n            {itemCode: \"223300\", count: 7}\n        ],\n        status: \"paid\"\n    };\n\n    // Converts a `record` representation to its XML representation.\n    xml result = check xmldata:toXml(data);\n    io:println(result);\n}\n"
  },
  {
    "path": "examples/xml-from-record-conversion/xml_from_record_conversion.md",
    "content": "# Record to XML conversion\n\nThe `data.xmldata` library provides APIs to perform the conversion from a Ballerina record to XML.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_from_record_conversion.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out xml_from_record_conversion.out :::\n"
  },
  {
    "path": "examples/xml-from-record-conversion/xml_from_record_conversion.metatags",
    "content": "description: This BBE demonstrates the conversion from record to XML in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, record, xml\n"
  },
  {
    "path": "examples/xml-from-record-conversion/xml_from_record_conversion.out",
    "content": "$ bal run xml_from_record_conversion.bal\n<ns:Invoice xmlns=\"example.com\" xmlns:ns=\"http://sdf.com\" status=\"paid\"><id>1</id><items xmlns=\"http://example1.com\"><itemCode>223345</itemCode><count>1</count></items><items xmlns=\"http://example1.com\"><itemCode>223300</itemCode><count>7</count></items></ns:Invoice>\n"
  },
  {
    "path": "examples/xml-iteration/xml_iteration.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    xml x1 = xml `<name>Sherlock Holmes</name>\n                    <details>\n                      <author>Sir Arthur Conan Doyle</author>\n                      <language>English</language>\n                    </details>`;\n\n    // `foreach` iterates over each item.\n    foreach var item in x1 {\n        io:println(item);\n    }\n\n    // The `forEach()` function available in the `lang.xml` library iterates over each item.\n    x1.forEach((e) => io:println(e));\n}\n"
  },
  {
    "path": "examples/xml-iteration/xml_iteration.md",
    "content": "# XML iteration\n\nThe `foreach` statement and `.forEach()` function available in the `lang.xml` library iterate the XML over each item.\n\n::: code xml_iteration.bal :::\n\n::: out xml_iteration.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML operations](/learn/by-example/xml-operations/)\n- [Foreach statement](/learn/by-example/foreach-statement/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-iteration/xml_iteration.metatags",
    "content": "description: This BBE demonstrates how to iterate over each item in XML in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml iteration, forEach\n"
  },
  {
    "path": "examples/xml-iteration/xml_iteration.out",
    "content": "$ bal run xml_iteration.bal\n<name>Sherlock Holmes</name>\n\n\n<details>\n                      <author>Sir Arthur Conan Doyle</author>\n                      <language>English</language>\n                    </details>\n<name>Sherlock Holmes</name>\n\n\n<details>\n                      <author>Sir Arthur Conan Doyle</author>\n                      <language>English</language>\n                    </details>\n"
  },
  {
    "path": "examples/xml-mutation/xml_mutation.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    xml:Element x1 = xml `<details>\n                            <author>Sir Arthur Conan Doyle</author>\n                            <language>English</language>\n                        </details>`;\n\n    // Sets the children of an XML element.\n    // This panics if it would result in the element structure becoming cyclic.\n    x1.setChildren(xml `<language>French</language>`);\n    io:println(x1);\n\n    // Changes the name of an XML element.\n    x1.setName(\"updatedDetails\");\n    io:println(x1);\n}\n"
  },
  {
    "path": "examples/xml-mutation/xml_mutation.md",
    "content": "# XML mutation\n\nIt is possible to mutate XML elements using functions available in the `lang.xml`.\n\n::: code xml_mutation.bal :::\n\n::: out xml_mutation.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML operations](/learn/by-example/xml-operations/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-mutation/xml_mutation.metatags",
    "content": "description: This BBE demonstrates how to update XML values.\nkeywords: ballerina, ballerina by example, bbe, xml, set children, change xml name\n"
  },
  {
    "path": "examples/xml-mutation/xml_mutation.out",
    "content": "$ bal run xml_mutation.bal\n<details><language>French</language></details>\n<updatedDetails><language>French</language></updatedDetails>\n"
  },
  {
    "path": "examples/xml-namespaces/xml_namespaces.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // The `p:e` qualified name, where `http://example.com/` is the namespace name bound to `p`,\n    // is expanded into `{http://example.com/}e`.\n    xml:Element e = xml `<p:e xmlns:p=\"http://example.com/\"/>`;\n    string name = e.getName();\n    io:println(name);\n}\n"
  },
  {
    "path": "examples/xml-namespaces/xml_namespaces.md",
    "content": "# XML namespaces\n\nThe goal is to support namespaces without adding complexity if you don’t use them. The  `ns:x` qualified name in XML is expanded into `{url}x` where `url` is the namespace name bound to `ns`. \n\nThe XML namespace declarations are kept as attributes using the standard binding of [xmlns](http://www.w3.org/2000/xmlns/).\n\n::: code xml_namespaces.bal :::\n\n::: out xml_namespaces.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n"
  },
  {
    "path": "examples/xml-namespaces/xml_namespaces.metatags",
    "content": "description: This BBE demonstrates xml namespaces in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml namespace\n"
  },
  {
    "path": "examples/xml-namespaces/xml_namespaces.out",
    "content": "$ bal run xml_namespaces.bal\n{http://example.com/}e\n"
  },
  {
    "path": "examples/xml-navigation/xml_navigation.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    xml x = xml \n        `<items>\n            <!--Contents-->\n            <book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n            <book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <pen><kind>marker</kind><color>blue</color></pen>\n        </items>`;\n\n    // `x.<items>` - retrieves every element in `x` named `items`.\n    xml a = x.<items>;\n    io:println(a);\n\n    // `x/*` - for every element `e` in `x`, retrieves the children of `e`.\n    xml b = x/*;\n    io:println(b);\n\n    // `x/<planner>` - for every element `e` in `x`, retrieves every element named `planner` \n    // in the children of `e`.\n    xml c = x/<planner>;\n    io:println(c);\n\n    // `x/<planner|pen>` - for every element `e` in `x`, retrieves every element named \n    // `planner` or `pen` in the children of `e`.\n    xml d = x/<planner|pen>;\n    io:println(d);\n\n    // `x/<*>` - for every element `e` in `x`, retrieves every element in the children of `e`.\n    xml e = x/<*>;\n    io:println(e);\n\n    // `x/**/<name>` - for every element `e` in `x`, retrieves every element named `name` in\n    // the descendants of `e`.\n    xml f = x/**/<name>;\n    io:println(f);\n\n    // `x/<book>[0]` - for every element `e` in `x`, retrieves the first element named `book` in\n    // the children of `e`.\n    xml g = x/<book>[0];\n    io:println(g);\n}\n"
  },
  {
    "path": "examples/xml-navigation/xml_navigation.md",
    "content": "# XML navigation \n\nXML navigation expressions allow for convenient navigation of XML element structure, in a similar way to XPath.\n\n::: code xml_navigation.bal :::\n\n::: out xml_navigation.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML operations](/learn/by-example/xml-operations/)\n- [XML access](/learn/by-example/xml-access/)\n"
  },
  {
    "path": "examples/xml-navigation/xml_navigation.metatags",
    "content": "description: This BBE demonstrates XML navigation\nkeywords: ballerina, ballerina by example, bbe, xml, xml navigation\n"
  },
  {
    "path": "examples/xml-navigation/xml_navigation.out",
    "content": "$ bal run xml_navigation.bal\n<items>\n            <!--Contents-->\n            <book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n            <book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <pen><kind>marker</kind><color>blue</color></pen>\n        </items>\n\n            <!--Contents-->\n            <book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n            <book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n            <pen><kind>marker</kind><color>blue</color></pen>\n        \n<planner>Daily Planner<kind>day</kind><pages>365</pages></planner>\n<planner>Daily Planner<kind>day</kind><pages>365</pages></planner><pen><kind>marker</kind><color>blue</color></pen>\n<book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book><planner>Daily Planner<kind>day</kind><pages>365</pages></planner><book>\n                <name>The Sign of Four</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book><pen><kind>marker</kind><color>blue</color></pen>\n<name>A Study in Scarlet</name><name>Arthur Conan Doyle</name><name>The Sign of Four</name><name>Arthur Conan Doyle</name>\n<book>\n                <name>A Study in Scarlet</name>\n                <author><name>Arthur Conan Doyle</name></author>\n            </book>\n"
  },
  {
    "path": "examples/xml-operations/xml_operations.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    xml x1 = xml `<name>Sherlock Holmes</name>`;\n    xml:Element x2 = \n        xml `<details>\n                <author>Sir Arthur Conan Doyle</author>\n                <language>English</language>\n            </details>`;\n\n    //   '+' or `x1.concat(x2)` can be used for concatenation.\n    xml x3 = x1 + x2;\n    io:println(x3);\n\n    xml x4 = xml `<name>Sherlock Holmes</name>\n                    <details>\n                        <author>Sir Arthur Conan Doyle</author>\n                        <language>English</language>\n                    </details>`;\n\n    // `==` does a deep equality check.\n    boolean eq = x3 == x4;\n    io:println(eq);\n\n}\n"
  },
  {
    "path": "examples/xml-operations/xml_operations.md",
    "content": "# XML operations\n\nIn XML, It is possible to perform concatenation and deep equals checks.\n\n::: code xml_operations.bal :::\n\n::: out xml_operations.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-operations/xml_operations.metatags",
    "content": "description: This BBE demonstrates XML concatenation and how to use deep equality checks for XML in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml, xml operations\n"
  },
  {
    "path": "examples/xml-operations/xml_operations.out",
    "content": "$ bal run xml_operations.bal\n<name>Sherlock Holmes</name><details>\n                <author>Sir Arthur Conan Doyle</author>\n                <language>English</language>\n            </details>\nfalse\n"
  },
  {
    "path": "examples/xml-subtyping/xml_subtyping.bal",
    "content": "import ballerina/io;\n\npublic function main() {\n    // An `xml` value belongs to an `xml:Element` if it consists of just an element item.\n    xml:Element firstElement = xml `<p>Hello</p>`;\n\n    // Similarly, a value belongs to the `xml:Comment` or `xml:ProcessingInstruction` if it\n    // consists of just a comment item or a processing instruction item.\n    xml:Comment comment = xml `<!--This is a comment-->`;\n    io:println(comment);\n\n    xml:ProcessingInstruction procInst = xml `<?target data?>`;\n    io:println(procInst);\n\n    // An `xml` value belongs to the `xml:Text` if it consists of only a text item or is empty.\n    xml:Text empty = xml ``;\n    io:println(empty);\n    xml:Text text = xml `Hello World`;\n    io:println(text);\n\n    string hello = \"Hello\";\n    string world = \"World\";\n\n    // `xml:createText` can be used to convert a string to `xmlText`.\n    xml:Text xmlString = xml:createText(hello + \" \" + world);\n    io:println(xmlString);\n\n    xml:Element secondElement = xml `<q>World</q>`;\n\n    // Concatenating multiple items results in a sequence of items (`xml<T>`).\n    // The concatenation below will result in a sequence of XML elements (`xml<xml:Element>`).\n    xml resultElement = firstElement + secondElement;\n    io:println(resultElement is xml<xml:Element>);\n\n    xml xmlHelloWorld = xml `<p>hello</p>World`;\n\n    // An `xml` value belongs to the `xml<T>` type if each of its members belongs to type `T`.\n    io:println(xmlHelloWorld is xml<xml:Element>);\n\n    io:println(resultElement);\n    rename(resultElement, \"q\", \"r\");\n    io:println(resultElement);\n}\n\n// Functions in `lang.xml` use subtyping to provide safe and convenient typing.\n// For example, `x.elements()` returns element items in `x` as type\n// `xml<xml:Element>` and `e.getName()` and `e.setName()` are defined when\n// `e` has type `xml:Element`.\nfunction rename(xml x, string oldName, string newName) {\n    foreach xml:Element e in x.elements() {\n        if e.getName() == oldName {\n            e.setName(newName);\n        }\n        rename(e.getChildren(), oldName, newName);\n    }\n}\n"
  },
  {
    "path": "examples/xml-subtyping/xml_subtyping.md",
    "content": "# XML subtyping\n\n- An `xml` value belongs to `xml:Element` if it consists of just an element item. Similarly for `xml:Comment` and `xml:ProcessingInstruction`. \n- An `xml` value belongs to `xml:Text` if it consists of a text item or is  empty.\n- An `xml` value belongs to the type `xml<T>` if each of its members belong to `T`.\n\nFunctions in `lang.xml` use this to provide safe and convenient typing.\n\nFor example, `x.elements()` returns element items in `x` as type  `xml<xml:Element>` and `e.getName()` and `e.setNam ()` are defined when `e` has type `xml:Element`.\n\n::: code xml_subtyping.bal :::\n\n::: out xml_subtyping.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML operations](/learn/by-example/xml-operations/)\n- [`lang.xml` - Module documentation](https://lib.ballerina.io/ballerina/lang.xml/latest/)\n"
  },
  {
    "path": "examples/xml-subtyping/xml_subtyping.metatags",
    "content": "description: This BBE demonstrates XML subtyping in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml, xml subtyping\n"
  },
  {
    "path": "examples/xml-subtyping/xml_subtyping.out",
    "content": "$ bal run xml_subtyping.bal\n<!--This is a comment-->\n<?target data?>\n\nHello World\nHello World\ntrue\nfalse\n<p>Hello</p><q>World</q>\n<p>Hello</p><r>World</r>\n"
  },
  {
    "path": "examples/xml-templates/xml_templates.bal",
    "content": "import ballerina/io;\n\nstring url = \"https://ballerina.io\";\n\n// `xml` values can be constructed using an XML template expression.\n// Attribute values can have `string` values as interpolated expressions.\nxml content = xml `<a href=\"${url}\">Ballerina</a> is an <em>exciting</em> new language!`;\n\n// Interpolated expressions can also be in content (`xml` or `string` values).\nxml p = xml `<p>${content}</p>`;\n\npublic function main() {\n    io:println(content);\n    io:println(p);\n}\n"
  },
  {
    "path": "examples/xml-templates/xml_templates.md",
    "content": "# XML templates\n\n`xml` values can be constructed using an XML template expression. Phase 2 processing for `xml` template tag parses strings using  the XML 1.0 Recommendation's grammar for content (what XML allows  between a start-tag and an end-tag).\n\nInterpolated expressions can be in content (`xml` or `string` values) or in attribute values (`string` values).\n\n::: code xml_templates.bal :::\n\n::: out xml_templates.out :::"
  },
  {
    "path": "examples/xml-templates/xml_templates.metatags",
    "content": "description: This BBE demonstrates XML templates in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml, xml template\n"
  },
  {
    "path": "examples/xml-templates/xml_templates.out",
    "content": "$ bal run xml_templates.bal\n<a href=\"https://ballerina.io\">Ballerina</a> is an <em>exciting</em> new language!\n<p><a href=\"https://ballerina.io\">Ballerina</a> is an <em>exciting</em> new language!</p>\n"
  },
  {
    "path": "examples/xml-templates-and-query/xml_templates_and_query.bal",
    "content": "import ballerina/io;\n\ntype Person record {|\n    string name;\n    string country;\n|};\n\nfunction personsToXml(Person[] persons) returns xml {\n    // Uses a template containing a query expression, which also contains a template.\n    return xml`<data>${from var {name, country} in persons\n           select xml`<person country=\"${country}\">${name}</person>`}</data>`;\n}\n\npublic function main() {\n    Person[] persons = [\n        {name: \"Jane\", country: \"USA\"},\n        {name: \"Mike\", country: \"Germany\"}\n    ];\n    io:println(personsToXml(persons));\n}\n"
  },
  {
    "path": "examples/xml-templates-and-query/xml_templates_and_query.md",
    "content": "# XML templates and query\n\nXML templates can be combined with queries. It is possible to have a template containing a query expression, which also contains a template.\n\n::: code xml_templates_and_query.bal :::\n\n::: out xml_templates_and_query.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [Query expressions](/learn/by-example/query-expressions/)\n- [Iterating over xml with query](/learn/by-example/iterating-over-xml-with-query/)\n"
  },
  {
    "path": "examples/xml-templates-and-query/xml_templates_and_query.metatags",
    "content": "description: This BBE demonstrates the use of XML templates and queries in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xml templates, query\n"
  },
  {
    "path": "examples/xml-templates-and-query/xml_templates_and_query.out",
    "content": "$ bal run xml_templates_and_query.bal\n<data><person country=\"USA\">Jane</person><person country=\"Germany\">Mike</person></data>\n"
  },
  {
    "path": "examples/xml-to-json-conversion/xml_to_json_conversion.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\n// Defines a record type to represent the XML structure.\ntype Address record {\n    string street;\n    string city;\n};\n\ntype Store record {\n    string name;\n    Address address;\n    string[] codes;\n    @xmldata:Attribute\n    string id;\n};\n\npublic function main() returns error? {\n    // Creates an XML value.\n    xml xmlValue = xml `<Store id=\"AST\">\n                          <name>Anne</name>\n                          <address>\n                              <street>Main</street>\n                              <city>94</city>\n                          </address>\n                          <codes>4</codes>\n                          <codes>8</codes>\n                        </Store>`;\n    // Converts the XML value to a record type.\n    Store store = check xmldata:parseAsType(xmlValue);\n    // Converts the record value to a JSON value.\n    json jsonValue = store.toJson();\n    io:println(jsonValue);\n}\n"
  },
  {
    "path": "examples/xml-to-json-conversion/xml_to_json_conversion.md",
    "content": "# XML to JSON conversion\n\nThe `data.xmldata` library provides APIs to convert XML to a Ballerina record, which can then be converted to JSON.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_to_json_conversion.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out xml_to_json_conversion.out :::\n"
  },
  {
    "path": "examples/xml-to-json-conversion/xml_to_json_conversion.metatags",
    "content": "description: This BBE demonstrates the conversion from XML to JSON in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, json, xml\n"
  },
  {
    "path": "examples/xml-to-json-conversion/xml_to_json_conversion.out",
    "content": "$ bal run xml_to_json_conversion.bal\n{\"name\":\"Anne\",\"address\":{\"street\":\"Main\",\"city\":\"94\"},\"codes\":[\"4\",\"8\"],\"id\":\"AST\"}\n"
  },
  {
    "path": "examples/xml-to-record/xml_to_record.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\ntype Book record {\n    int id;\n    string title;\n    string author;\n};\n\nxml xmlData = xml `\n<book>\n    <id>10024</id>\n    <title>Clean Code</title>\n    <author>Robert C. Martin</author>\n</book>`;\n\nstring xmlStr = string `\n<book>\n    <id>10024</id>\n    <title>Clean Code</title>\n    <author>Robert C. Martin</author>\n</book>`;\n\npublic function main() returns error? {\n    // Convert the XML value to a record type.\n    Book book1 = check xmldata:parseAsType(xmlData);\n    io:println(book1);\n\n    // Convert the XML string to a record type.\n    Book book2 = check xmldata:parseString(xmlStr);\n    io:println(book2);\n\n    byte[] xmlByteArr = xmlStr.toBytes();\n    // Convert the XML byte array to a record type.\n    Book book3 = check xmldata:parseBytes(xmlByteArr);\n    io:println(book3);\n\n    stream<byte[], error?> byteBlockStream = new (new ByteBlockGenerator(xmlStr));\n    // Convert the XML byte block stream to a record type.\n    Book book4 = check xmldata:parseStream(byteBlockStream);\n    io:println(book4);\n}\n\n// Defines a class called `ByteBlockGenerator`, which implements the `next()` method.\n// This will be invoked when the `next()` method of the stream gets invoked.\nclass ByteBlockGenerator {\n    private int index = 0;\n    private final byte[] byteArr;\n    private final int arraySize;\n\n    public function init(string data) {\n        self.byteArr = data.toBytes();\n        self.arraySize = self.byteArr.length();\n    }\n\n    public isolated function next() returns record {|byte[] value;|}|error? {\n        if self.index >= self.arraySize {\n            return;\n        }\n        int startIndex = self.index;\n        self.index = startIndex + 4 > self.arraySize ? self.arraySize : startIndex + 3;\n        return {value: self.byteArr.slice(startIndex, self.index)};\n    }\n}\n"
  },
  {
    "path": "examples/xml-to-record/xml_to_record.md",
    "content": "# XML to Record conversion\n\nThe `data.xmldata` library provides multiple APIs to perform the conversion from XML source, which can be provided as a `string`, `byte array`, `byte block stream`, or `xml`, into a Ballerina record.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_to_record.bal :::\n\n::: out xml_to_record.out :::\n"
  },
  {
    "path": "examples/xml-to-record/xml_to_record.metatags",
    "content": "description: This BBE demonstrates how to convert a XML source, which can be provided as a string, byte array, byte block stream, or xml, into a Ballerina record.\nkeywords: ballerina, ballerina by example, BBE, xml, record, stream, byte array\n"
  },
  {
    "path": "examples/xml-to-record/xml_to_record.out",
    "content": "$ bal run xml_to_record.bal\n{\"id\":10024,\"title\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n{\"id\":10024,\"title\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n{\"id\":10024,\"title\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n{\"id\":10024,\"title\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n"
  },
  {
    "path": "examples/xml-to-record-conversion/xml_to_record_conversion.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\n// Defines a record type with annotations.\n@xmldata:Namespace {\n    prefix: \"ns\",\n    uri: \"http://sdf.com\"\n}\ntype Invoice record {\n    int id;\n    Item[] purchased_item;\n    @xmldata:Attribute\n    string status?;\n};\n\n@xmldata:Namespace {\n    uri: \"example.com\"\n}\ntype Item record {\n    string itemCode;\n    int item_count;\n};\n\npublic function main() returns error? {\n    xml data = xml `<ns:Invoice xmlns=\"example.com\"\n                        xmlns:ns=\"http://sdf.com\" status=\"paid\">\n                        <id>1</id>\n                        <purchased_item>\n                            <itemCode>223345</itemCode>\n                            <item_count>1</item_count>\n                        </purchased_item>\n                        <purchased_item>\n                            <itemCode>223300</itemCode>\n                            <item_count>7</item_count>\n                        </purchased_item>\n                    </ns:Invoice>`;\n\n    // Converts an XML representation to its `record` representation.\n    Invoice output = check xmldata:parseAsType(data);\n    io:println(output);\n}\n"
  },
  {
    "path": "examples/xml-to-record-conversion/xml_to_record_conversion.md",
    "content": "# XML to Record conversion\n\nThe `data.xmldata` library provides an API to perform the conversion from XML to a Ballerina record.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_to_record_conversion.bal :::\n\nTo run this sample, use the `bal run` command.\n\n::: out xml_to_record_conversion.out :::\n"
  },
  {
    "path": "examples/xml-to-record-conversion/xml_to_record_conversion.metatags",
    "content": "description: This BBE demonstrates the conversion from XML to record in Ballerina.\nkeywords: ballerina, ballerina by example, BBE, record, xml\n"
  },
  {
    "path": "examples/xml-to-record-conversion/xml_to_record_conversion.out",
    "content": "$ bal run xml_to_record_conversion.bal\n{\"id\":1,\"purchased_item\":[{\"itemCode\":\"223345\",\"item_count\":1},{\"itemCode\":\"223300\",\"item_count\":7}],\"status\":\"paid\"}\n"
  },
  {
    "path": "examples/xml-to-record-with-projection/xml_to_record_with_projection.bal",
    "content": "import ballerina/data.xmldata;\nimport ballerina/io;\n\n// Define a closed record type to capture the required elements and attributes from the XML data.\ntype Book record {|\n    string name;\n    string author;\n|};\n\nxml xmlData = xml `\n<book>\n    <name>Clean Code</name>\n    <author>Robert C. Martin</author>\n    <year>2008</year>\n    <publisher>Prentice Hall</publisher>\n</book>`;\n\nstring xmlStr = string `\n<book>\n    <name>Clean Code</name>\n    <author>Robert C. Martin</author>\n    <year>2008</year>\n    <publisher>Prentice Hall</publisher>\n</book>`;\n\npublic function main() returns error? {\n    // Based on the expected type, it selectively converts the XML data to the record type.\n    Book book = check xmldata:parseAsType(xmlData);\n    io:println(book);\n\n    // Based on the expected type, it selectively converts the XML string to the record type.\n    Book book2 = check xmldata:parseString(xmlStr);\n    io:println(book2);\n}\n"
  },
  {
    "path": "examples/xml-to-record-with-projection/xml_to_record_with_projection.md",
    "content": "# XML to record conversion with projection\n\nThe `data.xmldata` library provides multiple APIs to selectively convert elements and attributes from a XML source, which can be provided as a `string`, `byte array`, `byte block stream`, or `xml`, into a Ballerina record.\n\nFor more information on the underlying module, see the [`data.xmldata` module](https://lib.ballerina.io/ballerina/data.xmldata/latest/).\n\n::: code xml_to_record_with_projection.bal :::\n\n::: out xml_to_record_with_projection.out :::\n"
  },
  {
    "path": "examples/xml-to-record-with-projection/xml_to_record_with_projection.metatags",
    "content": "description: This BBE demonstrates how to selectively convert fields from a XML source, which can be provided as a string, byte array, byte block stream, or xml, into a Ballerina record.\nkeywords: ballerina, ballerina by example, BBE, xml, record, data projection \n"
  },
  {
    "path": "examples/xml-to-record-with-projection/xml_to_record_with_projection.out",
    "content": "$ bal run xml_to_record_with_projection.bal\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n{\"name\":\"Clean Code\",\"author\":\"Robert C. Martin\"}\n"
  },
  {
    "path": "examples/xmlns-declarations/xmlns_declarations.bal",
    "content": "import ballerina/io;\n\n// The identifier followed by the `as` keyword is the prefix bound to the namespace name.\n// Here `eg` is bound to `\"http://example.com\"`.\nxmlns \"http://example.com\" as eg;\n\npublic function main() {\n    // The prefixes to which namespaces declarations are bound to can be used in XML templates.\n    xml x = xml `<eg:doc>Hello</eg:doc>`;\n\n    // `xmlns` declarations are also allowed at block level.\n    // The `ex` prefix is also bound to `\"http://example.com\"`.\n    xmlns \"http://example.com\" as ex;\n\n    // The prefixes can also be used in XML navigation. \n    boolean b = x === x.<ex:doc>;\n\n    // Since both `eg` and `ex` bind to the same namespace URL, the following evaluates to `true`.\n    io:println(b);\n\n    // An XML qualified name `ex:doc` evaluates to the string `{http://example.com}doc` where \n    // `http://example.com` is the namespace URL bound to `ex`.\n    string exdoc = ex:doc;\n    io:println(exdoc);\n}\n"
  },
  {
    "path": "examples/xmlns-declarations/xmlns_declarations.md",
    "content": "# XMLNS declarations\n\nThe `xmlns` declarations are like import declarations, but bind the prefix to a namespace URL rather than a module. The `xmlns` declarations in the Ballerina module provide namespace context for parsing `xml` templates. \n\nThe Qualified names in Ballerina modules are expanded into `strings` using the `xmlns` declarations in the module. The `xmlns` declarations are also allowed at block level.\n\n::: code xmlns_declarations.bal :::\n\n::: out xmlns_declarations.out :::\n\n## Related links\n- [XML data model](/learn/by-example/xml-data-model/)\n- [XML namespaces](/learn/by-example/xml-namespaces/)\n"
  },
  {
    "path": "examples/xmlns-declarations/xmlns_declarations.metatags",
    "content": "description: This BBE demonstrates xmlns declarations in Ballerina.\nkeywords: ballerina, ballerina by example, bbe, xmlns declarations\n"
  },
  {
    "path": "examples/xmlns-declarations/xmlns_declarations.out",
    "content": "$ bal run xmlns_declarations.bal\ntrue\n{http://example.com}doc\n"
  },
  {
    "path": "examples/xslt-transformation/xslt_transformation.bal",
    "content": "import ballerina/io;\nimport ballerina/xslt;\n\npublic function main() returns error? {\n    // Gets an `XML` value, which needs to be transformed.\n    xml sourceXml = getXml();\n    // Gets an `XSL` style sheet represented in an XML value.\n    xml xsl = getXsl();\n    // Transforms the `XML` content to another format.\n    // For details, see https://lib.ballerina.io/ballerina/xslt/latest#transform.\n    xml target = check xslt:transform(sourceXml, xsl);\n    \n    io:println(\"Transformed XML: \", target);\n}\n\n// Returns an `XML` element, which needs to be transformed.\nfunction getXml() returns xml {\n    return xml `<samples>\n                    <song>\n                        <title>Summer of 69</title>\n                        <artist>Bryan Adams</artist>\n                        <country>Canada</country>\n                        <year>1984</year>\n                    </song>\n                    <song>\n                        <title>Zombie</title>\n                        <artist>Bad Wolves</artist>\n                        <country>USA</country>\n                        <year>2018</year>\n                    </song>\n                </samples>`;\n}\n\n// Returns an `XSL` style sheet represented by an XML element.\nfunction getXsl() returns xml {\n    return xml\n        `<xsl:stylesheet version=\"1.0\" \n                         xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n            <xsl:template match=\"/\">\n                <html>\n                    <body>\n                        <h2>All time favourites</h2>\n                        <table border=\"1\">\n                            <tr bgcolor=\"#9acd33\">\n                                <th>Title</th>\n                                <th>Artist</th>\n                            </tr>\n                        <xsl:for-each select=\"samples/song\">\n                            <tr>\n                                <td>\n                                    <xsl:value-of select=\"title\"/>\n                                </td>\n                                <td>\n                                    <xsl:value-of select=\"artist\"/>\n                                </td>\n                            </tr>\n                        </xsl:for-each>\n                        </table>\n                    </body>\n                </html>\n            </xsl:template>\n        </xsl:stylesheet>`;\n}\n"
  },
  {
    "path": "examples/xslt-transformation/xslt_transformation.md",
    "content": "# XSLT transformation\n\nThe `xslt` library provides an API to transform XML content to HTML using XSL transformation.\n\nFor more information on the underlying module, see the [`xslt` module](https://lib.ballerina.io/ballerina/xslt/latest/).\n\n::: code xslt_transformation.bal :::\n\nTo run this sample, use the `bal run` command.:\n\n::: out xslt_transformation.out :::"
  },
  {
    "path": "examples/xslt-transformation/xslt_transformation.metatags",
    "content": "description: This BBE demonstrates how the XML content can be transformed into HTML using a given XSL transformation.\nkeywords: ballerina, ballerina by example, bbe, xslt, xml, html, xsl, transformation\n"
  },
  {
    "path": "examples/xslt-transformation/xslt_transformation.out",
    "content": "$ bal run xslt_transformation.bal\nTransformed XML: <html>\n<body>\n<h2>All time favourites</h2>\n<table border=\"1\">\n<tr bgcolor=\"#9acd33\">\n<th>Title</th><th>Artist</th>\n</tr>\n<tr>\n<td>Summer of 69</td><td>Bryan Adams</td>\n</tr>\n<tr>\n<td>Zombie</td><td>Bad Wolves</td>\n</tr>\n</table>\n</body>\n</html>\n"
  },
  {
    "path": "examples/yaml-to-anydata/yaml_to_anydata.bal",
    "content": "import ballerina/data.yaml;\nimport ballerina/io;\n\ntype ServerConfig record {|\n    string host;\n    int port;\n    string protocol;\n|};\n\nfinal string yamlString = string\n        `\n        host: \"localhost\"\n        port: 8080\n        protocol: \"http\"`;\n\npublic function main() returns error? {\n    // Parse the YAML string as a record.\n    ServerConfig serverConfig1 = check yaml:parseString(yamlString);\n    io:println(serverConfig1);\n\n    byte[] yamlByteArr = yamlString.toBytes();\n    // Parse the YAML byte array as a record.\n    ServerConfig serverConfig2 = check yaml:parseBytes(yamlByteArr);\n    io:println(serverConfig2);\n\n    stream<byte[], error?> byteBlockStream = new (new ByteBlockGenerator(yamlString));\n    // Parse the YAML byte block stream as a record.\n    ServerConfig serverConfig3 = check yaml:parseStream(byteBlockStream);\n    io:println(serverConfig3);\n}\n\n// Defines a class called `ByteBlockGenerator`, which is stream implementor with a `next()` method.\n// This `next()` method is called when iterating over a stream created with a `ByteBlockGenerator` value.\nclass ByteBlockGenerator {\n    private int index = 0;\n    private final byte[] byteArr;\n    private final int arraySize;\n\n    public function init(string data) {\n        self.byteArr = data.toBytes();\n        self.arraySize = self.byteArr.length();\n    }\n\n    public isolated function next() returns record {|byte[] value;|}|error? {\n        if self.index >= self.arraySize {\n            return;\n        }\n        int startIndex = self.index;\n        self.index = startIndex + 4 > self.arraySize ? self.arraySize : startIndex + 3;\n        return {value: self.byteArr.slice(startIndex, self.index)};\n    }\n}\n"
  },
  {
    "path": "examples/yaml-to-anydata/yaml_to_anydata.md",
    "content": "# YAML to anydata conversion\n\nThe `data.yaml` library provides multiple functions to parse YAML source, in the form of a string, byte array, or byte block stream, as a value that belongs to a subtype of `anydata`.\n\nFor more information on the underlying module, see the [`data.yaml` module](https://lib.ballerina.io/ballerina/data.yaml/latest/).\n\n::: code yaml_to_anydata.bal :::\n\n::: out yaml_to_anydata.out :::\n"
  },
  {
    "path": "examples/yaml-to-anydata/yaml_to_anydata.metatags",
    "content": "description: This BBE demonstrates how to parse a YAML source, which can be provided as a string, byte array, or byte block stream, as a value that belongs to a subtype of anydata.\nkeywords: ballerina, ballerina by example, BBE, yaml, record, stream, byte array\n"
  },
  {
    "path": "examples/yaml-to-anydata/yaml_to_anydata.out",
    "content": "$ bal run yaml_to_anydata.bal\n{\"host\":\"localhost\",\"port\":8080,\"protocol\":\"http\"}\n{\"host\":\"localhost\",\"port\":8080,\"protocol\":\"http\"}\n{\"host\":\"localhost\",\"port\":8080,\"protocol\":\"http\"}\n"
  },
  {
    "path": "examples/yaml-to-anydata-with-projection/yaml_to_anydata_with_projection.bal",
    "content": "import ballerina/data.yaml;\nimport ballerina/io;\n\ntype ServerConfig record {|\n    string host;\n    int port;\n    int[2] remotePorts;\n    DatabaseConfig database;\n|};\n\ntype DatabaseConfig record {|\n    string dbName;\n    string username;\n|};\n\npublic function main() returns error? {\n    // Similar to content read from a YAML file.\n    string yamlString = string `\n        host: \"localhost\"\n        port: 8080\n        remotePorts: [9000, 9001, 9002, 9003]\n        protocol: \"http\"\n        database:\n          dbName: \"testdb\"\n          username: \"dbuser\"\n          password: \"dbpassword\"`;\n\n    // Based on the expected type, this function selectively constructs the record from the YAML string.\n    ServerConfig serverConfig = check yaml:parseString(yamlString);\n    // The `password` field is excluded in the created record value.\n    // Only the first two elements from the source are used to create the `remotePorts` array.\n    io:println(serverConfig);\n}\n"
  },
  {
    "path": "examples/yaml-to-anydata-with-projection/yaml_to_anydata_with_projection.md",
    "content": "# YAML to anydata conversion with projection\n\nThe `data.yaml` library provides multiple APIs to selectively parse elements and attributes from a YAML source, in the form of a string, byte array, or byte block stream, into a Ballerina record. Using projection, users can selectively add fields to records and limit the sizes of arrays.\n\nIn this example, the `password` attribute is excluded when creating the `DatabaseConfig` record, and only the first two elements from the source are used to create the `remotePorts` array.\n\nFor more information on the underlying module, see the [`data.yaml` module](https://lib.ballerina.io/ballerina/data.yaml/latest/).\n\n::: code yaml_to_anydata_with_projection.bal :::\n\n::: out yaml_to_anydata_with_projection.out :::\n"
  },
  {
    "path": "examples/yaml-to-anydata-with-projection/yaml_to_anydata_with_projection.metatags",
    "content": "description: This BBE demonstrates how to selectively convert fields from a YAML source, which can be provided as a string, byte array, or byte block stream, into a Ballerina record with projection.\nkeywords: ballerina, ballerina by example, BBE, yaml, record, data projection \n"
  },
  {
    "path": "examples/yaml-to-anydata-with-projection/yaml_to_anydata_with_projection.out",
    "content": "$ bal run yaml_to_anydata_with_projection.bal\n{\"host\":\"localhost\",\"port\":8080,\"remotePorts\":[9000,9001],\"database\":{\"dbName\":\"testdb\",\"username\":\"dbuser\"}}\n"
  },
  {
    "path": "gradle/javaProject.gradle",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\napply plugin: \"java\"\napply plugin: \"com.github.spotbugs\"\napply plugin: \"checkstyle\"\napply plugin: \"jacoco\"\n\nrepositories {\n    mavenLocal()\n    maven {\n        url = 'https://maven.wso2.org/nexus/content/repositories/releases/'\n    }\n\n    maven {\n        url = 'https://maven.wso2.org/nexus/content/groups/wso2-public/'\n    }\n\n    maven {\n        url = 'https://repo.maven.apache.org/maven2'\n    }\n}\n\nconfigurations {\n    jacocoRuntime\n}\n\ndependencies {\n    implementation \"org.slf4j:slf4j-api:${slf4jVersion}\"\n    testImplementation \"org.slf4j:slf4j-api:${slf4jVersion}\"\n\n    constraints {\n        implementation \"com.fasterxml.jackson.core:jackson-databind:2.11.1\"\n        implementation \"com.github.jknack:handlebars:4.2.0\"\n        implementation \"com.google.code.findbugs:jsr305:3.0.2\"\n        implementation \"info.picocli:picocli:4.0.1\"\n        implementation \"io.swagger.core.v3:swagger-core:2.1.6\"\n        implementation \"io.swagger.core.v3:swagger-models:2.1.6\"\n        implementation \"io.swagger.parser.v3:swagger-parser-v2-converter:2.0.24\"\n        implementation \"io.swagger.parser.v3:swagger-parser:2.0.24\"\n        implementation \"javax.ws.rs:javax.ws.rs-api:2.1.1\"\n        implementation \"org.ballerinalang:ballerina-lang:${ballerinaLangVersion}\"\n        implementation \"org.ballerinalang:ballerina-parser:${ballerinaLangVersion}\"\n        implementation \"org.ballerinalang:ballerina-cli:${ballerinaLangVersion}\"\n        implementation \"org.ballerinalang:formatter-core:${ballerinaLangVersion}\"\n        implementation \"org.ballerinalang:ballerina-tools-api:${ballerinaLangVersion}\"\n        implementation \"io.ballerina.stdlib:http-native:${stdlibHttpVersion}\"\n        testImplementation \"org.testng:testng:${testngVersion}\"\n    }\n\n    jacocoRuntime \"org.jacoco:org.jacoco.agent:${jacoco.toolVersion}:runtime\"\n    checkstyle \"com.puppycrawl.tools:checkstyle:${puppycrawlCheckstyleVersion}\"\n}\n\nsourceCompatibility = JavaVersion.VERSION_21\n\ntasks.withType(JavaCompile) {\n    options.encoding = 'UTF-8'\n}\n\njacoco {\n    toolVersion = \"0.8.10\"\n}\n\ntest {\n    systemProperty \"ballerina.home\", \"$buildDir\"\n    systemProperty \"org.apache.commons.logging.Log\", \"org.apache.commons.logging.impl.NoOpLog\"\n    testLogging {\n        showStackTraces = true\n        showStandardStreams = true\n        events \"failed\"\n        exceptionFormat \"full\"\n    }\n    jacoco {\n        enabled = true\n        destinationFile = file(\"$buildDir/coverage-reports/jacoco.exec\")\n        includeNoLocationClasses = true\n        excludes = ['jdk.internal.*']\n    }\n}\n\ncheckstyle {\n    toolVersion '10.12.1'\n    configFile rootProject.file(\"config/checkstyle/build/checkstyle.xml\")\n    configProperties = [\"suppressionFile\": rootProject.file(\"config/checkstyle/build/suppressions.xml\")]\n    checkstyleTest.enabled = true\n    checkstyleMain.enabled = false\n}\n\nspotbugsMain {\n    spotbugsMain.enabled = false\n    ignoreFailures = true\n    effort = \"max\"\n    reportLevel = \"low\"\n    reportsDir = file(\"$project.buildDir/reports/spotbugs\")\n    def excludeFile = file(\"spotbugs-exclude.xml\")\n    if (excludeFile.exists()) {\n        it.excludeFilter = excludeFile\n    }\n    reports {\n        text.enabled = false\n    }\n}\n\nspotbugsTest {\n    it.enabled = false\n}\n\njacocoTestReport {\n    reports {\n        xml.required = true\n    }\n}\n\ncheckstyleMain.dependsOn(\":config:checkstyle:downloadMultipleFiles\")\ncheckstyleTest.dependsOn(\":config:checkstyle:downloadMultipleFiles\")\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.2.1-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "org.gradle.caching=true\ngroup=org.ballerinalang\n# During the release workflow, the following will get bumped automatically\nversion=2201.14.0-SNAPSHOT\ncodeName=swan-lake\n\nballerinaLangVersion=2201.14.0-20260513-003900-6983b294f4c\nballerinaJreVersion=3.0.0\ndependencyJREVersion=jdk-21.0.5+11-jre\nspecVersion=2024R1\nslf4jVersion=1.7.30\nbalstdlibBranch=master\ndevIdpUrl=https://dev.api.asgardeo.io/oauth2/token/.well-known/openid-configuration\n\n# Stdlib Level 01\nstdlibIoVersion=1.8.0\nstdlibJavaArraysVersion=1.6.0\nstdlibTimeVersion=2.8.0\nstdlibUrlVersion=2.6.1\nstdlibXmldataVersion=2.9.1\nstdlibMathVectorVersion=1.2.0\nobserveVersion=1.7.0\n\n# Stdlib Level 02\nstdlibAvroVersion=1.2.1\nstdlibConstraintVersion=1.7.0\nstdlibCryptoVersion=2.9.2\nstdlibDataXmldataVersion=1.5.2\nstdlibLogVersion=2.17.0\nstdlibOsVersion=1.10.1\nstdlibPersistVersion=1.6.0\nstdlibProtobufVersion=1.8.0\nstdlibRandomVersion=1.7.0\nstdlibTaskVersion=2.11.0\nstdlibXsltVersion=2.9.1\nobserveInternalVersion=1.7.0\n\n# Stdlib Level 03\nstdlibCacheVersion=3.10.0\nstdlibFileVersion=1.12.0\nstdlibFtpVersion=2.18.0\nstdlibLdapVersion=1.3.0\nstdlibMimeVersion=2.12.0\nstdlibTcpVersion=1.13.2\nstdlibUdpVersion=1.13.2\nstdlibUuidVersion=1.10.0\n\n# Stdlib Level 04\nstdlibAuthVersion=2.14.0\nstdlibDataCsvVersion=0.8.1\nstdlibDataJsonDataVersion=1.1.3\nstdlibDataYamlVersion=0.8.0\nstdlibEdiVersion=1.5.3\nstdlibEmailVersion=2.13.0\nstdlibJwtVersion=2.15.1\nstdlibMqttVersion=1.4.0\nstdlibOAuth2Version=2.15.0\nstdlibTomlVersion=0.8.0\nstdlibYamlVersion=0.8.0\n\n# Stdlib Level 05\nstdlibHttpVersion=2.16.2\nstdlibMessagingVersion=1.0.0\n\n# Stdlib Level 06\nstdlibGrpcVersion=1.14.2\nstdlibSoapVersion=2.3.0\nstdlibTransactionVersion=1.12.0\nstdlibWebsocketVersion=2.15.1\nstdlibWebsubVersion=2.15.0\nstdlibWebsubhubVersion=1.16.0\n\n# Stdlib Level 07\nstdlibGraphqlVersion=1.17.0\nstdlibSqlVersion=1.17.1\n\n# Stdlib Level 08\nstdlibMcpVersion=1.0.3\n\n# Stdlib Level 09\nstdlibAiVersion=1.11.1\n\n# Stdlib Level 10\nstdlibAiNpVersion=0.5.1\n\n# OpenAPI Module\nopenapiModuleVersion=2.4.0\n\n# Dev Tools\ndevToolsVersion=2.6.1\nballerinaCommandVersion=1.5.1\n\n# API Doc UI\ndocUiApi=https://api.dev-central.ballerina.io/2.0/docs/doc-ui\n\n# CLI Tools\nopenapiToolVersion=2.4.0\npersistToolVersion=1.7.0\ngraphqlToolVersion=0.14.0\nprotocToolVersion=1.0.0\nasyncapiToolVersion=0.12.0\n\nc2cVersion=4.0.0-20250915-120000-41c6c17\n\ninstallerVersion=500db315-7e0b-4ae3-8780-bdb358f81cfd\n"
  },
  {
    "path": "gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\nAPP_HOME=$( cd \"${APP_HOME:-./}\" && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command;\n#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of\n#     shell script including quotes and variable substitutions, so put them in\n#     double quotes to make sure that they get re-expanded; and\n#   * put everything else in single quotes, so that it's not re-expanded.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\"==\"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\r\n@rem This is normally unused\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif %ERRORLEVEL% equ 0 goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif %ERRORLEVEL% equ 0 goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nset EXIT_CODE=%ERRORLEVEL%\r\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\r\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\r\nexit /b %EXIT_CODE%\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "installers/linux-deb/README.md",
    "content": "# ballerina-linux-deb-installers\n"
  },
  {
    "path": "installers/linux-deb/build-ballerina-linux-deb-x64.sh",
    "content": "#!/bin/bash\n\nfunction printUsage() {\n    echo \"Usage:\"\n    echo \"$0 [options]\"\n    echo \"options:\"\n    echo \"    -v (--version)\"\n    echo \"        version of the ballerina distribution\"\n    echo \"    -p (--path)\"\n    echo \"        path of the ballerina distributions\"\n    echo \"    -a (--arch)\"\n    echo \"        architecture of the ballerina distribution\"\n    echo \"        If not specified : x86\"\n    echo \"        arm : aarch64/arm64\"\n    echo \"    -d (--dist)\"\n    echo \"        ballerina distribution type either of the followings\"\n    echo \"        If not specified both distributions will be built\"\n    echo \"        1. ballerina\"\n    echo \"        2. ballerina-runtime\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs -d ballerina\"\n}\n\nBUILD_ALL_DISTRIBUTIONS=false\nPOSITIONAL=()\nwhile [[ $# -gt 0 ]]\ndo\nkey=\"$1\"\n\ncase ${key} in\n    -v|--version)\n    BALLERINA_VERSION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -p|--path)\n    DIST_PATH=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -a|--arch)\n    ARCH=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -d|--dist)\n    DISTRIBUTION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    *)    # unknown option\n    POSITIONAL+=(\"$1\") # save it in an array for later\n    shift # past argument\n    ;;\nesac\ndone\n\nif [ -z \"$BALLERINA_VERSION\" ]; then\n    echo \"Please enter the version of the ballerina pack\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DIST_PATH\" ]; then\n    echo \"Please enter the path of the ballerina packs\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DISTRIBUTION\" ]; then\n    BUILD_ALL_DISTRIBUTIONS=true\nfi\n\nif [ -z \"$ARCH\" ]; then\n    BALLERINA_PLATFORM=ballerina-${BALLERINA_VERSION}-linux\nelse\n    if [ \"$ARCH\" = \"arm\" ]; then\n        BALLERINA_PLATFORM=ballerina-${BALLERINA_VERSION}-linux-arm\n    else\n        echo \"Please enter a valid architecture for the ballerina pack\"\n        printUsage\n        exit 1\n    fi\nfi\n\nBALLERINA_DISTRIBUTION_LOCATION=${DIST_PATH}\nBALLERINA_INSTALL_DIRECTORY=ballerina-${BALLERINA_VERSION}\n\necho \"Build started at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n\nfunction deleteTargetDirectory() {\n    echo \"Deleting target directory\"\n    rm -rf target\n}\n\nfunction extractPack() {\n    echo \"Extracting the ballerina distribution, \" $1\n    rm -rf target/original\n    mkdir -p target/original\n    unzip $1 -d target/original > /dev/null 2>&1\n    mv target/original/$2 target/original/${BALLERINA_INSTALL_DIRECTORY}\n}\n\nfunction createPackInstallationDirectory() {\n    rm -rf target/${BALLERINA_INSTALL_DIRECTORY}/usr/lib/ballerina\n    mkdir -p target/${BALLERINA_INSTALL_DIRECTORY}/usr/lib/ballerina\n    chmod -R 755 target/${BALLERINA_INSTALL_DIRECTORY}/usr/lib/ballerina\n    mv target/original/${BALLERINA_INSTALL_DIRECTORY}/* target/${BALLERINA_INSTALL_DIRECTORY}/usr/lib/ballerina\n\n    rm -rf target/${BALLERINA_INSTALL_DIRECTORY}/usr/share/doc/${BALLERINA_INSTALL_DIRECTORY}\n    mkdir -p target/${BALLERINA_INSTALL_DIRECTORY}/usr/share/doc/${BALLERINA_INSTALL_DIRECTORY}\n    chmod -R 755 target/${BALLERINA_INSTALL_DIRECTORY}/usr/share/doc/${BALLERINA_INSTALL_DIRECTORY}\n}\n\nfunction copyDebianDirectory() {\n    if [ \"$ARCH\" = \"arm\" ]; then\n        cp -R resources/arm/DEBIAN target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN\n    else\n        cp -R resources/amd/DEBIAN target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN\n    fi\n    sed -i -e 's/__BALLERINA_VERSION__/'${BALLERINA_VERSION}'/g' target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN/postinst\n    sed -i -e 's/__BALLERINA_VERSION__/'${BALLERINA_VERSION}'/g' target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN/postrm\n    sed -i -e 's/__BALLERINA_VERSION__/'${BALLERINA_VERSION}'/g' target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN/control\n    chmod 755 target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN/postrm\n    chmod 755 target/${BALLERINA_INSTALL_DIRECTORY}/DEBIAN/postinst\n}\n\nfunction createBallerinaPlatform() {\n    echo \"Creating ballerina platform installer\"\n\n    extractPack \"$BALLERINA_DISTRIBUTION_LOCATION/$BALLERINA_PLATFORM.zip\" ${BALLERINA_PLATFORM}\n    createPackInstallationDirectory\n    copyDebianDirectory\n    mv target/${BALLERINA_INSTALL_DIRECTORY} target/${BALLERINA_PLATFORM}-x64\n    fakeroot dpkg-deb --build target/${BALLERINA_PLATFORM}-x64\n}\n\ndeleteTargetDirectory\n\nif [ \"$BUILD_ALL_DISTRIBUTIONS\" == \"true\" ]; then\n    echo \"Creating all distributions\"\n    createBallerinaPlatform\nelse\n    if [ \"$DISTRIBUTION\" == \"ballerina\" ]; then\n        echo \"Creating Ballerina Platform\"\n        createBallerinaPlatform\n    else\n        echo \"Error\"\n    fi\nfi\n\necho \"Build completed at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n"
  },
  {
    "path": "installers/linux-deb/resources/amd/DEBIAN/control",
    "content": "Package: ballerina-__BALLERINA_VERSION__\nVersion: 2-__BALLERINA_VERSION__\nMaintainer: Ballerina <admin@ballerinalang.org>\nArchitecture: amd64\nDescription: Ballerina\n Ballerina is a general purpose, concurrent and strongly typed\n programming language with both textual and graphical syntaxes, \n optimized for integration.\nInstalled-Size: 331000\n\n"
  },
  {
    "path": "installers/linux-deb/resources/amd/DEBIAN/postinst",
    "content": "rm -f /usr/lib/ballerina/bin/ballerina\nrm -f /usr/bin/bal\n\nln -sf /usr/lib/ballerina/bin/bal /usr/bin/bal\necho \"export BALLERINA_HOME=/usr/lib/bal\" >> /etc/profile.d/wso2.sh\n\nif [ \"$(basename -- \"$SHELL\")\" = \"bash\" ]; then\n    bal completion bash > /usr/share/bash-completion/completions/bal\n    chmod 766 /usr/share/bash-completion/completions/bal\nelif [ \"$(basename -- \"$SHELL\")\" = \"zsh\" ]; then\n    if [ ! -d ~/.ballerina ]; then\n        mkdir –m766 ~/.ballerina\n    fi\n    mkdir -p –m766 ~/.ballerina/completion\n    echo 'fpath=(~/.ballerina/completion $fpath)' >> ~/.zshrc\n    echo 'autoload -U compinit && compinit' >> ~/.zshrc\n    \\cp /usr/lib/ballerina/scripts/_bal ~/.ballerina/completion/\n    chmod 766 ~/.ballerina/completion/_bal\nfi\n\n"
  },
  {
    "path": "installers/linux-deb/resources/amd/DEBIAN/postrm",
    "content": "sudo rm /usr/bin/bal\nsed -i.bak '/BALLERINA_HOME/d' /etc/profile.d/wso2.sh\n\n"
  },
  {
    "path": "installers/linux-deb/resources/arm/DEBIAN/control",
    "content": "Package: ballerina-__BALLERINA_VERSION__\nVersion: 2-__BALLERINA_VERSION__\nMaintainer: Ballerina <admin@ballerinalang.org>\nArchitecture: arm64\nDescription: Ballerina\n Ballerina is a general purpose, concurrent and strongly typed\n programming language with both textual and graphical syntaxes, \n optimized for integration.\nInstalled-Size: 331000\n\n"
  },
  {
    "path": "installers/linux-deb/resources/arm/DEBIAN/postinst",
    "content": "rm -f /usr/lib/ballerina/bin/ballerina\nrm -f /usr/bin/bal\n\nln -sf /usr/lib/ballerina/bin/bal /usr/bin/bal\necho \"export BALLERINA_HOME=/usr/lib/bal\" >> /etc/profile.d/wso2.sh\n\nif [ \"$(basename -- \"$SHELL\")\" = \"bash\" ]; then\n    bal completion bash > /usr/share/bash-completion/completions/bal\n    chmod 766 /usr/share/bash-completion/completions/bal\nelif [ \"$(basename -- \"$SHELL\")\" = \"zsh\" ]; then\n    if [ ! -d ~/.ballerina ]; then\n        mkdir –m766 ~/.ballerina\n    fi\n    mkdir -p –m766 ~/.ballerina/completion\n    echo 'fpath=(~/.ballerina/completion $fpath)' >> ~/.zshrc\n    echo 'autoload -U compinit && compinit' >> ~/.zshrc\n    \\cp /usr/lib/ballerina/scripts/_bal ~/.ballerina/completion/\n    chmod 766 ~/.ballerina/completion/_bal\nfi\n\n"
  },
  {
    "path": "installers/linux-deb/resources/arm/DEBIAN/postrm",
    "content": "sudo rm /usr/bin/bal\nsed -i.bak '/BALLERINA_HOME/d' /etc/profile.d/wso2.sh\n\n"
  },
  {
    "path": "installers/linux-rpm/build-ballerina-linux-rpm-x64.sh",
    "content": "#!/bin/bash\n\nfunction printUsage() {\n    echo \"Usage:\"\n    echo \"$0 [options]\"\n    echo \"options:\"\n    echo \"    -v (--version)\"\n    echo \"        version of the ballerina distribution\"\n    echo \"    -p (--path)\"\n    echo \"        path of the ballerina distributions\"\n    echo \"    -d (--dist)\"\n    echo \"        ballerina distribution type either of the followings\"\n    echo \"        If not specified both distributions will be built\"\n    echo \"        1. ballerina\"\n    echo \"        2. ballerina-runtime\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs -d ballerina\"\n}\n\nBUILD_ALL_DISTRIBUTIONS=false\nPOSITIONAL=()\nwhile [[ $# -gt 0 ]]\ndo\nkey=\"$1\"\n\ncase ${key} in\n    -v|--version)\n    BALLERINA_VERSION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -p|--path)\n    DIST_PATH=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -d|--dist)\n    DISTRIBUTION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    *)    # unknown option\n    POSITIONAL+=(\"$1\") # save it in an array for later\n    shift # past argument\n    ;;\nesac\ndone\n\nif [ -z \"$BALLERINA_VERSION\" ]; then\n    echo \"Please enter the version of the ballerina pack\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DIST_PATH\" ]; then\n    echo \"Please enter the path of the ballerina packs\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DISTRIBUTION\" ]; then\n    BUILD_ALL_DISTRIBUTIONS=true\nfi\n\nBALLERINA_DISTRIBUTION_LOCATION=${DIST_PATH}\nBALLERINA_PLATFORM=ballerina-${BALLERINA_VERSION}-linux\nBALLERINA_INSTALL_DIRECTORY=ballerina-${BALLERINA_VERSION}\nPLATFORM_SPEC_FILE=\"ballerina-tools.spec\"\nSPEC_FILES_LOCATION=\"rpmbuild/SPECS/\"\nPLATFORM_SPEC_FILE_LOC=${SPEC_FILES_LOCATION}/${PLATFORM_SPEC_FILE}\nRPM_BALLERINA_VERSION=$(echo \"${BALLERINA_VERSION//-/.}\")\n\necho \"Build started at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n\nfunction extractPack() {\n    echo \"Extracting the ballerina distribution, \" $1\n    rm -rf rpmbuild/SOURCES\n    mkdir -p rpmbuild/SOURCES\n    unzip $1 -d rpmbuild/SOURCES/ > /dev/null 2>&1\n}\n\n# Set variables in SPEC file\n# Globals:\n#   BALLERINA_VERSION\n#   RPM_BALLERINA_VERSION\n#   PLATFORM_SPEC_FILE\n# Arguments:\n# Returns:\n#   None\nfunction setupVersion_platform() {\n    sed -i \"/Version:/c\\Version:        ${RPM_BALLERINA_VERSION}\" ${PLATFORM_SPEC_FILE_LOC}\n    sed -i \"/%define _ballerina_version/c\\%define _ballerina_version ${BALLERINA_VERSION}\" ${PLATFORM_SPEC_FILE_LOC}\n    sed -i \"/%define _ballerina_tools_dir/c\\%define _ballerina_tools_dir ${BALLERINA_PLATFORM}\" ${PLATFORM_SPEC_FILE_LOC}\n    sed -i \"s/export BALLERINA_HOME=/export BALLERINA_HOME=\\/usr\\/lib64\\/ballerina\\/\" ${PLATFORM_SPEC_FILE_LOC}\n    sed -i \"s?SED_BALLERINA_HOME?/usr/lib64/ballerina/ballerina-${BALLERINA_VERSION}?\" ${PLATFORM_SPEC_FILE_LOC}\n}\n\n# Create Ballerina Platform RPM\n# Globals:\n#   BALLERINA_DISTRIBUTION_LOCATION\n#   BALLERINA_PLATFORM\n#   PLATFORM_SPEC_FILE\n# Arguments:\n# Returns:\n#   None\nfunction createBallerinaPlatform() {\n    echo \"Creating ballerina platform installer\"\n    extractPack \"$BALLERINA_DISTRIBUTION_LOCATION/$BALLERINA_PLATFORM.zip\"\n    [ -f ${PLATFORM_SPEC_FILE_LOC} ] && rm -f ${PLATFORM_SPEC_FILE_LOC}\n    cp resources/${PLATFORM_SPEC_FILE} ${SPEC_FILES_LOCATION}\n    setupVersion_platform\n    rpmbuild -bb --define \"_topdir  $(pwd)/rpmbuild\" ${PLATFORM_SPEC_FILE_LOC}\n}\n\nif [ \"$BUILD_ALL_DISTRIBUTIONS\" == \"true\" ]; then\n    echo \"Creating all distributions\"\n    createBallerinaPlatform\nelse\n    if [ \"$DISTRIBUTION\" == \"ballerina\" ]; then\n        echo \"Creating Ballerina Platform\"\n        createBallerinaPlatform\n    else\n        echo \"Error\"\n    fi\nfi\n\necho \"Build completed at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n"
  },
  {
    "path": "installers/linux-rpm/resources/ballerina-runtime.spec",
    "content": "%define _ballerina_name ballerina\n%define _ballerina_version\n%define _ballerina_tools_dir\n\nName:           ballerina-runtime\nVersion:\nRelease:        1\nSummary:        Ballerina is a general purpose, concurrent and strongly typed programming language with both textual and graphical syntaxes, optimized for integration.\nLicense:        Apache license 2.0\nURL:            https://ballerina.io/\n\n# Disable Automatic Dependencies\nAutoReqProv: no\n# Override RPM file name\n%define _rpmfilename %%{ARCH}/ballerina-%{_ballerina_version}-runtime-linux-x64.rpm\n# Disable Jar repacking\n%define __jar_repack %{nil}\n\n%description\nBallerina allows you to code with a statically-typed, interaction-centric programming language where microservices, APIs, and streams are first-class constructs. You can use your preferred IDE and CI/CD tools. Discover, consume, and share packages that integrate endpoints with Ballerina Central. Build binaries, containers, and Kubernetes artifacts and deploy as chaos-ready services on cloud and serverless infrastructure. Integrate distributed endpoints with simple syntax for resiliency, circuit breakers, transactions, and events.\n\n%pre\nrm -f /usr/bin/bal > /dev/null 2>&1\n\n%prep\nrm -rf %{_topdir}/BUILD/*\ncp -r %{_topdir}/SOURCES/%{_ballerina_tools_dir}/* %{_topdir}/BUILD/\n%build\n%install\nrm -rf $RPM_BUILD_ROOT\ninstall -d %{buildroot}%{_libdir}/ballerina/%{_ballerina_name}-runtime-%{_ballerina_version}\ncp -r bin bre lib src %{buildroot}%{_libdir}/ballerina/%{_ballerina_name}-runtime-%{_ballerina_version}/\n\n%post\nln -sf %{_libdir}/ballerina/%{_ballerina_name}-runtime-%{_ballerina_version}/bin/ballerina /usr/bin/%{_ballerina_name}\necho 'export BALLERINA_HOME=' >> /etc/profile.d/wso2.sh\nchmod 0755 /etc/profile.d/wso2.sh\n\n%postun\nsed -i.bak '\\:SED_BALLERINA_HOME:d' /etc/profile.d/wso2.sh\nif [ \"$(readlink /usr/bin/bal)\" = \"%{_libdir}/ballerina/ballerina-runtime-%{_ballerina_version}/bin/ballerina\" ]\nthen\n  rm -f /usr/bin/ballerina\nfi\n\n%clean\nrm -rf %{_topdir}/BUILD/*\nrm -rf %{buildroot}\nbal -v\n\n%files\n%{_libdir}/ballerina/%{_ballerina_name}-runtime-%{_ballerina_version}\n%doc COPYRIGHT LICENSE README.md"
  },
  {
    "path": "installers/linux-rpm/resources/ballerina-tools.spec",
    "content": "%define _ballerina_name bal\n%define _ballerina_version\n%define _ballerina_tools_dir\n\nName:           ballerina\nVersion:\nRelease:        1\nSummary:        Ballerina is a general purpose, concurrent and strongly typed programming language with both textual and graphical syntaxes, optimized for integration.\nLicense:        Apache license 2.0\nURL:            https://ballerina.io/\n\n# Disable Automatic Dependencies\nAutoReqProv: no\n# Override RPM file name\n%define _rpmfilename %%{ARCH}/ballerina-%{_ballerina_version}-linux-x64.rpm\n# Disable Jar repacking\n%define __jar_repack %{nil}\n\n%description\nBallerina allows you to code with a statically-typed, interaction-centric programming language where microservices, APIs, and streams are first-class constructs. You can use your preferred IDE and CI/CD tools. Discover, consume, and share packages that integrate endpoints with Ballerina Central. Build binaries, containers, and Kubernetes artifacts and deploy as chaos-ready services on cloud and serverless infrastructure. Integrate distributed endpoints with simple syntax for resiliency, circuit breakers, transactions, and events.\n\n%pre\nrm -f /usr/bin/bal > /dev/null 2>&1\n\n%prep\nrm -rf %{_topdir}/BUILD/*\ncp -r %{_topdir}/SOURCES/%{_ballerina_tools_dir}/* %{_topdir}/BUILD/\n\n%install\nrm -rf $RPM_BUILD_ROOT\ninstall -d %{buildroot}%{_libdir}/ballerina/\ncp -r ./* %{buildroot}%{_libdir}/ballerina/\n\n%post\nrm -f %{_libdir}/ballerina/bin/ballerina\nrm -f /usr/bin/bal\nln -sf %{_libdir}/ballerina/bin/bal /usr/bin/%{_ballerina_name}\necho 'export BALLERINA_HOME=' >> /etc/profile.d/wso2.sh\nchmod 0755 /etc/profile.d/wso2.sh\n\nif [ \"$(basename -- \"$SHELL\")\" = \"bash\" ]; then\n    bal completion bash > /usr/share/bash-completion/completions/bal\n    chmod 766 /usr/share/bash-completion/completions/bal\nelif [ \"$(basename -- \"$SHELL\")\" = \"zsh\" ]; then\n    if [ ! -d ~/.ballerina ]; then\n        mkdir –m766 ~/.ballerina\n    fi\n    mkdir -p –m766 ~/.ballerina/completion\n    echo 'fpath=(~/.ballerina/completion $fpath)' >> ~/.zshrc\n    echo 'autoload -U compinit && compinit' >> ~/.zshrc\n    \\cp %{_libdir}/ballerina/scripts/_bal ~/.ballerina/completion/\n    chmod 766 ~/.ballerina/completion/_bal\nfi\n\n%postun\nsed -i.bak '\\:SED_BALLERINA_HOME:d' /etc/profile.d/wso2.sh\n\nif [ \"$(readlink /usr/bin/ballerina)\" = \"%{_libdir}/ballerina/bin/ballerina\" ]\nthen\n  rm -f /usr/bin/ballerina\nfi\n\n%clean\nrm -rf %{_topdir}/BUILD/*\nrm -rf %{buildroot}\nbal -v\n\n%files\n%{_libdir}/ballerina/\n"
  },
  {
    "path": "installers/linux-rpm/rpmbuild/BUILDROOT/.gitkeep",
    "content": ""
  },
  {
    "path": "installers/linux-rpm/rpmbuild/RPMS/.gitkeep",
    "content": ""
  },
  {
    "path": "installers/linux-rpm/rpmbuild/SOURCES/.gitkeep",
    "content": ""
  },
  {
    "path": "installers/linux-rpm/rpmbuild/SPECS/.gitkeep",
    "content": ""
  },
  {
    "path": "installers/linux-rpm/rpmbuild/SRPMS/.gitkeep",
    "content": ""
  },
  {
    "path": "installers/mac/build-ballerina-macos-x64.sh",
    "content": "#!/bin/bash\n\nfunction printUsage() {\n    echo \"Usage:\"\n    echo \"$0 [options]\"\n    echo \"options:\"\n    echo \"    -v (--version)\"\n    echo \"        version of the ballerina distribution\"\n    echo \"    -p (--path)\"\n    echo \"        path of the ballerina distributions\"\n    echo \"    -a (--arch)\"\n    echo \"        architecture of the ballerina distribution\"\n    echo \"        If not specified : x86\"\n    echo \"        arm : aarch64/arm64\"\n    echo \"    -d (--dist)\"\n    echo \"        ballerina distribution type either of the followings\"\n    echo \"        If not specified both distributions will be built\"\n    echo \"        1. ballerina\"\n    echo \"        2. ballerina-runtime\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs\"\n    echo \"eg: $0 -v 1.0.0 -p /home/username/Packs -d ballerina\"\n}\n\nBUILD_ALL_DISTRIBUTIONS=false\nPOSITIONAL=()\nwhile [[ $# -gt 0 ]]\ndo\nkey=\"$1\"\n\ncase ${key} in\n    -v|--version)\n    BALLERINA_VERSION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -p|--path)\n    DIST_PATH=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -a|--arch)\n    ARCH=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    -d|--dist)\n    DISTRIBUTION=\"$2\"\n    shift # past argument\n    shift # past value\n    ;;\n    *)    # unknown option\n    POSITIONAL+=(\"$1\") # save it in an array for later\n    shift # past argument\n    ;;\nesac\ndone\n\nif [ -z \"$BALLERINA_VERSION\" ]; then\n    echo \"Please enter the version of the ballerina pack\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DIST_PATH\" ]; then\n    echo \"Please enter the path of the ballerina packs\"\n    printUsage\n    exit 1\nfi\n\nif [ -z \"$DISTRIBUTION\" ]; then\n    BUILD_ALL_DISTRIBUTIONS=true\nfi\n\nif [ -z \"$ARCH\" ]; then\n    BALLERINA_PLATFORM=ballerina-${BALLERINA_VERSION}-macos\nelse\n    if [ \"$ARCH\" = \"arm\" ]; then\n        BALLERINA_PLATFORM=ballerina-${BALLERINA_VERSION}-macos-arm\n    else\n        echo \"Please enter a valid architecture for the ballerina pack\"\n        printUsage\n        exit 1\n    fi\nfi\n\n\nBALLERINA_DISTRIBUTION_LOCATION=${DIST_PATH}\nBALLERINA_INSTALL_DIRECTORY=ballerina-${BALLERINA_VERSION}\nBALLERINA_DIST_VERSION=\"$(cut -d'-' -f1 <<<${BALLERINA_VERSION})\"\n\necho \"Build started at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n\nfunction deleteTargetDirectory() {\n    echo \"Deleting target directory\"\n    rm -rf target\n}\n\nfunction extractPack() {\n    echo \"Extracting the ballerina distribution, \" $1\n    rm -rf target/original\n    mkdir -p target/original\n    unzip $1 -d target/original > /dev/null 2>&1\n    mv target/original/$2 target/original/${BALLERINA_INSTALL_DIRECTORY}\n}\n\nfunction createPackInstallationDirectory() {\n    rm -rf target/darwin\n    cp -r darwin target/darwin\n\n    sed -i -e 's/__BALLERINA_VERSION__/'${BALLERINA_DIST_VERSION}'/g' target/darwin/scripts/postinstall\n    chmod -R 755 target/darwin/scripts/postinstall\n\n    sed -i -e 's/__BALLERINA_VERSION__/'${BALLERINA_VERSION}'/g' target/darwin/Distribution\n    chmod -R 755 target/darwin/Distribution\n\n    rm -rf target/darwinpkg\n    mkdir -p target/darwinpkg\n    chmod -R 755 target/darwinpkg\n\n    mkdir -p target/darwinpkg/etc/paths.d\n    chmod -R 755 target/darwinpkg/etc/paths.d\n    \n    echo \"/Library/Ballerina/bin\" >> target/darwinpkg/etc/paths.d/bal\n    chmod -R 644 target/darwinpkg/etc/paths.d/bal\n\n    mkdir -p target/darwinpkg/Library/Ballerina\n    chmod -R 755 target/darwinpkg/Library/Ballerina\n\n    mv target/original/${BALLERINA_INSTALL_DIRECTORY}/* target/darwinpkg/Library/Ballerina/\n\n\n    rm -rf target/package\n    mkdir -p target/package\n    chmod -R 755 target/package\n\n    mkdir -p target/pkg\n    chmod -R 755 target/pkg\n}\n\nfunction buildPackage() {\n    pkgbuild --identifier org.ballerina.${BALLERINA_VERSION} \\\n    --version ${BALLERINA_VERSION} \\\n    --scripts target/darwin/scripts \\\n    --root target/darwinpkg \\\n    target/package/ballerina.pkg\n}\n\nfunction buildProduct() {\n    productbuild --distribution target/darwin/Distribution \\\n    --resources target/darwin/Resources \\\n    --package-path target/package \\\n    target/pkg/$1 > /dev/null 2>&1\n}\n\nfunction createBallerinaPlatform() {\n    echo \"Creating ballerina platform installer\"\n    extractPack \"$BALLERINA_DISTRIBUTION_LOCATION/$BALLERINA_PLATFORM.zip\" ${BALLERINA_PLATFORM}\n    createPackInstallationDirectory true\n    buildPackage\n    buildProduct ${BALLERINA_PLATFORM}-x64.pkg\n}\n\ndeleteTargetDirectory\n\nif [ \"$BUILD_ALL_DISTRIBUTIONS\" == \"true\" ]; then\n    echo \"Creating all distributions\"\n    # createBallerinaRuntime\n    createBallerinaPlatform\nelse\n    if [ \"$DISTRIBUTION\" == \"ballerina\" ]; then\n        echo \"Creating Ballerina Platform\"\n        createBallerinaPlatform\n    # elif [ \"$DISTRIBUTION\" == \"ballerina-runtime\" ]; then\n    #     echo \"Creating Ballerina Runtime\"\n    #     createBallerinaRuntime\n    else\n        echo \"Error\"\n    fi\nfi\n\necho \"Build completed at\" $(date +\"%Y-%m-%d %H:%M:%S\")\n"
  },
  {
    "path": "installers/mac/darwin/Distribution",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<installer-script minSpecVersion=\"1.000000\">\n    <title>Ballerina</title>\n    <background mime-type=\"image/png\" file=\"dialog.png\"/>\n    <!--license file=\"LICENSE\"/>\n    <welcome file=\"WELCOME\" /-->\n    <options customize=\"never\" allow-external-scripts=\"no\"/>\n    <domains enable_localSystem=\"true\" />\n    <installation-check script=\"installCheck();\"/>\n    <script>\nfunction installCheck() {\n    if(!(system.compareVersions(system.version.ProductVersion, '10.6.0') >= 0)) {\n        my.result.title = 'Unable to install';\n        my.result.message = 'Ballerina requires Mac OS X 10.6 or later.';\n        my.result.type = 'Fatal';\n        return false;\n    }\n    if(system.files.fileExistsAtPath('/Library/Ballerina/bin/ballerina')) {\n        my.result.title = 'Previous Installation Detected';\n        my.result.message = 'A previous installation of Ballerina exists at /Library/Ballerina. This installer will remove the previous installation prior to installing. Please back up any data before proceeding.';\n        my.result.type = 'Warning';\n        return false;\n    }\n    return true;\n}\n    </script>\n    <choices-outline>\n        <line choice=\"ballerina\"/>\n    </choices-outline>\n    <choice id=\"ballerina\" title=\"Ballerina\">\n        <pkg-ref id=\"ballerina.pkg\"/>\n    </choice>\n    <pkg-ref id=\"ballerina.pkg\" auth=\"Root\">ballerina.pkg</pkg-ref>\n</installer-script>\n"
  },
  {
    "path": "installers/mac/darwin/app.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array>\n\t<dict>\n\t\t<key>BundleIsRelocatable</key>\n\t\t<false/>\n\t\t<key>RootRelativeBundlePath</key>\n\t\t<string>Applications/Ballerina Composer.app</string>\n\t</dict>\n</array>\n</plist>\n"
  },
  {
    "path": "installers/mac/darwin/scripts/postinstall",
    "content": "#!/bin/bash\nBALLERINAROOT=/Library/Ballerina\necho \"Fixing permissions\"\ncd $BALLERINAROOT\nfind distributions/ballerina-__BALLERINA_VERSION__ -exec chmod ugo+r \\{\\} \\;\nfind bin -exec chmod ugo+rx \\{\\} \\;\nfind dependencies -type d -exec chmod ugo+rx \\{\\} \\;\nfind lib -exec chmod -R ugo+r \\{\\} \\;\nchmod o-w .\n\nrm -f /Library/Ballerina/bin/ballerina\nrm -f /etc/paths.d/ballerina\n"
  },
  {
    "path": "installers/windows/build-ballerina-windows-x64.bat",
    "content": "@echo off\n\nset BALPOS=windows\nset ICONDIST=resources\\icons\n\n:argumentLoop\nIF NOT \"%1\"==\"\" (\n    IF \"%1\"==\"--dist\" (\n        SET DIST=%2\n        SHIFT\n    )\n    IF \"%1\"==\"--version\" (\n        SET BALLERINA_VERSION=%2\n        SHIFT\n    )\n\tIF \"%1\"==\"--path\" (\n        SET DISTLOC=%2\n        SHIFT\n    )\n\tSHIFT\n\tgoto argumentLoop\n)\n\n\nIF \"%DIST%\"==\"\"  (\n\tset DIST=all\n)\n\nIF \"%DISTLOC%\"==\"\"  (\n\tset DISTLOC=resources\\dist\n)\n\nIF NOT \"%DIST%\"==\"all\" IF NOT \"%DIST%\"==\"ballerina\" IF NOT \"%DIST%\"==\"ballerina-runtime\" (\n\techo The syntax of the command is incorrect. Possible arguments for dist - all, ballerina, ballerina-runtime.\n\techo Ex: --dist ballerina\n\tgoto EOF\n)\n\nIF \"%BALLERINA_VERSION%\"==\"\"  (\n\techo The syntax of the command is incorrect. Missing argument version.\n\tgoto EOF\n)\n\nfor /f %%x in ('wmic path win32_utctime get /format:list ^| findstr \"=\"') do set %%x\nset UTC_TIME=%Year%-%Month%-%Day% %Hour%:%Minute%:%Second% UTC\n\nrmdir ballerina-%BALLERINA_VERSION%-windows /s /q >nul 2>&1\nrmdir target /s /q >nul 2>&1\n\nfor /f %%i in ('guid') do set UPGRADECODE=%%i\necho Upgrade Code - %UPGRADECODE%\n\nIF \"%DIST%\"==\"all\" (\n\tcall :createballerinaWin64Installer\n) ELSE (\n\tcall :create%DIST%Win64Installer\n)\n\ngoto EOF\n\n\n:createballerinaWin64Installer\nset BALZIP=%DISTLOC%\\ballerina-%BALLERINA_VERSION%-windows.zip\nset BALDIST=ballerina-%BALLERINA_VERSION%-windows\nset BALPARCH=x64\nset INSTALLERPARCH=amd64\nset MSI=ballerina-%BALLERINA_VERSION%-%BALPOS%-%BALPARCH%.msi\nset INSTALLERNAME=\"Ballerina %BALLERINA_VERSION%\"\ncall :createInstaller\ngoto EOF\n\n:createballerinaWin586Installer\nset BALZIP=%DISTLOC%\\ballerina-%BALLERINA_VERSION%-windows.zip\nset BALDIST=ballerina-%BALLERINA_VERSION%-windows\nset BALPARCH=i586\nset INSTALLERPARCH=386\nset MSI=ballerina-%BALLERINA_VERSION%-%BALPOS%-%BALPARCH%.msi\nset INSTALLERNAME=\"Ballerina %BALLERINA_VERSION%\"\ncall :createInstaller\ngoto EOF\n\n:createInstaller\nrmdir target\\installer-resources /s /q >nul 2>&1\npowershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('%BALZIP%', '.'); }\"\nxcopy  %ICONDIST% %BALDIST%\\icons /e /i >nul 2>&1\n\necho %BALDIST% build started at '%UTC_TIME%' for %BALPOS% %BALPARCH%\n\necho Creating the Installer...\n\nheat dir %BALDIST% -nologo -v -gg -g1 -srd -sfrag -sreg -cg AppFiles -template fragment -dr INSTALLDIR -var var.SourceDir -out target\\installer-resources\\AppFiles.wxs\ncandle -nologo -sw -dinstallerName=%INSTALLERNAME% -dbalVersion=%BALLERINA_VERSION% -dWixbalVersion=1.0.0 -dUpgradeCode=%UPGRADECODE% -dArch=%INSTALLERPARCH% -dSourceDir=%BALDIST% -out target\\installer-resources\\ -ext WixUtilExtension resources\\installer.wxs target\\installer-resources\\AppFiles.wxs\nlight -nologo -dcl:high -sw -ext WixUIExtension -ext WixUtilExtension -loc resources\\en-us.wxl target\\installer-resources\\AppFiles.wixobj target\\installer-resources\\installer.wixobj -o target\\msi\\%MSI%\n\nrmdir ballerina-%BALLERINA_VERSION%-windows /s /q >nul 2>&1\n\necho %BALDIST% build completed at '%UTC_TIME%' for %BALPOS% %BALPARCH%\n\necho.\ngoto EOF\n\n:EOF\n"
  },
  {
    "path": "installers/windows/resources/en-us.wxl",
    "content": "<WixLocalization Culture=\"en-us\" xmlns=\"http://schemas.microsoft.com/wix/2006/localization\">\n  <String Id=\"InstallDirDlgDescription\" Overridable=\"yes\">Click Change to install Ballerina to a different folder.</String>\n</WixLocalization>\n"
  },
  {
    "path": "installers/windows/resources/installer.wxs",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\"\n>\n    <?if $(var.Arch) = 386 ?>\n    <?define ProdId = {6147400c-24be-4f94-ba82-5a1c76320f10} ?>\n    <?define SysFolder=SystemFolder ?>\n    <?define PlatformArch=x86 ?>\n    <?define ProgramFilesDir=ProgramFilesFolder ?>\n    <?else?>\n    <?define ProdId = {8ca1298f-2d74-4ca1-8f56-1d1147df5034} ?>\n    <?define SysFolder=System64Folder ?>\n    <?define PlatformArch=x64 ?>\n    <?define ProgramFilesDir=ProgramFiles64Folder ?>\n    <?endif?>\n\n    <Product\n            Id=\"*\"\n            Name=\"$(var.installerName)\"\n            Language=\"1033\"\n            Version=\"$(var.WixbalVersion)\"\n            Manufacturer=\"https://ballerinalang.org/\"\n            UpgradeCode=\"$(var.UpgradeCode)\">\n        <Package\n                Id='*'\n                Keywords='Installer'\n                Description=\"The Ballerina Installer\"\n                Comments=\"The Ballerina Installer.\"\n                InstallerVersion=\"300\"\n                Compressed=\"yes\"\n                InstallScope=\"perMachine\"\n                Languages=\"1033\"\n                Platform=\"$(var.PlatformArch)\"/>\n\n        <UI>\n            <UIRef Id=\"WixUI_InstallDir\"/>\n            <Publish Dialog=\"WelcomeDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"InstallDirDlg\">NOT Installed</Publish>\n            <Publish Dialog=\"InstallDirDlg\" Control=\"Back\" Event=\"NewDialog\" Value=\"WelcomeDlg\" Order=\"2\">1</Publish>\n            <Publish Dialog=\"InstallDirDlg\" Control=\"Next\" Event=\"NewDialog\" Value=\"PrepareDlg\" Order=\"5\">\n                WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=\"1\"\n            </Publish>\n        </UI>\n\n        <Property Id=\"ARPCOMMENTS\"\n                  Value=\"Ballerina is a general purpose, concurrent and strongly typed programming language with both textual and graphical syntaxes, optimized for integration.\"/>\n        <Property Id=\"ARPCONTACT\" Value=\"https://ballerinalang.org/\"/>\n        <Property Id=\"ARPHELPLINK\" Value=\"https://ballerinalang.org/\"/>\n        <Property Id=\"ARPREADME\" Value=\"https://ballerinalang.org/\"/>\n        <Property Id=\"ARPURLINFOABOUT\" Value=\"https://ballerinalang.org/\"/>\n        <Media Id='1' Cabinet=\"bal.cab\" EmbedCab=\"yes\" CompressionLevel=\"high\"/>\n        <Condition Message=\"Windows XP or greater required.\">VersionNT >= 500</Condition>\n        <MajorUpgrade AllowDowngrades=\"yes\"/>\n        <SetDirectory Id=\"INSTALLDIRROOT\" Value=\"[$(var.ProgramFilesDir)]\"/>\n        <CustomAction\n                Id=\"SetApplicationRootDirectory\"\n                Property=\"ARPINSTALLLOCATION\"\n                Value=\"[INSTALLDIR]\"/>\n        <!-- Define the directory structure and environment variables -->\n        <Directory Id=\"TARGETDIR\" Name=\"SourceDir\">\n            <Directory Id=\"INSTALLDIRROOT\">\n                <Directory Id=\"INSTALLDIR\" Name=\"Ballerina\">\n                </Directory>\n            </Directory>\n            <Directory Id=\"ProgramMenuFolder\">\n                <Directory Id=\"BallerinaProgramShortcutsDir\" Name=\"Ballerina\"/>\n            </Directory>\n            <Directory Id=\"EnvironmentEntries\">\n                <Directory Id=\"BallerinaEnvironmentEntries\" Name=\"Ballerina\"/>\n            </Directory>\n        </Directory>\n        <!-- Programs Menu Shortcuts -->\n        <DirectoryRef Id=\"BallerinaProgramShortcutsDir\">\n            <Component Id=\"Component_BallerinaProgramShortCuts\" Guid=\"{764ee6d4-917f-422c-87cb-cc0fff389765}\">\n                <Shortcut\n                        Id=\"UninstallShortcut\"\n                        Name=\"Uninstall Ballerina\"\n                        Description=\"Uninstalls Ballerina\"\n                        Target=\"[$(var.SysFolder)]msiexec.exe\"\n                        Arguments=\"/x [ProductCode]\"/>\n                <RemoveFolder\n                        Id=\"BallerinaProgramShortcutsDir\"\n                        On=\"uninstall\"/>\n                <RegistryValue\n                        Root=\"HKCU\"\n                        Key=\"Software\\Ballerina\"\n                        Name=\"ShortCuts\"\n                        Type=\"integer\"\n                        Value=\"1\"\n                        KeyPath=\"yes\"/>\n            </Component>\n        </DirectoryRef>\n        <!-- Registry & Environment Settings -->\n        <DirectoryRef Id=\"BallerinaEnvironmentEntries\">\n            <Component Id=\"Component_BallerinaEnvironment\" Guid=\"{f9f2e5e9-d6fb-4ef3-8faf-38b5fd283237}\">\n                <RegistryKey\n                        Root=\"HKCU\"\n                        Key=\"Software\\Ballerina-$(var.balVersion)\"\n                        Action=\"create\">\n                    <RegistryValue\n                            Name=\"installed\"\n                            Type=\"integer\"\n                            Value=\"1\"\n                            KeyPath=\"yes\"/>\n                    <RegistryValue\n                            Name=\"installLocation\"\n                            Type=\"string\"\n                            Value=\"[INSTALLDIR]\"/>\n                </RegistryKey>\n                <RegistryKey\n                        Root=\"HKCR\"\n                        Key=\".balo\\DefaultIcon\"\n                        Action=\"createAndRemoveOnUninstall\">\n                    <RegistryValue\n                            Type=\"string\"\n                            Value=\"[INSTALLDIR]\\icons\\balo-teal.ico\"/>\n                </RegistryKey>\n                <RegistryKey\n                        Root=\"HKCR\"\n                        Key=\".balx\\DefaultIcon\"\n                        Action=\"createAndRemoveOnUninstall\">\n                    <RegistryValue\n                            Type=\"string\"\n                            Value=\"[INSTALLDIR]\\icons\\balx-teal.ico\"/>\n                </RegistryKey>\n                <RegistryKey\n                        Root=\"HKCR\"\n                        Key=\".bal\\DefaultIcon\"\n                        Action=\"createAndRemoveOnUninstall\">\n                    <RegistryValue\n                            Type=\"string\"\n                            Value=\"[INSTALLDIR]\\icons\\bal-teal.ico\"/>\n                </RegistryKey>\n                <Environment\n                        Id=\"BallerinaHome\"\n                        Action=\"set\"\n                        Part=\"all\"\n                        Name=\"BALLERINA_HOME\"\n                        Permanent=\"no\"\n                        System=\"yes\"\n                        Value=\"[INSTALLDIR]\"/>\n                <Environment\n                        Id=\"BallerinaPathEntry\"\n                        Action=\"set\"\n                        Part=\"last\"\n                        Name=\"PATH\"\n                        Permanent=\"no\"\n                        System=\"yes\"\n                        Value=\"%BALLERINA_HOME%\\bin\"/>\n                <RemoveFolder\n                        Id=\"BallerinaEnvironmentEntries\"\n                        On=\"uninstall\"/>\n                <RemoveFile \n                        Id=\"PreviousBallerinaCommand\"  \n                        On =\"install\" \n                        Name=\"ballerina.bat\"/>\n            </Component>\n        </DirectoryRef>\n        <!-- Install the files -->\n        <Feature\n                Id=\"BallerinaTools\"\n                Title=\"Ballerina\"\n                Level=\"1\">\n            <ComponentRef Id=\"Component_BallerinaEnvironment\"/>\n            <ComponentGroupRef Id=\"AppFiles\"/>\n            <ComponentRef Id=\"Component_BallerinaProgramShortCuts\"/>\n        </Feature>\n        <!-- Update the environment -->\n        <InstallExecuteSequence>\n            <Custom Action=\"SetApplicationRootDirectory\" Before=\"InstallFinalize\"/>\n        </InstallExecuteSequence>\n        <!-- Include the user interface -->\n        <WixVariable Id=\"WixUIBannerBmp\" Value=\"resources/Banner.jpg\"/>\n        <WixVariable Id=\"WixUIDialogBmp\" Value=\"resources/Dialog.jpg\"/>\n        <Property Id=\"WIXUI_INSTALLDIR\" Value=\"INSTALLDIR\"/>\n    </Product>\n</Wix>\n"
  },
  {
    "path": "issue_template.md",
    "content": "**Description:**\r\n<!-- Give a brief description of the issue -->\r\n\r\n**Suggested Labels:**\r\n<!-- Optional comma separated list of suggested labels. Non committers can’t assign labels to issues, so this will help issue creators who are not a committer to suggest possible labels-->\r\n\r\n**Suggested Assignees:**\r\n<!--Optional comma separated list of suggested team members who should attend the issue. Non committers can’t assign issues to assignees, so this will help issue creators who are not a committer to suggest possible assignees-->\r\n\r\n**Affected Product Version:**\r\n\r\n**OS, DB, other environment details and versions:**    \r\n\r\n**Steps to reproduce:**\r\n\r\n\r\n**Related Issues:**\r\n<!-- Any related issues such as sub tasks, issues reported in other repositories (e.g component repositories), similar problems, etc. -->"
  },
  {
    "path": "language-server-simulator/build.gradle",
    "content": "description = 'Ballerina Language Server Simulator'\n\napply from: \"$rootDir/gradle/javaProject.gradle\"\n\next {\n    distributionDir = \"distribution\"\n    nbalSourceDir = \"nBallerinaSrc\"\n    fhirSourceDir = \"fhirSrc\"\n    shortVersion = \"${version}\".split(\"-\")[0]\n}\n\nconfigurations {\n    jBallerinaDistribution\n    ballerinaDistribution\n}\n\ndependencies {\n    implementation \"org.slf4j:slf4j-api:${project.slf4jApiVersion}\"\n    implementation group: 'org.ballerinalang', name: 'ballerina-lang', version: \"${ballerinaLangVersion}\"\n    implementation group: 'org.ballerinalang', name: 'ballerina-parser', version: \"${ballerinaLangVersion}\"\n    implementation group: 'org.ballerinalang', name: 'language-server-core', version: \"${ballerinaLangVersion}\"\n    implementation group: 'org.ballerinalang', name: 'ballerina-tools-api', version: \"${ballerinaLangVersion}\"\n    implementation group: 'org.ballerinalang', name: 'language-server-commons', version: \"${ballerinaLangVersion}\"\n    implementation(group: 'org.eclipse.lsp4j', name:'org.eclipse.lsp4j', version:\"${eclipseLsp4jVersion}\") {\n        exclude group: 'com.google.guava', module: 'guava'\n    }\n    implementation (group: 'org.eclipse.lsp4j', name:'org.eclipse.lsp4j.jsonrpc', version:\"${eclipseLsp4jJsonrpcVersion}\"){\n        exclude group: 'com.google.guava', module: 'guava'\n    }\n    implementation \"org.slf4j:slf4j-jdk14:${slf4jJdk14Version}\"\n    implementation \"com.google.code.gson:gson:${gsonVersion}\"\n\n    jBallerinaDistribution project(path: \":ballerina\", configuration: \"jBallerinaDistribution\")\n    ballerinaDistribution project(path: \":ballerina\", configuration: \"ballerinaDistribution\")\n}\n\ntask unpackBallerinaDistribution(type: Copy) {\n    dependsOn configurations.jBallerinaDistribution\n    dependsOn configurations.ballerinaDistribution\n    def sourceDir = \"${buildDir}/${distributionDir}\"\n    from zipTree { \"${rootDir}/ballerina/build/distributions/ballerina-${version}-swan-lake.zip\" }\n    new File(\"${sourceDir}\").mkdirs()\n    into new File(\"${sourceDir}\")\n}\n\ntask copyPackages() {\n    dependsOn unpackBallerinaDistribution\n    def sourceDir = \"${buildDir}/${distributionDir}\" +\n            \"/ballerina-${version}-swan-lake/distributions/ballerina-${shortVersion}/repo\"\n    copy {\n        from \"${sourceDir}\"\n        into \"${buildDir}/repo\"\n    }\n}\n\ntask downloadBalTestProject(type: Download) {\n    // Download nBallerina latest tag\n    src \"https://github.com/ballerina-platform/nballerina/archive/refs/heads/main.zip\"\n    onlyIfModified true\n    dest new File(\"${buildDir}/nballeirna-src.zip\")\n}\n\ntask downloadBalFHIRTestProject(type: Download) {\n    // Download nBallerina latest tag\n    src \"https://github.com/ballerina-platform/module-ballerinax-health.fhir.r4/archive/refs/tags/uscore-v1.0.5.zip\"\n    onlyIfModified true\n    dest new File(\"${buildDir}/fhir-src.zip\")\n}\n\ntask unpackBalTestProject(type: Copy) {\n    dependsOn downloadBalTestProject\n    def sourceDir = \"${buildDir}/${nbalSourceDir}\"\n    from zipTree { \"${buildDir}/nballeirna-src.zip\" }\n    new File(\"${sourceDir}\").mkdirs()\n    into new File(\"${sourceDir}\")\n}\n\ntask unpackBalFHIRTestProject(type: Copy) {\n    dependsOn downloadBalFHIRTestProject\n    def sourceDir = \"${buildDir}/${fhirSourceDir}\"\n    from zipTree { \"${buildDir}/fhir-src.zip\" }\n    new File(\"${sourceDir}\").mkdirs()\n    into new File(\"${sourceDir}\")\n}\n\ntask runLSSimulatorOnnBallerina(type: JavaExec) {\n    dependsOn copyPackages\n    dependsOn unpackBalTestProject\n\n    def extractedBalSrcDir = \"${buildDir}/${nbalSourceDir}/nballerina-main/compiler\"\n    systemProperty \"ls.simulation.src\", \"${extractedBalSrcDir}\"\n\n    systemProperty \"ballerina.home\", \"$buildDir/\"\n    systemProperty \"ballerina.version\", \"${ballerinaLangVersion}\"\n    systemProperty \"ls.simulation.duration\", \"60\"\n    systemProperty \"ls.simulation.skipGenerators\", System.getProperty(\"ls.simulation.skipGenerators\")\n    systemProperty \"LANG_REPO_BUILD\", \"false\"\n\n    jvmArgs = ['-XX:+HeapDumpOnOutOfMemoryError', \"-XX:HeapDumpPath=$rootDir/dump.hprof\"]\n\n    maxHeapSize \"1536m\"\n    group = \"Execution\"\n    description = \"Run the main class with JavaExecTask\"\n    classpath = sourceSets.main.runtimeClasspath\n    main = \"org.ballerinalang.langserver.simulator.EditorSimulator\"\n}\n\ntask runLSSimulatorOnFHIR(type: JavaExec) {\n    dependsOn copyPackages\n    dependsOn unpackBalFHIRTestProject\n\n    def extractedBalSrcDir = \"${buildDir}/${fhirSourceDir}/module-ballerinax-health.fhir.r4-uscore-v1.0.5/base\"\n    systemProperty \"ls.simulation.src\", \"${extractedBalSrcDir}\"\n\n    systemProperty \"ballerina.home\", \"$buildDir/\"\n    systemProperty \"ballerina.version\", \"${ballerinaLangVersion}\"\n    systemProperty \"ls.simulation.duration\", \"60\"\n    systemProperty \"ls.simulation.skipGenerators\", System.getProperty(\"ls.simulation.skipGenerators\")\n    systemProperty \"LANG_REPO_BUILD\", \"false\"\n\n    jvmArgs = ['-XX:+HeapDumpOnOutOfMemoryError', \"-XX:HeapDumpPath=$rootDir/dump.hprof\"]\n\n    maxHeapSize \"1536m\"\n    group = \"Execution\"\n    description = \"Run the main class with JavaExecTask\"\n    classpath = sourceSets.main.runtimeClasspath\n    main = \"org.ballerinalang.langserver.simulator.EditorSimulator\"\n}\n\ntasks.compileJava {\n    doFirst {\n        options.encoding = 'UTF-8'\n        options.compilerArgs = [\n                '--module-path', classpath.asPath,\n        ]\n        classpath = files()\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/gradle.properties",
    "content": "eclipseLsp4jVersion=0.15.0\neclipseLsp4jJsonrpcVersion=0.15.0\nslf4jJdk14Version=1.7.26\ngsonVersion=2.9.1\nslf4jApiVersion=1.7.s26\n"
  },
  {
    "path": "language-server-simulator/src/main/java/module-info.java",
    "content": "module io.ballerina.language.server.simulator {\n    uses org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator;\n    requires org.eclipse.lsp4j;\n    requires io.ballerina.language.server.commons;\n    requires io.ballerina.language.server.core;\n    requires org.eclipse.lsp4j.jsonrpc;\n    requires io.ballerina.lang;\n    requires io.ballerina.parser;\n    requires io.ballerina.tools.api;\n    requires com.google.gson;\n    requires org.slf4j;\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/Editor.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator;\n\nimport org.ballerinalang.langserver.BallerinaLanguageServer;\nimport org.ballerinalang.langserver.commons.command.CommandArgument;\nimport org.ballerinalang.langserver.util.TestUtil;\nimport org.eclipse.lsp4j.ExecuteCommandParams;\nimport org.eclipse.lsp4j.jsonrpc.Endpoint;\n\nimport java.nio.file.Path;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Represents the editor used by the end user, which editor consists of a set of open tabs.\n *\n * @since 2201.8.0\n */\npublic class Editor {\n\n    private final BallerinaLanguageServer languageServer;\n    private final Endpoint endpoint;\n\n    private final List<EditorTab> tabs = new ArrayList<>();\n    private EditorTab activeTab;\n\n    private boolean isPulled = false;\n\n    private Editor(BallerinaLanguageServer languageServer, Endpoint endpoint) {\n        this.languageServer = languageServer;\n        this.endpoint = endpoint;\n    }\n\n    /**\n     * Simulates opening the editor. Here we initialize the language server.\n     *\n     * @return Editor instance\n     */\n    public static Editor open() {\n        BallerinaLanguageServer languageServer = new BallerinaLanguageServer();\n\n        EditorOutputStream outputStream = new EditorOutputStream();\n        Endpoint endpoint = TestUtil.initializeLanguageSever(languageServer, outputStream);\n        Editor editor = new Editor(languageServer, endpoint);\n        outputStream.setEditor(editor);\n        return editor;\n    }\n\n    public EditorTab openFile(Path filePath) {\n        //Pull missing modules from central\n        if (!isPulled) {\n            CommandArgument uriArg = CommandArgument.from(\"doc.uri\", filePath);\n            List<Object> args = new ArrayList<>();\n            args.add(uriArg);\n            ExecuteCommandParams params = new ExecuteCommandParams(\"PULL_MODULE\", args);\n            TestUtil.getExecuteCommandResponse(params, endpoint);\n            isPulled = true;\n        }\n\n        EditorTab editorTab = tabs.stream()\n                .filter(tab -> tab.filePath().equals(filePath))\n                .findFirst()\n                .orElseGet(() -> {\n                    EditorTab tab = new EditorTab(filePath, endpoint, languageServer);\n                    tabs.add(tab);\n                    return tab;\n                });\n        this.activeTab = editorTab;\n        return editorTab;\n    }\n\n    public void closeFile(Path filePath) {\n        Iterator<EditorTab> iterator = tabs.iterator();\n        while (iterator.hasNext()) {\n            EditorTab tab = iterator.next();\n            if (filePath.equals(tab.filePath())) {\n                if (activeTab != null && activeTab.equals(tab)) {\n                    activeTab = null;\n                }\n                iterator.remove();\n            }\n        }\n    }\n\n    public void closeTab(EditorTab tab) {\n        tabs.remove(tab);\n        if (activeTab != null && activeTab.equals(tab)) {\n            activeTab = null;\n        }\n    }\n\n    public void close() {\n        this.languageServer.shutdown();\n        tabs.forEach(EditorTab::close);\n    }\n\n    public EditorTab activeTab() {\n        return activeTab;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/EditorOutputStream.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator;\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\nimport org.eclipse.lsp4j.jsonrpc.RemoteEndpoint;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.charset.Charset;\n\n/**\n * A custom output stream to consume messages sent from LS to the LS client side.\n *\n * @since 2201.8.0\n */\nclass EditorOutputStream extends ByteArrayOutputStream {\n\n    private static final Logger logger = LoggerFactory.getLogger(EditorOutputStream.class);\n\n    private Editor editor;\n\n    /**\n     * LSP4J invokes this method after writing a message to the stream. At that point, we should have the complete\n     * message in the byte array. Here we consume that and reset the array.\n     *\n     * @throws IOException IO errors\n     * @see RemoteEndpoint#request(String, Object)\n     */\n    @Override\n    public void flush() throws IOException {\n        String message = this.toString(Charset.defaultCharset());\n        reset();\n        try {\n            process(message);\n        } catch (Throwable t) {\n            logger.error(\"Error processing message\", t);\n        }\n    }\n\n    /**\n     * Process a received message. We are interested in log message events and telemetry events to identify errors\n     * occurred.\n     *\n     * @param message JSON RPC message received\n     */\n    void process(String message) {\n        String[] parts = message.replace(\"\\r\\n\", \"\\n\").split(\"\\n\");\n        if (parts.length > 1) {\n            message = parts[parts.length - 1];\n            JsonElement jsonMsg = JsonParser.parseString(message);\n\n            if (jsonMsg.isJsonObject()) {\n                JsonObject obj = jsonMsg.getAsJsonObject();\n                String method = obj.get(\"method\").getAsString();\n\n                switch (method) {\n                    case \"telemetry/event\":\n                        logger.info(\"Got telemetry event: {}\", obj);\n                        if (editor != null && editor.activeTab() != null) {\n                            logger.info(\"Current file: {}\", editor.activeTab().filePath());\n                            logger.info(\"Current file content: \\n{}\\n========================\",\n                                    editor.activeTab().textDocument().toString());\n                        }\n                        break;\n                    case \"window/logMessage\":\n                        logger.info(\"Received log message event: {}\", obj);\n                        break;\n                    case \"textDocument/publishDiagnostics\":\n                        // pass\n                    default:\n                        // pass\n                }\n            }\n        }\n    }\n\n    public void setEditor(Editor editor) {\n        this.editor = editor;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/EditorSimulator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator;\n\nimport io.ballerina.compiler.syntax.tree.ModuleMemberDeclarationNode;\nimport io.ballerina.compiler.syntax.tree.ModulePartNode;\nimport io.ballerina.compiler.syntax.tree.NodeList;\nimport io.ballerina.tools.text.LinePosition;\nimport org.ballerinalang.langserver.simulator.generators.Generators;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.security.SecureRandom;\nimport java.time.Instant;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n/**\n * The main class to simulate the behavior of language server. Similarly to how vscode client use LSP to send different\n * updates, this sends similar messages via JSON RPC to the language server.\n *\n * @since 2201.8.0\n */\npublic class EditorSimulator {\n\n    private static final Logger logger = LoggerFactory.getLogger(EditorSimulator.class);\n\n    private static final String PROP_DURATION = \"ls.simulation.duration\";\n    public static final String PROP_SOURCE_DIR = \"ls.simulation.src\";\n\n    private static final SecureRandom random = new SecureRandom();\n\n    public static void main(String[] args) throws IOException {\n        try {\n            run();\n        } catch (Exception e) {\n            logger.error(\"Error occurred while running the simulator\", e);\n            throw e;\n        }\n    }\n\n    public static void run() throws IOException {\n        int durationSeconds = Integer.parseInt(System.getProperty(PROP_DURATION, \"60\")) * 60;\n        String projectPath = System.getProperty(PROP_SOURCE_DIR);\n        if (projectPath == null) {\n            throw new IllegalArgumentException(\"No ballerina project path provided\");\n        }\n\n        Path path = Paths.get(projectPath);\n        logger.info(\"Using project: {}, path: {}\", path.toString(), projectPath);\n\n        List<Path> balFiles = Files.list(path)\n                .filter(Files::isRegularFile)\n                .filter(p -> p.getFileName() != null)\n                .filter(p -> p.getFileName().toString().endsWith(\".bal\"))\n                .collect(Collectors.toList());\n\n        if (balFiles.isEmpty()) {\n            throw new IllegalArgumentException(\"No bal files found in the provided directory\");\n        }\n\n        Path modulesPath = path.resolve(\"modules\");\n        if (Files.exists(modulesPath)) {\n            Files.list(modulesPath)\n                    .filter(Files::isDirectory)\n                    .flatMap(modPath -> {\n                        try {\n                            return Files.list(modPath)\n                                    .filter(Files::isRegularFile)\n                                    .filter(p -> p.getFileName() != null)\n                                    .filter(p -> p.getFileName().toString().endsWith(\".bal\"));\n                        } catch (IOException e) {\n                            logger.error(\"Unable to read path: {}\", modPath);\n                            return Stream.empty();\n                        }\n                    })\n                    .forEach(balFiles::add);\n        }\n\n        logger.info(\"Found bal files in project: {}\", balFiles.stream()\n                .map(Path::toString).collect(Collectors.joining(\"\\n\")));\n\n        Editor editor = Editor.open();\n        Runtime.getRuntime().addShutdownHook(new Thread(editor::close));\n\n        long endTime = Instant.now().getEpochSecond() + durationSeconds;\n        while (Instant.now().getEpochSecond() < endTime) {\n            int i = random.nextInt(balFiles.size());\n            Path balFile = balFiles.get(i);\n            EditorTab editorTab = editor.openFile(balFile);\n\n            logger.info(\"Generating random code snippet\");\n            // Get random generator type\n            Generators.Type type = getRandomGenerator();\n            logger.info(\"Generating snippet of type: {}\", type);\n            String content = Generators.generate(type);\n\n            if (type == Generators.Type.IMPORT_STATEMENT) {\n                // Set cursor to start of the file\n                editorTab.cursor(0, 0);\n            } else {\n                // Select a random place to type random code\n                ModulePartNode modulePartNode = editorTab.syntaxTree().rootNode();\n                NodeList<ModuleMemberDeclarationNode> members = modulePartNode.members();\n                ModuleMemberDeclarationNode moduleMemberDeclarationNode = members.get(random.nextInt(members.size()));\n                LinePosition linePosition = moduleMemberDeclarationNode.location().lineRange().startLine();\n                // Set cursor to start of random node\n                editorTab.cursor(linePosition.line(), linePosition.offset());\n            }\n\n            logger.info(\"Typing in editor tab: {} -> {}\", editorTab, content);\n            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {\n                editorTab.type(content);\n                editorTab.completions();\n            });\n\n            // While the snippet is being typed, check if we have reached a timeout\n            while (!future.isDone() && Instant.now().getEpochSecond() < endTime) {\n                logger.info(\"Remaining time: {}\", endTime - Instant.now().getEpochSecond());\n                try {\n                    Thread.sleep(60 * 1000L);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                    logger.warn(\"Interrupted editing\", e);\n                    break;\n                }\n            }\n\n            try {\n                int sleepSecs = 1 + random.nextInt(5);\n                Thread.sleep(sleepSecs * 1000L);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                logger.warn(\"Interrupted simulation\", e);\n                break;\n            }\n        }\n\n        logger.info(\"Exiting...\");\n        editor.close();\n        System.exit(0);\n    }\n\n    /**\n     * Generate a random syntax tree node (top level) to be inserted to the source document.\n     *\n     * @return Source for a random top level node.\n     */\n    public static Generators.Type getRandomGenerator() {\n        List<Generators.Type> types = Arrays.stream(Generators.Type.values())\n                .filter(Generators.Type::isTopLevelNode)\n                .collect(Collectors.toList());\n\n        // Get random generator\n        return types.get(random.nextInt(types.size()));\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/EditorTab.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator;\n\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\nimport io.ballerina.compiler.syntax.tree.SyntaxTree;\nimport io.ballerina.projects.Document;\nimport io.ballerina.tools.text.LinePosition;\nimport io.ballerina.tools.text.TextDocument;\nimport io.ballerina.tools.text.TextDocumentChange;\nimport io.ballerina.tools.text.TextDocuments;\nimport io.ballerina.tools.text.TextEdit;\nimport io.ballerina.tools.text.TextRange;\nimport org.ballerinalang.langserver.BallerinaLanguageServer;\nimport org.ballerinalang.langserver.util.TestUtil;\nimport org.eclipse.lsp4j.CodeActionContext;\nimport org.eclipse.lsp4j.Position;\nimport org.eclipse.lsp4j.Range;\nimport org.eclipse.lsp4j.jsonrpc.Endpoint;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.nio.charset.Charset;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.security.SecureRandom;\nimport java.util.Collections;\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\n\n/**\n * Represents a tab in the {@link Editor}. Simulates the behavior of cursor and current text in the document.\n *\n * @since 2201.8.0\n */\npublic class EditorTab {\n\n    private static final Logger logger = LoggerFactory.getLogger(EditorTab.class);\n\n    private final Path filePath;\n    private final Endpoint endpoint;\n    private final BallerinaLanguageServer languageServer;\n\n    private TextDocument textDocument;\n    private Position cursor;\n\n    private final SecureRandom random = new SecureRandom();\n    private final PrintWriter writer = new PrintWriter(System.out, true, Charset.defaultCharset());\n\n    public EditorTab(Path filePath, Endpoint endpoint, BallerinaLanguageServer languageServer) {\n        this.filePath = filePath;\n        this.endpoint = endpoint;\n        this.languageServer = languageServer;\n        try {\n            String content = Files.readString(filePath);\n            this.textDocument = TextDocuments.from(content);\n            logger.info(\"Opening document: {}\", filePath);\n            TestUtil.openDocument(endpoint, filePath);\n            LinePosition linePosition = textDocument.linePositionFrom(content.length() - 1);\n            cursor(linePosition.line(), linePosition.offset());\n        } catch (IOException e) {\n            throw new IllegalArgumentException(e);\n        }\n    }\n\n    /**\n     * Simulates a user typing the provided content in the editor. Content is typed character by character similarly to\n     * how a user does it.\n     *\n     * @param content Text content to be typed in the editor.\n     */\n    public void type(String content) {\n        int missCount = 0;\n        for (int i = 0; i < content.length(); i++) {\n            String typedChar = Character.toString(content.charAt(i));\n\n            int startOffset = textDocument.textPositionFrom(LinePosition.from(cursor.getLine(), cursor.getCharacter()));\n            TextEdit edit = TextEdit.from(TextRange.from(startOffset, 0), typedChar);\n            TextDocumentChange change = TextDocumentChange.from(new TextEdit[]{edit});\n            textDocument = textDocument.apply(change);\n\n            LinePosition newLinePos = textDocument.linePositionFrom(startOffset + 1);\n            try {\n                TestUtil.didChangeDocument(this.endpoint, this.filePath, textDocument.toString());\n            } catch (Throwable t) {\n                logger.error(\"Caught error in didChange\", t);\n            }\n            cursor(newLinePos.line(), newLinePos.offset());\n\n            if (i % 10 == 0) {\n                float completionPercentage = ((float) i / (float) content.length()) * 100;\n                writer.printf(\"%.1f%%\\r\", completionPercentage);\n            }\n\n            // Get completions in the background\n            if (i % 3 == 0) {\n                CompletableFuture.runAsync(this::completions);\n                CompletableFuture.runAsync(this::codeActions);\n            }\n\n            if (isDocumentNotInSync()) {\n                missCount++;\n            }\n\n            try {\n                Thread.sleep(100 + (long) random.nextInt(300));\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                logger.error(\"Interrupted\", e);\n                break;\n            }\n        }\n        logger.info(\"Typed provided content in file: {} -> \\n{}\",\n                filePath, content.substring(0, Math.min(20, content.length())));\n        logger.info(\"Typed {} characters with {} out of sync scenarios\", content.length(), missCount);\n\n        while (isDocumentNotInSync()) {\n            logger.info(\"Document out of sync. Waiting 30 seconds and syncing...\");\n            try {\n                Thread.sleep(30 * (long) 1000);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                break;\n            }\n            TestUtil.didChangeDocument(this.endpoint, this.filePath, textDocument.toString());\n        }\n    }\n\n    /**\n     * Check if the document in this instance is similar to that is in the language server.\n     *\n     * @return True if the document content is not equal to that in workspace manager\n     */\n    private boolean isDocumentNotInSync() {\n        Optional<Document> document = languageServer.getWorkspaceManager().document(filePath);\n        if (document.isPresent()) {\n            return !document.get().textDocument().toString().equals(textDocument.toString());\n        } else {\n            logger.warn(\"Document not found in workspace manager: {}\", filePath);\n        }\n\n        return true;\n    }\n\n    /**\n     * Get completions for the current cursor position.\n     */\n    public void completions() {\n        String completionResponse = TestUtil.getCompletionResponse(filePath.toString(), cursor, endpoint, \"\");\n        JsonObject json = JsonParser.parseString(completionResponse).getAsJsonObject();\n        boolean hasError = false;\n        String resultProp = \"result\";\n        if (json.has(resultProp) && json.get(resultProp).isJsonObject()) {\n            JsonObject result = json.getAsJsonObject(resultProp);\n            if (!result.has(\"left\") || !result.get(\"left\").isJsonArray()) {\n                hasError = true;\n            }\n        } else {\n            hasError = true;\n        }\n\n        if (hasError) {\n            logger.warn(\"Completion request unsuccessful! cursor: {} -> {}\", filePath, cursor);\n        }\n    }\n\n    /**\n     * Get code actions for the current cursor position.\n     */\n    public void codeActions() {\n        CodeActionContext codeActionContext = new CodeActionContext(Collections.emptyList());\n        Range range = new Range(cursor, cursor);\n        TestUtil.getCodeActionResponse(endpoint, filePath.toString(), range, codeActionContext);\n    }\n\n    public void cursor(int line, int offset) {\n        this.cursor = new Position(line, offset);\n    }\n\n    public Position cursor() {\n        return this.cursor;\n    }\n\n    public SyntaxTree syntaxTree() {\n        return SyntaxTree.from(textDocument);\n    }\n\n    public TextDocument textDocument() {\n        return textDocument;\n    }\n\n    public Path filePath() {\n        return filePath;\n    }\n\n    public void close() {\n        logger.info(\"Closing document: {}\", filePath());\n        TestUtil.closeDocument(endpoint, filePath());\n    }\n\n    @Override\n    public String toString() {\n        return \"EditorTab{\" +\n                \"filePath=\" + filePath +\n                \", cursor=(\" + cursor.getLine() + \", \" + cursor.getCharacter() + \")\" +\n                '}';\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }\n        if (o == null || getClass() != o.getClass()) {\n            return false;\n        }\n        EditorTab editorTab = (EditorTab) o;\n        return Objects.equals(filePath, editorTab.filePath);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(filePath);\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/ClassGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\n\n/**\n * Class code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class ClassGenerator extends CodeSnippetGenerator {\n\n    @Override\n    public String generate() {\n        return generateRandomClass();\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.CLASS;\n    }\n\n    private String generateRandomClass() {\n        FunctionGenerator functionGenerator = Generators.getGenerator(Generators.Type.FUNCTION);\n\n        int numOfFunctions = 1 + random.nextInt(100);\n        String body = IntStream.range(0, numOfFunctions)\n                .mapToObj(i -> functionGenerator.generateRandomFunction(\"fn\" + i, \"string\"))\n                .collect(Collectors.joining(\"\\n\"));\n        return \"class AClass {\\n\" +\n                \"    \" + body + \"\\n\" +\n                \"}\";\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/CodeSnippetGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport java.security.SecureRandom;\nimport java.util.List;\n\n/**\n * Abstract implementation of code snippet generator for the LS simulator.\n *\n * @since 2201.8.0\n */\npublic abstract class CodeSnippetGenerator {\n\n    protected final List<String> primitiveTypes = List.of(\"string\", \"int\", \"float\", \"decimal\", \"boolean\");\n    protected SecureRandom random = new SecureRandom();\n\n    public abstract String generate();\n\n    public abstract Generators.Type type();\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/FunctionGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\n/**\n * Function code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class FunctionGenerator extends CodeSnippetGenerator {\n\n    @Override\n    public String generate() {\n        return generateRandomFunction();\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.FUNCTION;\n    }\n\n    public String generateRandomFunction() {\n        String name = \"fn\";\n        String returnType = \"string\";\n        return generateRandomFunction(name, returnType);\n    }\n\n    public String generateRandomFunction(String name, String returnType) {\n        return \"\\npublic function \" + name + \"() returns \" + returnType + \" {\\n\" +\n                \"    \" + getRandomFunctionBody(returnType) + \"\\n\" +\n                \"}\\n\";\n    }\n\n    public String getRandomFunctionBody(String returnType) {\n        StatementGenerator statementGenerator = Generators.getGenerator(Generators.Type.STATEMENT);\n        String body = \"\";\n        body += \"\\t\" + statementGenerator.getRandomStatement();\n        body += \"\\t\" + statementGenerator.getRandomStatement();\n        body += \"\\t\" + statementGenerator.getRandomStatement();\n        body += \"\\treturn \" + returnType + \";\";\n        return body;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/Generators.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.util.EnumMap;\nimport java.util.ServiceLoader;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n/**\n * Factory to access {@link CodeSnippetGenerator}s.\n *\n * @since 2201.8.0\n */\npublic class Generators {\n\n    private static final Logger logger = LoggerFactory.getLogger(Generators.class);\n    private static final String PROP_SKIPPED_GENERATORS = \"ls.simulation.skipGenerators\";\n    private static final Generators instance = new Generators();\n    private final EnumMap<Generators.Type, CodeSnippetGenerator> GENERATORS;\n\n    private Generators() {\n        // Get skipped generators\n        String property = System.getProperty(PROP_SKIPPED_GENERATORS, \"\");\n        Set<Type> skippedGenerators = Stream.of(property.split(\",\"))\n                .filter(type -> !type.isBlank())\n                .map(Type::valueOf)\n                .collect(Collectors.toSet());\n        logger.info(\"Skipping generators of type: \" + skippedGenerators);\n\n        // Load generators\n        GENERATORS = new EnumMap<>(Generators.Type.class);\n        ServiceLoader.load(CodeSnippetGenerator.class)\n                .forEach(generator -> {\n                    if (!skippedGenerators.contains(generator.type())) {\n                        GENERATORS.put(generator.type(), generator);\n                    }\n                });\n    }\n\n    /**\n     * Generate a code snippet of provided type.\n     *\n     * @param type Type of the required code snippet.\n     * @return Generated code snippet.\n     */\n    public static String generate(Type type) {\n        if (getInstance().GENERATORS.containsKey(type)) {\n            return instance.GENERATORS.get(type).generate();\n        }\n\n        return \"\";\n    }\n\n    public static <T> T getGenerator(Type type) {\n        return (T) instance.GENERATORS.get(type);\n    }\n\n    public static Generators getInstance() {\n        return instance;\n    }\n\n    /**\n     * Different types of code snippets which can be generated.\n     */\n    public enum Type {\n        FUNCTION(true),\n        CLASS(true),\n        SERVICE(true),\n        TYPE_DEFINITION(true),\n        STATEMENT(false),\n        MATCH_STATEMENT(false),\n        VARIABLE_DECLARATION_STATEMENT(true),\n        IMPORT_STATEMENT(true);\n\n        private final boolean topLevelNode;\n\n        Type(boolean topLevelNode) {\n            this.topLevelNode = topLevelNode;\n        }\n\n        public boolean isTopLevelNode() {\n            return topLevelNode;\n        }\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/ImportStatementGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\nimport org.ballerinalang.langserver.simulator.EditorSimulator;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\n/**\n * Import statement snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class ImportStatementGenerator extends CodeSnippetGenerator {\n\n    private static final String PACKAGE_NAME = \"nballerina\";\n\n    @Override\n    public String generate() {\n        //Look for modules in the source and generate import statements for them.\n        String projectPath = System.getProperty(EditorSimulator.PROP_SOURCE_DIR);\n        if (projectPath == null) {\n            return \"\";\n        }\n        Path path = Paths.get(projectPath);\n        Path modulesPath = path.resolve(\"modules\");\n        if (Files.exists(modulesPath)) {\n            try (Stream<Path> paths = Files.list(modulesPath)) {\n                List<String> imports = paths.filter(Files::isDirectory)\n                        .map(p -> \"import \" + PACKAGE_NAME + \".\" + p.getFileName() + \";\")\n                        .collect(Collectors.toList());\n                if (!imports.isEmpty()) {\n                    return imports.get(random.nextInt(imports.size()));\n                }\n            } catch (IOException e) {\n                //ignore\n            }\n        }\n        return \"\";\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.IMPORT_STATEMENT;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/MatchStatementGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\n/**\n * Match statement code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class MatchStatementGenerator extends CodeSnippetGenerator {\n\n    /**\n     * Generates a match statement.\n     *\n     * @return Match statement\n     */\n    @Override\n    public String generate() {\n        // This statement has intentionally added syntax errors.\n        return \"\\nmatch t {\\n\" +\n                \"    () => {\\n}\" +\n                \"    [1, 2] => {\\n}\" +\n                \"    [1, 2, 10] => {\\n}\" +\n                \"    [int => {\\n\" +\n                \"    _ => {\\n}\" +\n                \"}\\n\";\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.MATCH_STATEMENT;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/ServiceGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\n/**\n * Service code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class ServiceGenerator extends CodeSnippetGenerator {\n\n    @Override\n    public String generate() {\n        return generateRandomService();\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.SERVICE;\n    }\n\n    public String generateRandomService() {\n        return \"\\nservice /context1 on new http:Listener(8080) {\\n\" +\n                \"    resource function get path1(http:Caller caller, http:Request req) {\\n\" +\n                \"        \\n\" +\n                \"    }\\n\" +\n                \"}\\n\";\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/StatementGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\n/**\n * Statement code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class StatementGenerator extends CodeSnippetGenerator {\n\n    @Override\n    public String generate() {\n        return getRandomStatement();\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.STATEMENT;\n    }\n\n    public String getRandomStatement() {\n        switch (random.nextInt(2)) {\n            case 0:\n                return Generators.generate(Generators.Type.MATCH_STATEMENT);\n            case 1:\n            default:\n                return Generators.generate(Generators.Type.VARIABLE_DECLARATION_STATEMENT);\n        }\n    }\n\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/TypeDefinitionGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Type definition code snippet generator.\n *\n * @since 2201.8.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class TypeDefinitionGenerator extends CodeSnippetGenerator {\n\n    private final List<String> generatedTypeDefNames = new ArrayList<>();\n    private int typeCount = 0;\n\n    @Override\n    public String generate() {\n        switch (random.nextInt(3)) {\n            case 1:\n                return generateUnionType();\n            case 2:\n                return generateRecordType();\n            case 3:\n            default:\n                return generateObjectTypeDef();\n        }\n    }\n\n    public String generateRecordType() {\n        String typeName = \"Rec\" + typeCount;\n\n        List<String> fields = new ArrayList<>();\n        for (int i = 0; i < 2 + random.nextInt(100); i++) {\n            String field;\n            if (random.nextBoolean() || generatedTypeDefNames.isEmpty()) {\n                field = String.format(\"\\t%s field%d;\", primitiveTypes.get(random.nextInt(primitiveTypes.size())), i);\n            } else {\n                field = String.format(\"\\t%s field%d;\",\n                        generatedTypeDefNames.get(random.nextInt(generatedTypeDefNames.size())), i);\n            }\n            fields.add(field);\n        }\n\n        typeCount++;\n        generatedTypeDefNames.add(typeName);\n        return String.format(\"%ntype %s {|%n%s%n|};%n\", typeName, String.join(\"\\n\", fields));\n    }\n\n    public String generateUnionType() {\n        // Member types\n        Set<String> memberTypes = new HashSet<>();\n        for (int i = 0; i < 2 + random.nextInt(3); i++) {\n            String memberType;\n            do {\n                if (random.nextBoolean() || generatedTypeDefNames.isEmpty()) {\n                    memberType = primitiveTypes.get(random.nextInt(primitiveTypes.size()));\n                } else {\n                    memberType = generatedTypeDefNames.get(random.nextInt(generatedTypeDefNames.size()));\n                }\n            } while (memberTypes.contains(memberType));\n            memberTypes.add(memberType);\n        }\n\n        String typeName = \"Type\" + typeCount;\n        typeCount++;\n        generatedTypeDefNames.add(typeName);\n        return String.format(\"%ntype %s %s;%n\", typeName, String.join(\" | \", memberTypes));\n    }\n\n    public String generateObjectTypeDef() {\n        String typeName = \"ObjectDef\" + typeCount;\n        typeCount++;\n        generatedTypeDefNames.add(typeName);\n        return \"\\ntype \" + typeName + \" object {\\n\" +\n                \"\\n\\tpublic function doSomething() returns UnkType;\\n\" +\n                \"};\\n\";\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.TYPE_DEFINITION;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/java/org/ballerinalang/langserver/simulator/generators/VarDeclarationStatementGenerator.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.ballerinalang.langserver.simulator.generators;\n\nimport org.ballerinalang.annotation.JavaSPIService;\n\n/**\n * Variable declaration code snippet generator.\n *\n * @since 2.0.0\n */\n@JavaSPIService(\"org.ballerinalang.langserver.org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator\")\npublic class VarDeclarationStatementGenerator extends CodeSnippetGenerator {\n\n    private int varCount = 0;\n\n    public String generate() {\n        varCount++;\n        return String.format(\"%n%s %s = createVar();%n\",\n                primitiveTypes.get(random.nextInt(primitiveTypes.size())), \"myVar\" + varCount);\n    }\n\n    @Override\n    public Generators.Type type() {\n        return Generators.Type.VARIABLE_DECLARATION_STATEMENT;\n    }\n}\n"
  },
  {
    "path": "language-server-simulator/src/main/resources/META-INF/services/org.ballerinalang.langserver.simulator.generators.CodeSnippetGenerator",
    "content": "org.ballerinalang.langserver.simulator.generators.VarDeclarationStatementGenerator\norg.ballerinalang.langserver.simulator.generators.TypeDefinitionGenerator\norg.ballerinalang.langserver.simulator.generators.StatementGenerator\norg.ballerinalang.langserver.simulator.generators.ImportStatementGenerator\norg.ballerinalang.langserver.simulator.generators.ServiceGenerator\norg.ballerinalang.langserver.simulator.generators.ClassGenerator\norg.ballerinalang.langserver.simulator.generators.MatchStatementGenerator\norg.ballerinalang.langserver.simulator.generators.FunctionGenerator\n"
  },
  {
    "path": "project-api-tests/build.gradle",
    "content": " /*\n  ~ * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n  ~ *\n  ~ * Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ * you may not use this file except in compliance with the License.\n  ~ * You may obtain a copy of the License at\n  ~ *\n  ~ * http://www.apache.org/licenses/LICENSE-2.0\n  ~ *\n  ~ * Unless required by applicable law or agreed to in writing, software\n  ~ * distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ * See the License for the specific language governing permissions and\n  ~ * limitations under the License.\n  ~ */\n\napply from: \"$rootDir/gradle/javaProject.gradle\"\n\ndescription = 'Ballerina - Central Tests'\n\nconfigurations {\n    jBallerinaDistribution\n    ballerinaDistribution\n    ballerinaLinuxDistribution\n    ballerinaMacDistribution\n    ballerinaWindowsDistribution\n}\n\ndependencies {\n    testImplementation \"org.testng:testng:${testngVersion}\"\n    testImplementation \"net.lingala.zip4j:zip4j:${netLingalaZip4jVersion}\"\n    testImplementation \"commons-io:commons-io:${commonsIoVersion}\"\n    testImplementation \"org.apache.commons:commons-lang3:${commonsLang3Version}\"\n    testImplementation \"org.ballerinalang:ballerina-lang:${ballerinaLangVersion}\"\n    testImplementation \"org.ballerinalang:jballerina-debugger-integration-test:${ballerinaLangVersion}\"\n    testImplementation \"org.ballerinalang:ballerina-test-utils:${ballerinaLangVersion}\"\n    testImplementation \"org.eclipse.lsp4j:org.eclipse.lsp4j.debug:${lsp4jDebugVersion}\"\n    testImplementation \"com.fasterxml.jackson.core:jackson-databind:2.12.3\"\n    testImplementation \"com.squareup.okhttp3:okhttp:3.14.0\"\n\n    jBallerinaDistribution project(path: \":ballerina\", configuration: \"jBallerinaDistribution\")\n    ballerinaDistribution project(path: \":ballerina\", configuration: \"ballerinaDistribution\")\n    ballerinaLinuxDistribution project(path: \":ballerina\", configuration: \"ballerinaLinuxDistribution\")\n    ballerinaMacDistribution project(path: \":ballerina\", configuration: \"ballerinaMacDistribution\")\n    ballerinaWindowsDistribution project(path: \":ballerina\", configuration: \"ballerinaWindowsDistribution\")\n}\n\ntask centralTests {\n    dependsOn configurations.jBallerinaDistribution\n    dependsOn configurations.ballerinaDistribution\n    dependsOn configurations.ballerinaLinuxDistribution\n    dependsOn configurations.ballerinaWindowsDistribution\n    test {\n        systemProperty \"distributions.dir\", \"$buildDir/../../ballerina/build/distributions\"\n        systemProperty \"target.dir\", \"$buildDir\"\n        systemProperty \"maven.version\", \"$version\"\n        systemProperty \"examples.dir\", \"$buildDir/../../examples\"\n        systemProperty \"line.check.extensions\", \".java, .bal\"\n        systemProperty \"short.version\", \"$version\".split(\"-\")[0]\n        systemProperty \"server.zip\", \"$buildDir/../../ballerina/build/distributions/ballerina-${System.getProperty(\"short.version\")}.zip\"\n        systemProperty \"code.name\", \"${codeName}\"\n\n        useTestNG() {\n            suites 'src/test/resources/testng.xml'\n        }\n        testLogging {\n            showStandardStreams = true\n        }\n    }\n}\n\n\n task checkURL {\n     doLast {\n         try {\n             URL url = new URL(\"${devIdpUrl}\")\n             HttpURLConnection connection = (HttpURLConnection) url.openConnection()\n             connection.setRequestMethod(\"GET\")\n             connection.connect()\n\n             int code = connection.getResponseCode()\n             if (code == 200) {\n                 logger.lifecycle(\"Connection to ${devIdpUrl} is successful. Running tests...\")\n                 ext.isURLAvailable = true\n             } else {\n                 logger.lifecycle(\"Connection to ${devIdpUrl} is not successful. Skipping tests...\")\n                 logger.lifecycle(\"-----------------------------------------\")\n                 logger.lifecycle(\" WARNING: Skipping the project api tests\")\n                 logger.lifecycle(\"-----------------------------------------\")\n                 ext.isURLAvailable = false\n             }\n         } catch(Exception ex) {\n             logger.lifecycle(\"Connection to ${devIdpUrl} is not successful. Exception while connecting to \" +\n                     \"${devIdpUrl}. Skipping tests...\")\n             logger.lifecycle(\"-----------------------------------------\")\n             logger.lifecycle(\" WARNING: Skipping the project api tests\")\n             logger.lifecycle(\"-----------------------------------------\")\n             ext.isURLAvailable = false\n         }\n     }\n }\n\n test {\n     dependsOn checkURL\n     onlyIf {\n         checkURL.isURLAvailable\n     }\n     dependsOn centralTests\n }\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/BalToolTest.java",
    "content": "/*\n * Copyright (c) 2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport com.google.gson.JsonObject;\nimport com.google.gson.JsonParser;\nimport io.ballerina.projects.BalToolsManifest;\nimport io.ballerina.projects.BalToolsToml;\nimport io.ballerina.projects.JvmTarget;\nimport io.ballerina.projects.internal.BalToolsManifestBuilder;\nimport io.ballerina.projects.util.ProjectUtils;\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.testng.Assert;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.BeforeGroups;\nimport org.testng.annotations.Test;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Optional;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\nimport java.util.zip.ZipOutputStream;\n\nimport static io.ballerina.projects.util.ProjectConstants.BALA_DIR_NAME;\nimport static io.ballerina.projects.util.ProjectConstants.CENTRAL_REPOSITORY_CACHE_NAME;\nimport static io.ballerina.projects.util.ProjectConstants.REPOSITORIES_DIR;\nimport static org.ballerina.projectapi.CentralTestUtils.OUTPUT_NOT_CONTAINS_EXP_MSG;\nimport static org.ballerina.projectapi.CentralTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executeCommand;\nimport static org.ballerina.projectapi.TestUtils.executeHelpCommand;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\nimport static org.ballerina.projectapi.TestUtils.executeToolCommand;\n\npublic class BalToolTest {\n    private Path tempWorkspaceDirectory;\n    private Map<ToolSubCommand, ToolEnvironment> toolEnvironments;\n\n    static final String ORG_NAME = \"bctestorg\";\n    static final String TOOL_ID = \"disttest\";\n    static final String PACKAGE_NAME = \"disttestpackage\";\n    static final String NON_EXISTING_TOOL = \"disttest2\";\n    static final String LATEST_VERSION = \"1.1.0\";\n    static final String SPECIFIC_VERSION = \"1.0.0\";\n    static final String PATCH_VERSION = \"1.0.1\";\n    static final String NON_EXISTING_VERSION = \"1.0.3\";\n    static final String INCOMPATIBLE_DIST_VERSION = \"1.0.4\";\n    static final String PULL = \"pull\";\n    static final String REMOVE = \"remove\";\n    static final String UPDATE = \"update\";\n    static final String USE = \"use\";\n    static final String LIST = \"list\";\n    static final String SEARCH = \"search\";\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        TestUtils.setupDistributions();\n        Path tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        this.tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        createSettingToml(tempHomeDirectory);\n        this.toolEnvironments = setToolEnvironmentsForSubCommands();\n        Map<String, String> envVariables = TestUtils.addEnvVariables(getEnvVariables(), tempHomeDirectory);\n        copyTestResourcesToTempWorkspace();\n        pushToolPackages(envVariables);\n    }\n\n    @BeforeGroups(value = \"pull\")\n    public void setupPullTests() {\n        // Remove the tool from bal-tools.toml if exists\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        BalToolsManifest balToolsManifest = BalToolsManifestBuilder.from(balToolsToml).build();\n        balToolsManifest.removeTool(TOOL_ID);\n        balToolsToml.modify(balToolsManifest);\n\n        // Delete the tool from local cache if exists\n        Path toolPath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(ORG_NAME, PACKAGE_NAME));\n        if (Files.exists(toolPath)) {\n            ProjectUtils.deleteDirectory(toolPath);\n        }\n    }\n\n    @Test(description = \"Pull a tool without specifying a version\", groups = {\"pull\"})\n    public void testPullToolWithoutVersion() throws IOException, InterruptedException {\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)), toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-pull-without-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool \" + TOOL_ID + \" is not available in bal-tools.toml\");\n        }\n        BalToolsManifest.Tool tool = toolOpt.get();\n        Assert.assertEquals(tool.id(), TOOL_ID);\n        Assert.assertEquals(tool.version(), LATEST_VERSION);\n        Assert.assertEquals(tool.org(), ORG_NAME);\n        Assert.assertEquals(tool.name(), PACKAGE_NAME);\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(tool.org(), tool.name(), tool.version()));\n        if (!Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool \" + TOOL_ID + \":\" + LATEST_VERSION + \" is not available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Pull a tool again without specifying a version\",\n            dependsOnMethods = \"testPullToolWithoutVersion\", groups = {\"pull\"})\n    public void testPullToolAgainWithoutVersion() throws IOException, InterruptedException {\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)), toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-pull-again-without-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool \" + TOOL_ID + \" is not available in bal-tools.toml\");\n        }\n        BalToolsManifest.Tool tool = toolOpt.get();\n        Assert.assertEquals(tool.id(), TOOL_ID);\n        Assert.assertEquals(tool.version(), LATEST_VERSION);\n        Assert.assertEquals(tool.org(), ORG_NAME);\n        Assert.assertEquals(tool.name(), PACKAGE_NAME);\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(tool.org(), tool.name(), tool.version()));\n        if (!Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool \" + TOOL_ID + \":\" + LATEST_VERSION + \" is not available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Pull a tool with a specific version\",\n            dependsOnMethods = {\"testPullToolAgainWithoutVersion\"}, groups = {\"pull\"})\n    public void testPullToolWithASpecificVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-pull-with-specific-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool \" + TOOL_ID + \" is not available in bal-tools.toml\");\n        }\n        BalToolsManifest.Tool tool = toolOpt.get();\n        Assert.assertEquals(tool.id(), TOOL_ID);\n        Assert.assertEquals(tool.version(), SPECIFIC_VERSION);\n        Assert.assertEquals(tool.org(), ORG_NAME);\n        Assert.assertEquals(tool.name(), PACKAGE_NAME);\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(tool.org(), tool.name(), tool.version()));\n        if (!Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool \" + TOOL_ID + \":\" + SPECIFIC_VERSION + \" is not available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(), readExpectedCmdOutsAsString(\n                \"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Pull a tool again with a specific version\",\n            dependsOnMethods = \"testPullToolWithASpecificVersion\", groups = {\"pull\"})\n    public void testPullToolAgainWithASpecificVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-pull-again-with-specific-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool \" + TOOL_ID + \" is not available in bal-tools.toml\");\n        }\n        BalToolsManifest.Tool tool = toolOpt.get();\n        Assert.assertEquals(tool.id(), TOOL_ID);\n        Assert.assertEquals(tool.version(), SPECIFIC_VERSION);\n        Assert.assertEquals(tool.org(), ORG_NAME);\n        Assert.assertEquals(tool.name(), PACKAGE_NAME);\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(tool.org(), tool.name(), tool.version()));\n        if (!Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool \" + TOOL_ID + \":\" + SPECIFIC_VERSION + \" is not available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(), readExpectedCmdOutsAsString(\n                \"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Pull a tool with a non existing version\",\n            dependsOnMethods = \"testPullToolWithASpecificVersion\", groups = {\"pull\"})\n    public void testPullToolWithANonExistingVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + NON_EXISTING_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-pull-with-non-existing-version.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.PULL).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getTool(TOOL_ID, NON_EXISTING_VERSION, null);\n        if (toolOpt.isPresent()) {\n            Assert.fail(\"Tool \" + toolIdAndVersion + \" should not be in bal-tools.toml\");\n        }\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.PULL).centralCachePath\n                .resolve(Path.of(ORG_NAME, TOOL_ID, NON_EXISTING_VERSION));\n        if (Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool \" + TOOL_ID + \":\" + NON_EXISTING_VERSION + \"  should not be available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(), readExpectedCmdOutsAsString(\n                \"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Pull a tool version with incompatible distribution\",\n            dependsOnMethods = \"testPullToolWithASpecificVersion\", groups = {\"pull\"})\n    public void testPullAToolVersionWithIncompatibleDistribution() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + INCOMPATIBLE_DIST_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-pull-with-incompatible-dist.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.PULL).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(), readExpectedCmdOutsAsString(\n                \"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @BeforeGroups(value = \"remove\")\n    public void setupRemoveTests() throws IOException, InterruptedException {\n        // Pull a specific version of a tool\n        String specificToolVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, specificToolVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n\n        // Pull the latest tool version\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n\n        // Pull tool version with incompatible distribution\n        String incompToolVersion = TOOL_ID + \":\" + INCOMPATIBLE_DIST_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, incompToolVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n\n        // Add the dist incompatible version to the toml file\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        BalToolsManifest balToolsManifest = BalToolsManifestBuilder.from(balToolsToml).build();\n        balToolsManifest.addTool(TOOL_ID, ORG_NAME, PACKAGE_NAME, INCOMPATIBLE_DIST_VERSION, false, null);\n        balToolsToml.modify(balToolsManifest);\n    }\n\n    @Test(description = \"Remove a non existing tool\", groups = {\"remove\"})\n    public void testRemoveANonExistingTool() throws IOException, InterruptedException {\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, NON_EXISTING_TOOL)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n\n        // Validate the command output\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-remove-non-existing-tool.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                NON_EXISTING_TOOL, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(\n                outputs.getLeft(),\n                readExpectedCmdOutsAsString(\"tool-execute-unknown-cmd-non-existing.txt\"));\n        Assert.assertEquals(outputs.getRight(), \"\");\n    }\n\n    @Test(description = \"Remove a non existing version of a tool\", groups = {\"remove\"})\n    public void testRemoveANonExistingVersionOfATool() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + NON_EXISTING_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n\n        // Validate the command output\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-remove-non-existing-version.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Remove a tool version with incompatible distribution\", groups = {\"remove\"})\n    public void testRemoveToolVersionWithIncompatibleDistribution() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + INCOMPATIBLE_DIST_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-remove-with-incompatible-dist.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Remove a tool version with incompatible distribution\", groups = {\"remove\"})\n    public void testRemoveToolActiveVersion() throws IOException, InterruptedException {\n        // Make the latest version active\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        BalToolsManifest balToolsManifest = BalToolsManifestBuilder.from(balToolsToml).build();\n        balToolsManifest.setActiveToolVersion(TOOL_ID, LATEST_VERSION, null);\n        balToolsToml.modify(balToolsManifest);\n\n        // Remove the active version\n        String toolIdAndVersion = TOOL_ID + \":\" + LATEST_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-remove-active-version.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Remove a specific tool version\",\n            dependsOnMethods = {\"testRemoveANonExistingVersionOfATool\",\n                    \"testRemoveToolVersionWithIncompatibleDistribution\", \"testRemoveToolActiveVersion\"},\n            groups = {\"remove\"})\n    public void testRemoveASpecificToolVersion() throws IOException, InterruptedException {\n        // Make the latest version active\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        BalToolsManifest balToolsManifest = BalToolsManifestBuilder.from(balToolsToml).build();\n        balToolsManifest.setActiveToolVersion(TOOL_ID, LATEST_VERSION, null);\n        balToolsToml.modify(balToolsManifest);\n\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n\n        // Check for tool availability in bal-tools.toml\n        Optional<BalToolsManifest.Tool> toolOpt = balToolsManifest.getTool(TOOL_ID, SPECIFIC_VERSION, null);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is not available to be removed\");\n        }\n\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-remove-specific-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        toolOpt = BalToolsManifestBuilder.from(balToolsToml).build().getTool(TOOL_ID, SPECIFIC_VERSION, null);\n        if (toolOpt.isPresent()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is available in bal-tools.toml\");\n        }\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.REMOVE).centralCachePath\n                .resolve(Path.of(ORG_NAME, PACKAGE_NAME, SPECIFIC_VERSION));\n        if (Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Remove all tool versions\", dependsOnMethods = {\"testRemoveASpecificToolVersion\"},\n            groups = {\"remove\"})\n    public void testRemoveAllToolVersions() throws IOException, InterruptedException {\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + TOOL_ID + \"' is not available to be removed\");\n        }\n\n        // Remove all versions of the tool\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-remove-all.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.REMOVE).balToolsTomlPath);\n        toolOpt = BalToolsManifestBuilder.from(balToolsToml).build().getActiveTool(TOOL_ID);\n        if (toolOpt.isPresent()) {\n            Assert.fail(\"Tool \" + TOOL_ID + \" is available in bal-tools.toml\");\n        }\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.REMOVE).centralCachePath\n                .resolve(Path.of(ORG_NAME, PACKAGE_NAME));\n        if (Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool '\" + TOOL_ID + \"' is available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.REMOVE).envVariables);\n        Assert.assertEquals(outputs.getLeft(),\n                readExpectedCmdOutsAsString(\"tool-execute-unknown-cmd.txt\"));\n        Assert.assertEquals(outputs.getRight(), \"\");\n    }\n\n    @BeforeGroups(value = \"update\")\n    public void setupUpdateTests() throws IOException, InterruptedException {\n        // Remove all versions of the tool\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        getString(cmdExec.getErrorStream());\n\n        // Pull an older version of the tool\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n    }\n\n    @Test(description = \"Update a non-existing tool\", groups = {\"update\"})\n    public void testUpdateNonExistingTool() throws IOException, InterruptedException {\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(UPDATE, NON_EXISTING_TOOL)),\n                toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-update-non-existing.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.UPDATE).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(NON_EXISTING_TOOL);\n        if (toolOpt.isPresent()) {\n            Assert.fail(\"Tool \" + NON_EXISTING_TOOL + \" should not be available in bal-tools.toml\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                NON_EXISTING_TOOL, toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        Assert.assertEquals(\n                outputs.getLeft(),\n                readExpectedCmdOutsAsString(\"tool-execute-unknown-cmd-non-existing.txt\"));\n        Assert.assertEquals(outputs.getRight(), \"\");\n    }\n\n    @Test(description = \"Update a tool with new patch and minor versions\", groups = {\"update\"})\n    public void testUpdateToolWithNewPatchAndMinor() throws IOException, InterruptedException {\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.UPDATE).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion +\n                    \"' should be the current version in bal-tools.toml before update command\");\n        }\n\n        // Update the tool\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(UPDATE, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-update-with-new-patch-and-minor.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.UPDATE).balToolsTomlPath);\n        toolOpt = BalToolsManifestBuilder.from(balToolsToml).build().getActiveTool(TOOL_ID);\n        toolIdAndVersion = TOOL_ID + \":\" + LATEST_VERSION;\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is not available in bal-tools.toml\");\n        }\n\n        // Check for tool availability in local cache\n        Path toolVersionCachePath = toolEnvironments.get(ToolSubCommand.UPDATE).centralCachePath\n                .resolve(Path.of(ORG_NAME, PACKAGE_NAME, LATEST_VERSION));\n        if (!Files.exists(toolVersionCachePath)) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is not available in local cache\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Update a tool with no new versions\",\n            dependsOnMethods = {\"testUpdateToolWithNewPatchAndMinor\"}, groups = {\"update\"})\n    public void testUpdateToolWithNoNewVersions() throws IOException, InterruptedException {\n        // Check for tool availability in bal-tools.toml\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.UPDATE).balToolsTomlPath);\n        Optional<BalToolsManifest.Tool> toolOpt = BalToolsManifestBuilder.from(balToolsToml).build()\n                .getActiveTool(TOOL_ID);\n        String toolIdAndVersion = TOOL_ID + \":\" + LATEST_VERSION;\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' should be the current version in bal-tools.toml\");\n        }\n\n        // Update the tool\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(UPDATE, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-update-with-no-new-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Check for tool availability in bal-tools.toml\n        balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.UPDATE).balToolsTomlPath);\n        toolOpt = BalToolsManifestBuilder.from(balToolsToml).build().getActiveTool(TOOL_ID);\n        toolIdAndVersion = TOOL_ID + \":\" + LATEST_VERSION;\n        if (toolOpt.isEmpty()) {\n            Assert.fail(\"Tool '\" + toolIdAndVersion + \"' is not available in bal-tools.toml\");\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.UPDATE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @BeforeGroups(value = \"use\")\n    public void setupUseTests() throws IOException, InterruptedException {\n        // Pull the latest tool version\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)), toolEnvironments.get(ToolSubCommand.USE).envVariables);\n\n        // Pull a specific version of a tool\n        String specificToolVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, specificToolVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n\n        // Pull tool version with incompatible distribution\n        String incompToolVersion = TOOL_ID + \":\" + INCOMPATIBLE_DIST_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, incompToolVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n\n        // Add the dist incompatible version to the toml file\n        BalToolsToml balToolsToml = BalToolsToml.from(toolEnvironments.get(ToolSubCommand.USE).balToolsTomlPath);\n        BalToolsManifest balToolsManifest = BalToolsManifestBuilder.from(balToolsToml).build();\n        balToolsManifest.addTool(TOOL_ID, ORG_NAME, PACKAGE_NAME, INCOMPATIBLE_DIST_VERSION, false, null);\n        balToolsToml.modify(balToolsManifest);\n    }\n\n    @Test(description = \"Use a newer tool version\", groups = {\"use\"})\n    public void testUseNewToolVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + LATEST_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(USE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-use-new-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.1.0.txt\"));\n    }\n\n    @Test(description = \"Use a newer tool version\", dependsOnMethods = {\"testUseNewToolVersion\"}, groups = {\"use\"})\n    public void testUseOldToolVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(USE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-use-old-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Use the currently active tool version\",\n            dependsOnMethods = {\"testUseOldToolVersion\"}, groups = {\"use\"})\n    public void testUseCurrentlyActiveToolVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(USE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-use-active-version.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Use a non existent tool version\", dependsOnMethods = {\"testUseCurrentlyActiveToolVersion\"},\n            groups = {\"use\"})\n    public void testUseNonExistentToolVersion() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + NON_EXISTING_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(USE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-use-non-existent-version.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"Use a tool version built with incompatible distribution\",\n            dependsOnMethods = \"testUseNonExistentToolVersion\", groups = {\"use\"})\n    public void testUseToolVersionWithIncompatibleDistribution() throws IOException, InterruptedException {\n        String toolIdAndVersion = TOOL_ID + \":\" + INCOMPATIBLE_DIST_VERSION;\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(USE, toolIdAndVersion)),\n                toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-use-with-incompatible-dist.txt\");\n        if (!cmdErrors.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdErrors);\n        }\n\n        // Execute the tool\n        Pair<String, String> outputs = executeHelpFlagOfTool(\n                TOOL_ID, toolEnvironments.get(ToolSubCommand.USE).envVariables);\n        Assert.assertEquals(outputs.getLeft(), \"\");\n        Assert.assertEquals(outputs.getRight(),\n                readExpectedCmdOutsAsString(\"tool-execute-specific-help-1.0.0.txt\"));\n    }\n\n    @Test(description = \"List all tools when there are no tools\", groups = {\"list\"})\n    public void testListToolsWhenNoToolsInstalled() throws IOException, InterruptedException {\n        // Remove the tool entirely\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(REMOVE, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.LIST).envVariables);\n\n        // List all tools\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(List.of(LIST)), toolEnvironments.get(ToolSubCommand.LIST).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-list-with-no-tools.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    @Test(description = \"List all tools when there are multiple versions of tools\", groups = {\"list\"})\n    public void testListToolsWithMultipleToolVersions() throws IOException, InterruptedException {\n        // Pull the latest tool version\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)), toolEnvironments.get(ToolSubCommand.LIST).envVariables);\n\n        // Pull a specific version of a tool\n        String specificToolVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, specificToolVersion)),\n                toolEnvironments.get(ToolSubCommand.LIST).envVariables);\n\n        // List all tools\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(List.of(LIST)), toolEnvironments.get(ToolSubCommand.LIST).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-list-with-multiple-tool-versions.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    @Test(description = \"Search a tool with tool id\", groups = {\"list\"})\n    public void testSearchAToolWithId() throws IOException, InterruptedException {\n        Process cmdExec = executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(SEARCH, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.SEARCH).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-search-with-tool-id.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    @BeforeGroups(value = \"execute_tool\")\n    public void setupExecuteToolTests() throws IOException, InterruptedException {\n        // Pull a specific version of a tool\n        String specificToolVersion = TOOL_ID + \":\" + SPECIFIC_VERSION;\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, specificToolVersion)),\n                toolEnvironments.get(ToolSubCommand.EXECUTE).envVariables);\n\n        // Pull the latest tool version\n        executeToolCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(PULL, TOOL_ID)),\n                toolEnvironments.get(ToolSubCommand.EXECUTE).envVariables);\n    }\n\n    @Test(description = \"Execute bal help with the tool installed\", groups = {\"execute_tool\"})\n    public void testExecuteGeneralHelpWithToolInstalled() throws IOException, InterruptedException {\n        Process cmdExec = executeHelpCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory, new ArrayList<>(),\n                toolEnvironments.get(ToolSubCommand.EXECUTE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-execute-general-help.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    @Test(description = \"Execute bal help disttest with the tool installed\", groups = {\"execute_tool\"})\n    public void testExecuteToolSpecificHelpWithToolInstalled() throws IOException, InterruptedException {\n        Process cmdExec = executeHelpCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(List.of(TOOL_ID)), toolEnvironments.get(ToolSubCommand.EXECUTE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\n                \"tool-execute-specific-help-1.1.0.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    @Test(description = \"Execute disstest tool\", groups = {\"execute_tool\"})\n    public void testExecuteTool() throws IOException, InterruptedException {\n        Process cmdExec = executeCommand(TOOL_ID, DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(List.of(\"arg1\")), toolEnvironments.get(ToolSubCommand.EXECUTE).envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        if (!cmdErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cmdErrors);\n        }\n\n        // Validate the command output\n        String cmdOutput = getString(cmdExec.getInputStream());\n        String expectedOutput = readExpectedCmdOutsAsString(\"tool-execute-tool.txt\");\n        if (!cmdOutput.contains(expectedOutput)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedOutput + \"\\nactual output:\" + cmdOutput);\n        }\n    }\n\n    private Map<ToolSubCommand, BalToolTest.ToolEnvironment> setToolEnvironmentsForSubCommands() {\n        return Arrays.stream(ToolSubCommand.values()).map(\n                toolSubCommand -> {\n                    try {\n                        return getToolEnvironment(toolSubCommand);\n                    } catch (IOException e) {\n                        throw new RuntimeException(e);\n                    }\n                }).collect(Collectors.toMap(\n                toolEnvironment -> toolEnvironment.subCommand, toolEnvironment -> toolEnvironment));\n    }\n\n    private BalToolTest.ToolEnvironment getToolEnvironment(ToolSubCommand subCommand) throws IOException {\n        Path tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        Map<String, String> envVariables = TestUtils.addEnvVariables(getEnvVariables(),\n                tempHomeDirectory);\n        Path balToolsTomlPath = tempHomeDirectory.resolve(\".config\").resolve(\"bal-tools.toml\");\n        Path centralCachePath = tempHomeDirectory.resolve(\n                Path.of(REPOSITORIES_DIR, CENTRAL_REPOSITORY_CACHE_NAME, BALA_DIR_NAME));\n        return new BalToolTest.ToolEnvironment(subCommand, envVariables, balToolsTomlPath, centralCachePath);\n    }\n\n    private void copyTestResourcesToTempWorkspace() {\n        try {\n            URI testResourcesURI = Objects.requireNonNull(BalToolTest.class.getClassLoader().getResource(\"bal-tool\")).\n                    toURI();\n            Path start = Paths.get(testResourcesURI);\n            Files.walkFileTree(start, new CentralTest.Copy(start, tempWorkspaceDirectory));\n        } catch (URISyntaxException | IOException e) {\n            Assert.fail(\"error loading resources\");\n        }\n    }\n\n    private void pushToolPackages(Map<String, String> envVariables) throws IOException, InterruptedException {\n        for (String version :\n                Arrays.asList(SPECIFIC_VERSION, PATCH_VERSION, INCOMPATIBLE_DIST_VERSION, LATEST_VERSION)) {\n            Path packagePath = tempWorkspaceDirectory.resolve(\"v\" + version).resolve(PACKAGE_NAME);\n            Process pack = executePackCommand(DISTRIBUTION_FILE_NAME, packagePath, new LinkedList<>(), envVariables);\n            String packErrors = getString(pack.getErrorStream());\n            if (!packErrors.isEmpty()) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + packErrors);\n            }\n            Optional<Path> balaPath = getBalaPath(packagePath, version);\n            if (balaPath.isEmpty()) {\n                Assert.fail(\"Bala file not found for \" + TOOL_ID + \":\" + version);\n            }\n            // This should make the tools incompatible with the current distribution for incompatible version tests,\n            // and compatible with the current distribution (>=U11) for other versions.\n            String balVersion = version.equals(INCOMPATIBLE_DIST_VERSION) ? \"2201.99.0\" : \"2201.11.0\";\n            updateBallerinaVersionOfBala(balaPath.get(), balVersion);\n            Process build = executePushCommand(DISTRIBUTION_FILE_NAME, packagePath, new LinkedList<>(), envVariables);\n            String buildErrors = getString(build.getErrorStream());\n            if (!buildErrors.isEmpty() && !buildErrors.contains(\"already exists\")) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n            }\n        }\n    }\n\n    private Optional<Path> getBalaPath(Path packagePath, String version) {\n        Path balaRootPath = packagePath.resolve(\"target\").resolve(\"bala\");\n        String balaNamePrefix = ORG_NAME + \"-\" + PACKAGE_NAME + \"-\";\n        String balaNameSuffix = \"-\" + version + \".bala\";\n        for (JvmTarget jvmTarget : JvmTarget.values()) {\n            Path balaPath = balaRootPath.resolve(balaNamePrefix + jvmTarget.code() + balaNameSuffix);\n            if (Files.exists(balaPath)) {\n                return Optional.of(balaPath);\n            }\n        }\n        return Optional.empty();\n    }\n\n    private void updateBallerinaVersionOfBala(Path balaFilePath, String balVersion) throws IOException {\n        Path tempDir = Files.createTempDirectory(balaFilePath.getFileName().toString());\n        try {\n            unzipBalaFile(balaFilePath, tempDir);\n            updatePackageJsonBallerinaVersion(tempDir, balVersion);\n            zipBalaFile(tempDir, balaFilePath);\n        } catch (IOException e) {\n            Assert.fail(\"Failed to update the ballerina version of the bala file\", e);\n        }\n    }\n\n    private void unzipBalaFile(Path balaFilePath, Path destDir) throws IOException {\n        File destDirFile = destDir.toFile();\n        byte[] buffer = new byte[1024];\n        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(balaFilePath.toFile()))) {\n            ZipEntry zipEntry = zis.getNextEntry();\n            while (zipEntry != null) {\n                File newFile = newFile(destDirFile, zipEntry);\n                if (zipEntry.isDirectory()) {\n                    newFile.mkdirs();\n                } else {\n                    // Create all non-existing directories\n                    new File(newFile.getParent()).mkdirs();\n                    try (FileOutputStream fos = new FileOutputStream(newFile)) {\n                        int len;\n                        while ((len = zis.read(buffer)) > 0) {\n                            fos.write(buffer, 0, len);\n                        }\n                    }\n                }\n                zipEntry = zis.getNextEntry();\n            }\n            zis.closeEntry();\n        }\n    }\n\n    private File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {\n        File destFile = new File(destinationDir, zipEntry.getName());\n        String destDirPath = destinationDir.getCanonicalPath();\n        String destFilePath = destFile.getCanonicalPath();\n        if (!destFilePath.startsWith(destDirPath + File.separator)) {\n            throw new IOException(\"Entry is outside of the target dir: \" + zipEntry.getName());\n        }\n        return destFile;\n    }\n\n    private void updatePackageJsonBallerinaVersion(Path packagePath, String balVersion) throws IOException {\n        Path packageJsonPath = packagePath.resolve(\"package.json\");\n        String content = Files.readString(packageJsonPath);\n        JsonObject jsonObject = JsonParser.parseString(content).getAsJsonObject();\n\n        // Update the value for the given key\n        jsonObject.addProperty(\"ballerina_version\", balVersion);\n        Gson gson = new GsonBuilder().setPrettyPrinting().create();\n        String formattedJson = gson.toJson(jsonObject);\n        Files.writeString(packageJsonPath, formattedJson);\n    }\n\n    private void zipBalaFile(Path sourceDirPath, Path zipFilePath) throws IOException {\n        Files.deleteIfExists(zipFilePath);\n        Path zipFile = Files.createFile(zipFilePath);\n        try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(zipFile));\n             Stream<Path> walk = Files.walk(sourceDirPath)) {\n            walk.filter(path -> !Files.isDirectory(path))\n                    .forEach(path -> {\n                        ZipEntry zipEntry = new ZipEntry(sourceDirPath.relativize(path).toString());\n                        try {\n                            zs.putNextEntry(zipEntry);\n                            Files.copy(path, zs);\n                            zs.closeEntry();\n                        } catch (IOException e) {\n                            throw new RuntimeException(\"\\\"Failed to re-zip bala with error: \", e);\n                        }\n                    });\n        }\n    }\n\n    private String readExpectedCmdOutsAsString(String outputFileName) {\n        try {\n            return Files.readString(Path.of(Objects.requireNonNull(\n                    BalToolTest.class.getClassLoader().getResource(\n                            Path.of(\"bal-tool/cmd-outputs/\").resolve(outputFileName).toString())).toURI()));\n        } catch (IOException | URISyntaxException e) {\n            throw new RuntimeException(\"Error reading resource file\");\n        }\n    }\n\n    private Pair<String, String> executeHelpFlagOfTool(String toolId, Map<String, String> envVariables)\n            throws IOException, InterruptedException {\n        Process cmdExec = executeCommand(toolId, DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory,\n                new ArrayList<>(List.of(\"--help\")), envVariables);\n        String cmdErrors = getString(cmdExec.getErrorStream());\n        String cmdOutput = getString(cmdExec.getInputStream());\n        return Pair.of(cmdErrors, cmdOutput);\n    }\n\n    static class ToolEnvironment {\n        ToolSubCommand subCommand;\n        Map<String, String> envVariables;\n        Path balToolsTomlPath;\n        Path centralCachePath;\n\n        public ToolEnvironment(ToolSubCommand subCommand, Map<String, String> envVariables, Path balToolsTomlPath,\n                               Path centralCachePath) {\n            this.subCommand = subCommand;\n            this.envVariables = envVariables;\n            this.balToolsTomlPath = balToolsTomlPath;\n            this.centralCachePath = centralCachePath;\n        }\n    }\n}\n\nenum ToolSubCommand {\n    PULL, UPDATE, REMOVE, USE, LIST, SEARCH, EXECUTE\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/BuildTimeTest.java",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Objects;\n\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_HOME_DIR;\nimport static org.ballerina.projectapi.CentralTestUtils.TEST_MODE_ACTIVE;\nimport static org.ballerina.projectapi.CentralTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executeBuildCommand;\n\n/**\n * Tests related to build time.\n */\npublic class BuildTimeTest {\n\n    private static final PrintStream OUT = System.out;\n    private Path tempHome;\n    private Path tempWorkspace;\n    private Map<String, String> envVariables;\n\n    @BeforeClass\n    public void setup() throws IOException {\n        TestUtils.setupDistributions();\n        tempHome = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        tempWorkspace = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        createSettingToml(tempHome);\n        envVariables = addEnvVariables(getEnvVariables());\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(getClass().getClassLoader().getResource(\"build-time\")).\n                    toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI),\n                    new CentralTest.Copy(Paths.get(testResourcesURI), this.tempWorkspace));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n    }\n\n    @Test(enabled = false,\n            description = \"Build project twice to verify reduction in package resolution time due to caching.\")\n    public void testResolutionTimeReduction() throws IOException, InterruptedException {\n        String projectName = \"Project1\";\n        long expectedMinimumTimeDiff = 500;\n        long firstResolutionTime = getPackageResolutionTime(projectName);\n        OUT.println(\"Package resolution time for the first attempt: \" + firstResolutionTime);\n        long consecutiveResolutionTime = getPackageResolutionTime(projectName);\n        OUT.println(\"Package resolution time for the consecutive attempt: \" + consecutiveResolutionTime);\n        // Assert whether the resolution time has reduced more than the expected minimum time difference\n        Assert.assertTrue((firstResolutionTime - consecutiveResolutionTime) > expectedMinimumTimeDiff);\n    }\n\n    @Test(description = \"Verify the offline resolution during code generation.\")\n    public void testCodeGenOfflineResolution() throws IOException, InterruptedException {\n        String projectWithoutTest = \"Project2\";\n        String projectWithTest = \"Project3\";\n        long firstBuildTime = getPackageBuildTime(projectWithoutTest);\n        OUT.println(\"Package build time for the first attempt without tests: \" + firstBuildTime);\n        long secondBuildTime = getPackageBuildTime(projectWithTest);\n        OUT.println(\"Package build time for the consecutive attempt with tests: \" + secondBuildTime);\n        // Assert whether the resolution time has reduced more than the expected minimum time difference\n        Assert.assertTrue(firstBuildTime * 2 > secondBuildTime);\n    }\n\n    /**\n     * Get environment variables and add ballerina_home as a env variable the tmp directory.\n     *\n     * @return env directory variable array\n     */\n    private Map<String, String> addEnvVariables(Map<String, String> envVariables) {\n        envVariables.put(BALLERINA_HOME_DIR, tempHome.toString());\n        envVariables.put(TEST_MODE_ACTIVE, \"true\");\n        return envVariables;\n    }\n\n    /**\n     * Given the project name get the package resolution time in milliseconds.\n     *\n     * @param projectName ballerina project name\n     * @return package resolution time in milliseconds as a long\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    private long getPackageResolutionTime(String projectName) throws IOException, InterruptedException {\n        String targetDir = \"target\";\n        String buildTimeFileName = \"build-time.json\";\n        String buildDumpFlag = \"--dump-build-time\";\n        String packageResolutionField = \"packageResolutionDuration\";\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspace.resolve(projectName),\n                new LinkedList<>(Collections.singletonList(buildDumpFlag)), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        Path buildTimeJson = this.tempWorkspace.resolve(projectName).resolve(targetDir).resolve(buildTimeFileName);\n        if (buildTimeJson.toFile().exists()) {\n            JsonNode jsonTree = new ObjectMapper().readTree(buildTimeJson.toFile());\n            return jsonTree.get(packageResolutionField).asLong();\n        } else {\n            Assert.fail(\"Unable to locate the JSON file with build time at \" + buildTimeJson.toString());\n        }\n        // Return 0 if there is a failure.\n        return 0;\n    }\n\n    /**\n     * Given the project name get the package build time in milliseconds.\n     *\n     * @param projectName ballerina project name\n     * @return package resolution time in milliseconds as a long\n     * @throws IOException\n     * @throws InterruptedException\n     */\n\n    private long getPackageBuildTime(String projectName) throws IOException, InterruptedException {\n        String targetDir = \"target\";\n        String buildTimeFileName = \"build-time.json\";\n        String buildDumpFlag = \"--dump-build-time\";\n        String totalDuration = \"totalDuration\";\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspace.resolve(projectName),\n                new LinkedList<>(Collections.singletonList(buildDumpFlag)), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        Path buildTimeJson = this.tempWorkspace.resolve(projectName).resolve(targetDir).resolve(buildTimeFileName);\n        if (buildTimeJson.toFile().exists()) {\n            JsonNode jsonTree = new ObjectMapper().readTree(buildTimeJson.toFile());\n            return jsonTree.get(totalDuration).asLong();\n        } else {\n            Assert.fail(\"Unable to locate the JSON file with build time at \" + buildTimeJson.toString());\n        }\n        // Return 0 if there is a failure.\n        return 0;\n    }\n\n    @AfterClass\n    private void cleanup() throws IOException {\n        deleteFiles(tempHome);\n        deleteFiles(tempWorkspace);\n    }\n\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/CentralNegativeTest.java",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Objects;\n\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_CENTRAL_ACCESS_TOKEN;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_DEV_CENTRAL;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_HOME_DIR;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_TOML;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.CentralTestUtils.getBalaPath;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getGenerateBalaLog;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.CentralTestUtils.randomPackageName;\nimport static org.ballerina.projectapi.CentralTestUtils.updateFileToken;\nimport static org.ballerina.projectapi.TestUtils.CODE_NAME;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTIONS_DIR;\nimport static org.ballerina.projectapi.TestUtils.MAVEN_VERSION;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\nimport static org.ballerina.projectapi.TestUtils.executeSearchCommand;\n\n/**\n * Negative tests related central packaging.\n */\npublic class CentralNegativeTest {\n\n    private Path tempHomeDirectory;\n    private Path tempWorkspaceDirectory;\n    private String packageAName;\n    private Map<String, String> envVariables;\n\n    private static final String ORG_NAME = \"bctestorg\";\n    private static final String DISTRIBUTION_FILE_NAME = \"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME;\n    private static final String DEFAULT_PKG_NAME = \"my_package\";\n    private static final String PROJECT_A = \"projectA\";\n    private static final String COMMON_VERSION = \"1.0.0\";\n    private static final String TEST_PREFIX = \"test_\";\n    private static final String ANY_PLATFORM = \"any\";\n    private static final String OUTPUT_NOT_CONTAINS_EXP_MSG = \"build output does not contain expected message:\";\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        setupDistributions();\n\n        tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        envVariables = getEnvVariables();\n\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(getClass().getClassLoader().getResource(\"central\")).toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI),\n                               new CentralTest.Copy(Paths.get(testResourcesURI), this.tempWorkspaceDirectory));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n\n        // Get random package names\n        do {\n            String randomString = randomPackageName(10);\n            this.packageAName = TEST_PREFIX + randomString + \"_\" + PROJECT_A;\n        } while (isPkgAvailableInCentral(this.packageAName));\n\n        isPkgAvailableInCentral(this.packageAName);\n\n        // Update Ballerina.toml files with new package name \"my_package\"\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_A).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageAName);\n    }\n\n    @Test(description = \"Build and push package with invalid access token\", enabled = false)\n    public void testPushPackageWithInvalidAccessToken() throws IOException, InterruptedException {\n        Map<String, String> envVariablesWithInvalidAccessToken = addEnvVariablesWithInvalidAccessToken(\n                this.envVariables);\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_A),\n                                            new LinkedList<>(), envVariablesWithInvalidAccessToken);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(ORG_NAME, this.packageAName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(ORG_NAME, this.packageAName, ANY_PLATFORM,\n                                                                         COMMON_VERSION));\n        }\n\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_A), ORG_NAME, this.packageAName, ANY_PLATFORM,\n                            COMMON_VERSION).toFile().exists());\n\n        Process push = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_A),\n                                          new LinkedList<>(), envVariablesWithInvalidAccessToken);\n        String pushErrors = getString(push.getErrorStream());\n        if (pushErrors.isEmpty()) {\n            Assert.fail(\"push command output does not contain any error\");\n        }\n\n        String expectedError = \"ballerina: unauthorized access token for organization: 'bctestorg'. \"\n                + \"reason: unauthorized to perform this operation as access token is invalid. \"\n                + \"check access token set in 'Settings.toml' file.\";\n        Assert.assertEquals(pushErrors, expectedError);\n    }\n\n    @AfterClass\n    private void cleanup() throws IOException {\n        deleteFiles(tempHomeDirectory);\n        deleteFiles(tempWorkspaceDirectory);\n    }\n\n    private Map<String, String> addEnvVariablesWithInvalidAccessToken(Map<String, String> envVariables) {\n        envVariables.put(BALLERINA_HOME_DIR, tempHomeDirectory.toString());\n        envVariables.put(BALLERINA_DEV_CENTRAL, \"true\");\n        envVariables.put(BALLERINA_CENTRAL_ACCESS_TOKEN, \"cedbeff5-some-invalid-token-f38d4abf\");\n        return envVariables;\n    }\n\n    /**\n     * Clean and set up distributions.\n     */\n    private void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + \".zip\"));\n    }\n\n    /**\n     * Check package already available in central.\n     *\n     * @param pkg package\n     * @return is package available in central\n     */\n    private boolean isPkgAvailableInCentral(String pkg) throws IOException, InterruptedException {\n        Process search = executeSearchCommand(DISTRIBUTION_FILE_NAME,\n                                              this.tempWorkspaceDirectory,\n                                              new LinkedList<>(Collections.singletonList(pkg)),\n                                              this.envVariables);\n        String buildErrors = getString(search.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(search.getInputStream());\n        return !buildOutput.contains(\"no modules found\");\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/CentralTest.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.StandardCopyOption;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.Map;\nimport java.util.Objects;\n\nimport static org.ballerina.projectapi.CentralTestUtils.ANY_PLATFORM;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_TOML;\nimport static org.ballerina.projectapi.CentralTestUtils.COMMON_VERSION;\nimport static org.ballerina.projectapi.CentralTestUtils.JAVA_PLATFORM;\nimport static org.ballerina.projectapi.CentralTestUtils.MAIN_BAL;\nimport static org.ballerina.projectapi.CentralTestUtils.OUTPUT_NOT_CONTAINS_EXP_MSG;\nimport static org.ballerina.projectapi.CentralTestUtils.PULLED_FROM_CENTRAL_MSG;\nimport static org.ballerina.projectapi.CentralTestUtils.TEST_PREFIX;\nimport static org.ballerina.projectapi.CentralTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteBalaOfPackage;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.CentralTestUtils.getBalaPath;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getGenerateBalaLog;\nimport static org.ballerina.projectapi.CentralTestUtils.getPushedToCentralLog;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.CentralTestUtils.isPkgAvailableInCentral;\nimport static org.ballerina.projectapi.CentralTestUtils.randomPackageName;\nimport static org.ballerina.projectapi.CentralTestUtils.updateFileToken;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePullCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\n\n/**\n * Tests related central packaging.\n */\npublic class CentralTest {\n\n    private Path tempHomeDirectory;\n    private Path tempWorkspaceDirectory;\n    private String packageAName;\n    private String packageBName;\n    private String packageCName;\n    private String packageDName;\n    private String packageEName;\n    private String packageFName;\n    private String packageGName;\n    private String packageSnapshotName;\n    private final String orgName = \"bctestorg\";\n    private Map<String, String> envVariables;\n\n    private static final String DEFAULT_PKG_NAME = \"my_package\";\n    private static final String PROJECT_A = \"projectA\";\n    private static final String PROJECT_B = \"projectB\";\n    private static final String PROJECT_C = \"projectC\";\n    private static final String PROJECT_D = \"projectD\";\n    private static final String PROJECT_E = \"projectE\";\n    private static final String PROJECT_F = \"projectF\";\n    private static final String PROJECT_G = \"projectG\";\n    private static final String PROJECT_SNAPSHOT = \"projectSnapshot\";\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        TestUtils.setupDistributions();\n        tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        createSettingToml(tempHomeDirectory);\n        envVariables = TestUtils.addEnvVariables(getEnvVariables(), tempHomeDirectory);\n\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(getClass().getClassLoader().getResource(\"central\")).toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI),\n                               new CentralTest.Copy(Paths.get(testResourcesURI), this.tempWorkspaceDirectory));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n\n        // Get random package names\n        do {\n            String randomString = randomPackageName(10);\n            this.packageAName = TEST_PREFIX + randomString + \"_\" + PROJECT_A;\n            this.packageBName = TEST_PREFIX + randomString + \"_\" + PROJECT_B;\n            this.packageCName = TEST_PREFIX + randomString + \"_\" + PROJECT_C;\n            this.packageDName = TEST_PREFIX + randomString + \"_\" + PROJECT_D;\n            this.packageEName = TEST_PREFIX + randomString + \"_\" + PROJECT_E;\n            this.packageFName = TEST_PREFIX + randomString + \"_\" + PROJECT_F;\n            this.packageGName = TEST_PREFIX + randomString + \"_\" + PROJECT_G;\n            this.packageSnapshotName = TEST_PREFIX + randomString + \"_\" + PROJECT_SNAPSHOT;\n        } while (isPkgAvailableInCentral(this.packageAName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageBName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageCName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageDName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageEName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageFName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageGName, tempWorkspaceDirectory, envVariables)\n                || isPkgAvailableInCentral(this.packageSnapshotName, tempWorkspaceDirectory, envVariables));\n\n        isPkgAvailableInCentral(this.packageAName, tempWorkspaceDirectory, envVariables);\n\n        // Update Ballerina.toml files with new package names\"my_package\"\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_A).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageAName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_B).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageBName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_C).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageCName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_D).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageDName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_E).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                this.packageEName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_F).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                this.packageFName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_G).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                this.packageGName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_SNAPSHOT).resolve(BALLERINA_TOML), DEFAULT_PKG_NAME,\n                        this.packageSnapshotName);\n        // Update imports\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_C).resolve(MAIN_BAL), \"<PKG_A>\",\n                        this.packageAName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_C).resolve(MAIN_BAL), \"<PKG_B>\",\n                        this.packageBName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_D).resolve(MAIN_BAL), \"<PKG_C>\",\n                        this.packageCName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_F).resolve(MAIN_BAL), \"<PKG_E>\",\n                this.packageEName);\n        updateFileToken(this.tempWorkspaceDirectory.resolve(PROJECT_G).resolve(MAIN_BAL), \"<PKG_F>\",\n                this.packageFName);\n    }\n\n    @Test(description = \"Build package A with a native lib dependency\")\n    public void testBuildPackageA() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_A),\n                                            new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageAName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageAName, ANY_PLATFORM,\n                                                                         COMMON_VERSION));\n        }\n\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_A), orgName, this.packageAName, ANY_PLATFORM,\n                            COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Push package A to central\", dependsOnMethods = \"testBuildPackageA\")\n    public void testPushPackageA() throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_A),\n                                       new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getPushedToCentralLog(orgName, packageAName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, packageAName));\n        }\n    }\n\n    @Test(description = \"Build package B which has java21 platform dependency\")\n    public void testBuildPackageB() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_B),\n                                       new LinkedList<>(), this.envVariables);\n\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageBName, JAVA_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageBName, JAVA_PLATFORM,\n                                                                         COMMON_VERSION));\n        }\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_B), orgName, this.packageBName, JAVA_PLATFORM,\n                            COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Build package C which depends on Package A and B\",\n            dependsOnMethods = { \"testPushPackageA\", \"testBuildPackageB\" })\n    public void testBuildPackageC() throws IOException, InterruptedException {\n        String expectedMsg = \"cannot resolve module '\" + orgName + \"/\" + this.packageBName + \" as pkgB'\";\n        String unexpectedMsg = \"cannot resolve module '\" + orgName + \"/\" + this.packageAName + \" as pkgA'\";\n\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_C),\n                                       new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (buildErrors.isEmpty()) {\n            Assert.fail(\"build output should contain errors.\");\n        }\n        if (buildErrors.contains(unexpectedMsg)) {\n            Assert.fail(\"build output should not contain unexpected message:\" + unexpectedMsg);\n        }\n        if (!buildErrors.contains(expectedMsg)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg);\n        }\n    }\n\n    @Test(description = \"Push package B to central\", dependsOnMethods = \"testBuildPackageC\")\n    public void testPushPackageB() throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_B),\n                                       new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getPushedToCentralLog(orgName, this.packageBName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, this.packageBName));\n        }\n    }\n\n    @Test(description = \"Build package C after pushing Package B\", dependsOnMethods = \"testPushPackageB\")\n    public void testBuildPackageCAgain() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_C),\n                                       new LinkedList<>(), this.envVariables);\n\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageCName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageCName, ANY_PLATFORM,\n                                                                         COMMON_VERSION));\n        }\n\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_C), orgName, this.packageCName, ANY_PLATFORM,\n                            COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Push package C to central\", dependsOnMethods = \"testBuildPackageCAgain\")\n    public void testPushPackageC() throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_C),\n                                       new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getPushedToCentralLog(orgName, this.packageCName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, this.packageCName));\n        }\n    }\n\n    @Test(description = \"Build package with pre-release version\")\n    public void testBuildSnapshotPackage() throws IOException, InterruptedException {\n        String snapshotVersion = \"1.0.0-snapshot\";\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME,\n                                            this.tempWorkspaceDirectory.resolve(PROJECT_SNAPSHOT),\n                                            new LinkedList<>(),\n                                            this.envVariables);\n\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(\n                orgName, this.packageSnapshotName, ANY_PLATFORM, snapshotVersion))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG\n                                + getGenerateBalaLog(orgName, this.packageSnapshotName, ANY_PLATFORM, snapshotVersion));\n        }\n\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_SNAPSHOT), orgName, this.packageSnapshotName,\n                            ANY_PLATFORM, snapshotVersion).toFile().exists());\n    }\n\n    @Test(description = \"Push package with pre-release version to central\",\n            dependsOnMethods = \"testBuildSnapshotPackage\")\n    public void testPushSnapshotPackage() throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME,\n                                           this.tempWorkspaceDirectory.resolve(PROJECT_SNAPSHOT),\n                                           new LinkedList<>(),\n                                           this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        String expectedMsg =\n                orgName + \"/\" + this.packageSnapshotName + \":1.0.0-snapshot pushed to central successfully\";\n        if (!buildOutput.contains(expectedMsg)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg);\n        }\n    }\n\n    @Test(description = \"Pull package with pre-release version from central\",\n            dependsOnMethods = \"testPushSnapshotPackage\")\n    public void testPullSnapshotPackage() throws IOException, InterruptedException {\n        String pkg = orgName + \"/\" + this.packageSnapshotName + \":1.0.0-snapshot\";\n\n        Process build = executePullCommand(DISTRIBUTION_FILE_NAME,\n                                           this.tempWorkspaceDirectory.resolve(PROJECT_SNAPSHOT),\n                                           new LinkedList<>(Collections.singletonList(pkg)),\n                                           this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        String expectedMsg = pkg + \" pulled from central successfully\";\n        if (!buildOutput.contains(expectedMsg)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg);\n        }\n    }\n\n    @Test(description = \"Build package E\")\n    public void testBuildPackageE() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_E),\n                new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageEName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageEName, ANY_PLATFORM,\n                    COMMON_VERSION));\n        }\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_E), orgName, this.packageEName, ANY_PLATFORM,\n                        COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Push package E to the central\", dependsOnMethods = \"testBuildPackageE\")\n    public void testPushPackageE() throws IOException, InterruptedException {\n        Process push = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_E),\n                new LinkedList<>(), this.envVariables);\n        String pushErrors = getString(push.getErrorStream());\n        if (!pushErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + pushErrors);\n        }\n        String pushOutput = getString(push.getInputStream());\n        if (!pushOutput.contains(getPushedToCentralLog(orgName, this.packageEName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, this.packageEName));\n        }\n    }\n\n    @Test(description = \"Build package F\", dependsOnMethods = \"testPushPackageE\")\n    public void testBuildPackageF() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_F),\n                new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageFName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageFName, ANY_PLATFORM,\n                    COMMON_VERSION));\n        }\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_F), orgName, this.packageFName, ANY_PLATFORM,\n                        COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Push package F to the central\", dependsOnMethods = \"testBuildPackageF\")\n    public void testPushPackageF() throws IOException, InterruptedException {\n        Process push = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_F),\n                new LinkedList<>(), this.envVariables);\n        String pushErrors = getString(push.getErrorStream());\n        if (!pushErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + pushErrors);\n        }\n        String pushOutput = getString(push.getInputStream());\n        if (!pushOutput.contains(getPushedToCentralLog(orgName, this.packageFName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, this.packageFName));\n        }\n    }\n\n    @Test(description = \"Build package G\", dependsOnMethods = \"testPushPackageF\")\n    public void testBuildPackageG() throws IOException, InterruptedException {\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_G),\n                new LinkedList<>(), this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName, this.packageGName, ANY_PLATFORM, COMMON_VERSION))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName, this.packageGName, ANY_PLATFORM,\n                    COMMON_VERSION));\n        }\n        Assert.assertTrue(\n                getBalaPath(this.tempWorkspaceDirectory.resolve(PROJECT_G), orgName, this.packageGName, ANY_PLATFORM,\n                        COMMON_VERSION).toFile().exists());\n    }\n\n    @Test(description = \"Push package G\", dependsOnMethods = \"testBuildPackageG\")\n    public void testPushPackageG() throws IOException, InterruptedException {\n        Process push = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PROJECT_G),\n                new LinkedList<>(), this.envVariables);\n        String pushErrors = getString(push.getErrorStream());\n        if (!pushErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + pushErrors);\n        }\n        String pushOutput = getString(push.getInputStream());\n        if (!pushOutput.contains(getPushedToCentralLog(orgName, this.packageGName))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, this.packageGName));\n        }\n    }\n\n    @Test(description = \"Pull package G from central. Should pull both E, F since they are dependencies of G.\",\n            dependsOnMethods = \"testPushPackageG\")\n    public void testPullPackageG() throws IOException, InterruptedException {\n        deleteBalaOfPackage(orgName, packageEName);\n        deleteBalaOfPackage(orgName, packageFName);\n        deleteBalaOfPackage(orgName, packageGName);\n\n        String pkgE = orgName + \"/\" + this.packageEName + \":1.0.0\";\n        String pkgF = orgName + \"/\" + this.packageFName + \":1.0.0\";\n        String pkgG = orgName + \"/\" + this.packageGName + \":1.0.0\";\n        Process pull = executePullCommand(DISTRIBUTION_FILE_NAME,\n                this.tempWorkspaceDirectory.resolve(PROJECT_G),\n                new LinkedList<>(Collections.singletonList(pkgG)),\n                this.envVariables);\n        String buildErrors = getString(pull.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(pull.getInputStream());\n        String expectedMsg1 = pkgE + PULLED_FROM_CENTRAL_MSG;\n        String expectedMsg2 = pkgF + PULLED_FROM_CENTRAL_MSG;\n        String expectedMsg3 = pkgG + PULLED_FROM_CENTRAL_MSG;\n        if (!buildOutput.contains(expectedMsg1)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg1);\n        }\n        if (!buildOutput.contains(expectedMsg2)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg2);\n        }\n        if (!buildOutput.contains(expectedMsg3)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedMsg3);\n        }\n    }\n\n    @AfterClass\n    private void cleanup() throws IOException {\n        deleteFiles(tempHomeDirectory);\n        deleteFiles(tempWorkspaceDirectory);\n    }\n\n    /**\n     * Copy test resources to temp directory.\n     */\n    static class Copy extends SimpleFileVisitor<Path> {\n        private final Path fromPath;\n        private final Path toPath;\n        private final StandardCopyOption copyOption;\n\n        Copy(Path fromPath, Path toPath, StandardCopyOption copyOption) {\n            this.fromPath = fromPath;\n            this.toPath = toPath;\n            this.copyOption = copyOption;\n        }\n\n        Copy(Path fromPath, Path toPath) {\n            this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);\n        }\n\n        @Override\n        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\n\n            Path targetPath = toPath.resolve(fromPath.relativize(dir).toString());\n            if (!Files.exists(targetPath)) {\n                Files.createDirectory(targetPath);\n            }\n            return FileVisitResult.CONTINUE;\n        }\n\n        @Override\n        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n\n            Files.copy(file, toPath.resolve(fromPath.relativize(file).toString()), copyOption);\n            return FileVisitResult.CONTINUE;\n        }\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/CentralTestUtils.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport io.ballerina.projects.util.ProjectConstants;\nimport io.ballerina.projects.util.ProjectUtils;\nimport org.testng.Assert;\n\nimport java.io.BufferedReader;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\nimport static org.ballerina.projectapi.TestUtils.executeSearchCommand;\nimport static org.ballerina.projectapi.TestUtils.executeToolCommand;\n\n/**\n * Utility class for central tests.\n */\npublic class CentralTestUtils {\n\n    private CentralTestUtils() {\n    }\n\n    static final String BALLERINA_HOME_DIR = \"BALLERINA_HOME_DIR\";\n    static final String BALLERINA_DEV_CENTRAL = \"BALLERINA_DEV_CENTRAL\";\n    static final String TEST_MODE_ACTIVE = \"TEST_MODE_ACTIVE\";\n    static final String BALLERINA_CENTRAL_ACCESS_TOKEN = \"BALLERINA_CENTRAL_ACCESS_TOKEN\";\n    static final String BALLERINA_TOML = \"Ballerina.toml\";\n    static final String DEPENDENCIES_TOML = \"Dependencies.toml\";\n    static final String BAL_TOOL_TOML = \"BalTool.toml\";\n    static final String MAIN_BAL = \"main.bal\";\n    static final String COMMON_VERSION = \"1.0.0\";\n    static final String TEST_PREFIX = \"test_\";\n    static final String ANY_PLATFORM = \"any\";\n    static final String JAVA_PLATFORM = \"java21\";\n    static final String BALLERINA_ARTIFACT_TYPE = \"bala\";\n    static final String OUTPUT_NOT_CONTAINS_EXP_MSG = \"build output does not contain expected message:\";\n    static final String PULLED_FROM_CENTRAL_MSG = \" pulled from central successfully\";\n    static final String PACKAGE_NAME_SEPARATOR = \"_\";\n    static final String PACKAGE_PATH_SEPARATOR = \"/\";\n\n    /**\n     * Generate random package name.\n     *\n     * @param count number of characters required\n     * @return generated name\n     */\n    static String randomPackageName(int count) {\n        String upperCaseAlpha = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n        String lowerCaseAlpha = \"abcdefghijklmnopqrstuvwxyz\";\n        String alpha = upperCaseAlpha + lowerCaseAlpha;\n        StringBuilder builder = new StringBuilder();\n        while (count-- != 0) {\n            int character = (int) (Math.random() * alpha.length());\n            builder.append(alpha.charAt(character));\n        }\n        return builder.toString();\n    }\n\n    /**\n     * Create Settings.toml inside the home repository.\n     *\n     * @throws IOException i/o exception when writing to file\n     */\n    static void createSettingToml(Path dirPath) throws IOException {\n        String content = \"[central]\\n accesstoken = \\\"\" + getProdToken() + \"\\\"\";\n        Files.write(dirPath.resolve(\"Settings.toml\"), content.getBytes(), StandardOpenOption.CREATE,\n                    StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    /**\n     * Get token of ballerina-dev-central required to push the module.\n     *\n     * @return token required to push the module.\n     */\n    private static String getDevToken() {\n        // staging and dev both has the same access token\n        return System.getenv(\"devCentralToken\");\n    }\n\n    /**\n     * Get token of ballerina-central required to push the module.\n     *\n     * @return token required to push the module.\n     */\n    private static String getProdToken() {\n        return System.getenv(\"prodCentralToken\");\n    }\n\n    /**\n     * Get token of ballerina-bot required to dispatch GitHub workflows.\n     *\n     * @return token required to dispatch GitHub workflows.\n     */\n    public static String getBallerinaBotWorkflow() {\n        return System.getenv(\"ballerinaBotWorkflow\");\n    }\n\n    /**\n     * Get environment variables and add ballerina_home as a env variable the tmp directory.\n     *\n     * @return env directory variable array\n     */\n    static Map<String, String> getEnvVariables() {\n        Map<String, String> envVarMap = System.getenv();\n        Map<String, String> retMap = new HashMap<>();\n        envVarMap.forEach(retMap::put);\n        return retMap;\n    }\n\n    /**\n     * Update the file token by changing the guess token.\n     *\n     * @param filePath    The file path.\n     * @param guessToken  The guess token.\n     * @param actualToken The guess token.\n     * @throws IOException Error when writing to Ballerina.toml\n     */\n    static void updateFileToken(Path filePath, String guessToken, String actualToken) throws IOException {\n        Stream<String> lines = Files.lines(filePath);\n        List<String> replaced = lines.map(line -> line.replaceAll(guessToken, actualToken))\n                .collect(Collectors.toList());\n        Files.write(filePath, replaced);\n        lines.close();\n    }\n\n    /**\n     * Convert input stream to string.\n     *\n     * @param outputs input stream\n     * @return converted string\n     * @throws IOException Error when reading from input stream\n     */\n    static String getString(InputStream outputs) throws IOException {\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(outputs))) {\n            Stream<String> logLines = br.lines();\n            String generatedLog = logLines.collect(Collectors.joining(\"\\n\"));\n            logLines.close();\n            return generatedLog;\n        }\n    }\n\n    /**\n     * Delete files inside directories.\n     *\n     * @param dirPath directory path\n     * @throws IOException throw an exception if an issue occurs\n     */\n    static void deleteFiles(Path dirPath) throws IOException {\n        if (dirPath == null) {\n            return;\n        }\n        Files.walk(dirPath).sorted(Comparator.reverseOrder()).forEach(path -> {\n            try {\n                Files.delete(path);\n            } catch (IOException e) {\n                Assert.fail(e.getMessage(), e);\n            }\n        });\n    }\n\n    /**\n     * Get generate bala log.\n     *\n     * @param org      org name\n     * @param pkgName  package name\n     * @param platform platform name\n     * @param version  package version\n     * @return generate bala log\n     */\n    static String getGenerateBalaLog(String org, String pkgName, String platform, String version) {\n        return \"Creating bala\\n\" + \"\\ttarget/bala/\" + org + \"-\" + pkgName + \"-\" + platform + \"-\" + version + \".bala\";\n    }\n\n    /**\n     * Get the log output when package is successfully pushed to Central.\n     *\n     * @param orgName Organization name\n     * @param pkgName Name of the package pushed to central\n     * @param version Package Version\n     * @return Expected log message\n     */\n    static String getPushedToCentralLog(String orgName, String pkgName, String version) {\n        return orgName + \"/\" + pkgName + \":\" + version + \" pushed to central successfully\";\n    }\n\n    /**\n     * Get pushed to central log.\n     *\n     * @param orgName Organization name\n     * @param pkgName package name\n     * @return pushed to central log\n     */\n    static String getPushedToCentralLog(String orgName, String pkgName) {\n        return orgName + \"/\" + pkgName + \":1.0.0 pushed to central successfully\";\n    }\n\n    /**\n     * Get executable jar path.\n     *\n     * @param projectPath project path\n     * @param pkgName     package name\n     * @return executable jar path\n     */\n    static Path getExecutableJarPath(Path projectPath, String pkgName) {\n        return projectPath.resolve(\"target\").resolve(\"bin\").resolve(pkgName + \".jar\");\n    }\n\n    /**\n     * Get executable jar path.\n     *\n     * @param projectPath project path\n     * @param org         org name\n     * @param pkgName     package name\n     * @param platform    platform name\n     * @param version     package version\n     * @return bala path\n     */\n    static Path getBalaPath(Path projectPath, String org, String pkgName, String platform, String version) {\n        return projectPath.resolve(\"target\").resolve(BALLERINA_ARTIFACT_TYPE)\n                .resolve(org + \"-\" + pkgName + \"-\" + platform + \"-\" + version + \".bala\");\n    }\n\n    /**\n     * Check if package already available on central.\n     *\n     * @param pkg package\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @return whether the package is available on central\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static boolean isPkgAvailableInCentral(String pkg, Path tempWorkspaceDirectory,\n                                           Map<String, String> envVariables) throws IOException, InterruptedException {\n        String buildOutput = searchPackageDetails(pkg, tempWorkspaceDirectory, envVariables);\n        return !buildOutput.contains(\"no modules found\");\n    }\n\n    /**\n     * Check if a tool is already available on central.\n     *\n     * @param toolId tool id\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @return whether the package is available on central\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static boolean isToolAvailableInCentral(String toolId, Path tempWorkspaceDirectory,\n                                           Map<String, String> envVariables) throws IOException, InterruptedException {\n        String buildOutput = searchToolDetails(toolId, tempWorkspaceDirectory, envVariables);\n        return !buildOutput.contains(\"no tools found\");\n    }\n\n    /**\n     * Returns true if the provided version is available on central.\n     *\n     * @param pkg package\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @param version version to check availability\n     * @return\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static boolean isPkgVersionAvailableInCentral(String pkg, Path tempWorkspaceDirectory,\n                                                  Map<String, String> envVariables, String version)\n            throws IOException, InterruptedException {\n        String buildOutput = searchPackageDetails(pkg, tempWorkspaceDirectory, envVariables);\n        return (!buildOutput.contains(\"no modules found\") && buildOutput.contains(version));\n    }\n\n    /**\n     * Search for the given package on Central.\n     *\n     * @param pkg package\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @return\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    private static String searchPackageDetails(String pkg, Path tempWorkspaceDirectory,\n                                           Map<String, String> envVariables) throws IOException, InterruptedException {\n        Process search = executeSearchCommand(DISTRIBUTION_FILE_NAME,\n                tempWorkspaceDirectory,\n                new LinkedList<>(Collections.singletonList(pkg)),\n                envVariables);\n        String buildErrors = getString(search.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        return getString(search.getInputStream());\n    }\n\n    /**\n     * Search for the given package on Central.\n     *\n     * @param toolId tool id\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @return\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    private static String searchToolDetails(String toolId, Path tempWorkspaceDirectory,\n                                            Map<String, String> envVariables)\n            throws IOException, InterruptedException {\n        Process search = executeToolCommand(DISTRIBUTION_FILE_NAME,\n                tempWorkspaceDirectory,\n                new ArrayList<>(Arrays.asList(\"search\", toolId)),\n                envVariables);\n        String buildErrors = getString(search.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        return getString(search.getInputStream());\n    }\n\n    /**\n     * Build bala for a package.\n     *\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param envVariables Environmental variables\n     * @param packageName Package\n     * @param orgName Organization name\n     * @param version Package Version\n     * @param additionalArgs Additional arguments to pass wben building package.\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static void buildPackageBala(Path tempWorkspaceDirectory, Map<String, String> envVariables, String packageName,\n                             String orgName, String version, List<String> additionalArgs)\n            throws IOException, InterruptedException {\n        List<String> argsCollection = new ArrayList(additionalArgs);\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME,\n                tempWorkspaceDirectory.resolve(packageName),\n                new LinkedList<>(argsCollection), envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getGenerateBalaLog(orgName,\n                packageName, ANY_PLATFORM, version))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getGenerateBalaLog(orgName,\n                    packageName, ANY_PLATFORM, version));\n        }\n        Assert.assertTrue(\n                getBalaPath(tempWorkspaceDirectory.resolve(packageName), orgName, packageName, ANY_PLATFORM,\n                        version).toFile().exists());\n    }\n\n    /**\n     * Push a bala to remote repository.\n     *\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param projectName Project name\n     * @param envVariables Environmental variables\n     * @param orgName Organization name\n     * @param packageName package\n     * @param version Package Version\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static void testPushPackage(Path tempWorkspaceDirectory, String projectName, Map<String, String> envVariables,\n                                String orgName, String packageName, String version)\n            throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory.resolve(projectName),\n                new LinkedList<>(), envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getPushedToCentralLog(orgName, packageName, version))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, packageName));\n        }\n    }\n\n    /**\n     * Push a bala to `local` repository.\n     *\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param projectName Project name\n     * @param envVariables Environmental variables\n     * @param orgName Organization name\n     * @param packageName package\n     * @param version Package Version\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    static void testPushPackageToLocal(Path tempWorkspaceDirectory, String projectName,\n                                       Map<String, String> envVariables, String orgName,\n                                       String packageName, String version)\n            throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory.resolve(projectName),\n                new LinkedList<>(Collections.singletonList(\"--repository=local\")), envVariables);\n        // The success message is pushed to error stream for this local push.\n        String buildOutput = getString(build.getInputStream());\n        String expectedLog = \"Successfully pushed target/bala/\" + orgName + \"-\" + packageName + \"-any-\" + version +\n                \".bala to 'local' repository.\";\n        if (!buildOutput.contains(expectedLog)) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + expectedLog);\n        }\n    }\n\n    /**\n     * Push a bala to central using bala path.\n     *\n     * @param tempWorkspaceDirectory Path to workspace\n     * @param projectName Project name\n     * @param envVariables Environmental variables\n     * @param orgName Organization name\n     * @param packageName package\n     * @param version Package Version\n     * @param balaPath Path to the bala file to be pushed\n     * @throws IOException\n     * @throws InterruptedException\n     */\n    public static void testPushPackageUsingBalaPath(Path tempWorkspaceDirectory, String projectName,\n                                       Map<String, String> envVariables, String orgName,\n                                       String packageName, String version, String balaPath)\n            throws IOException, InterruptedException {\n        Process build = executePushCommand(DISTRIBUTION_FILE_NAME, tempWorkspaceDirectory.resolve(projectName),\n                new LinkedList<>(Collections.singletonList(balaPath)), envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        if (!buildOutput.contains(getPushedToCentralLog(orgName, packageName, version))) {\n            Assert.fail(OUTPUT_NOT_CONTAINS_EXP_MSG + getPushedToCentralLog(orgName, packageName));\n        }\n    }\n\n    public static void deleteBalaOfPackage(String orgName, String packageName) {\n        Path balaPath = ProjectUtils.createAndGetHomeReposPath().resolve(ProjectConstants.REPOSITORIES_DIR)\n                .resolve(ProjectConstants.CENTRAL_REPOSITORY_CACHE_NAME).resolve(ProjectConstants.BALA_DIR_NAME)\n                .resolve(orgName);\n        Path packagePath = balaPath.resolve(packageName);\n        ProjectUtils.deleteDirectory(packagePath);\n    }\n\n    public static List<Path> getFileListByExtension(Path filesDirectory, String extension) throws IOException {\n        try (Stream<Path> packagesPathWalk = Files.walk(filesDirectory)) {\n            return packagesPathWalk\n                    .filter(Files::isRegularFile)\n                    .filter(p -> p.toString().endsWith(extension))\n                    .collect(Collectors.toList());\n        }\n    }\n\n    public static void replacePackageName(List<Path> filesToChange, String packageName,\n                                          String randomPackageName) throws IOException {\n        for (Path fileToChange : filesToChange) {\n            String oldContent = \"\";\n            BufferedReader reader = new BufferedReader(new FileReader(fileToChange.toFile()));\n            String line = reader.readLine();\n            while (line != null) {\n                oldContent = oldContent + line + System.lineSeparator();\n                line = reader.readLine();\n            }\n            if (oldContent.contains(packageName)) {\n                String newContent = oldContent.replaceAll(packageName, randomPackageName);\n                FileWriter writer = new FileWriter(fileToChange.toFile());\n                writer.write(newContent);\n                writer.close();\n            }\n            reader.close();\n        }\n    }\n\n    public static String getNewDirectoryName(String currentPackageName, String randomSuffix) {\n        String packageNameSplit = Arrays.stream(currentPackageName.split(\"\\\\.\")).\n                filter((b) -> b.startsWith(\"Package\")).toArray()[0].toString();\n        return currentPackageName.replace(packageNameSplit, packageNameSplit + PACKAGE_NAME_SEPARATOR + randomSuffix);\n    }\n\n    public static void replaceRandomPackageName(Path tempWorkspaceDirectory, String randomPackageName,\n                                                String packageName) throws IOException {\n        List<Path> balFiles = CentralTestUtils.getFileListByExtension(tempWorkspaceDirectory, \"bal\");\n        List<Path> tomlFiles = CentralTestUtils.getFileListByExtension(tempWorkspaceDirectory, \"toml\");\n        CentralTestUtils.replacePackageName(balFiles, packageName, randomPackageName);\n        CentralTestUtils.replacePackageName(tomlFiles, packageName, randomPackageName);\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/DistributionCompatibilityTest.java",
    "content": "/*\n * Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.ballerina.projectapi;\n\nimport org.apache.commons.io.FileUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.UncheckedIOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\nimport java.util.zip.ZipOutputStream;\n\nimport static org.ballerina.projectapi.CentralTestUtils.DEPENDENCIES_TOML;\nimport static org.ballerina.projectapi.CentralTestUtils.PACKAGE_NAME_SEPARATOR;\nimport static org.ballerina.projectapi.CentralTestUtils.buildPackageBala;\nimport static org.ballerina.projectapi.CentralTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getExecutableJarPath;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.CentralTestUtils.replaceRandomPackageName;\nimport static org.ballerina.projectapi.CentralTestUtils.testPushPackage;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executeBuildCommand;\n\n/**\n * Tests related to dependency resolution with distribution compatibility restrictions in central.\n */\npublic class DistributionCompatibilityTest {\n\n    private Path tempHomeDirectory;\n    private Path tempWorkspaceDirectory;\n    private Map<String, String> envVariables;\n    private String orgName = \"bctestorg\";\n    private String projectPath = \"distribution-tests\";\n    private String randomPackageSuffix;\n    private static final int BUFFER_SIZE = 4096;\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        TestUtils.setupDistributions();\n        tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        createSettingToml(tempHomeDirectory);\n        envVariables = TestUtils.addEnvVariables(getEnvVariables(), tempHomeDirectory);\n\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(\n                    getClass().getClassLoader().getResource(projectPath)).toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI),\n                    new CentralTest.Copy(Paths.get(testResourcesURI), this.tempWorkspaceDirectory));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n        String dependencyVersion = \"1.1.0\";\n\n        randomPackageSuffix = CentralTestUtils.randomPackageName(6);\n        String multiPackageName = \"disttestmultiples\";\n        String updatedMultiPackageName = multiPackageName + PACKAGE_NAME_SEPARATOR + randomPackageSuffix;\n        // Update directory to match the package name\n        replaceContainingDir(multiPackageName, updatedMultiPackageName);\n        modifyBala(multiPackageName, updatedMultiPackageName);\n        replaceRandomPackageName(tempWorkspaceDirectory, updatedMultiPackageName, multiPackageName);\n\n        // Push dependency built with beta6, 9999.0.0 and a 1.1.0 version of multiple dependencies\n        List<String> dependencyPackages = Arrays.asList(\"disttestpackbeta6\", \"forwardpack1\", updatedMultiPackageName);\n        for (String dependencyPackageName : dependencyPackages) {\n            if (!CentralTestUtils.isPkgAvailableInCentral(orgName + \"/\" + dependencyPackageName,\n                    tempWorkspaceDirectory, envVariables)) {\n                CentralTestUtils.testPushPackageUsingBalaPath(tempWorkspaceDirectory, dependencyPackageName,\n                        envVariables, orgName, dependencyPackageName, dependencyVersion,\n                        tempWorkspaceDirectory.resolve(dependencyPackageName).resolve(orgName + \"-\" +\n                                dependencyPackageName + \"-any-\" + dependencyVersion + \".bala\").toString());\n            }\n        }\n\n        // Delete the bala file for multiple dependencies\n        FileUtils.forceDelete(FileUtils.getFile(String.valueOf(tempWorkspaceDirectory.resolve(updatedMultiPackageName).\n                resolve(orgName + \"-\" + updatedMultiPackageName + \"-any-\" + dependencyVersion + \".bala\"))));\n\n        // Dependency built with this ballerina version\n        String dependencyPackage = \"disttestpack1\";\n        String updatedDependencyPackage = dependencyPackage + PACKAGE_NAME_SEPARATOR + randomPackageSuffix;\n        replaceRandomPackageName(tempWorkspaceDirectory, updatedDependencyPackage, dependencyPackage);\n        replaceContainingDir(dependencyPackage, updatedDependencyPackage);\n        if (!CentralTestUtils.isPkgAvailableInCentral(orgName + \"/\" + updatedDependencyPackage,\n                tempWorkspaceDirectory, envVariables)) {\n            pushToCentral(updatedDependencyPackage, dependencyVersion);\n        }\n    }\n\n    private void replaceContainingDir(String packageName, String updatedPackageName) {\n        File multiplesDir = new File(tempWorkspaceDirectory.toFile(), packageName);\n        File updatedMultiplesDir = new File(tempWorkspaceDirectory.toFile(), updatedPackageName);\n        if (multiplesDir.exists()) {\n            multiplesDir.renameTo(updatedMultiplesDir);\n        }\n    }\n\n    @Test(description = \"Verify dependency resolution with a dependency built with same distribution version.\")\n    public void testDependencyResolutionWithSameDist() throws IOException, InterruptedException {\n        String dependencyPackageName = \"disttestpack1\" + PACKAGE_NAME_SEPARATOR + randomPackageSuffix;\n        String dependencyVersion = \"1.1.0\";\n        String packageName = \"disttestpack2\";\n        buildPackage(packageName, new LinkedList<>());\n        verifyUpdatedDependencies(packageName, \"org = \\\"\" + orgName + \"\\\"\\n\" +\n                \"name = \\\"\" + dependencyPackageName + \"\\\"\\n\" +\n                \"version = \\\"\" + dependencyVersion + \"\\\"\");\n    }\n\n    @Test(description = \"Verify dependency resolution with a dependency built with an older distribution version.\")\n    public void testDependencyResolutionBackwardCompatibility() throws IOException, InterruptedException {\n        String dependencyPackageName = \"disttestpackbeta6\";\n        String dependencyVersion = \"1.1.0\";\n        String packageName = \"disttestpack3\";\n        buildPackage(packageName, new LinkedList<>());\n        verifyUpdatedDependencies(packageName, \"org = \\\"\" + orgName + \"\\\"\\n\" +\n                \"name = \\\"\" + dependencyPackageName + \"\\\"\\n\" +\n                \"version = \\\"\" + dependencyVersion + \"\\\"\");\n    }\n\n    @Test(description = \"Verify dependency resolution with a dependency built with a future distribution version.\")\n    public void testDependencyResolutionForwardCompatibility() throws IOException, InterruptedException {\n        verifyBuildPackage(\"disttestpack4\", \"forwardpack1\", new LinkedList<>());\n    }\n\n    @Test(description = \"Verify dependency resolution with multiple dependencies built with an older and \" +\n            \"current distribution version.\")\n    public void testWithMultipleDistDependencyVersions() throws IOException, InterruptedException {\n        // Push 1.1.1 built with this Ballerina version\n        String updatedVersion = \"1.1.1\";\n        String dependencyPackage = \"disttestmultiples\" + PACKAGE_NAME_SEPARATOR + randomPackageSuffix;\n\n        if (!CentralTestUtils.isPkgVersionAvailableInCentral(orgName + \"/\" + dependencyPackage,\n                tempWorkspaceDirectory, envVariables, updatedVersion)) {\n            // Build the bala for package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, dependencyPackage, orgName, updatedVersion,\n                    Collections.emptyList());\n            // Push the package to central\n            testPushPackage(tempWorkspaceDirectory, dependencyPackage, envVariables, orgName, dependencyPackage,\n                    updatedVersion);\n        }\n        String packageName = \"disttestpack5\";\n        buildPackage(packageName, new LinkedList<>());\n        verifyUpdatedDependencies(packageName, \"org = \\\"\" + orgName + \"\\\"\\n\" +\n                \"name = \\\"\" + dependencyPackage + \"\\\"\\n\" +\n                \"version = \\\"\" + updatedVersion + \"\\\"\");\n    }\n\n    private void buildPackage(String packageName, LinkedList args) throws IOException, InterruptedException {\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(packageName),\n                args, this.envVariables);\n        try (InputStream errStream = build.getErrorStream()) {\n            String buildErrors = getString(errStream);\n            if (!buildErrors.isEmpty()) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n            }\n            Assert.assertTrue(\n                    getExecutableJarPath(this.tempWorkspaceDirectory.resolve(packageName), packageName)\n                            .toFile().exists());\n        }\n    }\n\n    private void pushToCentral(String packageName, String version) throws IOException, InterruptedException {\n        if (!CentralTestUtils.isPkgAvailableInCentral(orgName + \"/\" + packageName, tempWorkspaceDirectory,\n                envVariables)) {\n            // Build the bala for package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, packageName, orgName, version,\n                    Collections.emptyList());\n            // Push the package to central\n            testPushPackage(tempWorkspaceDirectory, packageName, envVariables, orgName, packageName,\n                    version);\n        }\n    }\n\n    private void verifyUpdatedDependencies(String packageName, String dependencyUpdate) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(DEPENDENCIES_TOML);\n        String content = Files.readString(filePath);\n        Assert.assertTrue(content.contains(dependencyUpdate));\n    }\n\n    private void verifyBuildPackage(String packageName, String dependencyPackage, LinkedList args) throws IOException,\n            InterruptedException {\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(packageName),\n                args, this.envVariables);\n        try (InputStream errStream = build.getErrorStream()) {\n            String buildErrors = getString(errStream);\n            if (!buildErrors.isEmpty()) {\n                Assert.assertTrue(buildErrors.contains(\"cannot resolve module '\" + orgName + \"/\" + dependencyPackage +\n                        \" as _'\"));\n            } else {\n                Assert.fail(\"Build output does not contain the expected error\");\n            }\n        }\n    }\n\n    private void modifyBala(String packageName, String updatedPackageName) throws IOException {\n        // Open the zip file\n        String dependencyVersion = \"1.1.0\";\n        Path sourcePath = this.tempWorkspaceDirectory.resolve(updatedPackageName).resolve(orgName + \"-\" +\n                packageName + \"-any-\" + dependencyVersion + \".bala\");\n        File zipFile = new File(sourcePath.toString());\n        ZipFile zip = new ZipFile(zipFile);\n\n        // Create a new zip file with the updated contents\n        Path packageDir = this.tempWorkspaceDirectory.resolve(updatedPackageName);\n        if (!packageDir.toFile().exists()) {\n            Files.createDirectories(packageDir);\n        }\n        Path destinationPath = this.tempWorkspaceDirectory.resolve(updatedPackageName).resolve(orgName + \"-\" +\n                updatedPackageName + \"-any-\" + dependencyVersion + \".bala\");\n\n        // Create a temporary directory for the new contents\n        File tempDir = Files.createTempDirectory(\"zipFileModification\").toFile();\n\n        // Extract the zip file to the temporary directory\n        zip.stream()\n                .forEach(entry -> {\n                    try {\n                        String entryName = entry.getName();\n                        File entryFile = new File(tempDir, entryName);\n                        if (entry.isDirectory()) {\n                            entryFile.mkdirs();\n                        } else {\n                            entryFile.getParentFile().mkdirs();\n                            FileOutputStream outputStream = new FileOutputStream(entryFile);\n                            InputStream inputStream = zip.getInputStream(entry);\n                            byte[] buffer = new byte[BUFFER_SIZE];\n                            int bytesRead;\n                            while ((bytesRead = inputStream.read(buffer)) > 0) {\n                                outputStream.write(buffer, 0, bytesRead);\n                            }\n                            outputStream.close();\n                            inputStream.close();\n                        }\n                    } catch (IOException e) {\n                        throw new UncheckedIOException(e);\n                    }\n                });\n\n        // Rename the disttestmultiples module directory to disttestmultiples_<randomSuffix>\n        File disttestmultiplesDir = new File(tempDir, \"modules/\" + packageName);\n        if (disttestmultiplesDir.exists()) {\n            File disttestmultiplesXyztheDir = new File(tempDir, \"modules/\" + updatedPackageName);\n            disttestmultiplesDir.renameTo(disttestmultiplesXyztheDir);\n        }\n        Path packageJsonFile = Paths.get(tempDir.toString(), \"package.json\");\n        if (packageJsonFile.toFile().exists()) {\n            String content = new String(Files.readAllBytes(packageJsonFile));\n            content = content.replace(packageName, updatedPackageName);\n            Files.write(packageJsonFile, content.getBytes());\n        }\n        Path dependenciesJsonFile = Paths.get(tempDir.toString(), \"dependency-graph.json\");\n        if (dependenciesJsonFile.toFile().exists()) {\n            String content = new String(Files.readAllBytes(dependenciesJsonFile));\n            content = content.replace(packageName, updatedPackageName);\n            Files.write(dependenciesJsonFile, content.getBytes());\n        }\n        createBala(List.of(tempDir.listFiles()), destinationPath.toString());\n\n        // Clean up\n        zip.close();\n        FileUtils.deleteDirectory(tempDir);\n    }\n\n    private void createBala(List<File> listFiles, String destZipFile) throws FileNotFoundException,\n            IOException {\n        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destZipFile));\n        for (File file : listFiles) {\n            if (file.isDirectory()) {\n                zipDirectory(file, file.getName(), out);\n            } else {\n                zipFile(file, out);\n            }\n        }\n        out.flush();\n        out.close();\n    }\n\n    private void zipFile(File file, ZipOutputStream out)\n            throws IOException {\n        out.putNextEntry(new ZipEntry(file.getName()));\n        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(\n                file));\n        long bytesRead = 0;\n        byte[] bytesIn = new byte[BUFFER_SIZE];\n        int read = 0;\n        while ((read = inputStream.read(bytesIn)) != -1) {\n            out.write(bytesIn, 0, read);\n            bytesRead += read;\n        }\n        out.closeEntry();\n    }\n\n    private void zipDirectory(File folder, String parentFolder,\n                              ZipOutputStream out) throws IOException {\n        for (File file : folder.listFiles()) {\n            if (file.isDirectory()) {\n                zipDirectory(file, parentFolder + \"/\" + file.getName(), out);\n                continue;\n            }\n            out.putNextEntry(new ZipEntry(parentFolder + \"/\" + file.getName()));\n            BufferedInputStream bis = new BufferedInputStream(\n                    new FileInputStream(file));\n            long bytesRead = 0;\n            byte[] bytes = new byte[BUFFER_SIZE];\n            int read = 0;\n            while ((read = bis.read(bytes)) != -1) {\n                out.write(bytes, 0, read);\n                bytesRead += read;\n            }\n            out.closeEntry();\n        }\n    }\n\n    @AfterClass\n    private void cleanup() throws IOException {\n        deleteFiles(tempHomeDirectory);\n        deleteFiles(tempWorkspaceDirectory);\n    }\n\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/HierarchicalPackagesTest.java",
    "content": "/*\n * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\npackage org.ballerina.projectapi;\n\nimport org.apache.commons.io.FileUtils;\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.Test;\n\nimport java.io.BufferedReader;\nimport java.io.BufferedWriter;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStreamWriter;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport static java.nio.file.StandardOpenOption.APPEND;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_ARTIFACT_TYPE;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_HOME_DIR;\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_TOML;\nimport static org.ballerina.projectapi.CentralTestUtils.COMMON_VERSION;\nimport static org.ballerina.projectapi.CentralTestUtils.DEPENDENCIES_TOML;\nimport static org.ballerina.projectapi.CentralTestUtils.PACKAGE_NAME_SEPARATOR;\nimport static org.ballerina.projectapi.CentralTestUtils.PACKAGE_PATH_SEPARATOR;\nimport static org.ballerina.projectapi.CentralTestUtils.buildPackageBala;\nimport static org.ballerina.projectapi.CentralTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.CentralTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.CentralTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.CentralTestUtils.getExecutableJarPath;\nimport static org.ballerina.projectapi.CentralTestUtils.getNewDirectoryName;\nimport static org.ballerina.projectapi.CentralTestUtils.getString;\nimport static org.ballerina.projectapi.CentralTestUtils.replaceRandomPackageName;\nimport static org.ballerina.projectapi.CentralTestUtils.testPushPackage;\nimport static org.ballerina.projectapi.CentralTestUtils.testPushPackageToLocal;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executeBuildCommand;\n\n/**\n * Tests related to hierarchical packages.\n */\npublic class HierarchicalPackagesTest {\n\n    private Path tempHomeDirectory;\n    private Path tempWorkspaceDirectory;\n    private Map<String, String> envVariables;\n    private String randomPackageSuffix;\n    private String orgName = \"bctestorg\";\n    private String projectPath = \"hierarchical-packages\";\n    private String updatedVersion = \"1.0.1\";\n    private final String balExtension = \".bal\";\n    private final String modulesPath = \"modules\";\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        TestUtils.setupDistributions();\n        tempHomeDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-home-\");\n        tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n        createSettingToml(tempHomeDirectory);\n        envVariables = TestUtils.addEnvVariables(getEnvVariables(), tempHomeDirectory);\n\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(\n                    getClass().getClassLoader().getResource(projectPath)).toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI),\n                    new CentralTest.Copy(Paths.get(testResourcesURI), this.tempWorkspaceDirectory));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n\n        // Update the distribution-version in Dependencies.toml\n        Files.list(tempWorkspaceDirectory).forEach(path -> {\n            File dependenciesTomlTemplate = path.resolve(\"Dependencies-template.toml\").toFile();\n            if (dependenciesTomlTemplate.exists()) {\n                try {\n                    replaceDependenciesTomlVersion(path);\n                } catch (IOException e) {\n                    Assert.fail(\"error updating Dependencies.toml for \" + path.getFileName()\n                            + \" with error: \" + e.getMessage());\n                }\n            }\n        });\n\n        randomPackageSuffix = CentralTestUtils.randomPackageName(6);\n        Set<String> uniquePackageNames = new HashSet<>();\n\n        for (String packageName : tempWorkspaceDirectory.toFile().list()) {\n            File newPackageDirName = new File(tempWorkspaceDirectory.resolve(\n                    getNewDirectoryName(packageName, randomPackageSuffix)).toUri());\n            tempWorkspaceDirectory.resolve(packageName).toFile().renameTo(newPackageDirName);\n            uniquePackageNames.add(Arrays.stream(packageName.split(\"\\\\.\")).\n                    filter((b) -> b.startsWith(\"Package\")).toArray()[0].toString());\n        }\n        for (String packageName : uniquePackageNames) {\n            String randomPackageName = packageName + PACKAGE_NAME_SEPARATOR + randomPackageSuffix;\n            replaceRandomPackageName(tempWorkspaceDirectory, randomPackageName, packageName);\n        }\n\n        List<String> oldPackageNames = Arrays.asList(\"PackageH.test\", \"PackageJ.test\", \"PackageL.test\", \"PackageT.test\",\n                \"PackageH.test.mod\", \"PackageR.test\");\n        List<String> packageNames = oldPackageNames.stream()\n                .map(pkg -> getNewDirectoryName(pkg, randomPackageSuffix))\n                .collect(Collectors.toList());\n        List<String> versions = Arrays.asList(COMMON_VERSION, COMMON_VERSION, COMMON_VERSION, \"1.0.0-beta.1\",\n                updatedVersion, COMMON_VERSION);\n        for (int i = 0; i < packageNames.size(); i++) {\n            String packageName = packageNames.get(i);\n            String version = versions.get(i);\n            pushToCentral(packageName, version);\n        }\n        // Build and push updated Versions to Central\n        oldPackageNames = Arrays.asList(\"PackageJ.test\", \"PackageT.test\");\n        packageNames = oldPackageNames.stream()\n                .map(pkg -> getNewDirectoryName(pkg, randomPackageSuffix))\n                .collect(Collectors.toList());\n        List<String> previousVersions = Arrays.asList(COMMON_VERSION, \"1.0.0-beta.1\");\n        for (int i = 0; i < packageNames.size(); i++) {\n            String packageName = packageNames.get(i);\n            pushUpdatedVersion(previousVersions, i, packageName);\n        }\n        // Push package to local\n        String localPackageName = getNewDirectoryName(\"PackageQ.test\", randomPackageSuffix);\n        if (!CentralTestUtils.isPkgAvailableInCentral(orgName + PACKAGE_PATH_SEPARATOR + localPackageName,\n                tempWorkspaceDirectory, envVariables)) {\n            // Build the bala for package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, localPackageName, orgName, COMMON_VERSION,\n                    Collections.emptyList());\n            testPushPackageToLocal(tempWorkspaceDirectory, localPackageName, envVariables, orgName,\n                    localPackageName, COMMON_VERSION);\n        }\n    }\n\n    private void pushToCentral(String packageName, String version) throws IOException, InterruptedException {\n        if (!CentralTestUtils.isPkgAvailableInCentral(orgName + PACKAGE_PATH_SEPARATOR + packageName,\n                tempWorkspaceDirectory, envVariables)) {\n            // Build the bala for package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, packageName, orgName, version,\n                    Collections.emptyList());\n            // Push the package to central\n            testPushPackage(tempWorkspaceDirectory, packageName, envVariables, orgName, packageName,\n                    version);\n        }\n    }\n\n    private void pushUpdatedVersion(List<String> previousVersions, int i, String packageName) throws IOException,\n            InterruptedException {\n        if (!CentralTestUtils.isPkgVersionAvailableInCentral(orgName + PACKAGE_PATH_SEPARATOR + packageName,\n                tempWorkspaceDirectory, envVariables, updatedVersion)) {\n            // Update version details in Ballerina.toml\n            updateBallerinaToml(packageName, previousVersions.get(i), updatedVersion, \"\", \"\");\n            // Build the bala for package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, packageName, orgName, updatedVersion,\n                    Collections.emptyList());\n            // Push the package to central\n            testPushPackage(tempWorkspaceDirectory, packageName, envVariables, orgName, packageName,\n                    updatedVersion);\n        }\n    }\n\n\n\n    @Test(description = \"Verify build package behaviour for hierarchical package imports in two consecutive builds.\",\n    enabled = false)\n    public void testConsecutiveBuilds() throws IOException, InterruptedException {\n        String packageName = getNewDirectoryName(\"PackageI.test\", randomPackageSuffix);\n        // First build\n        buildPackage(packageName, new LinkedList<>());\n        // Consecutive build with existing `Dependencies.toml` and `build` file\n        buildPackage(packageName, new LinkedList<>());\n    }\n\n    @Test(description = \"Verify build package behaviour when there is an updated version for a hierarchical package\" +\n            \" import in Remote Repo.\")\n    public void testUpdatedVersionInRemote() throws IOException, InterruptedException {\n        String importedPackageName = getNewDirectoryName(\"PackageJ.test\", randomPackageSuffix);\n        String packageName = getNewDirectoryName(\"PackageK\", randomPackageSuffix);\n        // Check whether version in Dependencies.toml is the initial version\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, COMMON_VERSION));\n        // Build package when there is an updated version in Remote Repo\n        buildPackage(packageName, new LinkedList<>());\n        // Check if version has been updated in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, updatedVersion));\n    }\n\n    @Test(description = \"When a new module is added and published to remote repo and project is updated to use \" +\n            \"the new module, check if it pulls the latest even when sticky true\")\n    public void testUpdatedPackage() throws IOException, InterruptedException {\n        // Check if specific package version is available in central. If not build and push updated version.\n        String importedPackageName = getNewDirectoryName(\"PackageL.test\", randomPackageSuffix);\n        if (!CentralTestUtils.isPkgVersionAvailableInCentral(orgName + PACKAGE_PATH_SEPARATOR + importedPackageName,\n                tempWorkspaceDirectory, envVariables, updatedVersion)) {\n            // Add a module to the package\n            addNewModule(importedPackageName, \"doc.api\", \"mod.api\");\n            // Update version details in Ballerina.toml\n            updateBallerinaToml(importedPackageName, COMMON_VERSION, updatedVersion, \"\", \"\");\n            addExports(importedPackageName, new String[]{importedPackageName + \".doc.api\"});\n            // Build the bala for updated package\n            buildPackageBala(tempWorkspaceDirectory, envVariables, importedPackageName, orgName, updatedVersion,\n                    Collections.emptyList());\n            // Push the package to central\n            testPushPackage(tempWorkspaceDirectory, importedPackageName, envVariables, orgName, importedPackageName,\n                    updatedVersion);\n        }\n        String packageName = getNewDirectoryName(\"PackageM\", randomPackageSuffix);\n        // Check whether version in Dependencies.toml is the initial version\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, COMMON_VERSION));\n        // Import newly added module\n        updateImports(packageName, \"import \" + orgName + \"/\" + importedPackageName + \".doc.api as _;\",\n                \"main.bal\");\n        // Build updated package with sticky\n        buildPackage(packageName, new LinkedList<>(Collections.singletonList(\"--sticky\")));\n        // Check if version has been updated in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, updatedVersion));\n    }\n\n    @Test(description = \"Verify whether the correct packages are picked when there are two possible packages\" +\n            \" for an import\")\n    public void testTwoPossiblePackages() throws IOException, InterruptedException {\n        // Check if specific package version is available in central. If not build and push updated version.\n        String importedPackageName = getNewDirectoryName(\"PackageH.test.mod\", randomPackageSuffix);\n        // PackageN has already locked `orgName/PackageH.test:1.0.0`\n        String packageName = getNewDirectoryName(\"PackageN\", randomPackageSuffix);\n        // Import newly added module in new package `orgName/PackageH.test.mod:1.0.1`\n        updateImports(packageName, \"import \" + orgName + \"/\" + importedPackageName + \".api.doc as _;\", \"main.bal\");\n        // Build updated package with sticky\n        buildPackage(packageName, new LinkedList<>(Collections.singletonList(\"--sticky\")));\n        // Check if version has been updated in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, updatedVersion));\n        // Build package when there is an updated version in Remote Repo\n        buildPackage(packageName, new LinkedList<>());\n    }\n\n    @Test(description = \"Verify build package behaviour if hierarchical package needs to be pulled from local \" +\n            \"repository.\")\n    public void testPackageFromLocal() throws IOException, InterruptedException {\n        String packageName = getNewDirectoryName(\"PackageR\", randomPackageSuffix);\n        // Create symbolic link for this package in local repository\n        Path target = Paths.get(envVariables.get(BALLERINA_HOME_DIR)).resolve(\"repositories\").\n                resolve(\"local\").resolve(BALLERINA_ARTIFACT_TYPE).resolve(orgName);\n        Path link = Paths.get(envVariables.get(\"HOME\")).resolve(\".ballerina\").resolve(\"repositories\").\n                resolve(\"local\").resolve(BALLERINA_ARTIFACT_TYPE).resolve(orgName);\n        File linkDir = new File(link.toUri());\n        if (linkDir.exists()) {\n            FileUtils.deleteDirectory(linkDir);\n        }\n\n        Files.createDirectories(link.getParent());\n        Files.createSymbolicLink(link, target);\n        buildPackage(packageName, new LinkedList<>());\n        // Delete symbolic link for this package in local repository\n        if (linkDir.exists()) {\n            FileUtils.deleteDirectory(linkDir);\n        }\n    }\n\n    @Test(description = \"Verify build package behaviour when there is an updated version for a transitive \" +\n            \"hierarchical package dependency in Remote Repo.\")\n    public void testUpdateTransitiveDependency() throws IOException, InterruptedException {\n        String transitivePackagePrefix =  getNewDirectoryName(\"Transitive.PackageH.test\", randomPackageSuffix);\n        String randomSuffix = CentralTestUtils.randomPackageName(5);\n        String transitivePackageName = transitivePackagePrefix + PACKAGE_NAME_SEPARATOR + randomSuffix;\n        String importedPackagePrefix = getNewDirectoryName(\"PackageO.test\", randomPackageSuffix);\n        String importedPackageName = importedPackagePrefix + PACKAGE_NAME_SEPARATOR + randomSuffix;\n\n        String packageName = getNewDirectoryName(\"PackageP\", randomPackageSuffix);\n        pushPreRequisites(transitivePackagePrefix, transitivePackageName, importedPackagePrefix,\n                importedPackageName, packageName);\n\n        // Build the package that uses `importedPackageName` package\n        buildPackage(packageName, new LinkedList<>());\n        // Update transitive package version and push\n        pushUpdatedVersion(Arrays.asList(COMMON_VERSION), 0, transitivePackageName);\n\n        // Build the package that uses `importedPackageName` package with sticky true\n        buildPackage(packageName, new LinkedList<>(Collections.singletonList(\"--sticky\")));\n        // Check the old package version in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, transitivePackageName, COMMON_VERSION));\n\n        // Rebuild after clearing target\n        Path targetDir = tempWorkspaceDirectory.resolve(packageName).resolve(\"target\");\n        FileUtils.deleteDirectory(targetDir.toFile());\n        buildPackage(packageName, new LinkedList<>());\n        // Check if version has been updated in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, transitivePackageName, updatedVersion));\n    }\n\n    private void pushPreRequisites(String transitivePackagePrefix, String transitivePackageName,\n                                   String importedPackagePrefix, String importedPackageName, String packageName)\n            throws IOException, InterruptedException {\n        // Copy transitivePackage template as a new project\n        copyProject(transitivePackagePrefix, transitivePackageName);\n        // Copy importedPackage template as a new project\n        copyProject(importedPackagePrefix, importedPackageName);\n\n        // Build and push transitivePackage\n        pushToCentral(transitivePackageName, COMMON_VERSION);\n        // Build and push imported package\n        updateImports(importedPackageName, \"import \" + orgName + \"/\" + transitivePackageName + \" as _;\",\n                \"lib.bal\");\n        pushToCentral(importedPackageName, COMMON_VERSION);\n        updateImports(packageName, \"import \" + orgName + \"/\" + importedPackageName + \" as _;\",\n                \"main.bal\");\n    }\n\n    private void copyProject(String packagePrefix, String packageName) throws IOException {\n        Files.createDirectories(tempWorkspaceDirectory.resolve(packageName));\n        Files.walkFileTree(tempWorkspaceDirectory.resolve(packagePrefix),\n                    new CentralTest.Copy(tempWorkspaceDirectory.resolve(packagePrefix),\n                            tempWorkspaceDirectory.resolve(packageName)));\n        updateBallerinaToml(packageName, COMMON_VERSION, COMMON_VERSION,\n                \"\\\"\" + packagePrefix + \"\\\"\",\n                \"\\\"\" + packageName + \"\\\"\");\n    }\n\n    @Test(description = \"Verify build package behaviour when there is direct dependency added for another package \" +\n            \"with similar hierarchical name structure as a transitive dependency.\")\n    public void testTwoPossibleTransitiveDependencies() throws IOException, InterruptedException {\n        String transitivePackageName = getNewDirectoryName(\"PackageH.test\", randomPackageSuffix);\n        String directPackageName = getNewDirectoryName(\"PackageH.test.mod\", randomPackageSuffix);\n        String packageName = getNewDirectoryName(\"PackageS\", randomPackageSuffix);\n        // Build package with transitive dependency to \"PackageH.test\"\n        // PackageS <— PackageR.test <— PackageH.test\n        buildPackage(packageName, new LinkedList<>(Collections.emptyList()));\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, transitivePackageName, COMMON_VERSION));\n\n        // Add direct dependency for \"PackageH.test.mod\" and build\n        updateImports(packageName, \"import \" + orgName + \"/\" + directPackageName + \".api.doc as _;\", \"main.bal\");\n        buildPackage(packageName, new LinkedList<>(Collections.emptyList()));\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, directPackageName, updatedVersion));\n    }\n\n    // TODO: This test is disabled due to a bug in Central API. Need to re-enable once issue is fixed.\n    @Test(description = \"Verify build package behaviour when there is an updated version for a pre-release version \" +\n            \"of a hierarchical package import in Remote Repo.\", enabled = false)\n    public void testUpdateToPreReleaseVersionInRemote() throws IOException, InterruptedException {\n        String importedPackageName = getNewDirectoryName(\"PackageT.test\", randomPackageSuffix);\n        String packageName = getNewDirectoryName(\"PackageU\", randomPackageSuffix);\n        buildPackage(packageName, new LinkedList<>());\n        // Check if version has been updated in Dependencies.toml\n        verifyUpdatedDependencies(packageName, getDependencyUpdate(orgName, importedPackageName, updatedVersion));\n    }\n\n    private void buildPackage(String packageName, LinkedList args) throws IOException, InterruptedException {\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(packageName),\n                args, this.envVariables);\n        try (InputStream errStream = build.getErrorStream()) {\n            String buildErrors = getString(errStream);\n            if (!buildErrors.isEmpty()) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n            }\n            Assert.assertTrue(\n                    getExecutableJarPath(this.tempWorkspaceDirectory.resolve(packageName), packageName)\n                            .toFile().exists());\n        }\n    }\n\n    private void verifyUpdatedDependencies(String packageName, String dependencyUpdate) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(DEPENDENCIES_TOML);\n        String content = Files.readString(filePath);\n        Assert.assertTrue(content.contains(dependencyUpdate));\n    }\n\n    private void addNewModule(String packageName, String newModule, String moduleToCopy) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(modulesPath).resolve(newModule);\n        Files.createDirectory(filePath);\n        Files.createFile(filePath.resolve(newModule + balExtension));\n        Path filePathToCopy = tempWorkspaceDirectory.resolve(packageName).resolve(modulesPath).resolve(moduleToCopy).\n                resolve(moduleToCopy + balExtension);\n        Stream<String> lines = Files.lines(filePathToCopy);\n        Files.write(filePath.resolve(newModule + balExtension), lines.collect(Collectors.toList()));\n        lines.close();\n    }\n\n    private void updateBallerinaToml(String packageName, String previousVersion, String updatedVersion,\n                                     String previousExport, String newExport) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(BALLERINA_TOML);\n        Stream<String> lines = Files.lines(filePath);\n        List<String> replaced = lines.map(line -> {\n            String updatedLine = line.replaceAll(previousVersion, updatedVersion);\n            if (!(previousExport.isEmpty() && newExport.isEmpty())) {\n                updatedLine = updatedLine.replaceAll(previousExport, newExport);\n            }\n            return updatedLine;\n        }).collect(Collectors.toList());\n        Files.write(filePath, replaced);\n        lines.close();\n    }\n\n    private void addExports(String packageName, String[] moduleNames) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(BALLERINA_TOML);\n        List<String> exports = new ArrayList<>();\n        for (String mod : moduleNames) {\n            exports.add(\"\\n\");\n            exports.add(\"[[package.modules]]\");\n            exports.add(\"name = \\\"\" + mod + \"\\\"\");\n            exports.add(\"export = true\");\n        }\n        Files.write(filePath, exports, APPEND);\n    }\n\n    private void updateImports(String packageName, String s, String fileName) throws IOException {\n        Path filePath = tempWorkspaceDirectory.resolve(packageName).resolve(fileName);\n        Stream<String> lines = Files.lines(filePath);\n        List<String> updated = new ArrayList<>();\n        updated.add(s);\n        updated.addAll(lines.collect(Collectors.toList()));\n        Files.write(filePath, updated);\n        lines.close();\n    }\n\n    private String getDependencyUpdate(String orgName, String packageName, String updatedVersion) {\n        return \"org = \\\"\" + orgName + \"\\\"\\n\" + \"name = \\\"\" + packageName + \"\\\"\\n\" +\n                \"version = \\\"\" + updatedVersion + \"\\\"\";\n    }\n\n    private void replaceDependenciesTomlVersion(Path projectPath) throws IOException {\n        String currentDistrVersion = System.getProperty(\"short.version\");\n        Path dependenciesTomlTemplatePath = projectPath.resolve(\"Dependencies-template.toml\");\n        Path dependenciesTomlPath = projectPath.resolve(\"Dependencies.toml\");\n\n        try (FileInputStream input = new FileInputStream(dependenciesTomlTemplatePath.toString());\n             FileOutputStream output = new FileOutputStream(dependenciesTomlPath.toString());\n             BufferedReader reader = new BufferedReader(new InputStreamReader(input));\n             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output))) {\n            String line;\n            while ((line = reader.readLine()) != null) {\n                line = line.replace(\"**INSERT_DISTRIBUTION_VERSION_HERE**\", currentDistrVersion);\n                writer.write(line);\n                writer.newLine();\n            }\n        }\n    }\n\n    @AfterClass\n    private void cleanup() throws IOException {\n        deleteFiles(tempHomeDirectory);\n        deleteFiles(tempWorkspaceDirectory);\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/MavenCustomRepoTest.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com).\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport org.testng.Assert;\nimport org.testng.annotations.AfterClass;\nimport org.testng.annotations.BeforeClass;\nimport org.testng.annotations.BeforeGroups;\nimport org.testng.annotations.Test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.file.FileVisitResult;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.nio.file.SimpleFileVisitor;\nimport java.nio.file.StandardCopyOption;\nimport java.nio.file.attribute.BasicFileAttributes;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Optional;\n\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.createSettingToml;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.deleteArtifacts;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.deleteFiles;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.editVersionBallerinaToml;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.getEnvVariables;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.getString;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.packTrigger;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.pushTrigger;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.pasteStaticMainBalWithAllPkgs;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.pasteStaticMainBalWithPkg1AndPkg2;\nimport static org.ballerina.projectapi.MavenCustomRepoTestUtils.updateVersionForPackage;\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executeBuildCommand;\nimport static org.ballerina.projectapi.TestUtils.executeCleanCommand;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePullCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\n\npublic class MavenCustomRepoTest {\n\n    private static final String org = \"bctestorg\";\n    private static final String platform = \"any\";\n    private static final String PACKAGE_NAME = \"pkg1\";\n    static final String GITHUB_REPO_ID = \"github1\";\n    private static final String VERSION = \"0.1.0\";\n    private Path actualHomeDirectory;\n    private Path tempWorkspaceDirectory;\n    private Path actualHomeDirectoryClone;\n    private Map<String, String> envVariables;\n\n    @BeforeClass()\n    public void setUp() throws IOException, InterruptedException {\n        TestUtils.setupDistributions();\n            deleteArtifacts(org, \"pkg1\");\n            deleteArtifacts(org, \"pkg2\");\n            deleteArtifacts(org, \"pkg3\");\n              actualHomeDirectory = Paths.get(System.getProperty(\"user.home\")).resolve(\".ballerina\");\n        actualHomeDirectoryClone = Files.createTempDirectory(\"bal-test-integration-packaging-home-\")\n                .resolve(\".ballerina\");\n        Files.walkFileTree(actualHomeDirectory,\n                new MavenCustomRepoTest.Copy(actualHomeDirectory, actualHomeDirectoryClone));\n        deleteFiles(actualHomeDirectory, true);\n        tempWorkspaceDirectory = Files.createTempDirectory(\"bal-test-integration-packaging-workspace-\");\n\n        createSettingToml(actualHomeDirectory);\n        System.setProperty(\"user.home\", actualHomeDirectory.getParent().toString());\n        envVariables = TestUtils.addEnvVariables(getEnvVariables(), actualHomeDirectory);\n\n        // Copy test resources to temp workspace directory\n        try {\n            URI testResourcesURI = Objects.requireNonNull(getClass().getClassLoader()\n                    .getResource(\"maven-repos\")).toURI();\n            Files.walkFileTree(Paths.get(testResourcesURI), new MavenCustomRepoTest.Copy(Paths.get(testResourcesURI),\n                    this.tempWorkspaceDirectory));\n        } catch (URISyntaxException e) {\n            Assert.fail(\"error loading resources\");\n        }\n\n        publishBalaPackagesBeforeTests();\n    }\n\n    @Test(description = \"Push package to Github packages\", enabled = false)\n    public void testPushBalaGithub() throws IOException, InterruptedException {\n        List<String> args = new ArrayList<>();\n        Process build = executePackCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PACKAGE_NAME),\n                args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        String normalizedOutput = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n        String collapsed = normalizedOutput.replaceAll(\"\\\\s+\", \" \");\n        String expectedBalaPath = \"target/bala/\" + org + \"-\" + PACKAGE_NAME + \"-\" + platform + \"-\" + VERSION + \".bala\";\n\n        Assert.assertTrue(collapsed.contains(\"Creating bala\") && collapsed.contains(expectedBalaPath),\n                \"Expected creation message with path: \" + expectedBalaPath + System.lineSeparator()\n                        + \"Actual output: \" + buildOutput);\n        args = new ArrayList<>();\n        args.add(\"--repository=\" + GITHUB_REPO_ID);\n        build = executePushCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PACKAGE_NAME),\n                args, this.envVariables);\n        buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        buildOutput = getString(build.getInputStream());\n        String normalizedPushOutput = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n        String collapsedPush = normalizedPushOutput.replaceAll(\"\\\\s+\", \" \");\n        String expectedPushMsg = \"Successfully pushed target/bala/\" + org + \"-\" + PACKAGE_NAME + \"-any-\" + VERSION\n                + \".bala to '\" + GITHUB_REPO_ID + \"' repository.\";\n        Assert.assertTrue(collapsedPush.contains(expectedPushMsg),\n                \"Expected push success message. Actual output: \" + buildOutput);\n    }\n\n    @Test(description = \"Pull package from Github packages\", dependsOnMethods = \"testPushBalaGithub\", enabled = false)\n    public void testPullBalaGithub() throws IOException, InterruptedException {\n        List<String> args = new ArrayList<>();\n        args.add(org + \"/\" + PACKAGE_NAME + \":\" + VERSION);\n        args.add(\"--repository=\" + GITHUB_REPO_ID);\n        Process build = executePullCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(PACKAGE_NAME),\n                args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        Assert.assertTrue(buildOutput.contains(\"Successfully pulled the package from the custom repository\"));\n\n        Path packagePath = this.actualHomeDirectory.resolve(\"repositories\")\n                .resolve(GITHUB_REPO_ID).resolve(\"bala\").resolve(org).resolve(PACKAGE_NAME).resolve(VERSION);\n        Assert.assertTrue(Files.exists(packagePath.resolve(\"any\")));\n        deleteFiles(this.actualHomeDirectory.resolve(\"repositories\").resolve(GITHUB_REPO_ID), false);\n    }\n\n    @Test(description = \"Build a package offline using a module from Github packages\",\n            dependsOnMethods = \"testPullBalaGithub\", enabled = false)\n    public void testBuildBalaGithubOffline() throws IOException, InterruptedException {\n        List<String> args = new ArrayList<>();\n        args.add(\"--offline=true\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory\n                        .resolve(\"test-resolution\"),\n                args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        Assert.assertTrue(buildErrors.contains(\"cannot resolve module '\" + org + \"/pact as _'\"));\n    }\n\n    @Test(description = \"Build a package Online using a module from Github packages\",\n            dependsOnMethods = \"testBuildBalaGithubOffline\", enabled = false)\n    public void testBuildBalaGithubOnline() throws IOException, InterruptedException {\n        List<String> args = new ArrayList<>();\n        args.add(\"--offline=false\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory\n                        .resolve(\"test-resolution\"),\n                args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n        Assert.assertTrue(collapsed.contains(\"Generating executable\") && collapsed.contains(\"target/bin/test.jar\"),\n                \"Expected generating executable + target/bin/test.jar in output. Actual output: \" + buildOutput);\n    }\n\n     private void publishBalaPackagesBeforeTests() throws IOException, InterruptedException {\n         // Iteratively publish the requested versions: pkg1 -> 0.1.0, pkg2 -> 1.0.0 then pkg 3 -> 1.0.0\n        String[][] seq = {\n                 {\"pkg1\", \"0.1.0\"},\n                 {\"pkg2\", \"1.0.0\"},\n                 {\"pkg3\", \"1.0.0\"}\n         };\n\n         for (String[] entry : seq) {\n             String pkg = entry[0];\n             String ver = entry[1];\n             // packTrigger returns a Process; we don't use the process object, so don't assign it\n             packTrigger(pkg, this.tempWorkspaceDirectory, this.envVariables);\n             Process push = pushTrigger(pkg, this.tempWorkspaceDirectory, this.envVariables);\n             String pushOutput = getString(push.getInputStream());\n             String normalizedPushOutput = pushOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n             String collapsedPush = normalizedPushOutput.replaceAll(\"\\\\s+\", \" \");\n             Assert.assertTrue(collapsedPush.contains(\"Successfully pushed target/bala/\" + org + \"-\" + pkg + \"-any-\" +\n                             ver + \".bala to '\" + GITHUB_REPO_ID + \"' repository.\"), \"Expected push success \" +\n                     \"message. Actual output: \" + pushOutput);\n         }\n     }\n\n     @Test(description = \"Build a package with multiple dependencies from Github packages\")\n    public void testCase1_buildMyProject_assertDependenciesToml() throws IOException, InterruptedException {\n         List<String> args = new ArrayList<>();\n         Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory\n                         .resolve(\"myproject1\"),\n                 args, this.envVariables);\n         String buildErrors = getString(build.getErrorStream());\n         if (!buildErrors.isEmpty()) {\n             Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n         }\n\n         String buildOutput = getString(build.getInputStream());\n         String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n                 .replace(\"\\r\", \"\\n\");\n         String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n         Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                         collapsed.contains(\"target/bin/myproject1.jar\"),\n                 \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \"\n                         + buildOutput);\n\n         Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n         Optional<String> pkg1Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                 \"pkg1\");\n         Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                 \"pkg2\");\n\n         Assert.assertTrue(pkg1Version.isPresent(), \"Expected pkg1 to be present in Dependencies.toml\");\n         Assert.assertEquals(pkg1Version.get(), \"0.1.0\", \"Package version is not matching with the \" +\n                 \"pushed package version\");\n         Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n         Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"Package version is not matching with the\" +\n                 \"pushed package version\");\n    }\n\n    @BeforeGroups(\"testCase2\")\n    public void beforeGroupTestCase2() throws IOException {\n         Path projectDir = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n         try {\n             Assert.assertTrue(updateVersionForPackage(projectDir, \"pkg1\", \"0.1.0\"),\n                     \"pkg1 not found in Ballerina.toml\");\n             Assert.assertTrue(updateVersionForPackage(projectDir, \"pkg2\", \"1.0.0\"),\n                     \"pkg2 not found in Ballerina.toml\");\n         } catch (IOException e) {\n            Assert.fail(\"Error updating package versions in Ballerina.toml before Test Case 2. \" + e.getMessage());\n         }\n         pasteStaticMainBalWithPkg1AndPkg2(projectDir);\n     }\n\n   @Test(description = \"Push more packages to Github to test locking mode results\",\n           dependsOnMethods = \"testCase1_buildMyProject_assertDependenciesToml\")\n   public void testCase2_publishAdditionalVersionsForDeps() throws IOException, InterruptedException {\n\n       // Publish multiple versions for pkg1 (Dep1)\n       String[] pkg1Versions = {\"0.1.1\", \"0.2.0\", \"1.0.0\"};\n       for (String ver : pkg1Versions) {\n           // Update package version, pack and push\n           editVersionBallerinaToml(this.tempWorkspaceDirectory.resolve(\"pkg1\"), ver);\n           // packTrigger returns a Process we don't need; call directly\n           packTrigger(\"pkg1\", this.tempWorkspaceDirectory, this.envVariables);\n           Process p = pushTrigger(\"pkg1\", this.tempWorkspaceDirectory, this.envVariables);\n           String pushOutput = getString(p.getInputStream());\n           // Normalize output so Windows backslashes don't break the assertion\n           String normalizedPushOutput = pushOutput.replace(\"\\\\\", \"/\")\n                   .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n           String collapsedPush = normalizedPushOutput.replaceAll(\"\\\\s+\", \" \");\n           String expectedPushMsg1 = \"Successfully pushed target/bala/\" + org + \"-pkg1-any-\" + ver\n                   + \".bala to '\" + GITHUB_REPO_ID + \"' repository.\";\n           Assert.assertTrue(collapsedPush.contains(expectedPushMsg1),\n                   \"Expected push success message. Actual output: \" + pushOutput);\n       }\n\n       // Publish multiple versions for pkg2 (Dep2)\n       String[] pkg2Versions = {\"1.1.1\", \"1.1.0\", \"2.0.0\"};\n       for (String ver : pkg2Versions) {\n           // Update package version, pack and push\n           editVersionBallerinaToml(this.tempWorkspaceDirectory.resolve(\"pkg2\"), ver);\n           Process p = packTrigger(\"pkg2\", this.tempWorkspaceDirectory, this.envVariables);\n           String ignoredPackOut = getString(p.getInputStream());\n           p = pushTrigger(\"pkg2\", this.tempWorkspaceDirectory, this.envVariables);\n           String pushOutput = getString(p.getInputStream());\n           // Normalize output so Windows backslashes don't break the assertion\n           String normalizedPushOutput = pushOutput.replace(\"\\\\\", \"/\")\n                   .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n           String collapsedPush = normalizedPushOutput.replaceAll(\"\\\\s+\", \" \");\n           String expectedPushMsg2 = \"Successfully pushed target/bala/\" + org + \"-pkg2-any-\" + ver\n                   + \".bala to '\" + GITHUB_REPO_ID + \"' repository.\";\n           Assert.assertTrue(collapsedPush.contains(expectedPushMsg2),\n                   \"Expected push success message. Actual output: \" + pushOutput);\n       }\n\n   }\n\n   @Test(description = \"Build package with soft locking mode\",\n           dependsOnMethods = \"testCase2_publishAdditionalVersionsForDeps\", groups = \"testCase2\")\n    public void testCase2_1_softLockingMode_resolvesLatestCompatible() throws IOException, InterruptedException {\n    List<String> args = new ArrayList<>();\n\n       File dependencyPathBefore = this.tempWorkspaceDirectory.resolve(\"myproject1\")\n               .resolve(\"Dependencies.toml\").toFile();\n       if (dependencyPathBefore.exists()) {\n           if (!dependencyPathBefore.delete()) {\n               Assert.fail(\"Could not delete Dependencies.toml at \" + dependencyPathBefore.getAbsolutePath());\n           }\n           List<String> cleanArgs = new ArrayList<>();\n           Process clean = executeCleanCommand(DISTRIBUTION_FILE_NAME,\n                   this.tempWorkspaceDirectory.resolve(\"myproject1\"), cleanArgs, this.envVariables);\n           String cleanErrors = getString(clean.getErrorStream());\n           if (!cleanErrors.isEmpty()) {\n               Assert.fail(OUTPUT_CONTAIN_ERRORS + cleanErrors);\n           }\n       }\n    args.add(\"--locking-mode=soft\");\n    Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n            args, this.envVariables);\n    String buildErrors = getString(build.getErrorStream());\n    if (!buildErrors.isEmpty()) {\n        Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n    }\n    String buildOutput = getString(build.getInputStream());\n    String normalized = buildOutput.replace(\"\\\\\", \"/\")\n            .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n    String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n    Assert.assertTrue(collapsed.contains(\"Generating executable\") && collapsed.contains(\"target/bin/myproject1.jar\"),\n            \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \" + buildOutput);\n\n       Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n       Optional<String> pkg1Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg1\");\n       Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg2\");\n       Assert.assertTrue(pkg1Version.isPresent(), \"Expected pkg1 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg1Version.get(), \"0.1.1\", \"Package version is not matching with \" +\n               \"the expected package version\");\n       Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg2Version.get(), \"1.1.1\", \"Package version is not matching with \" +\n               \"the expected package version\");\n   }\n\n   @Test(description = \"Build package with medium locking mode\",\n           dependsOnMethods = \"testCase2_publishAdditionalVersionsForDeps\", groups = \"testCase2\")\n   public void testCase2_2_mediumLockingMode_resolvesConservative() throws IOException, InterruptedException {\n    List<String> args = new ArrayList<>();\n\n    File dependencyPathBefore = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\").toFile();\n    if (dependencyPathBefore.exists()) {\n        if (!dependencyPathBefore.delete()) {\n            Assert.fail(\"Could not delete Dependencies.toml at \" + dependencyPathBefore.getAbsolutePath());\n        }\n        List<String> cleanArgs = new ArrayList<>();\n        Process clean = executeCleanCommand(DISTRIBUTION_FILE_NAME,\n                this.tempWorkspaceDirectory.resolve(\"myproject1\"), cleanArgs, this.envVariables);\n        String cleanErrors = getString(clean.getErrorStream());\n        if (!cleanErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + cleanErrors);\n        }\n    }\n    args.add(\"--locking-mode=medium\");\n    Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n            args, this.envVariables);\n    String buildErrors = getString(build.getErrorStream());\n    if (!buildErrors.isEmpty()) {\n        Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n    }\n    String buildOutput = getString(build.getInputStream());\n    String normalized = buildOutput.replace(\"\\\\\", \"/\")\n            .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n    String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n    Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                    collapsed.contains(\"target/bin/myproject1.jar\"), \"Expected generating executable + \" +\n            \"target/bin/myproject1.jar in output. Actual output: \" + buildOutput);\n\n    Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n    Optional<String> pkg1Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n            \"pkg1\");\n    Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n            \"pkg2\");\n    Assert.assertTrue(pkg1Version.isPresent(), \"Expected pkg1 to be present in Dependencies.toml\");\n    Assert.assertEquals(pkg1Version.get(), \"0.1.1\", \"Package version is not matching with the \" +\n            \"expected package version\");\n    Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n    Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"Package version is not matching with the \" +\n            \"expected package version\");\n   }\n\n   // HARD mode enforces exact compiler update reproducibility.\n    // Build is expected to fail if the project was built using a different Swan Lake update.\n   @Test(description = \"Build package with hard locking mode\",\n           dependsOnMethods = \"testCase2_publishAdditionalVersionsForDeps\", groups = \"testCase2\")\n   public void testCase2_3_hardLockingMode_enforcesExact() throws IOException, InterruptedException {\n    List<String> args = new ArrayList<>();\n    File dependencyPathBefore = this.tempWorkspaceDirectory.resolve(\"myproject1\")\n            .resolve(\"Dependencies.toml\").toFile();\n       if (dependencyPathBefore.exists()) {\n           if (!dependencyPathBefore.delete()) {\n               Assert.fail(\"Could not delete Dependencies.toml at \" + dependencyPathBefore.getAbsolutePath());\n           }\n           List<String> cleanArgs = new ArrayList<>();\n           Process clean = executeCleanCommand(DISTRIBUTION_FILE_NAME,\n                   this.tempWorkspaceDirectory.resolve(\"myproject1\"), cleanArgs, this.envVariables);\n           String cleanErrors = getString(clean.getErrorStream());\n           if (!cleanErrors.isEmpty()) {\n               Assert.fail(OUTPUT_CONTAIN_ERRORS + cleanErrors);\n           }\n       }\n\n    args.add(\"--locking-mode=hard\");\n    Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n            args, this.envVariables);\n    String buildErrors = getString(build.getErrorStream());\n    if (!buildErrors.isEmpty()) {\n        Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n    }\n    String buildOutput = getString(build.getInputStream());\n    String normalized = buildOutput.replace(\"\\\\\", \"/\")\n            .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n    String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n\n    Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                    collapsed.contains(\"target/bin/myproject1.jar\"),\n               \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \"\n                       + buildOutput);\n\n       Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n       Optional<String> pkg1Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg1\");\n       Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg2\");\n       Assert.assertTrue(pkg1Version.isPresent(), \"Expected pkg1 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg1Version.get(), \"0.1.0\", \"Package version is not matching with the \" +\n               \"expected package version\");\n       Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"Package version is not matching with the \" +\n               \"expected package version\");\n\n    }\n\n   @Test(description = \"Build package with locked mode\", dependsOnMethods = {\"testCase2_publishAdditionalVersions\" +\n           \"ForDeps\", \"testCase2_3_hardLockingMode_enforcesExact\"}, groups = \"testCase2\")\n   public void testCase2_4_lockedMode_usesLockedVersions() throws IOException, InterruptedException {\n    List<String> args = new ArrayList<>();\n    args.add(\"--locking-mode=locked\");\n    Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n            args, this.envVariables);\n    String buildErrors = getString(build.getErrorStream());\n    if (!buildErrors.isEmpty()) {\n        Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n    }\n    String buildOutput = getString(build.getInputStream());\n    String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n            .replace(\"\\r\", \"\\n\");\n    String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n    Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                    collapsed.contains(\"target/bin/myproject1.jar\"),\n            \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \"\n                    + buildOutput);\n\n       Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n       Optional<String> pkg1Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg1\");\n       Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n               \"pkg2\");\n       Assert.assertTrue(pkg1Version.isPresent(), \"Expected pkg1 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg1Version.get(), \"0.1.0\", \"Package version is not matching with the \" +\n               \"expected package version\");\n       Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n       Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"Package version is not matching with the \" +\n               \"expected package version\");\n   }\n\n   @Test(description = \"Build package with backwards compatibility\", dependsOnGroups = \"testCase2\")\n   public void testCase3_backwardCompatibility_legacyBallerinaToml() throws IOException, InterruptedException {\n        Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n        if (Files.deleteIfExists(dependencyPath)) {\n            // Use separate argument lists for clean and build to avoid reusing/mutating the same list\n            List<String> cleanArgs = new ArrayList<>();\n            Process clean = executeCleanCommand(DISTRIBUTION_FILE_NAME,\n                    this.tempWorkspaceDirectory.resolve(\"myproject1\"), cleanArgs, this.envVariables);\n            String cleanErrors = getString(clean.getErrorStream());\n            if (!cleanErrors.isEmpty()) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + cleanErrors);\n            }\n            List<String> buildArgs = new ArrayList<>();\n            Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME,\n                    this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n                    buildArgs, this.envVariables);\n             String buildErrors = getString(build.getErrorStream());\n             if (!buildErrors.isEmpty()) {\n                 Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n             }\n             String buildOutput = getString(build.getInputStream());\n             String normalized = buildOutput.replace(\"\\\\\", \"/\")\n                     .replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n             String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n             Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                             collapsed.contains(\"target/bin/myproject1.jar\"),\n                     \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \"\n                             + buildOutput);\n             Path dependencyPath2 = this.tempWorkspaceDirectory.resolve(\"myproject1\")\n                     .resolve(\"Dependencies.toml\");\n             Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath2,\n                     \"pkg2\");\n             Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n             Assert.assertEquals(pkg2Version.get(), \"1.1.1\", \"Package version is not matching with \" +\n                     \"the expected package version\");\n        } else {\n            Assert.fail(\"Could not delete Dependencies.toml file to test backwards compatibility\");\n        }\n    }\n\n    private void pinPkg1AndPkg2To100() throws IOException, InterruptedException {\n        Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n        if (Files.exists(dependencyPath)) {\n            boolean deleted = Files.deleteIfExists(dependencyPath);\n            if (!deleted) {\n                Assert.fail(\"Could not delete Dependencies.toml at \" + dependencyPath);\n            }\n            List<String> cleanArgs = new ArrayList<>();\n            Process clean = executeCleanCommand(DISTRIBUTION_FILE_NAME,\n                    this.tempWorkspaceDirectory.resolve(\"myproject1\"), cleanArgs, this.envVariables);\n            String cleanErrors = getString(clean.getErrorStream());\n            if (!cleanErrors.isEmpty()) {\n                Assert.fail(OUTPUT_CONTAIN_ERRORS + cleanErrors);\n            }\n        }\n\n        Path ballerinaTOML = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n        Assert.assertTrue(updateVersionForPackage(ballerinaTOML, \"pkg1\", \"1.0.0\"),\n                \"pkg1 not found in Ballerina.toml\");\n        Assert.assertTrue(updateVersionForPackage(ballerinaTOML, \"pkg2\", \"1.0.0\"),\n                \"pkg2 not found in Ballerina.toml\");\n        List<String> args = new ArrayList<>();\n        args.add(\"--locking-mode=hard\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME,\n                this.tempWorkspaceDirectory.resolve(\"myproject1\"), args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n    }\n\n   // New: run this setup only before the Test Case 4 group\n    @BeforeGroups(\"testCase4\")\n    public void beforeGroupTestCase4() throws IOException, InterruptedException {\n        pinPkg1AndPkg2To100();\n    }\n\n    @Test(description = \"Test case 4.1: Add dep3 and build with SOFT locking mode\",\n            dependsOnGroups = \"testCase2\", groups = \"testCase4\")\n     public void testCase4_1_addDep3_softLocking() throws IOException, InterruptedException {\n        Path projectDir = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n        // Ensure legacy dependency for pkg3 is present (idempotent)\n        MavenCustomRepoTestUtils.ensureLegacyDependency(projectDir, \"bctestorg\", \"pkg3\", \"1.0.0\", GITHUB_REPO_ID);\n        List<String> args = new ArrayList<>();\n        args.add(\"--locking-mode=soft\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir, args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n        Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                        collapsed.contains(\"target/bin/myproject1.jar\"),\n                \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \" + buildOutput);\n\n        Path dependencyPath = projectDir.resolve(\"Dependencies.toml\");\n        Optional<String> pkg3Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg3\");\n        Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg2\");\n        Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg2Version.get(), \"1.1.1\", \"pkg2 version should be 1.1.1\");\n        Assert.assertTrue(pkg3Version.isPresent(), \"Expected pkg3 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg3Version.get(), \"1.0.0\", \"pkg3 version should be 1.0.0\");\n    }\n\n    @Test(description = \"Test case 4.2: Add dep3 and build with MEDIUM (default) locking mode\",\n            dependsOnGroups = \"testCase2\", groups = \"testCase4\")\n    public void testCase4_2_addDep3_mediumLocking() throws IOException, InterruptedException {\n        Path projectDir = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n        // Ensure legacy dependency for pkg3 is present (idempotent)\n        MavenCustomRepoTestUtils.pasteStaticMainBalWithPkg1AndPkg2(projectDir);\n        // Remove existing Dependencies.toml in an idempotent way\n        Files.deleteIfExists(projectDir.resolve(\"Dependencies.toml\"));\n        List<String> args = new ArrayList<>();\n        args.add(\"--locking-mode=hard\");\n        Process buildCleanup = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir,\n                args, this.envVariables);\n        String buildCleanupErrors = getString(buildCleanup.getErrorStream());\n        if (!buildCleanupErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildCleanupErrors);\n        }\n        pasteStaticMainBalWithAllPkgs(projectDir);\n        args = new ArrayList<>();\n        args.add(\"--locking-mode=medium\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir, args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n                .replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n        Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                        collapsed.contains(\"target/bin/myproject1.jar\"),\n                \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \"\n                        + buildOutput);\n\n        Path dependencyPath = projectDir.resolve(\"Dependencies.toml\");\n        Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg2\");\n        Optional<String> pkg3Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg3\");\n        Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"Pkg2 version should be 1.0.0\");\n        Assert.assertTrue(pkg3Version.isPresent(), \"Expected pkg3 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg3Version.get(), \"1.0.0\", \"pkg3 version should be 1.0.0\");\n    }\n\n    @Test(description = \"Test case 4.3: Add dep3 and build with HARD locking mode\",\n            dependsOnGroups = \"testCase2\", groups = \"testCase4\")\n    public void testCase4_3_addDep3_hardLocking() throws IOException, InterruptedException {\n        Path projectDir = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n        // Ensure legacy dependency for pkg3 is present (idempotent)\n        MavenCustomRepoTestUtils.pasteStaticMainBalWithPkg1AndPkg2(projectDir);\n        // Remove existing Dependencies.toml in an idempotent way\n        Files.deleteIfExists(projectDir.resolve(\"Dependencies.toml\"));\n        List<String> args = new ArrayList<>();\n        args.add(\"--locking-mode=hard\");\n        Process buildCleanup = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir,\n                args, this.envVariables);\n        String buildCleanupErrors = getString(buildCleanup.getErrorStream());\n        if (!buildCleanupErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildCleanupErrors);\n        }\n        pasteStaticMainBalWithAllPkgs(projectDir);\n        args = new ArrayList<>();\n        args.add(\"--locking-mode=hard\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir, args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n                .replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n        Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                        collapsed.contains(\"target/bin/myproject1.jar\"),\n                \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \" + buildOutput);\n\n        Path dependencyPath = projectDir.resolve(\"Dependencies.toml\");\n        Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg2\");\n        Optional<String> pkg3Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg3\");\n        Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n        Assert.assertTrue(pkg3Version.isPresent(), \"Expected pkg3 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg2Version.get(), \"1.0.0\", \"pkg2 version should be 1.0.0\");\n        Assert.assertEquals(pkg3Version.get(), \"1.0.0\", \"pkg3 version should be 1.0.0\");\n    }\n\n    @Test(description = \"Test case 4.4: Add dep3 and build with LOCKED locking mode\",\n          dependsOnGroups = \"testCase2\", groups = \"testCase4\")\n     public void testCase4_4_addDep3_lockedLocking() throws IOException, InterruptedException {\n        Path projectDir = this.tempWorkspaceDirectory.resolve(\"myproject1\");\n        MavenCustomRepoTestUtils.pasteStaticMainBalWithPkg1AndPkg2(projectDir);\n        Files.deleteIfExists(projectDir.resolve(\"Dependencies.toml\"));\n\n        List<String> args = new ArrayList<>();\n        args.add(\"--locking-mode=hard\");\n        Process buildCleanup = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir,\n                args, this.envVariables);\n        String buildCleanupErrors = getString(buildCleanup.getErrorStream());\n        if (!buildCleanupErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildCleanupErrors);\n        }\n\n        pasteStaticMainBalWithAllPkgs(projectDir);\n\n        args = new ArrayList<>();\n        args.add(\"--locking-mode=locked\");\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, projectDir, args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n                .replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n\n        // Expect a locked-mode error when attempting to add new imports.\n        boolean stderrHasLockedMsg = buildErrors != null && (buildErrors.contains(\"cannot add new imports with\" +\n                \" --locking-mode=locked\")\n                || buildErrors.contains(\"package resolution contains errors\"));\n        boolean stdoutHasLockedMsg = collapsed.contains(\"cannot add new imports with --locking-mode=locked\")\n                || collapsed.contains(\"package resolution contains errors\");\n\n        Assert.assertTrue(stderrHasLockedMsg || stdoutHasLockedMsg,\n                \"Expected locked-mode error when adding new imports. stdout: \" + collapsed + \"\\nstderr: \" +\n                        buildErrors);\n\n        // Build should not have generated an executable in locked mode when adding new imports.\n        Assert.assertFalse(collapsed.contains(\"Generating executable\") &&\n                        collapsed.contains(\"target/bin/myproject1.jar\"),\n                \"Build unexpectedly succeeded in locked locking mode when adding new imports. stdout: \" +\n                        collapsed + \"\\nstderr: \" + buildErrors);\n    }\n\n    @Test(description = \"Add a new version for an existing dependency and build\",\n            dependsOnMethods = \"testCase2_publishAdditionalVersionsForDeps\")\n    public void testCase5_addVersionInBallerinaToml_buildSucceeds() throws IOException, InterruptedException {\n        // Update the package version in Ballerina.toml first, then build to pick up the change.\n        Assert.assertTrue(updateVersionForPackage(this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n                \"pkg2\", \"1.1.0\"), \"pkg2 not found in Ballerina.toml\");\n        List<String> args = new ArrayList<>();\n        Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME, this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n                args, this.envVariables);\n        String buildErrors = getString(build.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        String buildOutput = getString(build.getInputStream());\n        String normalized = buildOutput.replace(\"\\\\\", \"/\").replace(\"\\r\\n\", \"\\n\")\n                .replace(\"\\r\", \"\\n\");\n        String collapsed = normalized.replaceAll(\"\\\\s+\", \" \");\n        Assert.assertTrue(collapsed.contains(\"Generating executable\") &&\n                        collapsed.contains(\"target/bin/myproject1.jar\"),\n                \"Expected generating executable + target/bin/myproject1.jar in output. Actual output: \" + buildOutput);\n\n        Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n        Optional<String> pkg2Version = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg2\");\n        Assert.assertTrue(pkg2Version.isPresent(), \"Expected pkg2 to be present in Dependencies.toml\");\n        Assert.assertEquals(pkg2Version.get(), \"1.1.1\", \"Package version is not matching with the \" +\n                \"expected package version\");\n    }\n\n    @Test(description = \"Add an incompatible version for an existing dependency and build should fail\",\n            dependsOnMethods = \"testCase2_publishAdditionalVersionsForDeps\")\n    public void testCase5_addIncompatibleVersion_buildFails() throws IOException, InterruptedException {\n        Path dependencyPath = this.tempWorkspaceDirectory.resolve(\"myproject1\").resolve(\"Dependencies.toml\");\n        if (!Files.exists(dependencyPath)) {\n            // If the locked Dependencies.toml was removed by an earlier test, recreate a pinned state.\n            // pinPkg1AndPkg2To100 is idempotent and will create a hard-locked Dependencies.toml.\n            pinPkg1AndPkg2To100();\n        }\n\n        // Read the existing locked version so we can restore it after the test\n        String existingVersion = MavenCustomRepoTestUtils.getPackageVersionFromDependencies(dependencyPath,\n                \"pkg2\").orElse(\"\");\n\n        // Update Ballerina.toml to an incompatible version first, then run the build and assert failure\n        try {\n            Assert.assertTrue(updateVersionForPackage(this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n                            \"pkg2\", \"2.0.0\"),\n                    \"pkg2 not found in Ballerina.toml\");\n            List<String> args = new ArrayList<>();\n            Process build = executeBuildCommand(DISTRIBUTION_FILE_NAME,\n                    this.tempWorkspaceDirectory.resolve(\"myproject1\"), args, this.envVariables);\n            String buildErrors = getString(build.getErrorStream());\n            Assert.assertTrue(buildErrors.contains(\"incompatible with the version locked in Dependencies.toml\"),\n                    \"Incompatible version error message not found in the build errors. Actual stderr: \" + buildErrors);\n        } finally {\n            if (!existingVersion.isEmpty()) {\n                Assert.assertTrue(updateVersionForPackage(this.tempWorkspaceDirectory.resolve(\"myproject1\"),\n                                \"pkg2\", existingVersion),\n                        \"pkg2 not found when restoring version in Ballerina.toml\");\n            }\n         }\n        }\n\n    @AfterClass(alwaysRun = true)\n    public void cleanup() throws IOException {\n        deleteFiles(actualHomeDirectory, true);\n        Files.walkFileTree(actualHomeDirectoryClone,\n                new MavenCustomRepoTest.Copy(actualHomeDirectoryClone, actualHomeDirectory));\n        deleteFiles(actualHomeDirectoryClone, false);\n        deleteFiles(tempWorkspaceDirectory, false);\n        deleteArtifacts(org, \"pkg1\");\n        deleteArtifacts(org, \"pkg2\");\n        deleteArtifacts(org, \"pkg3\");\n    }\n\n    /**\n     * Copy test resources to temp directory.\n     */\n    static class Copy extends SimpleFileVisitor<Path> {\n        private final Path fromPath;\n        private final Path toPath;\n        private final StandardCopyOption copyOption;\n\n        Copy(Path fromPath, Path toPath, StandardCopyOption copyOption) {\n            this.fromPath = fromPath;\n            this.toPath = toPath;\n            this.copyOption = copyOption;\n        }\n\n        Copy(Path fromPath, Path toPath) {\n            this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);\n        }\n\n        @Override\n        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\n\n            Path targetPath = toPath.resolve(fromPath.relativize(dir).toString());\n            if (!Files.exists(targetPath)) {\n                Files.createDirectory(targetPath);\n            }\n            return FileVisitResult.CONTINUE;\n        }\n\n        @Override\n        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n\n            Files.copy(file, toPath.resolve(fromPath.relativize(file).toString()), copyOption);\n            return FileVisitResult.CONTINUE;\n        }\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/MavenCustomRepoTestUtils.java",
    "content": "/*\n * Copyright (c) 2023, WSO2 LLC. (http://wso2.com).\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport io.ballerina.toml.api.Toml;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport org.testng.Assert;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.StandardOpenOption;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport static org.ballerina.projectapi.TestUtils.DISTRIBUTION_FILE_NAME;\nimport static org.ballerina.projectapi.TestUtils.OUTPUT_CONTAIN_ERRORS;\nimport static org.ballerina.projectapi.TestUtils.executePackCommand;\nimport static org.ballerina.projectapi.TestUtils.executePushCommand;\n\n\n/**\n * Utility class for maven repository tests.\n */\npublic class MavenCustomRepoTestUtils {\n\n    /**\n     * Create Settings.toml inside the home repository.\n     * @param dirPath  folder path to the settings toml\n     * @throws IOException i/o exception when writing to file\n     */\n    static void createSettingToml(Path dirPath) throws IOException {\n        String content = \"[[repository.maven]]\\n \" +\n                \"id = \\\"github1\\\"\\n \" +\n                \"url = \\\"https://maven.pkg.github.com/ballerina-platform/ballerina-release\\\"\\n \" +\n                \"username = \\\"ballerina-platform\\\"\\n \" +\n                \"accesstoken = \\\"\" + getGithubToken() + \"\\\"\\n\";\n        Files.write(dirPath.resolve(\"Settings.toml\"), content.getBytes(), StandardOpenOption.CREATE,\n                StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    /**\n     * Get access token of GitHub required to push the module.\n     *\n     * @return token required to push the module.\n     */\n    private static String getGithubToken() {\n        return System.getenv(\"githubAccessToken\");\n    }\n\n    /**\n     * Get environment variables and add ballerina_home as a env variable the tmp directory.\n     *\n     * @return env directory variable array\n     */\n    static Map<String, String> getEnvVariables() {\n        Map<String, String> envVarMap = System.getenv();\n        Map<String, String> retMap = new HashMap<>();\n        envVarMap.forEach(retMap::put);\n        return retMap;\n    }\n\n    /**\n     * Convert input stream to string.\n     *\n     * @param outputs input stream\n     * @return converted string\n     * @throws IOException Error when reading from input stream\n     */\n    static String getString(InputStream outputs) throws IOException {\n        try (BufferedReader br = new BufferedReader(new InputStreamReader(outputs))) {\n            Stream<String> logLines = br.lines();\n            String generatedLog = logLines.collect(Collectors.joining(\"\\n\"));\n            logLines.close();\n            return generatedLog;\n        }\n    }\n\n    /**\n     * Delete files inside directories.\n     *\n     * @param dirPath              directory path\n     * @param deleteDirContentOnly delete only the content inside the directory\n     * @throws IOException throw an exception if an issue occurs\n     */\n    static void deleteFiles(Path dirPath, boolean deleteDirContentOnly) throws IOException {\n        Files.walk(dirPath)\n                .sorted(Comparator.reverseOrder())\n                .map(Path::toFile)\n                .forEach(File::delete);\n        if (deleteDirContentOnly) {\n            Files.createDirectories(dirPath);\n        }\n    }\n\n    /**\n     * Delete artifacts from GitHub.\n     * @param org           organization name\n     * @param packagename   package name\n     */\n    static void deleteArtifacts(String org, String packagename) throws IOException {\n        OkHttpClient client = new OkHttpClient();\n        Request request = new Request.Builder()\n                .url(\"https://api.github.com/orgs/ballerina-platform/packages/maven/\" + org + \".\" + packagename)\n                .header(\"Accept\", \"application/vnd.github+json\")\n                .header(\"Authorization\", \"Bearer \" + getGithubToken())\n                .header(\"X-GitHub-Api-Version\", \"2022-11-28\")\n                .delete()\n                .build();\n        client.newCall(request).execute();\n    }\n\n    /**\n     * Run the `ballerina pack` command for the given package and return the spawned Process.\n     *\n     * @param packageName the package directory name under the sourceDirectory\n     * @param sourceDirectory the path that contains the package folders\n     * @param envVariable environment variables to pass to the process\n     * @return the Process for the pack command\n     * @throws IOException if an I/O error occurs when starting the process\n     * @throws InterruptedException if the current thread is interrupted while waiting for the process\n     */\n    static Process packTrigger(String packageName, Path sourceDirectory, Map<String, String> envVariable)\n            throws IOException, InterruptedException {\n        Process process = executePackCommand(DISTRIBUTION_FILE_NAME,\n                sourceDirectory.resolve(packageName), new ArrayList<>(),\n                envVariable);\n\n        String buildErrors = getString(process.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        return process;\n    }\n\n    /**\n     * Run the `ballerina push` command for the given package and return the spawned Process.\n     *\n     * @param packageName the package directory name under the sourceDirectory\n     * @param sourceDirectory the path that contains the package folders\n     * @param envVariable environment variables to pass to the process\n     * @return the Process for the push command\n     * @throws IOException if an I/O error occurs when starting the process\n     * @throws InterruptedException if the current thread is interrupted while waiting for the process\n     */\n    static Process pushTrigger(String packageName, Path sourceDirectory, Map<String, String> envVariable)\n            throws IOException, InterruptedException {\n        List<String> args = new ArrayList<>();\n        args.add(\"--repository=\" + MavenCustomRepoTest.GITHUB_REPO_ID);\n\n        Process process = executePushCommand(DISTRIBUTION_FILE_NAME, sourceDirectory.resolve(packageName), args,\n                envVariable);\n        String buildErrors = getString(process.getErrorStream());\n        if (!buildErrors.isEmpty()) {\n            Assert.fail(OUTPUT_CONTAIN_ERRORS + buildErrors);\n        }\n        return process;\n    }\n    /**\n     * Replace the `version = ...` line inside the [package] section of a Ballerina.toml.\n     *\n     * <p>The method performs a simple text substitution: any line starting with\n     * {@code version =} is replaced with the provided version string. The file is\n     * overwritten with the updated contents.</p>\n     *\n     * @param sourceDirectory path to the project containing Ballerina.toml\n     * @param version the version string to set (e.g. \"1.0.0\")\n     * @throws IOException if reading or writing the Ballerina.toml fails\n     */\n    static void editVersionBallerinaToml(Path sourceDirectory, String version) throws IOException {\n        Path ballerinaTomlPath = sourceDirectory.resolve(\"Ballerina.toml\");\n        String toml = Files.readString(ballerinaTomlPath);\n\n        int pkgStart = toml.indexOf(\"[package]\");\n        if (pkgStart == -1) {\n            // No [package] block - append one\n            String appended = toml + System.lineSeparator() + \"[package]\" + System.lineSeparator()\n                    + \"version = \\\"\" + version + \"\\\"\";\n            Files.writeString(ballerinaTomlPath, appended, StandardOpenOption.TRUNCATE_EXISTING);\n            return;\n        }\n\n        int nextHeader = toml.indexOf(\"\\n[\", pkgStart + 1);\n        int blockEnd = nextHeader == -1 ? toml.length() : nextHeader;\n        String block = toml.substring(pkgStart, blockEnd);\n\n        Pattern versionLine = Pattern.compile(\"(?m)^(\\\\s*)version\\\\s*=.*$\");\n        Matcher vm = versionLine.matcher(block);\n        String newBlock;\n        if (vm.find()) {\n            // replace existing version line, preserve indentation\n            newBlock = vm.replaceFirst(\"$1version = \\\"\" + version + \"\\\"\");\n        } else {\n            // insert version after header line\n            int headerEnd = block.indexOf('\\n');\n            if (headerEnd == -1) {\n                newBlock = block + System.lineSeparator() + \"version = \\\"\" + version + \"\\\"\";\n            } else {\n                newBlock = block.substring(0, headerEnd + 1) + \"version = \\\"\" + version + \"\\\"\" +\n                        (headerEnd + 1 < block.length() ? \"\\n\" + block.substring(headerEnd + 1) : \"\");\n            }\n        }\n\n        String updated = toml.substring(0, pkgStart) + newBlock + toml.substring(blockEnd);\n        Files.writeString(ballerinaTomlPath, updated, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    /**\n     * Update (or insert) a `version = \"...\"` entry for the given package name inside a\n     * Ballerina.toml located in the project directory.\n     *\n     * <p>The helper searches for a line containing {@code name = \"<packageName>\"} and then\n     * replaces an existing {@code version =} line following it, or inserts one if missing.\n     * The operation is persisted to disk and the method returns whether a change was made.</p>\n     *\n     * @param sourceDirectory the project directory that contains Ballerina.toml\n     * @param packageName the package name to adjust (e.g. \"pkg1\")\n     * @param version the version string to set (e.g. \"1.1.0\")\n     * @return true if the file was modified, false if the package name was not found\n     * @throws IOException if reading or writing the file fails\n     **/\n    static boolean updateVersionForPackage(Path sourceDirectory, String packageName, String version)\n            throws IOException {\n        Path ballerinaTomlPath = sourceDirectory.resolve(\"Ballerina.toml\");\n        List<String> lines = Files.readAllLines(ballerinaTomlPath);\n\n        for (int i = 0; i < lines.size(); i++) {\n            String trimmed = lines.get(i).trim();\n            // look for name = \"pkg\"\n            if (trimmed.startsWith(\"name\") && trimmed.contains(\"\\\"\" + packageName + \"\\\"\")) {\n                // search forward for version line until next section header\n                for (int j = i + 1; j < lines.size(); j++) {\n                    String t = lines.get(j).trim();\n                    if (t.startsWith(\"[\")) {\n                        // reached next section, insert version right after the name line\n                        lines.add(i + 1, \"version = \\\"\" + version + \"\\\"\");\n                        Files.write(ballerinaTomlPath, lines);\n                        return true;\n                    }\n                    if (t.startsWith(\"version\")) {\n                        // replace existing version line\n                        lines.set(j, \"version = \\\"\" + version + \"\\\"\");\n                        Files.write(ballerinaTomlPath, lines);\n                        return true;\n                    }\n                }\n                // reached EOF without finding version or next section: append version after name\n                lines.add(i + 1, \"version = \\\"\" + version + \"\\\"\");\n                Files.write(ballerinaTomlPath, lines);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Read a Dependencies.toml and return the version string for the given package name if present.\n     *\n     * @param dependencyTomlPath path to Dependencies.toml\n     * @param packageName        package name to look up\n     * @return Optional version string\n     * @throws IOException when reading the toml fails\n     */\n    static Optional<String> getPackageVersionFromDependencies(Path dependencyTomlPath, String packageName)\n            throws IOException {\n        Toml toml = Toml.read(dependencyTomlPath);\n        List<Toml> packages = toml.getTables(\"package\");\n        return packages.stream()\n                .filter(pkg -> pkg.get(\"name\").map(n -> n.toString()).orElse(\"\").equals(packageName))\n                .map(pkg -> pkg.get(\"version\").map(v -> v.toString()))\n                .filter(Optional::isPresent)\n                .map(Optional::get)\n                .findFirst();\n    }\n\n    /**\n     * Add or update a [[dependency]] in Ballerina.toml for the given org and package, then update the source.\n     *\n     * @param projectDir the project directory containing Ballerina.toml\n     * @param org the organization/group id of the dependency (e.g., \"bctestorg\")\n     * @param name the package name of the dependency (e.g., \"pkg1\")\n     * @param version the version to pin for the dependency (e.g., \"1.0.0\")\n     * @param repository the repository id to use for the dependency (e.g., \"github1\")\n     * @throws IOException if reading or writing the Ballerina.toml fails\n     */\n    public static void ensureLegacyDependency(Path projectDir, String org, String name, String version,\n                                              String repository) throws IOException {\n        Path ballerinaTomlPath = projectDir.resolve(\"Ballerina.toml\");\n        if (!Files.exists(ballerinaTomlPath)) {\n            throw new IOException(\"Missing Ballerina.toml in project: \" + projectDir);\n        }\n        String toml = Files.readString(ballerinaTomlPath);\n        String desiredDepBlock = \"\\n[[dependency]]\\norg=\\\"\" + org + \"\\\"\\nname=\\\"\" + name + \"\\\"\\nversion=\\\"\" + version +\n                \"\\\"\\nrepository=\\\"\" + repository + \"\\\"\\n\";\n\n        // Find an existing [[dependency]] block for the given org+name\n        Pattern depPattern = Pattern.compile(\"(?is)\\\\[\\\\[dependency\\\\]\\\\].*?org\\\\s*=\\\\s*\\\"\" +\n                Pattern.quote(org) + \"\\\".*?name\\\\s*=\\\\s*\\\"\" + Pattern.quote(name) + \"\\\"\" +\n                \".*?(?=\\\\z|\\\\[\\\\[dependency\\\\]\\\\])\");\n        Matcher matcher = depPattern.matcher(toml);\n        if (matcher.find()) {\n            String existingBlock = matcher.group(0);\n            // Try to extract version if present\n            Pattern verPat = Pattern.compile(\"version\\\\s*=\\\\s*\\\"([^\\\"]*)\\\"\", Pattern.CASE_INSENSITIVE);\n            Matcher vm = verPat.matcher(existingBlock);\n            if (vm.find()) {\n                String existingVersion = vm.group(1);\n                if (existingVersion.equals(version)) {\n                    // already the desired version\n                    // Ensure source-level usage and return\n                    if (\"pkg1\".equals(name) || \"pkg2\".equals(name) || \"pkg3\".equals(name)) {\n                        pasteStaticMainBalWithAllPkgs(projectDir);\n                    }\n                    return;\n                }\n            }\n            // Version differs or missing -> replace the whole dependency block with the desired block\n            String updatedToml = toml.substring(0, matcher.start()) + desiredDepBlock + toml.substring(matcher.end());\n            Files.writeString(ballerinaTomlPath, updatedToml);\n        } else {\n            // No existing dependency block -> append\n            Files.writeString(ballerinaTomlPath, toml + desiredDepBlock);\n        }\n\n        // Ensure source-level usage so the package becomes a compile-time dependency\n        if (\"pkg1\".equals(name) || \"pkg2\".equals(name) || \"pkg3\".equals(name)) {\n            pasteStaticMainBalWithAllPkgs(projectDir);\n        }\n    }\n\n    /**\n     * Writes a deterministic `main.bal` that imports pkg2 and pkg1 and calls pkg2:main() then pkg1:main().\n     * it returns early if the file already contains the imports and calls.\n     *\n     * @param projectDir the project directory where main.bal should be written\n     * @throws IOException if an I/O error occurs while creating or writing the file\n     */\n    public static void pasteStaticMainBalWithPkg1AndPkg2(Path projectDir) throws IOException {\n        Path mainBal = projectDir.resolve(\"main.bal\");\n        if (!Files.exists(mainBal)) {\n            mainBal = projectDir.resolve(\"src\").resolve(\"main.bal\");\n        }\n        if (mainBal.getParent() != null && !Files.exists(mainBal.getParent())) {\n            Files.createDirectories(mainBal.getParent());\n        }\n\n        String import1 = \"import bctestorg/pkg1;\";\n        String import2 = \"import bctestorg/pkg2;\";\n        String call1 = \"pkg1:main();\";\n        String call2 = \"pkg2:main();\";\n\n\n\n        String snippet = import2 + \"\\n\" + import1 + \"\\n\" +\n                \"\\n\" +\n                \"public function main(string... args) {\\n\" +\n                \"    // Ensure pkg2 then pkg1 are used so they become compile-time dependencies\\n\" +\n                \"    \" + call2 + \"\\n\" +\n                \"    \" + call1 + \"\\n\" +\n                \"}\\n\";\n\n        Files.writeString(mainBal, snippet, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n\n    /**\n     * Writes a single deterministic `main.bal` that uses pkg2, pkg1 and pkg3.\n     *  it returns early if the file already contains the imports and calls.\n     *\n     * @param projectDir the project directory where main.bal should be written\n     * @throws IOException if an I/O error occurs while creating or writing the file\n     */\n    public static void pasteStaticMainBalWithAllPkgs(Path projectDir) throws IOException {\n        Path mainBal = projectDir.resolve(\"main.bal\");\n        if (!Files.exists(mainBal)) {\n            mainBal = projectDir.resolve(\"src\").resolve(\"main.bal\");\n        }\n        if (mainBal.getParent() != null && !Files.exists(mainBal.getParent())) {\n            Files.createDirectories(mainBal.getParent());\n        }\n\n        String import1 = \"import bctestorg/pkg1;\";\n        String import2 = \"import bctestorg/pkg2;\";\n        String import3 = \"import bctestorg/pkg3;\";\n        String call1 = \"pkg1:main();\";\n        String call2 = \"pkg2:main();\";\n        String call3 = \"pkg3:main();\";\n\n        if (Files.exists(mainBal)) {\n            String existing = Files.readString(mainBal);\n            if (existing.contains(import1) && existing.contains(import2) && existing.contains(import3)\n                    && existing.contains(call1) && existing.contains(call2) && existing.contains(call3)) {\n                return; // already contains desired snippet\n            }\n        }\n\n        String snippet = import2 + \"\\n\" + import1 + \"\\n\" + import3 + \"\\n\" +\n                \"\\n\" +\n                \"public function main(string... args) {\\n\" +\n                \"    // Ensure pkg2, pkg1 and pkg3 are used so they become compile-time dependencies\\n\" +\n                \"    \" + call2 + \"\\n\" +\n                \"    \" + call1 + \"\\n\" +\n                \"    \" + call3 + \"\\n\" +\n                \"}\\n\";\n\n        Files.writeString(mainBal, snippet, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n}\n"
  },
  {
    "path": "project-api-tests/src/test/java/org/ballerina/projectapi/TestUtils.java",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * WSO2 Inc. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\npackage org.ballerina.projectapi;\n\nimport net.lingala.zip4j.ZipFile;\nimport net.lingala.zip4j.exception.ZipException;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\n\nimport java.io.IOException;\nimport java.io.PrintStream;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.List;\nimport java.util.Map;\n\nimport static org.ballerina.projectapi.CentralTestUtils.BALLERINA_HOME_DIR;\nimport static org.ballerina.projectapi.CentralTestUtils.TEST_MODE_ACTIVE;\n\n/**\n * Utility class for tests.\n */\npublic class TestUtils {\n\n    private TestUtils() {\n    }\n\n    private static final PrintStream OUT = System.out;\n    private static final Path TARGET_DIR = Paths.get(System.getProperty(\"target.dir\"));\n    private static final Path TEST_DISTRIBUTION_PATH = TARGET_DIR.resolve(\"test-distribution\");\n    public static final Path MAVEN_VERSION = Paths.get(System.getProperty(\"maven.version\"));\n    public static final Path DISTRIBUTIONS_DIR = Paths.get(System.getProperty(\"distributions.dir\"));\n    public static final Path CODE_NAME = Paths.get(System.getProperty(\"code.name\"));\n    public static final String OUTPUT_CONTAIN_ERRORS = \"build output contain errors:\";\n    public static final String DISTRIBUTION_FILE_NAME = \"ballerina-\" + MAVEN_VERSION + \"-\" + CODE_NAME;\n\n    /**\n     * Execute ballerina command.\n     *\n     * @param distributionName The name of the distribution.\n     * @param sourceDirectory  The directory where the sources files are location.\n     * @param args             The arguments to be passed to the build command.\n     * @return inputream with log outputs\n     * @throws IOException          Error executing build command.\n     * @throws InterruptedException Interrupted error executing build command.\n     */\n    public static Process executeCommand(String command, String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        args.add(0, command);\n        // Use platform-specific bal executable: on Windows use bal.bat, otherwise use bal\n        String osName = System.getProperty(\"os.name\");\n        String balExecutable = \"bal\";\n        if (osName != null && osName.toLowerCase().contains(\"win\")) {\n            balExecutable = \"bal.bat\";\n        }\n        args.add(0, TEST_DISTRIBUTION_PATH.resolve(distributionName).resolve(\"bin\").resolve(balExecutable).toString());\n\n        OUT.println(\"Executing: \" + StringUtils.join(args, ' '));\n\n        ProcessBuilder pb = new ProcessBuilder(args);\n\n        // Add env variables\n        if (envProperties != null) {\n            Map<String, String> env = pb.environment();\n            for (Map.Entry<String, String> entry : envProperties.entrySet()) {\n                env.put(entry.getKey(), entry.getValue());\n            }\n        }\n\n        pb.directory(sourceDirectory.toFile());\n        Process process = pb.start();\n        int exitCode = process.waitFor();\n        return process;\n    }\n\n    public static Process executeBuildCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"build\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executePackCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"pack\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executePushCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"push\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executePullCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"pull\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executeSearchCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"search\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executeToolCommand(String distributionName, Path sourceDirectory,\n            List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"tool\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executeHelpCommand(String distributionName, Path sourceDirectory,\n             List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"help\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executeCleanCommand(String distributionName, Path sourceDirectory,\n             List<String> args, Map<String, String> envProperties) throws IOException, InterruptedException {\n        return executeCommand(\"clean\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    public static Process executeNewCommand(String distributionName, Path sourceDirectory,\n                                            List<String> args, Map<String, String> envProperties)\n            throws IOException, InterruptedException {\n        return executeCommand(\"new\", distributionName, sourceDirectory, args, envProperties);\n    }\n\n    /**\n     * Clean and setup the distribution.\n     *\n     * @throws IOException\n     */\n    static void setupDistributions() throws IOException {\n        TestUtils.cleanDistribution();\n        TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + \".zip\"));\n    }\n\n    /**\n     * Extracts a distribution to a temporary directory.\n     *\n     * @param distributionZipPath Path to the distribution.\n     * @throws ZipException Error occurred when extracting.\n     */\n    public static void prepareDistribution(Path distributionZipPath) throws ZipException {\n        OUT.println(\"Extracting: \" + distributionZipPath.normalize());\n        ZipFile zipFile = new ZipFile(distributionZipPath.toFile());\n        zipFile.extractAll(TEST_DISTRIBUTION_PATH.toAbsolutePath().toString());\n    }\n\n    /**\n     * Delete the temporary directory used to extract distributions.\n     *\n     * @throws IOException If temporary directory does not exists.\n     */\n    public static void cleanDistribution() throws IOException {\n        FileUtils.deleteDirectory(TEST_DISTRIBUTION_PATH.toFile());\n    }\n\n    /**\n     * Get environment variables and add ballerina_home as a env variable the tmp directory.\n     *\n     * @return env directory variable array\n     */\n    static Map<String, String> addEnvVariables(Map<String, String> envVariables, Path tempHomeDirectory) {\n        envVariables.put(BALLERINA_HOME_DIR, tempHomeDirectory.toString());\n        envVariables.put(TEST_MODE_ACTIVE, \"true\");\n        return envVariables;\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/build.gradle",
    "content": "plugins {\n    id 'java'\n}\n\ngroup 'org.example'\nversion '1.0.0'\n\nrepositories {\n    mavenLocal()\n    maven {\n        url = 'https://maven.wso2.org/nexus/content/repositories/releases/'\n    }\n\n    maven {\n        url = 'https://maven.wso2.org/nexus/content/groups/wso2-public/'\n    }\n\n    maven {\n        url = 'https://repo.maven.apache.org/maven2'\n    }\n    maven {\n        url = 'https://maven.pkg.github.com/ballerina-platform/*'\n        credentials {\n            username System.getenv(\"packageUser\")\n            password System.getenv(\"packagePAT\")\n        }\n    }\n}\n\ndependencies {\n    implementation 'org.ballerinalang:ballerina-cli:2201.8.0-SNAPSHOT'\n    implementation 'info.picocli:picocli:4.0.1'\n    implementation group: 'org.talend.sdk.component', name: 'sample', version: '10.57.0'\n}\n\ntest {\n    useJUnitPlatform()\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\nAPP_HOME=$( cd \"${APP_HOME:-./}\" && pwd -P ) || exit\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=${0##*/}\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n# Collect all arguments for the java command;\n#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of\n#     shell script including quotes and variable substitutions, so put them in\n#     double quotes to make sure that they get re-expanded; and\n#   * put everything else in single quotes, so that it's not re-expanded.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/settings.gradle",
    "content": "rootProject.name = 'DistTestCommand'\ninclude 'src:main:main'\nfindProject(':src:main:main')?.name = 'main'\ninclude 'untitled'\ninclude 'main'\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/src/main/java/disttest/cli/DistTestCommand.java",
    "content": "package disttest.cli;\n\nimport io.ballerina.cli.BLauncherCmd;\nimport picocli.CommandLine;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.PrintStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\n\n@CommandLine.Command(name = \"disttest\", description = \"The tool implementation for ballerina distribution tool tests\")\npublic class DistTestCommand implements BLauncherCmd {\n    private final PrintStream printStream;\n\n    @CommandLine.Option(names = {\"--help\", \"-h\", \"?\"}, usageHelp = true)\n    private boolean helpFlag;\n\n    @CommandLine.Parameters(description = \"User name\")\n    private List<String> argList;\n\n    public DistTestCommand() {\n        this.printStream = System.out;\n    }\n\n    public DistTestCommand(PrintStream printStream) {\n        this.printStream = printStream;\n    }\n\n    @Override\n    public void execute() {\n        if (helpFlag) {\n            StringBuilder out = new StringBuilder();\n            appendHelpText(out);\n            printStream.println(out);\n            return;\n        }\n        if (argList == null || argList.size() < 1) {\n            printStream.println(\"dist test command 1.0.0 is executing with no args\\n\");\n            return;\n        }\n        printStream.println(\"dist test command 1.0.0 is executing with args \" + argList.get(0) + \"\\n\");\n    }\n\n    @Override\n    public String getName() {\n        return \"disttest\";\n    }\n\n    @Override\n    public void printLongDesc(StringBuilder out) {\n        appendHelpText(out);\n    }\n\n    @Override\n    public void printUsage(StringBuilder out) {\n        out.append(\"A sample tool built for testing bal tool functionality\");\n    }\n\n    @Override\n    public void setParentCmdParser(CommandLine parentCmdParser) {\n    }\n\n    private void appendHelpText(StringBuilder out) {\n        Class<?> clazz = DistTestCommand.class;\n        ClassLoader classLoader = clazz.getClassLoader();\n        InputStream inputStream = classLoader.getResourceAsStream(\"disttest.help\");\n        if (inputStream != null) {\n            try (InputStreamReader inputStreamREader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);\n                 BufferedReader br = new BufferedReader(inputStreamREader)) {\n                String content = br.readLine();\n                out.append(content);\n                while ((content = br.readLine()) != null) {\n                    out.append('\\n').append(content);\n                }\n            } catch (IOException e) {\n                out.append(\"Helper text is not available.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/src/main/resources/META-INF/services/io.ballerina.cli.BLauncherCmd",
    "content": "disttest.cli.DistTestCommand"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/DistTestCommand/src/main/resources/disttest.help",
    "content": "Sample tool used for testing the bal tools in ballerina distribution tests.\nbal disttest <arg1>\n\n--args--\n    <arg1>\n        The argument to be printed.\n\nversion: 1.0.0\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-general-help.txt",
    "content": "   Tool Commands:\n        disttest        The tool implementation for ballerina distribution tool tests"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-specific-help-1.0.0.txt",
    "content": "Sample tool used for testing the bal tools in ballerina distribution tests.\nbal disttest <arg1>\n\n--args--\n    <arg1>\n        The argument to be printed.\n\nversion: 1.0.0"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-specific-help-1.1.0.txt",
    "content": "Sample tool used for testing the bal tools in ballerina distribution tests.\nbal disttest <arg1>\n\n--args--\n    <arg1>\n        The argument to be printed.\n\nversion: 1.1.0"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-tool.txt",
    "content": "dist test command 1.1.0 is executing with args arg1"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-unknown-cmd-non-existing.txt",
    "content": "ballerina: unknown command 'disttest2'\nRun 'bal help' for usage."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-execute-unknown-cmd.txt",
    "content": "ballerina: unknown command 'disttest'\nRun 'bal help' for usage."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-list-with-multiple-tool-versions.txt",
    "content": "|TOOL ID               |VERSION         |REPO       |\n|----------------------|----------------|-----------|\n|disttest              |  1.1.0         |central    |\n|disttest              |* 1.0.0         |central    |"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-list-with-no-tools.txt",
    "content": "no tools found locally."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-again-with-specific-version.txt",
    "content": "tool 'disttest:1.0.0' is already available locally.\ntool 'disttest:1.0.0' is already active."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-again-without-version.txt",
    "content": "tool 'disttest:1.1.0' is already available locally.\ntool 'disttest:1.1.0' is already active."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-with-incompatible-dist.txt",
    "content": "ballerina: tool 'disttest:1.0.4' is not compatible with the current Ballerina distribution"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-with-non-existing-version.txt",
    "content": "unexpected error occurred while pulling tool:error: tool not found for: disttest:1.0.3"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-with-specific-version.txt",
    "content": "tool 'disttest:1.0.0' pulled successfully.\ntool 'disttest:1.0.0' successfully set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-pull-without-version.txt",
    "content": "tool 'disttest:1.1.0' pulled successfully.\ntool 'disttest:1.1.0' successfully set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-active-version.txt",
    "content": "ballerina: cannot remove active tool 'disttest:1.1.0'."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-all.txt",
    "content": "tool 'disttest' successfully removed."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-non-existing-tool.txt",
    "content": "ballerina: tool 'disttest2' not found."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-non-existing-version.txt",
    "content": "ballerina: tool 'disttest:1.0.3' not found."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-specific-version.txt",
    "content": "tool 'disttest:1.0.0' successfully removed."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-remove-with-incompatible-dist.txt",
    "content": "ballerina: tool 'disttest:1.0.4' is not compatible with the current Ballerina distribution"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-search-with-tool-id.txt",
    "content": "Ballerina Central\n=================\n\n|ID          |PACKAGE      |DESCRIPTION  |DATE            |VERSION      |\n|------------|-------------|-------------|----------------|-------------|\n|disttest    |bctestorg... |Sample to... |"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-update-non-existing.txt",
    "content": "ballerina: tool 'disttest2' is not installed."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-update-with-new-patch-and-minor.txt",
    "content": "tool 'disttest:1.1.0' pulled successfully.\ntool 'disttest:1.1.0' successfully set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-update-with-no-new-version.txt",
    "content": "tool 'disttest' is already up-to-date."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-use-active-version.txt",
    "content": "tool 'disttest:1.0.0' is the current active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-use-new-version.txt",
    "content": "tool 'disttest:1.1.0' successfully set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-use-non-existent-version.txt",
    "content": "tool 'disttest:1.0.3' is not found. Run 'bal tool pull disttest:1.0.3' to fetch and set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-use-old-version.txt",
    "content": "tool 'disttest:1.0.0' successfully set as the active version."
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/cmd-outputs/tool-use-with-incompatible-dist.txt",
    "content": "ballerina: tool 'disttest:1.0.4' is not compatible with the current Ballerina distribution"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.0/disttestpackage/BalTool.toml",
    "content": "[tool]\nid=\"disttest\"\n\n[[dependency]]\npath=\"./resources/DistTestCommand-1.0.0.jar\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.0/disttestpackage/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpackage\"\nversion = \"1.0.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.0/disttestpackage/README.md",
    "content": "# disttest\n\n## Description\nSample tool used for testing the bal tools in ballerina distribution tests.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.1/disttestpackage/BalTool.toml",
    "content": "[tool]\nid=\"disttest\"\n\n[[dependency]]\npath=\"./resources/DistTestCommand-1.0.1.jar\""
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.1/disttestpackage/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpackage\"\nversion = \"1.0.1\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.1/disttestpackage/Package.md",
    "content": "# disttest\n\n## Description\nSample tool used for testing the bal tools in ballerina distribution tests.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.4/disttestpackage/BalTool.toml",
    "content": "[tool]\nid=\"disttest\"\n\n[[dependency]]\npath=\"./resources/DistTestCommand-1.0.4.jar\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.4/disttestpackage/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpackage\"\nversion = \"1.0.4\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.0.4/disttestpackage/README.md",
    "content": "# disttest\n\n## Description\nSample tool used for testing the bal tools in ballerina distribution tests.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.1.0/disttestpackage/BalTool.toml",
    "content": "[tool]\nid=\"disttest\"\n\n[[dependency]]\npath=\"./resources/DistTestCommand-1.1.0.jar\""
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.1.0/disttestpackage/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpackage\"\nversion = \"1.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/bal-tool/v1.1.0/disttestpackage/README.md",
    "content": "# disttest\n\n## Description\nSample tool used for testing the bal tools in ballerina distribution tests.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project1/Ballerina.toml",
    "content": "[package]\norg = \"testorg\"\nname = \"project1\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project1/main.bal",
    "content": "import ballerina/io;\nimport ballerina/random;\nimport ballerina/uuid;\nimport ballerina/http as _;\nimport ballerina/log as _;\nimport ballerina/file as _;\nimport ballerina/graphql as _;\n\npublic function main() returns error? {\n    // Generates a random decimal number between 0.0 and 1.0.\n    float randomDecimal = random:createDecimal();\n    io:println(\"Random decimal number: \", randomDecimal);\n\n    // Generates a random number between the given start(inclusive) and end(exclusive) values.\n    int randomInteger = check random:createIntInRange(1, 100);\n    io:println(\"Random integer number in range: \", randomInteger);\n    return;\n}\n\n\npublic function uuidGen() returns error? {\n    // Tests a string to see if it is a valid UUID.\n    boolean valid = uuid:validate(\"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID validated: \", valid.toString());\n\n    // Detects the RFC version of a UUID.\n    uuid:Version v = check uuid:getVersion(\n                                \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID version: \", v.toString());\n\n    // Converts a UUID string to an array of bytes.\n    byte[] uuidBytes1 = check uuid:toBytes(\n                                  \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID bytes: \", uuidBytes1);\n\n    // Converts a UUID string to a UUID record.\n    uuid:Uuid uuidRecord1 = check uuid:toRecord(\n                            \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID record: \", uuidRecord1);\n\n    uuid:Uuid uuidRecord = {\n        timeLow: 1133987422,\n        timeMid: 13817,\n        timeHiAndVersion: 4587,\n        clockSeqHiAndReserved: 173,\n        clockSeqLo: 193,\n        node: 2485377957890\n    };\n    // Converts a UUID record to a UUID string.\n    string uuidString1 = check uuid:toString(uuidRecord);\n    io:println(\"UUID string: \", uuidString1);\n\n    // Converts a UUID record to an array of bytes.\n    byte[] uuidBytes2 = check uuid:toBytes(uuidRecord);\n    io:println(\"UUID bytes: \", uuidBytes2);\n\n    // Converts a UUID bytes array to a UUID string.\n    string uuidString2 = check uuid:toString(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID string: \", uuidString2);\n\n    // Converts a UUID bytes array to a UUID record.\n    uuid:Uuid uuidRecord2 = check uuid:toRecord(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID record: \", uuidRecord2);\n    return;\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project2/Ballerina.toml",
    "content": "[package]\norg = \"testorg\"\nname = \"project1\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project2/main.bal",
    "content": "import ballerina/io;\nimport ballerina/random;\nimport ballerina/uuid;\nimport ballerina/http as _;\nimport ballerina/log as _;\nimport ballerina/file as _;\nimport ballerina/graphql as _;\n\npublic function main() returns error? {\n    // Generates a random decimal number between 0.0 and 1.0.\n    float randomDecimal = random:createDecimal();\n    io:println(\"Random decimal number: \", randomDecimal);\n\n    // Generates a random number between the given start(inclusive) and end(exclusive) values.\n    int randomInteger = check random:createIntInRange(1, 100);\n    io:println(\"Random integer number in range: \", randomInteger);\n    return;\n}\n\n\npublic function uuidGen() returns error? {\n    // Tests a string to see if it is a valid UUID.\n    boolean valid = uuid:validate(\"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID validated: \", valid.toString());\n\n    // Detects the RFC version of a UUID.\n    uuid:Version v = check uuid:getVersion(\n                                \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID version: \", v.toString());\n\n    // Converts a UUID string to an array of bytes.\n    byte[] uuidBytes1 = check uuid:toBytes(\n                                  \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID bytes: \", uuidBytes1);\n\n    // Converts a UUID string to a UUID record.\n    uuid:Uuid uuidRecord1 = check uuid:toRecord(\n                            \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID record: \", uuidRecord1);\n\n    uuid:Uuid uuidRecord = {\n        timeLow: 1133987422,\n        timeMid: 13817,\n        timeHiAndVersion: 4587,\n        clockSeqHiAndReserved: 173,\n        clockSeqLo: 193,\n        node: 2485377957890\n    };\n    // Converts a UUID record to a UUID string.\n    string uuidString1 = check uuid:toString(uuidRecord);\n    io:println(\"UUID string: \", uuidString1);\n\n    // Converts a UUID record to an array of bytes.\n    byte[] uuidBytes2 = check uuid:toBytes(uuidRecord);\n    io:println(\"UUID bytes: \", uuidBytes2);\n\n    // Converts a UUID bytes array to a UUID string.\n    string uuidString2 = check uuid:toString(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID string: \", uuidString2);\n\n    // Converts a UUID bytes array to a UUID record.\n    uuid:Uuid uuidRecord2 = check uuid:toRecord(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID record: \", uuidRecord2);\n    return;\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project3/Ballerina.toml",
    "content": "[package]\norg = \"testorg\"\nname = \"project1\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project3/main.bal",
    "content": "import ballerina/io;\nimport ballerina/random;\nimport ballerina/uuid;\nimport ballerina/http as _;\nimport ballerina/log as _;\nimport ballerina/file as _;\nimport ballerina/graphql as _;\n\npublic function main() returns error? {\n    // Generates a random decimal number between 0.0 and 1.0.\n    float randomDecimal = random:createDecimal();\n    io:println(\"Random decimal number: \", randomDecimal);\n\n    // Generates a random number between the given start(inclusive) and end(exclusive) values.\n    int randomInteger = check random:createIntInRange(1, 100);\n    io:println(\"Random integer number in range: \", randomInteger);\n    return;\n}\n\n\npublic function uuidGen() returns error? {\n    // Tests a string to see if it is a valid UUID.\n    boolean valid = uuid:validate(\"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID validated: \", valid.toString());\n\n    // Detects the RFC version of a UUID.\n    uuid:Version v = check uuid:getVersion(\n                                \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID version: \", v.toString());\n\n    // Converts a UUID string to an array of bytes.\n    byte[] uuidBytes1 = check uuid:toBytes(\n                                  \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID bytes: \", uuidBytes1);\n\n    // Converts a UUID string to a UUID record.\n    uuid:Uuid uuidRecord1 = check uuid:toRecord(\n                            \"4397465e-35f9-11eb-adc1-0242ac120002\");\n    io:println(\"UUID record: \", uuidRecord1);\n\n    uuid:Uuid uuidRecord = {\n        timeLow: 1133987422,\n        timeMid: 13817,\n        timeHiAndVersion: 4587,\n        clockSeqHiAndReserved: 173,\n        clockSeqLo: 193,\n        node: 2485377957890\n    };\n    // Converts a UUID record to a UUID string.\n    string uuidString1 = check uuid:toString(uuidRecord);\n    io:println(\"UUID string: \", uuidString1);\n\n    // Converts a UUID record to an array of bytes.\n    byte[] uuidBytes2 = check uuid:toBytes(uuidRecord);\n    io:println(\"UUID bytes: \", uuidBytes2);\n\n    // Converts a UUID bytes array to a UUID string.\n    string uuidString2 = check uuid:toString(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID string: \", uuidString2);\n\n    // Converts a UUID bytes array to a UUID record.\n    uuid:Uuid uuidRecord2 = check uuid:toRecord(\n                        [67,151,70,94,53,249,17,235,173,193,2,66,172,18,0,2]);\n    io:println(\"UUID record: \", uuidRecord2);\n    return;\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/build-time/Project3/tests/test.bal",
    "content": "import ballerina/test;\nimport ballerina/io;\n\n@test:Config {}\nfunction testFunction() {\n    io:println(\"I'm in test function!\");\n    test:assertEquals(10, 10);\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectA/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectA/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectA/main.bal",
    "content": "import ballerina/lang.'int as ints;\n\npublic function main() {\n    _ = testSum();\n}\n\npublic function testSum() returns int {\n    return ints:sum(10, 25, 35, 40);\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectB/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n[platform.java21]\ngraalvmCompatible=true\n\n[[platform.java21.dependency]]\ngroupId = \"org.slf4j\"\nartifactId = \"slf4j-api\"\nversion = \"1.7.30\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectB/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectB/main.bal",
    "content": "\npublic function main() {\n    _ = hello(\"World\");\n}\n\npublic function hello(string name) returns string {\n    return \"Hello \" + name;\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectC/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectC/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectC/main.bal",
    "content": "import bctestorg/<PKG_A> as pkgA;\nimport bctestorg/<PKG_B> as pkgB;\n\n\npublic function main() {\n    _ = pkgA:testSum();\n    _ = pkgB:hello(\"Package C\");\n}\n\npublic function printHelloWithSum(string name) returns string {\n    return pkgB:hello(name) + \":\" + pkgA:testSum().toString();\n}\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectD/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectD/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectD/main.bal",
    "content": "import bctestorg/<PKG_C> as pkgC;\n\npublic function main() {\n    _ = pkgC:printHelloWithSum(\"World\");\n}\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectE/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectE/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectE/main.bal",
    "content": "public function e() returns boolean {\n    return true;\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectF/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectF/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectF/main.bal",
    "content": "import bctestorg/<PKG_E> as pkgE;\n\npublic function f() returns boolean {\n    return pkgE:e();\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectG/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectG/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectG/main.bal",
    "content": "import bctestorg/<PKG_F> as pkgF;\n\npublic function g() returns boolean {\n    return pkgF:f();\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectSnapshot/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"my_package\"\nversion = \"1.0.0-snapshot\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectSnapshot/Package.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a main function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/central/projectSnapshot/main.bal",
    "content": "\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestmultiples/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestmultiples\"\nversion = \"1.1.1\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestmultiples/Module.md",
    "content": "Prints \"Hello, World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/latest\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestmultiples/Package.md",
    "content": "Prints \"Hello, World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello, World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestmultiples/disttestmultiples.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack1/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpack1\"\nversion = \"1.1.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack1/Module.md",
    "content": "Prints \"Hello, World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/latest\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack1/Package.md",
    "content": "Prints \"Hello, World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello, World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack1/disttestpack1.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack2/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpack2\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack2/main.bal",
    "content": "import bctestorg/disttestpack1 as _;\n\n// Prints `Hello, World!`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack3/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpack3\"\nversion = \"0.1.0\"\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack3/main.bal",
    "content": "import bctestorg/disttestpackbeta6 as _;\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack4/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpack4\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack4/main.bal",
    "content": "import bctestorg/forwardpack1 as _;\n\n// Prints `Hello, World!`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack5/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"disttestpack5\"\nversion = \"0.1.0\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/distribution-tests/disttestpack5/main.bal",
    "content": "import bctestorg/disttestmultiples as _;\n\n// Prints `Hello, World!`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageH.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n[[package.modules]]\nname = \"PackageH.test.mod.api\"\nexport = true\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/modules/mod.api/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/modules/mod.api/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test/modules/mod.api/mod.api.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageH.test.mod\"\nversion = \"1.0.1\"\nreadme = \"Package.md\"\n\n[[package.modules]]\nname = \"PackageH.test.mod.api\"\nexport = true\n\n[[package.modules]]\nname = \"PackageH.test.mod.api.doc\"\nexport = true\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api/api.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api.doc/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api.doc/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageH.test.mod/modules/api.doc/api.doc.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageI/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageI/Ballerina.toml",
    "content": "[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageI/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageH.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test.mod.api\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageI\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageH.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageI\", moduleName = \"PackageI\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageI/main.bal",
    "content": "import bctestorg/PackageH.test.mod.api as _;\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageJ.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageJ.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageJ.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageJ.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageJ.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageK/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageK/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageK\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageK/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageJ.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageJ.test\", moduleName = \"PackageJ.test\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageK\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageJ.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageK\", moduleName = \"PackageK\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageK/main.bal",
    "content": "import bctestorg/PackageJ.test as _;\n\n// Prints `Hello World`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageL.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n[[package.modules]]\nname = \"PackageL.test.mod.api\"\nexport = true\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageL.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageL.test\", moduleName = \"PackageL.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageL.test\", moduleName = \"PackageL.test.mod.api\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/modules/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/modules/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/modules/mod.api/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/modules/mod.api/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageL.test/modules/mod.api/mod.api.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageM/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageM/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageM\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageM/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageL.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageL.test\", moduleName = \"PackageL.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageL.test\", moduleName = \"PackageL.test.mod.api\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageM\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageL.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageM\", moduleName = \"PackageM\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageM/main.bal",
    "content": "import bctestorg/PackageL.test.mod.api as _;\n\n// Prints `Hello World`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageN/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageN/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageN\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageN/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageH.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test.mod.api\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageN\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageH.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageN\", moduleName = \"PackageN\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageN/main.bal",
    "content": "import bctestorg/PackageH.test.mod.api as _;\n\n// Prints `Hello World`.\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageO.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageO.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageO.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageO.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageO.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageO.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageP/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageP/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageP\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageP/main.bal",
    "content": "public function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageQ.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n[[package.modules]]\nname = \"PackageQ.test.mod.api\"\nexport = true\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageQ.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageQ.test\", moduleName = \"PackageQ.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageQ.test\", moduleName = \"PackageQ.test.mod.api\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/modules/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/modules/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/modules/mod.api/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/modules/mod.api/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageQ.test/modules/mod.api/mod.api.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageR\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n\n[[dependency]]\norg = \"bctestorg\"\nname = \"PackageQ.test\"\nversion = \"1.0.0\"\nrepository = \"local\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR/main.bal",
    "content": "import bctestorg/PackageQ.test.mod.api as _;\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageR.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageH.test\"\nversion = \"1.0.0\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test\"},\n\t{org = \"bctestorg\", packageName = \"PackageH.test\", moduleName = \"PackageH.test.mod.api\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageR.test\"\nversion = \"1.0.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageH.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageR.test\", moduleName = \"PackageR.test\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageR.test/lib.bal",
    "content": "import bctestorg/PackageH.test.mod.api as _;\n\n# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageS/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageS/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageS\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageS/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageH.test\"\nversion = \"1.0.0\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageR.test\"\nversion = \"1.0.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageH.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageR.test\", moduleName = \"PackageR.test\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageS\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageR.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageS\", moduleName = \"PackageS\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageS/main.bal",
    "content": "import bctestorg/PackageR.test as _;\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageT.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageT.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"PackageT.test\"\nversion = \"1.0.0-beta.1\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageT.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageT.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageT.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageU/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageU/Ballerina.toml",
    "content": "[build-options]\nobservabilityIncluded = false\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageU/Dependencies-template.toml",
    "content": "# AUTO-GENERATED FILE. DO NOT MODIFY.\n\n# This file is auto-generated by Ballerina for managing dependency versions.\n# It should not be modified by hand.\n\n[ballerina]\ndependencies-toml-version = \"2\"\ndistribution-version = \"**INSERT_DISTRIBUTION_VERSION_HERE**\"\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageT.test\"\nversion = \"1.0.0-beta.1\"\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageT.test\", moduleName = \"PackageT.test\"}\n]\n\n[[package]]\norg = \"bctestorg\"\nname = \"PackageU\"\nversion = \"0.1.0\"\ndependencies = [\n\t{org = \"bctestorg\", name = \"PackageT.test\"}\n]\nmodules = [\n\t{org = \"bctestorg\", packageName = \"PackageU\", moduleName = \"PackageU\"}\n]\n\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/PackageU/main.bal",
    "content": "import bctestorg/PackageT.test as _;\n\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/Transitive.PackageH.test/.gitignore",
    "content": "target\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/Transitive.PackageH.test/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"Transitive.PackageH.test\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/Transitive.PackageH.test/Module.md",
    "content": "Prints \"Hello World!\" with a main function.\n[//]: # (above is the module summary)\n\n# Module Overview\nProvides an overview about the module when generating the API documentations.\nFor example, refer to https://lib.ballerina.io/ballerina/io/0.6.0-beta.2\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/Transitive.PackageH.test/Package.md",
    "content": "Prints \"Hello World!\" with a hello function.\n[//]: # (above is the package summary)\n\n# Package Overview\nPrints \"Hello World!\" as the output to the command line using a hello function.\n"
  },
  {
    "path": "project-api-tests/src/test/resources/hierarchical-packages/Transitive.PackageH.test/lib.bal",
    "content": "# Prints `Hello` with input string name.\n#\n# + name - the input sting name\n# + return - \"Hello, \" with the input string name\n\npublic function hello(string name) returns string {\n    if !(name is \"\") {\n        return \"Hello, \" + name;\n    }\n    return \"Hello, World!\";\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/myproject1/.devcontainer.json",
    "content": "{\n  \"image\": \"ballerina/ballerina-devcontainer:2201.12.10\",\n  \"customizations\": {\n    \"vscode\": {\n      \"extensions\": [\"WSO2.ballerina\"]\n    }\n  }\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/myproject1/.gitignore",
    "content": "# Ballerina generates this directory during the compilation of a package.\n# It contains compiler-generated artifacts and the final executable if this is an application package.\ntarget/\n\n# Ballerina maintains the compiler-generated source code here.\n# Remove this if you want to commit generated sources.\ngenerated/\n\n# Contains configuration values used during development time.\n# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details.\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/myproject1/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"myproject1\"\nversion = \"0.1.0\"\ndistribution = \"2201.12.10\"\nreadme = \"Package.md\"\n\n[build-options]\nobservabilityIncluded = true\n\n\n[[dependency]]\norg=\"bctestorg\"\nname=\"pkg1\"\nversion=\"0.1.0\"\nrepository=\"github1\"\n\n[[dependency]]\norg=\"bctestorg\"\nname=\"pkg2\"\nversion=\"1.0.0\"\nrepository=\"github1\"\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/myproject1/Package.md",
    "content": "Package documentation for myproject1.\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/myproject1/main.bal",
    "content": "import bctestorg/pkg1;\nimport bctestorg/pkg2;\n\npublic function main() {\n    pkg1:main();\n    pkg2:main();\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pact/.devcontainer.json",
    "content": "{\n    \"image\": \"ballerina/ballerina-devcontainer:2201.6.0\",\n    \"extensions\": [\"WSO2.ballerina\"]\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pact/.gitignore",
    "content": "generated\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pact/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"pact\"\nversion = \"0.1.0\"\nreadme = \"Package.md\"\n\n[build-options]\nobservabilityIncluded = true\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pact/Package.md",
    "content": "jsjj\r\n\r\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pact/main.bal",
    "content": "\npublic function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg1/.devcontainer.json",
    "content": "{\n    \"image\": \"ballerina/ballerina-devcontainer:2201.6.0\",\n    \"extensions\": [\"WSO2.ballerina\"]\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg1/.gitignore",
    "content": "target\ngenerated\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg1/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"pkg1\"\nversion = \"0.1.0\"\nreadme = \"Package.md\"\n\n[build-options]\nobservabilityIncluded = true\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg1/Package.md",
    "content": "Package documentation for pkg1.\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg1/main.bal",
    "content": "public function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg2/.devcontainer.json",
    "content": "{\n    \"image\": \"ballerina/ballerina-devcontainer:2201.6.0\",\n    \"extensions\": [\"WSO2.ballerina\"]\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg2/.gitignore",
    "content": "target\ngenerated\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg2/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"pkg2\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n\n[build-options]\nobservabilityIncluded = true\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg2/Package.md",
    "content": "Package documentation for pkg2.\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg2/main.bal",
    "content": "public function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg3/.devcontainer.json",
    "content": "{\n    \"image\": \"ballerina/ballerina-devcontainer:2201.6.0\",\n    \"extensions\": [\"WSO2.ballerina\"]\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg3/.gitignore",
    "content": "target\ngenerated\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg3/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"pkg3\"\nversion = \"1.0.0\"\nreadme = \"Package.md\"\n\n\n[[dependency]]\norg = \"bctestorg\"\nname = \"pkg2\"\nversion = \"1.0.0\"\n\n\n[build-options]\nobservabilityIncluded = true\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg3/Package.md",
    "content": "Package documentation for pkg3.\n\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/pkg3/main.bal",
    "content": "public function main() {\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/test-resolution/.devcontainer.json",
    "content": "{\n    \"image\": \"ballerina/ballerina-devcontainer:2201.6.0\",\n    \"extensions\": [\"WSO2.ballerina\"],\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/test-resolution/.gitignore",
    "content": "target\ngenerated\nConfig.toml\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/test-resolution/Ballerina.toml",
    "content": "[package]\norg = \"bctestorg\"\nname = \"test\"\nversion = \"0.1.0\"\n\n[build-options]\nobservabilityIncluded = true\n\n [[dependency]]\n org = \"bctestorg\"\n name = \"pact\"\n version = \"0.2.0\"\n repository=\"github1\"\n"
  },
  {
    "path": "project-api-tests/src/test/resources/maven-repos/test-resolution/main.bal",
    "content": "import bctestorg/pact as _;\nimport ballerina/io;\n\npublic function main() {\n    io:println(\"Hello World!\");\n}\n"
  },
  {
    "path": "project-api-tests/src/test/resources/testng.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n ~ Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~      http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n-->\n\n<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\" >\n\n<suite name=\"Ballerina-Dev-Tools-Test-Suite\">\n    <test name=\"ballerina-dev-tools-tests\" parallel=\"false\">\n        <packages>\n            <package name=\"org.ballerina.projectapi\"/>\n        </packages>\n    </test>\n</suite>\n"
  },
  {
    "path": "pull_request_template.md",
    "content": "## Purpose\r\n> Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.\r\n\r\n## Goals\r\n> Describe the solutions that this feature/fix will introduce to resolve the problems described above\r\n\r\n## Approach\r\n> Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.\r\n\r\n## User stories\r\n> Summary of user stories addressed by this change>\r\n\r\n## Release note\r\n> Brief description of the new feature or bug fix as it will appear in the release notes\r\n\r\n## Documentation\r\n> Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact\r\n\r\n## Training\r\n> Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable\r\n\r\n## Certification\r\n> Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.\r\n\r\n## Marketing\r\n> Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable\r\n\r\n## Automation tests\r\n - Unit tests \r\n   > Code coverage information\r\n - Integration tests\r\n   > Details about the test cases and coverage\r\n\r\n## Security checks\r\n - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no\r\n - Ran FindSecurityBugs plugin and verified report? yes/no\r\n - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no\r\n\r\n## Samples\r\n> Provide high-level details about the samples related to this feature\r\n\r\n## Related PRs\r\n> List any other related PRs\r\n\r\n## Migrations (if applicable)\r\n> Describe migration steps and platforms on which migration has been tested\r\n\r\n## Test environment\r\n> List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested\r\n \r\n## Learning\r\n> Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem."
  },
  {
    "path": "release-notes.md",
    "content": "# Overview to Ballerina 0.970.0\nBrief summary of overview and primary improvements of the new release\n\n# Compatibility and Support\nAny changes that break backwards compatibility such as syntax changes. Porting concepts, removal/addition of OS support. We can include any known issues for a OS or any platform\n\n# How to Update?\nExplain how to update this specific version. Specify about backward compatibility with previous components versions\n\n# Improvements\n## Language & Runtime\n- improvement1\n- improvement2\n\n## Standard Library\n- improvement1\n- improvement2\n\n## Build & Package Management\n\n## IDEs & Language Server\n\n## Ballerina for Java\n\n## Ballerina Sidecar\n\n## Ballerina API Gateway\n\n## Ballerina Message Broker\n\n## Ballerina Transaction Coordinator\n\n## Ballerina Observability\n\n# Bug Fixes\nLink to the Github issues filtering for all the components\n\n# Getting Started\nYou can download the Ballerina distributions, try samples, and read the documentation at http://ballerinalang.org. You can also visit [Quick Tour][1] to get started. We encourage you to report issues, improvements, and suggestions at [Ballerina Github Repository][2].\n\n[1]: https://ballerinalang.org/docs/quick-tour/quick-tour\n[2]: https://github.com/ballerina-lang/ballerina/\n"
  },
  {
    "path": "resources/tools/COPYRIGHT.txt",
    "content": "\r\nCopyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\r\n\r\nThis product includes software developed at WSO2 (http://wso2.com/).\r\n\r\n=========================================================================\r\n==  ANTLR Notice                                                    ==\r\n=========================================================================\r\n\r\n[The BSD License]\r\nCopyright (c) 2012 Terence Parr and Sam Harwell\r\nAll rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without modification, are permitted\r\nprovided that the following conditions are met:\r\n\r\n\t- Redistributions of source code must retain the above copyright notice, this list of\r\n\t  conditions and the following disclaimer.\r\n\t- Redistributions in binary form must reproduce the above copyright notice, this list of\r\n\t  conditions and the following disclaimer in the documentation and/or other materials\r\n\t  provided with the distribution.\r\n\t- Neither the name of the author nor the names of its contributors may be used to endorse\r\n\t  or promote products derived from this software without specific prior written permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\r\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\r\nTHE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r\nSTRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\r\nTHE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n=========================================================================\r\n==  Saxon-HE Notice                                                    ==\r\n=========================================================================\r\n\r\nMost of the open source code in the Saxon product is governed by the Mozilla Public\r\nLicense version 2.0, which is reproduced below.\r\n\r\nhttps://www.mozilla.org/en-US/MPL/2.0/\r\n\r\n=========================================================================\r\n(This notice is included in the Saxon distribution because Saxon includes a QuickSort\r\nmodule that was originally developed by Wolfgang Hoschek at CERN, and which was licensed\r\nfor use under the conditions specified here.)\r\n\r\n\r\nCopyright © 1999 CERN - European Organization for Nuclear Research.\r\n\r\nPermission to use, copy, modify, distribute and sell this software and its documentation for any purpose\r\nis hereby granted without fee, provided that the above copyright notice appear in all copies and\r\nthat both that copyright notice and this permission notice appear in supporting documentation.\r\nCERN makes no representations about the suitability of this software for any purpose.\r\nIt is provided \"as is\" without expressed or implied warranty.\r\n\r\n=========================================================================\r\n\r\n\r\n(This notice is included in the Saxon distribution because Saxon's XPath parser\r\nwas originally derived from an XPath parser written by James Clark and made available\r\nunder this license. The Saxon XPath parser has since diverged very substantially, but\r\nthere are traces of the original code still present.)\r\n\r\nCopyright (c) 1998, 1999 James Clark\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of this software and associated documentation files (the\r\n\"Software\"), to deal in the Software without restriction, including\r\nwithout limitation the rights to use, copy, modify, merge, publish,\r\ndistribute, sublicense, and/or sell copies of the Software, and to\r\npermit persons to whom the Software is furnished to do so, subject to\r\nthe following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included\r\nin all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r\nIN NO EVENT SHALL JAMES CLARK BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r\nOTHER DEALINGS IN THE SOFTWARE.\r\n\r\nExcept as contained in this notice, the name of James Clark shall\r\nnot be used in advertising or otherwise to promote the sale, use or\r\nother dealings in this Software without prior written authorization\r\nfrom James Clark.\r\n=========================================================================\r\n\r\n\r\n(This notice is included in the Saxon distribution because Saxon\r\nuses code for conversion of XML Schema Regular expressions to\r\nJava/.NET regular expressions that was originally written by James\r\nClark and made available under this license. The Saxon version of\r\nthe code has been enhanced in various ways but is still recognizably\r\nbased on the original.)\r\n\r\nCopyright (c) 2001-2003 Thai Open Source Software Center Ltd\r\nAll rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without\r\nmodification, are permitted provided that the following conditions are\r\nmet:\r\n\r\n    Redistributions of source code must retain the above copyright\r\n    notice, this list of conditions and the following disclaimer.\r\n\r\n    Redistributions in binary form must reproduce the above copyright\r\n    notice, this list of conditions and the following disclaimer in\r\n    the documentation and/or other materials provided with the\r\n    distribution.\r\n\r\n    Neither the name of the Thai Open Source Software Center Ltd nor\r\n    the names of its contributors may be used to endorse or promote\r\n    products derived from this software without specific prior written\r\n    permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR\r\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n=========================================================================\r\n\r\n\r\n(This notice is included in the Saxon distribution because Saxon\r\nuses code performing Unicode Normalization that was originally written by Mark\r\nDavis and made available under this license. The Saxon version of the\r\ncode has been enhanced in various minor ways but is still recognizably\r\nbased on the original. For details of modifications, see the comments in\r\nthe source code.)\r\n\r\n\r\nCOPYRIGHT AND PERMISSION NOTICE\r\nCopyright © 1991-2007 Unicode, Inc. All rights reserved. Distributed under the Terms of Use\r\nin http://www.unicode.org/copyright.html.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of the Unicode\r\ndata files and any associated documentation (the \"Data Files\") or Unicode software and any\r\nassociated documentation (the \"Software\") to deal in the Data Files or Software without\r\nrestriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,\r\nand/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or\r\nSoftware are furnished to do so, provided that (a) the above copyright notice(s) and this\r\npermission notice appear with all copies of the Data Files or Software, (b) both the above\r\ncopyright notice(s) and this permission notice appear in associated documentation, and\r\n(c) there is clear notice in each modified Data File or in the Software as well as in the\r\ndocumentation associated with the Data File(s) or Software that the data or software has\r\nbeen modified.\r\n\r\nTHE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.\r\nIN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE\r\nBE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,\r\nOR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\r\nWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\r\nARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA\r\nFILES OR SOFTWARE.\r\n\r\nExcept as contained in this notice, the name of a copyright holder shall not be used\r\nin advertising or otherwise to promote the sale, use or other dealings in these\r\nData Files or Software without prior written authorization of the copyright holder.\r\n\r\n=========================================================================\r\n==  SLF4J Notice                                                       ==\r\n=========================================================================\r\n\r\n Copyright (c) 2004-2017 QOS.ch\r\n All rights reserved.\r\n\r\n Permission is hereby granted, free  of charge, to any person obtaining\r\n a  copy  of this  software  and  associated  documentation files  (the\r\n \"Software\"), to  deal in  the Software without  restriction, including\r\n without limitation  the rights to  use, copy, modify,  merge, publish,\r\n distribute,  sublicense, and/or sell  copies of  the Software,  and to\r\n permit persons to whom the Software  is furnished to do so, subject to\r\n the following conditions:\r\n\r\n The  above  copyright  notice  and  this permission  notice  shall  be\r\n included in all copies or substantial portions of the Software.\r\n\r\n THE  SOFTWARE IS  PROVIDED  \"AS  IS\", WITHOUT  WARRANTY  OF ANY  KIND,\r\n EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF\r\n MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND\r\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r\n LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r\n OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION\r\n WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "resources/tools/INSTALL.txt",
    "content": "                                                    ~ BALLERINA ~\n                                                    =============\n\n\nPREREQUISITES\n-------------\n\nBallerina requires JRE 17.\nCheck https://adoptopenjdk.net/releases.html?variant=openjdk21&jvmVariant=hotspot to download the JRE relevant to your system.\nThis is the Java version we have used when testing Ballerina.\n\n\nINSTALLING BALLERINA\n--------------------\n\n- Unzip the Ballerina archive in the desired directory. This will be the Ballerina installation directory.\n\n- Set the path of the installation directory to the BALLERINA_HOME environment variable.\n\n- Add the `<BALLERINA_HOME>/bin` path to your system's path variable.\n\n\n- If you have installed Java 21 already, you are all set! Just make sure that the JAVA_HOME environment variable is set correctly.\n\n- If you do not have Java 21 or if you have a different version of Java, download a compatible JRE 17 version as specified in the prerequisites.\n\n    - To set the obtained JRE as the one used by Ballerina, extract the downloaded JRE `zip/tar.gz` to the `<BALLERINA_HOME>/dependencies/jdk-21.0.5+11-jre` directory.\n    - Once you are done, the directory structure should look exactly like the following:\n        <BALLERINA_HOME>/dependencies/\n        └── jdk-21.0.5+11-jre\n            ├── bin\n            ├── bundle\n            ├── conf\n            ├── legal\n            ├── lib\n            ├── man\n            └── release\n    - Ensure that the directory which contains the JRE is named \"jdk-21.0.5+11-jre\"\n\n- Finally, to verify whether Ballerina is installed properly, you can run the `bal version` command. If Ballerina was installed correctly, you should see an output similar to the following:\n    $ bal version\n    Ballerina Swan Lake Alpha 1\n    Language specification v2020-12-17\n    Update Tool 0.8.14\n\n\nINSTALLING THE VS CODE PLUGIN\n-----------------------------\n\n- The VS Code plugin for Ballerina can be installed through the VS Code Marketplace. Look up \"Ballerina\" in the Marketplace and you should get the download page for the Ballerina plugin.\n\n** Note **: For the VS Code plugin to work, the BALLERINA_HOME environment variable should be set and the <BALLERINA_HOME>/bin added to the path variable of the system.\n\n\nDOCUMENTATION\n-------------\n\nThe following resources should help you get up and running with Ballerina:\n\n- Ballerina by Example: https://ballerina.io/learn/by-example\n\n- Ballerina How-To guides: https://ballerina.io/learn/\n\n- Ballerina standard library API docs: https://ballerina.io/learn/api-docs/ballerina\n\n- Ballerina language specification: https://ballerina.io/spec\n"
  },
  {
    "path": "resources/tools/LICENSE.txt",
    "content": "                                 Apache License\r\n                           Version 2.0, January 2004\r\n                        http://www.apache.org/licenses/\r\n\r\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction,\r\n      and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by\r\n      the copyright owner that is granting the License.\r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all\r\n      other entities that control, are controlled by, or are under common\r\n      control with that entity. For the purposes of this definition,\r\n      \"control\" means (i) the power, direct or indirect, to cause the\r\n      direction or management of such entity, whether by contract or\r\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n      outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n      exercising permissions granted by this License.\r\n\r\n      \"Source\" form shall mean the preferred form for making modifications,\r\n      including but not limited to software source code, documentation\r\n      source, and configuration files.\r\n\r\n      \"Object\" form shall mean any form resulting from mechanical\r\n      transformation or translation of a Source form, including but\r\n      not limited to compiled object code, generated documentation,\r\n      and conversions to other media types.\r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or\r\n      Object form, made available under the License, as indicated by a\r\n      copyright notice that is included in or attached to the work\r\n      (an example is provided in the Appendix below).\r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object\r\n      form, that is based on (or derived from) the Work and for which the\r\n      editorial revisions, annotations, elaborations, or other modifications\r\n      represent, as a whole, an original work of authorship. For the purposes\r\n      of this License, Derivative Works shall not include works that remain\r\n      separable from, or merely link (or bind by name) to the interfaces of,\r\n      the Work and Derivative Works thereof.\r\n\r\n      \"Contribution\" shall mean any work of authorship, including\r\n      the original version of the Work and any modifications or additions\r\n      to that Work or Derivative Works thereof, that is intentionally\r\n      submitted to Licensor for inclusion in the Work by the copyright owner\r\n      or by an individual or Legal Entity authorized to submit on behalf of\r\n      the copyright owner. For the purposes of this definition, \"submitted\"\r\n      means any form of electronic, verbal, or written communication sent\r\n      to the Licensor or its representatives, including but not limited to\r\n      communication on electronic mailing lists, source code control systems,\r\n      and issue tracking systems that are managed by, or on behalf of, the\r\n      Licensor for the purpose of discussing and improving the Work, but\r\n      excluding communication that is conspicuously marked or otherwise\r\n      designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n      on behalf of whom a Contribution has been received by Licensor and\r\n      subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      copyright license to reproduce, prepare Derivative Works of,\r\n      publicly display, publicly perform, sublicense, and distribute the\r\n      Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      (except as stated in this section) patent license to make, have made,\r\n      use, offer to sell, sell, import, and otherwise transfer the Work,\r\n      where such license applies only to those patent claims licensable\r\n      by such Contributor that are necessarily infringed by their\r\n      Contribution(s) alone or by combination of their Contribution(s)\r\n      with the Work to which such Contribution(s) was submitted. If You\r\n      institute patent litigation against any entity (including a\r\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n      or a Contribution incorporated within the Work constitutes direct\r\n      or contributory patent infringement, then any patent licenses\r\n      granted to You under this License for that Work shall terminate\r\n      as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the\r\n      Work or Derivative Works thereof in any medium, with or without\r\n      modifications, and in Source or Object form, provided that You\r\n      meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or\r\n          Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices\r\n          stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works\r\n          that You distribute, all copyright, patent, trademark, and\r\n          attribution notices from the Source form of the Work,\r\n          excluding those notices that do not pertain to any part of\r\n          the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its\r\n          distribution, then any Derivative Works that You distribute must\r\n          include a readable copy of the attribution notices contained\r\n          within such NOTICE file, excluding those notices that do not\r\n          pertain to any part of the Derivative Works, in at least one\r\n          of the following places: within a NOTICE text file distributed\r\n          as part of the Derivative Works; within the Source form or\r\n          documentation, if provided along with the Derivative Works; or,\r\n          within a display generated by the Derivative Works, if and\r\n          wherever such third-party notices normally appear. The contents\r\n          of the NOTICE file are for informational purposes only and\r\n          do not modify the License. You may add Your own attribution\r\n          notices within Derivative Works that You distribute, alongside\r\n          or as an addendum to the NOTICE text from the Work, provided\r\n          that such additional attribution notices cannot be construed\r\n          as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and\r\n      may provide additional or different license terms and conditions\r\n      for use, reproduction, or distribution of Your modifications, or\r\n      for any such Derivative Works as a whole, provided Your use,\r\n      reproduction, and distribution of the Work otherwise complies with\r\n      the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise,\r\n      any Contribution intentionally submitted for inclusion in the Work\r\n      by You to the Licensor shall be under the terms and conditions of\r\n      this License, without any additional terms or conditions.\r\n      Notwithstanding the above, nothing herein shall supersede or modify\r\n      the terms of any separate license agreement you may have executed\r\n      with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade\r\n      names, trademarks, service marks, or product names of the Licensor,\r\n      except as required for reasonable and customary use in describing the\r\n      origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or\r\n      agreed to in writing, Licensor provides the Work (and each\r\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n      implied, including, without limitation, any warranties or conditions\r\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n      PARTICULAR PURPOSE. You are solely responsible for determining the\r\n      appropriateness of using or redistributing the Work and assume any\r\n      risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory,\r\n      whether in tort (including negligence), contract, or otherwise,\r\n      unless required by applicable law (such as deliberate and grossly\r\n      negligent acts) or agreed to in writing, shall any Contributor be\r\n      liable to You for damages, including any direct, indirect, special,\r\n      incidental, or consequential damages of any character arising as a\r\n      result of this License or out of the use or inability to use the\r\n      Work (including but not limited to damages for loss of goodwill,\r\n      work stoppage, computer failure or malfunction, or any and all\r\n      other commercial damages or losses), even if such Contributor\r\n      has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing\r\n      the Work or Derivative Works thereof, You may choose to offer,\r\n      and charge a fee for, acceptance of support, warranty, indemnity,\r\n      or other liability obligations and/or rights consistent with this\r\n      License. However, in accepting such obligations, You may act only\r\n      on Your own behalf and on Your sole responsibility, not on behalf\r\n      of any other Contributor, and only if You agree to indemnify,\r\n      defend, and hold each Contributor harmless for any liability\r\n      incurred by, or claims asserted against, such Contributor by reason\r\n      of your accepting any such warranty or additional liability.\r\n\r\n   END OF TERMS AND CONDITIONS\r\n\r\n   APPENDIX: How to apply the Apache License to your work.\r\n\r\n      To apply the Apache License to your work, attach the following\r\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\r\n      replaced with your own identifying information. (Don't include\r\n      the brackets!)  The text should be enclosed in the appropriate\r\n      comment syntax for the file format. We also recommend that a\r\n      file or class name and description of purpose be included on the\r\n      same \"printed page\" as the copyright notice for easier\r\n      identification within third-party archives.\r\n\r\n   Copyright {yyyy} {name of copyright owner}\r\n\r\n   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n   you may not use this file except in compliance with the License.\r\n   You may obtain a copy of the License at\r\n\r\n       http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n   Unless required by applicable law or agreed to in writing, software\r\n   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n   See the License for the specific language governing permissions and\r\n   limitations under the License.\r\n"
  },
  {
    "path": "resources/tools/PATENTS.txt",
    "content": "Additional IP Rights Grant (Patents)\r\n\r\n\"This implementation\" means the copyrightable works distributed by\r\nWSO2 as part of the Ballerina project.\r\n\r\nWSO2 hereby grants to You a perpetual, worldwide, non-exclusive,\r\nno-charge, royalty-free, irrevocable (except as stated in this section)\r\npatent license to make, have made, use, offer to sell, sell, import,\r\ntransfer and otherwise run, modify and propagate the contents of this\r\nimplementation of Ballerina, where such license applies only to those patent\r\nclaims, both currently owned or controlled by WSO2 and acquired in\r\nthe future, licensable by WSO2 that are necessarily infringed by this\r\nimplementation of Ballerina.  This grant does not include claims that would be\r\ninfringed only as a consequence of further modification of this\r\nimplementation.  If you or your agent or exclusive licensee institute or\r\norder or agree to the institution of patent litigation against any\r\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\r\nthat this implementation of Ballerina or any code incorporated within this\r\nimplementation of Ballerina constitutes direct or contributory patent\r\ninfringement, or inducement of patent infringement, then any patent\r\nrights granted to you under this License for this implementation of Ballerina\r\nshall terminate as of the date such litigation is filed.\r\n"
  },
  {
    "path": "resources/tools/README.txt",
    "content": "=========\nBALLERINA\n=========\n\n\nDESCRIPTION\n-----------\n\nBallerina is an open source programming language and platform for cloud-era application programmers to easily write\nsoftware that just works.\n\n\nINSTALLATION\n------------\n\nFor information on how to install and set up Ballerina, refer to the INSTALL.txt file in the Ballerina home directory.\n\n\nUSAGE\n-----\n\nOnce you have installed Ballerina, you can open a terminal and run the `bal` command to use Ballerina. Try running\n`bal version` to verify that everything is in order. You should see an output similar to the following:\n    $ bal version\n    jBallerina 1.1.0\n    Language specification 2019R3\n    Ballerina tool 0.8.0\n\nRun `bal help` for more information on the commands and the options available.\n\nCheck out our quick tour guide (https://ballerina.io/learn/quick-tour/) to get up and running with Ballerina in no time.\n\n\nSUPPORT\n-------\n\nIf you run in to any problems while using Ballerina, you can use the following mediums to raise your issues and get them\nresolved.\n\n- Discord server: https://discord.gg/ballerinalang\n- Stackoverflow: https://stackoverflow.com/questions/tagged/ballerina\n- Ballerina developer group: https://groups.google.com/forum/#!forum/ballerina-dev\n- Ballerina Github repository: https://github.com/ballerina-platform/ballerina-lang\n- Ballerina Twitter handle: https://twitter.com/ballerinalang\n"
  },
  {
    "path": "resources/tools/distributions/ballerina-version",
    "content": "ballerina-@version@\n"
  },
  {
    "path": "resources/tools/distributions/installer-version",
    "content": "@uuid@\n"
  },
  {
    "path": "resources/tools/scripts/install",
    "content": "#!/bin/bash\n# ---------------------------------------------------------------------------\n#  Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n#\n#  Licensed under the Apache License, Version 2.0 (the \"License\");\n#  you may not use this file except in compliance with the License.\n#  You may obtain a copy of the License at\n#\n#  http://www.apache.org/licenses/LICENSE-2.0\n#\n#  Unless required by applicable law or agreed to in writing, software\n#  distributed under the License is distributed on an \"AS IS\" BASIS,\n#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#  See the License for the specific language governing permissions and\n#  limitations under the License.\n\nif [ \"$(uname)\" == \"Darwin\" ]\nthen\n    CURRENT_PATH=$(dirname \"$0\")\nelse\n    CURRENT_PATH=\"$(dirname \"$(readlink -f \"$0\")\")\"\nfi\n\n\\cp $CURRENT_PATH/ballerina-command-@ballerinaCommandVersion@/lib/ballerina-command-@ballerinaCommandVersion@.jar $CURRENT_PATH/../lib\n\nif [ $? -ne '0' ]; then\n  echo \"error occurred while copying ballerina jar\"\n  # remove if copied with an error.\n  if [ -f \"$CURRENT_PATH/../lib/ballerina-command-@ballerinaCommandVersion@.jar\" ]; then\n        rm -rf $CURRENT_PATH/../lib/ballerina-command-@ballerinaCommandVersion@.jar\n  fi\n  exit $?\nfi\n\n\\cp $CURRENT_PATH/ballerina-command-@ballerinaCommandVersion@/bin/bal $CURRENT_PATH/../bin\n\nif [ $? -ne '0' ]; then\n  echo \"error occurred while copying ballerina file.\"\n  # remove already copied jar.\n  if [ -f \"$CURRENT_PATH/../lib/ballerina-command-@ballerinaCommandVersion@.jar\" ]; then\n        rm -rf $CURRENT_PATH/../lib/ballerina-command-@ballerinaCommandVersion@.jar\n  fi\n  exit $?\nfi\n\necho \"Tool version updated to the latest version: @ballerinaCommandVersion@\"\necho \"Cleaning old files...\"\n\nfor file in $CURRENT_PATH/../lib/*; do\n    if [ -f \"$file\" ] && [[ \"$file\" == *ballerina-command*.jar ]] && [[ \"$file\" != *ballerina-command-@ballerinaCommandVersion@.jar ]]; then\n\trm -rf $file\n    fi\ndone\n"
  },
  {
    "path": "resources/tools/scripts/install.bat",
    "content": "@echo off\n\nREM ---------------------------------------------------------------------------\nREM  Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\nREM\nREM  WSO2 Inc. licenses this file to you under the Apache License,\nREM  Version 2.0 (the \"License\"); you may not use this file except\nREM  in compliance with the License.\nREM  You may obtain a copy of the License at\nREM\nREM      http://www.apache.org/licenses/LICENSE-2.0\nREM\nREM  Unless required by applicable law or agreed to in writing,\nREM  software distributed under the License is distributed on an\nREM  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nREM  KIND, either express or implied. See the License for the\nREM  specific language governing permissions and limitations\nREM  under the License.\nREM ---------------------------------------------------------------------------\n\nsetlocal\nset CURRENT_PATH=%~sdp0\n\nxcopy /q %CURRENT_PATH%\\ballerina-command-@ballerinaCommandVersion@\\lib\\ballerina-command-@ballerinaCommandVersion@.jar  %CURRENT_PATH%\\..\\lib /Y\n\nif %errorlevel% neq 0 (\n    echo error occurred while copying ballerina jar\n    REM remove if copied with an error.\n    if exist %CURRENT_PATH%\\..\\lib\\ballerina-command-@ballerinaCommandVersion@.jar (\n        del /F/Q %CURRENT_PATH%\\..\\lib\\ballerina-command-@ballerinaCommandVersion@.jar\n    )\n    exit /b %errorlevel%\n)\n\nxcopy /q %CURRENT_PATH%\\ballerina-command-@ballerinaCommandVersion@\\bin\\bal.bat  %CURRENT_PATH%\\..\\bin /Y\n\nif %errorlevel% neq 0 (\n    echo error occurred while copying ballerina.bat\n    REM remove if copied with an error.\n    if exist %CURRENT_PATH%\\..\\lib\\ballerina-command-@ballerinaCommandVersion@.jar (\n        del /F/Q %CURRENT_PATH%\\..\\lib\\ballerina-command-@ballerinaCommandVersion@.jar\n    )\n    exit /b %errorlevel%\n)\n\necho Tool version updated to the latest version: @ballerinaCommandVersion@\necho Cleaning old files...\n\nfor %%f in (%CURRENT_PATH%\\..\\lib\\*ballerina-command*.jar) do (\n\techo %%f|find /i \"ballerina-command-@ballerinaCommandVersion@.jar\">nul\n    \tif errorlevel 1 (\n\t   del /F/Q \"%%f\"\n\t)\n)\nexit /b\n"
  },
  {
    "path": "settings.gradle",
    "content": "/*\n * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nplugins {\n    id \"com.gradle.enterprise\" version \"3.13.2\"\n}\n\nrootProject.name = 'ballerina-distribution'\ninclude ':ballerina'\ninclude ':ballerina-distribution-test'\ninclude ':devtools-integration-tests'\ninclude ':project-api-tests'\ninclude 'dist-repo-builder'\ninclude 'build-time-tests'\ninclude 'cache-generator'\ninclude 'config:checkstyle'\n\nproject(':ballerina').projectDir = \"$rootDir/ballerina\" as File\nproject(':ballerina-distribution-test').projectDir = \"$rootDir/ballerina-test\" as File\nproject(':dist-repo-builder').projectDir = \"$rootDir/dist-repo-builder\" as File\nproject(':cache-generator').projectDir = \"$rootDir/cache-generator\" as File\nproject(':config').projectDir = \"$rootDir config\" as File\n\ngradleEnterprise {\n    buildScan {\n        termsOfServiceUrl = 'https://gradle.com/terms-of-service'\n        termsOfServiceAgree = 'yes'\n    }\n}\ninclude 'language-server-simulator'\n\n"
  },
  {
    "path": "stdlib-integration-tests/auth/tests/Config.toml",
    "content": "[[ballerina.auth.users]]\nusername=\"alice\"\npassword=\"alice@123\"\nscopes=[\"admin\", \"developer\"]\n\n[[ballerina.auth.users]]\nusername=\"bob\"\npassword=\"bob@123\"\nscopes=[\"developer\"]\n"
  },
  {
    "path": "stdlib-integration-tests/auth/tests/auth_test.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/test;\n\nlistener http:Listener authListener = new(25001, {\n    secureSocket: {\n        key: {\n            path: \"tests/resources/keystore/ballerinaKeystore.p12\",\n            password: \"ballerina\"\n        }\n    }\n});\n\n@http:ServiceConfig {\n    auth: [\n        {\n            fileUserStoreConfig: {},\n            scopes: [\"admin\"]\n        }\n    ]\n}\nservice /foo on authListener {\n    resource function get bar() returns string {\n        return \"Hello World!\";\n    }\n}\n\n@test:Config {}\npublic function testAuthModuleFileUserStore1() {\n    http:Client clientEP = checkpanic new(\"https://localhost:25001\", {\n        secureSocket: {\n           cert: {\n               path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n               password: \"ballerina\"\n           }\n        },\n        auth: {\n            username: \"alice\",\n            password: \"alice@123\"\n        }\n    });\n    http:Response|http:ClientError response = clientEP->get(\"/foo/bar\");\n    if (response is http:Response) {\n        assertOK(response);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n\n@test:Config {}\npublic function testAuthModuleFileUserStore2() {\n    http:Client clientEP = checkpanic new(\"https://localhost:25001\", {\n        secureSocket: {\n           cert: {\n               path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n               password: \"ballerina\"\n           }\n        },\n        auth: {\n            username: \"bob\",\n            password: \"bob@123\"\n        }\n    });\n    http:Response|http:ClientError response = clientEP->get(\"/foo/bar\");\n    if (response is http:Response) {\n        assertForbidden(response);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n\n@test:Config {}\npublic function testAuthModuleFileUserStore3() {\n    http:Client clientEP = checkpanic new(\"https://localhost:25001\", {\n        secureSocket: {\n           cert: {\n               path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n               password: \"ballerina\"\n           }\n        },\n        auth: {\n            username: \"eve\",\n            password: \"eve@123\"\n        }\n    });\n    http:Response|http:ClientError response = clientEP->get(\"/foo/bar\");\n    if (response is http:Response) {\n        assertUnauthorized(response);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n\nfunction assertOK(http:Response res) {\n    test:assertEquals(res.statusCode, http:STATUS_OK, msg = \"Response code mismatched\");\n}\n\nfunction assertUnauthorized(http:Response res) {\n    test:assertEquals(res.statusCode, http:STATUS_UNAUTHORIZED, msg = \"Response code mismatched\");\n}\n\nfunction assertForbidden(http:Response res) {\n    test:assertEquals(res.statusCode, http:STATUS_FORBIDDEN, msg = \"Response code mismatched\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/crypto/tests/crypto_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/crypto;\nimport ballerina/test;\n\n@test:Config {}\nfunction testDecodePrivateKey() {\n    crypto:KeyStore keyStore = {\n        path: \"tests/resources/keystore/ballerinaKeystore.p12\",\n        password: \"ballerina\"\n    };\n    var result = crypto:decodeRsaPrivateKeyFromKeyStore(keyStore, \"ballerina\", \"ballerina\");\n    if (result is crypto:PrivateKey) {\n        test:assertEquals(result.algorithm, \"RSA\", msg = \"Invalid algorithm of decoded private key.\");\n    } else {\n        test:assertFail(msg = \"Test Failed! \" + <string>result.message());\n    }\n}\n\n@test:Config {}\nfunction testDecodePublicKey() {\n    crypto:TrustStore truststore = {\n        path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n        password: \"ballerina\"\n    };\n    var result = crypto:decodeRsaPublicKeyFromTrustStore(truststore, \"ballerina\");\n    if (result is crypto:PublicKey) {\n        test:assertEquals(result.algorithm, \"RSA\", msg = \"Invalid algorithm of decoded public key.\");\n    } else {\n        test:assertFail(msg = \"Test Failed! \" + <string>result.message());\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/email/tests/email_test.bal",
    "content": "import ballerina/email;\nimport ballerina/test;\n\n@test:Config {}\nfunction testEmail() returns @tainted error?{\n    email:SmtpClient smtpClient = check new (\"smtp.email.com\", \"sender@email.com\"\n        , \"pass123\");\n    email:Message email = {\n        to: [\"receiver1@email.com\", \"receiver2@email.com\"],\n        cc: [\"receiver3@email.com\", \"receiver4@email.com\"],\n        bcc: [\"receiver5@email.com\"],\n        subject: \"Sample Email\",\n        body: \"This is a sample email.\",\n        'from: \"author@email.com\",\n        sender: \"sender@email.com\",\n        replyTo: [\"replyTo1@email.com\", \"replyTo2@email.com\"]\n    };\n    test:assertEquals(email.subject, \"Sample Email\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/ftp/tests/ftp_test.bal",
    "content": "import ballerina/ftp;\nimport ballerina/test;\n\n@test:Config {}\nfunction testFtp() {\n    ftp:ClientEndpointConfig config = {\n            protocol: ftp:FTP,\n            host: \"127.0.0.1\",\n            port: 21212,\n            secureSocket: {\n                basicAuth: {\n                    username: \"wso2\",\n                    password: \"wso2123\"\n                }\n            }\n    };\n    test:assertEquals(config.host, \"127.0.0.1\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/http/tests/http_1_1_passthrough_test.bal",
    "content": "\n// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/lang.'string as strings;\nimport ballerina/mime;\nimport ballerina/test;\n\nlistener http:Listener passthroughEP1 = new(9113);\n\nservice http:Service /passthrough on passthroughEP1 {\n\n    resource function get .(http:Request clientRequest) returns http:Response|http:InternalServerError|error {\n        http:Client nyseEP1 = check new(\"http://localhost:9113\");\n        http:Response|error response = nyseEP1->get(\"/nyseStock/stocks\");\n        if (response is http:Response) {\n            return response;\n        } else {\n            return { body: \"error occurred while invoking the service\" };\n        }\n    }\n\n    resource function post forwardMultipart(http:Request clientRequest) returns http:Response|http:InternalServerError|error {\n        http:Client nyseEP1 = check new(\"http://localhost:9113\");\n        http:Response|error response = nyseEP1->forward(\"/nyseStock/stocksAsMultiparts\", clientRequest);\n        if (response is http:Response) {\n            return response;\n        } else {\n            return { body: \"error occurred while invoking the service\" };\n        }\n    }\n\n    resource function post forward(http:Request clientRequest) returns http:Ok|http:InternalServerError|error {\n        http:Client nyseEP1 = check new(\"http://localhost:9113\");\n        http:Response|error response = nyseEP1->forward(\"/nyseStock/entityCheck\", clientRequest);\n        if (response is http:Response) {\n            var entity = response.getEntity();\n            if (entity is mime:Entity) {\n                string|error payload = entity.getText();\n                if (payload is string) {\n                    http:Ok ok = {body: payload + \", \" + checkpanic entity.getHeader(\"X-check-header\")};\n                    return ok;\n                } else {\n                    http:InternalServerError err = {body: payload.toString()};\n                    return err;\n                }\n            } else {\n                http:InternalServerError err = {body: entity.toString()};\n                return err;\n            }\n        } else {\n            http:InternalServerError err = {body: response.toString()};\n            return err;\n        }\n    }\n}\n\nservice http:Service /nyseStock on passthroughEP1 {\n\n    resource function get stocks() returns json {\n        return { \"exchange\": \"nyse\", \"name\": \"IBM\", \"value\": \"127.50\" };\n    }\n\n    resource function post stocksAsMultiparts(http:Caller caller, http:Request clientRequest) returns error? {\n        mime:Entity[] bodyParts = check clientRequest.getBodyParts();\n        check caller->respond(bodyParts);\n    }\n\n    resource function post entityCheck(http:Request clientRequest) returns http:Response|http:InternalServerError|error? {\n        http:Response res = new;\n        var entity = clientRequest.getEntity();\n        if (entity is mime:Entity) {\n            json|error textPayload = entity.getText();\n            if (textPayload is string) {\n                mime:Entity mimeEntity = new;\n                mimeEntity.setText(\"payload :\" + textPayload + \", header: \" + check entity.getHeader(\"Content-type\"));\n                mimeEntity.setHeader(\"X-check-header\", \"entity-check-header\");\n                res.setEntity(mimeEntity);\n                return res;\n            }\n            return {body: \"Error while retrieving from entity\"};\n        }\n        return {body: \"Error while retrieving from request\"};\n    }\n}\n\n@test:Config {}\npublic function testPassthroughServiceByBasePath() returns error? {\n    http:Client httpClient = check new(\"http://localhost:9113\");\n    json resp = check httpClient->get(\"/passthrough\");\n    test:assertEquals(resp, {\"exchange\":\"nyse\", \"name\":\"IBM\", \"value\":\"127.50\"});\n}\n\n@test:Config {}\npublic function testPassthroughServiceWithMimeEntity() returns error?  {\n    http:Client httpClient = checkpanic new(\"http://localhost:9113\");\n    string resp = check httpClient->post(\"/passthrough/forward\", \"Hello from POST!\");\n    test:assertEquals(resp, \"payload :Hello from POST!, header: text/plain, entity-check-header\");\n}\n\n@test:Config {}\npublic function testPassthroughWithMultiparts() {\n    http:Client httpClient = checkpanic new(\"http://localhost:9113\");\n    mime:Entity textPart1 = new;\n    textPart1.setText(\"Part1\");\n    textPart1.setHeader(\"Content-Type\", \"text/plain; charset=UTF-8\");\n\n    mime:Entity textPart2 = new;\n    textPart2.setText(\"Part2\");\n    textPart2.setHeader(\"Content-Type\", \"text/plain\");\n\n    mime:Entity[] bodyParts = [textPart1, textPart2];\n    http:Request request = new;\n    request.setBodyParts(bodyParts, contentType = mime:MULTIPART_FORM_DATA);\n    http:Response|error resp = httpClient->post(\"/passthrough/forwardMultipart\", request);\n    if (resp is http:Response) {\n        string contentType = checkpanic resp.getHeader(\"content-type\");\n        test:assertTrue(strings:includes(contentType, \"multipart/form-data\"));\n        var respBodyParts = resp.getBodyParts();\n        if (respBodyParts is mime:Entity[]) {\n            test:assertEquals(respBodyParts.length(), 2);\n            string|error textPart = respBodyParts[0].getText();\n            if (textPart is string) {\n                test:assertEquals(textPart, \"Part1\");\n            } else {\n                test:assertFail(msg = \"Found an unexpected output: \" + textPart.message());\n            }\n            string|error txtPart2 = respBodyParts[1].getText();\n            if (txtPart2 is string) {\n                test:assertEquals(txtPart2, \"Part2\");\n            } else {\n                test:assertFail(msg = \"Found an unexpected output: \" + txtPart2.message());\n            }\n        }\n    } else {\n        test:assertFail(msg = \"Found unexpected output: \" +  resp.message());\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/http/tests/http_2_0_server_push_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/io;\nimport ballerina/lang.'string as strings;\nimport ballerina/test;\n\nlistener http:Listener serverPushFrontendEP = new(9115);\nlistener http:Listener serverPushBackendEP = new(9116, { httpVersion: \"2.0\" });\n\nhttp:Client serverPushClient = checkpanic new(\"http://localhost:9115\");\nhttp:Client backendClientEP = checkpanic new(\"http://localhost:9116\", { httpVersion: \"2.0\" });\n\nservice /frontend on serverPushFrontendEP {\n\n    resource function get .(http:Caller caller, http:Request clientRequest) {\n\n        http:Request serviceReq = new;\n        http:HttpFuture httpFuture = new;\n        // Submit a request\n        http:HttpFuture|http:ClientError submissionResult = backendClientEP->submit(\"GET\", \"/backend/main\", serviceReq);\n        if (submissionResult is http:HttpFuture) {\n            httpFuture = submissionResult;\n        } else {\n            io:println(\"Error occurred while submitting a request\");\n            json errMsg = { \"error\": \"error occurred while submitting a request\" };\n            checkpanic caller->respond(errMsg);\n            return;\n        }\n\n        // Check whether promises exists\n        http:PushPromise?[] promises = [];\n        int promiseCount = 0;\n        boolean hasPromise = backendClientEP->hasPromise(httpFuture);\n        while (hasPromise) {\n            http:PushPromise pushPromise = new;\n            // Get the next promise\n            http:PushPromise|http:ClientError nextPromiseResult = backendClientEP->getNextPromise(httpFuture);\n            if (nextPromiseResult is http:PushPromise) {\n                pushPromise = nextPromiseResult;\n            } else {\n                io:println(\"Error occurred while fetching a push promise\");\n                json errMsg = { \"error\": \"error occurred while fetching a push promise\" };\n                checkpanic caller->respond(errMsg);\n                return;\n            }\n\n            io:println(\"Received a promise for \" + pushPromise.path);\n            // Store required promises\n            promises[promiseCount] = pushPromise;\n            promiseCount = promiseCount + 1;\n            hasPromise = backendClientEP->hasPromise(httpFuture);\n        }\n        // By this time 3 promises should be received, if not send an error response\n        if (promiseCount != 3) {\n            json errMsg = { \"error\": \"expected number of promises not received\" };\n            checkpanic caller->respond(errMsg);\n            return;\n        }\n        io:println(\"Number of promises received : \" + promiseCount.toString());\n\n        // Get the requested resource\n        http:Response response = new;\n        http:Response|http:ClientError result = backendClientEP->getResponse(httpFuture);\n        if (result is http:Response) {\n            response = result;\n        } else {\n            io:println(\"Error occurred while fetching response\");\n            json errMsg = { \"error\": \"error occurred while fetching response\" };\n            checkpanic caller->respond(errMsg);\n            return;\n        }\n\n        var responsePayload = response.getJsonPayload();\n        json responseJsonPayload = {};\n        if (responsePayload is json) {\n            responseJsonPayload = responsePayload;\n        } else {\n            json errMsg = { \"error\": \"expected response message not received\" };\n            checkpanic caller->respond(errMsg);\n            return;\n        }\n        // Check whether correct response received\n        string responseStringPayload = responseJsonPayload.toString();\n        if (!(strings:includes(responseStringPayload, \"main\"))) {\n            json errMsg = { \"error\": \"expected response message not received\" };\n            checkpanic caller->respond(errMsg);\n            return;\n        }\n        io:println(\"Response : \" + responseStringPayload);\n\n        // Fetch required promised responses\n        foreach var p in promises {\n            http:PushPromise promise = <http:PushPromise>p;\n            http:Response promisedResponse = new;\n            http:Response|http:ClientError promisedResponseResult = backendClientEP->getPromisedResponse(promise);\n            if (promisedResponseResult is http:Response) {\n                promisedResponse = promisedResponseResult;\n            } else {\n                io:println(\"Error occurred while fetching promised response\");\n                json errMsg = { \"error\": \"error occurred while fetching promised response\" };\n                checkpanic caller->respond(errMsg);\n                return;\n            }\n\n            json promisedJsonPayload = {};\n            var promisedPayload = promisedResponse.getJsonPayload();\n            if (promisedPayload is json) {\n                promisedJsonPayload = promisedPayload;\n            } else {\n                json errMsg = { \"error\": \"expected promised response not received\" };\n                checkpanic caller->respond(errMsg);\n                return;\n            }\n\n            // check whether expected\n            string expectedVal = promise.path.substring(1, 10);\n            string promisedStringPayload = promisedJsonPayload.toString();\n            if (!(strings:includes(promisedStringPayload, expectedVal))) {\n                json errMsg = { \"error\": \"expected promised response not received\" };\n                checkpanic caller->respond(errMsg);\n                return;\n            }\n            io:println(\"Promised resource : \" + promisedStringPayload);\n        }\n\n        // By this time everything has went well, hence send a success response\n        json successMsg = { \"status\": \"successful\" };\n        checkpanic caller->respond(successMsg);\n    }\n}\n\nservice /backend on serverPushBackendEP {\n\n    resource function get main(http:Caller caller, http:Request req) {\n\n        io:println(\"Request received\");\n\n        // Send a Push Promise\n        http:PushPromise promise1 = new(\"/resource1\", \"POST\");\n        checkpanic caller->promise(promise1);\n\n        // Send another Push Promise\n        http:PushPromise promise2 = new(\"/resource2\", \"POST\");\n        checkpanic caller->promise(promise2);\n\n        // Send one more Push Promise\n        http:PushPromise promise3 = new;\n        // create with default params\n        promise3.path = \"/resource3\";\n        // set parameters\n        promise3.method = \"POST\";\n        checkpanic caller->promise(promise3);\n\n        // Construct requested resource\n        json msg = { \"response\": { \"name\": \"main resource\" } };\n\n        // Send the requested resource\n        checkpanic caller->respond(msg);\n\n        // Construct promised resource1\n        http:Response push1 = new;\n        msg = { \"push\": { \"name\": \"resource1\" } };\n        push1.setJsonPayload(msg);\n\n        // Push promised resource1\n        checkpanic caller->pushPromisedResponse(promise1, push1);\n\n        http:Response push2 = new;\n        msg = { \"push\": { \"name\": \"resource2\" } };\n        push2.setJsonPayload(msg);\n\n        // Push promised resource2\n        checkpanic caller->pushPromisedResponse(promise2, push2);\n\n        http:Response push3 = new;\n        msg = { \"push\": { \"name\": \"resource3\" } };\n        push3.setJsonPayload(msg);\n\n        // Push promised resource3\n        checkpanic caller->pushPromisedResponse(promise3, push3);\n    }\n}\n\n//Test HTTP/2.0 Server Push scenario\n@test:Config {}\nfunction testPushPromise() {\n    http:Response|error response = serverPushClient->get(\"/frontend\");\n    if (response is http:Response) {\n        test:assertEquals(response.statusCode, 200, msg = \"Found unexpected output\");\n        test:assertEquals(checkpanic response.getHeader(\"content-type\"), \"application/json\");\n        var payload = response.getJsonPayload();\n        if payload is json {\n            test:assertEquals(payload, {status:\"successful\"}, msg = \"Found unexpected output\");\n        } else {\n            test:assertFail(msg = \"Found unexpected output type: \" + payload.message());\n        }\n\n    } else {\n        test:assertFail(msg = \"Found unexpected output type: \" + (<error>response).message());\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/http/tests/rest_introspection_test.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/openapi;\nimport ballerina/test;\n\nlistener http:Listener restIntrospectionEP = new(9118);\n\n@openapi:ServiceInfo {\n  embed: true\n}\nservice /hello on restIntrospectionEP {\n    resource function get world() returns string {\n        return \"Hello, World!\";\n    }\n}\n\nhttp:Client restApiClient = checkpanic new(\"http://localhost:9118\");\n\n//Test Introspection Resource availability\n@test:Config {\n  enable: false\n}\nfunction testIntrospectionResourceAvailability() returns error? {\n    http:Response response = check restApiClient->options(\"/hello\");\n    test:assertEquals(response.statusCode, 204);\n    test:assertTrue(response.hasHeader(\"Link\"), \"Could not find the Link header\");\n    string linkHeader = check response.getHeader(\"Link\");\n    test:assertEquals(linkHeader, \"</hello/openapi-doc-dygixywsw>;rel=\\\"service-desc\\\"\");\n}\n\njson openApiDocumentation = {\n  \"openapi\" : \"3.0.1\",\n  \"info\" : {\n    \"title\" : \"Hello\",\n    \"version\" : \"1.0.0\"\n  },\n  \"servers\" : [ {\n    \"url\" : \"{server}:{port}/hello\",\n    \"variables\" : {\n      \"server\" : {\n        \"default\" : \"http://localhost\"\n      },\n      \"port\" : {\n        \"default\" : \"9118\"\n      }\n    }\n  } ],\n  \"paths\" : {\n    \"/world\" : {\n      \"get\" : {\n        \"operationId\" : \"operation_get_/world\",\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"Ok\",\n            \"content\" : {\n              \"text/plain\" : {\n                \"schema\" : {\n                  \"type\" : \"string\"\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  },\n  \"components\" : { }\n};\n\n//Test REST API Doc\n@test:Config {\n  enable: false\n}\nfunction testRestApiDoc() returns error? {\n    json receivedApiDoc = check restApiClient->get(\"/hello/openapi-doc-dygixywsw\");\n    test:assertEquals(receivedApiDoc, openApiDocumentation);\n}\n\nservice /disabled on restIntrospectionEP {\n    resource function get world() returns string {\n        return \"Hello, World!\";\n    }\n}\n\n@test:Config {}\nfunction testUnavailableIntrospectionResource() returns error? {\n    http:Response response = check restApiClient->options(\"/disabled\");\n    test:assertEquals(response.statusCode, 204);\n    test:assertFalse(response.hasHeader(\"Link\"), \"Found link header in errorneous scenario\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/index.json",
    "content": "[\n  {\n    \"name\": \"TCP standard library \",\n    \"path\": \"tcp\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Email standard library \",\n    \"path\": \"email\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"URL standard library \",\n    \"path\": \"url\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Crypto standard library \",\n    \"path\": \"crypto\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Auth standard library \",\n    \"path\": \"auth\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"JWT standard library \",\n    \"path\": \"jwt\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Task standard library \",\n    \"path\": \"task\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"OAuth2 standard library \",\n    \"path\": \"oauth2\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"HTTP standard library\",\n    \"path\": \"http\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"MIME standard library\",\n    \"path\": \"mime\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Websub start hub and register topic\",\n    \"path\": \"websub\",\n    \"enableTest\": false\n  },\n  {\n    \"name\": \"UDP standard library \",\n    \"path\": \"udp\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"WebSocket standard library\",\n    \"path\": \"websocket\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Transaction standard library\",\n    \"path\": \"transaction\",\n    \"enableTest\": true\n  },\n  {\n    \"name\": \"Library package test\",\n    \"path\": \"library_package_test\",\n    \"enableTest\": true\n  }\n]\n"
  },
  {
    "path": "stdlib-integration-tests/jwt/tests/jwt_test.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/test;\n\nlistener http:Listener jwtListener = new(25002, {\n    secureSocket: {\n        key: {\n            path: \"tests/resources/keystore/ballerinaKeystore.p12\",\n            password: \"ballerina\"\n        }\n    }\n});\n\n@http:ServiceConfig {\n    auth: [\n        {\n            scopes: [\"write\", \"update\"],\n            jwtValidatorConfig: {\n                issuer: \"wso2\",\n                audience: \"ballerina\",\n                signatureConfig: {\n                    trustStoreConfig: {\n                        trustStore: {\n                            path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n                            password: \"ballerina\"\n                        },\n                        certAlias: \"ballerina\"\n                    }\n                },\n                scopeKey: \"scp\"\n            }\n        }\n    ]\n}\nservice /foo on jwtListener {\n    resource function get bar() returns string {\n        return \"Hello World!\";\n    }\n}\n\nconst string JWT = \"eyJhbGciOiJSUzI1NiIsICJ0eXAiOiJKV1QiLCAia2lkIjoiTlRBeFptTXhORE15WkRnM01UVTFaR00wTXpFek9ESmhaV0k\" +\n                    \"0TkRObFpEVTFPR0ZrTmpGaU1RIn0.eyJzdWIiOiJhZG1pbiIsICJpc3MiOiJ3c28yIiwgImV4cCI6MTkyNTk1NTcyNCwgIm\" +\n                    \"p0aSI6IjEwMDA3ODIzNGJhMjMiLCAiYXVkIjpbImJhbGxlcmluYSJdLCAic2NwIjoid3JpdGUifQ.H99ufLvCLFA5i1gfCt\" +\n                    \"klVdPrBvEl96aobNvtpEaCsO4v6_EgEZYz8Pg0B1Y7yJPbgpuAzXEg_CzowtfCTu3jUFf5FH_6M1fWGko5vpljtCb5Xknt_\" +\n                    \"YPqvbk5fJbifKeXqbkCGfM9c0GS0uQO5ss8StquQcofxNgvImRV5eEGcDdybkKBNkbA-sJFHd1jEhb8rMdT0M0SZFLnhrPL\" +\n                    \"8edbFZ-oa-ffLLls0vlEjUA7JiOSpnMbxRmT-ac6QjPxTQgNcndvIZVP2BHueQ1upyNorFKSMv8HZpATYHZjgnJQSpmt3Oa\" +\n                    \"oFJ6pgzbFuniVNuqYghikCQIizqzQNfC7JUD8wA\";\n\n@test:Config {}\npublic function testJwtModule() {\n    http:Client clientEP = checkpanic new(\"https://localhost:25002\", {\n        secureSocket: {\n           cert: {\n               path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n               password: \"ballerina\"\n           }\n        },\n        auth: {\n            token: JWT\n        }\n    });\n    http:Response|http:ClientError response = clientEP->get(\"/foo/bar\");\n    if (response is http:Response) {\n        assertOK(response);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n\nfunction assertOK(http:Response res) {\n    test:assertEquals(res.statusCode, http:STATUS_OK, msg = \"Response code mismatched\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/library_package_test/Ballerina.toml",
    "content": "[package]\norg = \"wso2\"\nname = \"test_package\"\nversion = \"0.1.0\"\n\n[build-options]\noffline = true\n\n"
  },
  {
    "path": "stdlib-integration-tests/library_package_test/main.bal",
    "content": "// Copyright (c) 2026 WSO2 LLC. (http://www.wso2.com)\n//\n// WSO2 LLC. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\n\nimport ballerina/io as _;\nimport ballerina/jballerina.java.arrays as _;\nimport ballerina/math.vector as _;\nimport ballerina/persist as _;\nimport ballerina/time as _;\nimport ballerina/url as _;\nimport ballerina/avro as _;\nimport ballerina/constraint as _;\nimport ballerina/crypto as  _;\nimport ballerina/log as  _;\nimport ballerina/os as _;\nimport ballerina/protobuf as _;\nimport ballerina/random as  _;\nimport ballerina/xslt as  _;\nimport ballerina/data.yaml as _;\nimport ballerina/file as _;\nimport ballerina/ldap as _;\nimport ballerina/mime as _;\nimport ballerina/tcp as _;\nimport ballerina/udp as _;\nimport ballerina/uuid as _;\nimport ballerina/data.csv as _;\nimport ballerina/data.jsondata as _;\nimport ballerina/data.xmldata as _;\nimport ballerina/edi as _;\nimport ballerina/mqtt as _;\nimport ballerina/task as _;\nimport ballerina/toml as _;\nimport ballerina/yaml as _;\nimport ballerina/cache as _;\nimport ballerina/email as _;\nimport ballerina/ftp as _;\nimport ballerina/messaging as _;\nimport ballerina/auth as _;\nimport ballerina/jwt as _;\nimport ballerina/oauth2 as _;\nimport ballerina/http as _;\nimport ballerina/ai as _;\nimport ballerina/grpc as _;\nimport ballerina/soap as _;\nimport ballerina/websocket as _;\nimport ballerina/websub as _;\nimport ballerina/websubhub as _;\nimport ballerina/ai.np as _;\nimport ballerina/graphql as _;\nimport ballerina/sql as _;\nimport ballerina/openapi as _;\nimport ballerina/mcp as _;\n"
  },
  {
    "path": "stdlib-integration-tests/mime/tests/mime_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/mime;\nimport ballerina/test;\n\n@test:Config {}\nfunction testMimeFunctions() {\n    mime:Entity entity = new;\n    string entityBody = \"Hello Ballerina!\";\n    entity.setBody(entityBody);\n    var stringPayload = entity.getText();\n    if stringPayload is string {\n        test:assertEquals(stringPayload, entityBody, msg = \"Found unexpected output\");\n    } else {\n        test:assertFail(msg = \"Found unexpected output type\");\n    }\n\n    entity = new;\n    json jsonContent = {code:123};\n    entity.setHeader(\"content-type\", \"application/yang-patch+json\");\n    entity.setJson(jsonContent);\n    var JsonPayload = entity.getJson();\n    if JsonPayload is json {\n        test:assertEquals(JsonPayload, jsonContent, msg = \"Found unexpected output\");\n    } else {\n        test:assertFail(msg = \"Found unexpected output type\");\n    }\n    \n    string headerName = \"Content-Type\";\n    string headerValue = \"application/json\";\n    string headerNameToBeUsedForRetrieval = \"Content-Type\";\n    entity = new;\n    entity.addHeader(headerName, headerValue);\n    string returnVal = checkpanic entity.getHeader(headerNameToBeUsedForRetrieval);\n\n    test:assertEquals(returnVal, headerValue, msg = \"Found unexpected output\");\n\n}\n"
  },
  {
    "path": "stdlib-integration-tests/oauth2/tests/oauth2_test.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/test;\n\nlistener http:Listener oauth2Listener = new(25003, {\n    secureSocket: {\n        key: {\n            path: \"tests/resources/keystore/ballerinaKeystore.p12\",\n            password: \"ballerina\"\n        }\n    }\n});\n\n@http:ServiceConfig {\n    auth: [\n        {\n            scopes: [\"write\", \"update\"],\n            oauth2IntrospectionConfig: {\n                url: \"https://localhost:25999/oauth2/token/introspect\",\n                tokenTypeHint: \"access_token\",\n                scopeKey: \"scp\",\n                clientConfig: {\n                    secureSocket: {\n                       cert: {\n                           path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n                           password: \"ballerina\"\n                       }\n                    }\n                }\n            }\n        }\n    ]\n}\nservice /foo on oauth2Listener {\n    resource function get bar() returns string {\n        return \"Hello World!\";\n    }\n}\n\nconst string ACCESS_TOKEN = \"2YotnFZFEjr1zCsicMWpAA\";\n\n@test:Config {}\npublic function testOAuth2Module() {\n    http:Client clientEP = checkpanic new(\"https://localhost:25003\", {\n        secureSocket: {\n           cert: {\n               path: \"tests/resources/keystore/ballerinaTruststore.p12\",\n               password: \"ballerina\"\n           }\n        },\n        auth: {\n            token: ACCESS_TOKEN\n        }\n    });\n    http:Response|http:ClientError response = clientEP->get(\"/foo/bar\");\n    if (response is http:Response) {\n        assertOK(response);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n\nfunction assertOK(http:Response res) {\n    test:assertEquals(res.statusCode, http:STATUS_OK, msg = \"Response code mismatched\");\n}\n\n// Mock OAuth2 authorization server implementation, which treats the APIs with successful responses.\nlistener http:Listener authorizationServer = new(25999, {\n    secureSocket: {\n        key: {\n            path: \"tests/resources/keystore/ballerinaKeystore.p12\",\n            password: \"ballerina\"\n        }\n    }\n});\nservice /oauth2 on authorizationServer {\n    resource function post token/introspect(http:Request request) returns json {\n        string|http:ClientError payload = request.getTextPayload();\n        if (payload is string) {\n            string[] parts = re `&`.split(payload);\n            foreach string part in parts {\n                if (part.indexOf(\"token=\") is int) {\n                    string token = re `=`.split(part)[1];\n                    if (token == ACCESS_TOKEN) {\n                        json response = { \"active\": true, \"exp\": 3600, \"scp\": \"read write\" };\n                        return response;\n                    } else {\n                        json response = { \"active\": false };\n                        return response;\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/task/tests/http_service.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/lang.runtime;\nimport ballerina/task;\nimport ballerina/test;\nimport ballerina/time;\n\nconst HTTP_MESSAGE = \"Hello from http service\";\nconst TASK_MESSAGE = \"Hello from task service\";\n\nhttp:Client httpClient = check new (\"http://localhost:15001/HttpService\");\nlistener http:Listener backEndListener = new (15001);\nlistener http:Listener clientListener = new (15002);\n\nstring http_payload = \"\";\n\nservice / on clientListener {\n\n    resource function get .(http:Caller caller, http:Request request) returns error? {\n        var result = check caller->respond(http_payload);\n    }\n}\n\nservice /HttpService on backEndListener {\n\n    resource function post .(http:Caller caller, http:Request request) {\n        http:Response response = new;\n        var requestMessage = request.getTextPayload();\n        if (requestMessage is error) {\n            response.statusCode = 501;\n            response.setTextPayload(\"[HTTP Service] Failed to retrieve the request\");\n        } else {\n            if (requestMessage == TASK_MESSAGE) {\n                response.statusCode = 200;\n                response.setTextPayload(HTTP_MESSAGE);\n            } else {\n                response.statusCode = 400;\n                response.setTextPayload(\"[HTTP Service] Invalid Request Message Received\");\n            }\n        }\n        var result = caller->respond(response);\n        if (result is http:ListenerError) {\n            panic result;\n        }\n    }\n}\n\n@test:Config {}\nfunction testTaskWithHttpClient() returns error? {\n    http:Client multipleAttachmentClientEndpoint = check new (\"http://localhost:15002\");\n    time:Utc currentUtc = time:utcNow();\n    time:Utc newTime = time:utcAddSeconds(currentUtc, 1);\n    time:Civil time = time:utcToCivil(newTime);\n    task:JobId id = check task:scheduleJobRecurByFrequency(new Job(), 1, startTime = time);\n    runtime:sleep(4);\n    http:Response|http:ClientError response = multipleAttachmentClientEndpoint->get(\"/\");\n    if (response is http:Response) {\n        test:assertEquals(response.getTextPayload(), HTTP_MESSAGE, msg = \"Response payload mismatched\");\n    } else {\n        test:assertFail(msg = (<error>response).message());\n    }\n}\n\nclass Job {\n\n    *task:Job;\n\n    public function execute() {\n        http:Request request = new;\n        request.setTextPayload(TASK_MESSAGE);\n        http:Response|http:ClientError result = httpClient->post(\"/\", request);\n        if (result is http:ClientError) {\n            panic result;\n        } else {\n            if (result.statusCode == 200) {\n                var payload = result.getTextPayload();\n                if (payload is http:ClientError) {\n                    panic payload;\n                } else {\n                    http_payload = <@untainted string>payload;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/tcp/tests/mock_servers.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/tcp;\n\nconst int PORT1 = 8809;\nconst int PORT2 = 8023;\nconst int PORT3 = 8639;\nconst int PORT4 = 8475;\n\nstring keyPath = \"tests/resources/private.key\";\nstring certPath = \"tests/resources/public.crt\";\n\nlistener tcp:Listener echoServer = new tcp:Listener(PORT1);\nlistener tcp:Listener discardServer = new tcp:Listener(PORT2);\nlistener tcp:Listener closeServer = new tcp:Listener(PORT3);\n\nservice on echoServer {\n\n    isolated remote function onConnect(tcp:Caller caller) returns tcp:ConnectionService {\n        io:println(\"Client connected to echoServer: \", caller.remotePort);\n        return new EchoService();\n    }\n}\n\nservice class EchoService {\n    *tcp:ConnectionService;\n\n    remote function onBytes(tcp:Caller caller, readonly & byte[] data) returns tcp:Error? {\n        io:println(\"Echo: \", 'string:fromBytes(data));\n        return caller->writeBytes(data);\n    }\n\n    isolated remote function onError(tcp:Error err) {\n        io:println(err.message());\n    }\n\n    isolated remote function onClose() {\n        io:println(\"invoke on close\");\n    }\n}\n\n\nservice on discardServer {\n\n    isolated remote function onConnect(tcp:Caller caller) returns tcp:ConnectionService {\n        io:println(\"Client connected to discardServer: \", caller.remotePort);\n        return new DiscardService();\n    }\n}\n\nservice class DiscardService {\n    *tcp:ConnectionService;\n\n    remote function onBytes(readonly & byte[] data) {\n        // read and discard the message\n        io:println(\"Discard: \", 'string:fromBytes(data));\n    }\n}\n\nservice on closeServer {\n    isolated remote function onConnect(tcp:Caller caller) returns tcp:Error? {\n        io:println(\"Client connected to closeServer: \", caller.remotePort);\n        return caller->close();\n    }\n}\n\nservice on new tcp:Listener(PORT4, secureSocket = {\n    key: {\n        certFile: certPath,\n        keyFile: keyPath\n    },\n    protocol: {\n        name: tcp:TLS,\n        versions: [\"TLSv1.2\", \"TLSv1.1\"]\n    },\n    ciphers: [\"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA\"],\n    handshakeTimeout: 10\n}, localHost = \"localhost\") {\n\n    isolated remote function onConnect(tcp:Caller caller) returns tcp:ConnectionService {\n        io:println(\"Client connected to secureEchoServer: \", caller.remotePort);\n        return new SecureEchoService();\n    }\n}\n\nservice class SecureEchoService {\n    *tcp:ConnectionService;\n\n    remote function onBytes(readonly & byte[] data) returns byte[] {\n        io:println(\"Echo: \", 'string:fromBytes(data));\n        return data;\n    }\n\n    isolated remote function onError(tcp:Error err) {\n        io:println(err.message());\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/tcp/tests/resources/private.key",
    "content": "Bag Attributes\n    friendlyName: client\n    localKeyID: 54 69 6D 65 20 31 36 31 31 37 32 31 38 36 39 38 38 36 \nKey Attributes: <No Attributes>\n-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCLcLXa8m82YOJV\n8zKL9g6SkO66+1Vk+pGRdHoMWYhaXcg2Vc96NI+INATifZMe/xVd3sp286nOXR/T\nhKfHb1gTqmqSguhsbGJ0yl/ShO7Qwu1AB0TgMVef6izb/CiWUqrHQeJ5TzVBas6Q\nGR1Zc5jDDM9SqjTUitxdGRBMJ+n/CW+JICvqnxn1PVhZIadRksAyv+5P9xBg0EU7\nN6rbNZOTUOwxi01+D8nyW6TDz9SRW6GoaEjek5GLzSkRullAbVuoyqqlyT7SqMFP\nR++jRvwTq+zq0QLorVMtf1J0vdVpFR4uJRp3ZsHpxiGoJpltXsE9OjPvkVQUpTWV\n7Rb89ueNAgMBAAECggEBAIVZSnCSPEzSpmDv7LzwmMsNk2B5jxa8kY16yGUbEkzp\nNtjPg1UpAsKMjMdUs+eGphZZQ2Iyb4eMgy0yxYjyMFbOOJDYZBGcLSPnjW+z9Pbs\nExuSWAnW5idmOXQ/V0k60Vsw5LaCSzm+PMCNZAXxiHuvum0hnNhN26OknnNWEG72\nW7clr75VRnFVFqdoCOudLdbef0+HG/U4y0DSoLQByxD8kNr8FDB9jT8vbHXeqvfr\n3VfJCHIx1blDOi1glxLmiy5e79RWrPD2hJE930tvfgC1y9kcGtZvAZHKeJn4PgO6\nF9Nd5OYW/vWwYssZe6VHIJybuzAOhewxxZCxIMVik0ECgYEAvS4S4CJu8R3E0hyQ\nCCZEP9O5Jq8Ja2O2WjVUvbG9vdbCq68/HwSv3c6RlejbYIIZinL4BiIf9UXspjUh\nLPyEwUMKkbFwuDYEdAr5re83nVHJkCdHzXOs66S1/DhA/DQmd9dZdHzKh2kKXmZY\nbVz9eGAth9fkyANfwuvZSOadYUUCgYEAvLEZ5cW7sgigi6zggLUa8o+VSrAa5Wbj\n2hsksNyzFx6+VCZTA7B8TbGtqcN8+XxUp3qwEd7summ8dFFmM/y/bgKZgU2ogXuq\nK1UsZJSrqJLtm/DuxwPAdrF2BnICW9M8UyuIQlJ+3SqTMTWM43gHRJ3VmqboIj+G\n4GAmoyn3fakCgYBh1Ii4VbYvhGh7C4BEZp2WsEOoSI5Dda4gWkH3Uwo/OOc054xp\n2v+jYaaR8ng4IS9aFHhEm7MRINbvYLxGSlPQqX22uB8FdBG7fM1/cBy/g0MMA/Qy\nv+YleekOhHy+r61Q/hFplvsZKW3OQXjrHVKKxJnnDPNnp68G2vZjp7atTQKBgGNa\nrVQ7RZV8zWw+XwfmVIYb7HQjPkZEYv1ZBXzK+NHXskgE1fk/WHRgdhzJfmiverOk\n+kiupN+TBVQJ+FKvZuy6GbHn/i4Pu46Njo53adudYdeWiWPpKdJVptvF9E/9beot\nJdYmMf6qiE6E7+ZmMQ2EPhDsiZZe9Nn4Rt/rHRHhAoGABjXw6CZpTCWjE5aWABN4\nQBlzGXYt586UCl20v6qWs+DbjSL25BV0oXycBrUe5Mmcx2mN3zczWhcL2xGFe0vY\nFsBolkd0UrDKVDlt2IxR7FEYAjYCiTROqtGVC/4liaU4WPOXj2xzywpAqQh0onC8\nmk9VOWz0I9cxMx64mQ+blm8=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "stdlib-integration-tests/tcp/tests/resources/public.crt",
    "content": "Bag Attributes\n    friendlyName: client\n    localKeyID: 54 69 6D 65 20 31 36 31 31 37 32 31 38 36 39 38 38 36 \nsubject=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Unknown\n\nissuer=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Unknown\n\n-----BEGIN CERTIFICATE-----\nMIIDdzCCAl+gAwIBAgIEWN11KDANBgkqhkiG9w0BAQsFADBsMRAwDgYDVQQGEwdV\nbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD\nVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du\nMB4XDTIxMDEyNzA0MjkyNFoXDTIxMTEyMzA0MjkyNFowbDEQMA4GA1UEBhMHVW5r\nbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE\nChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAItwtdrybzZg4lXzMov2DpKQ\n7rr7VWT6kZF0egxZiFpdyDZVz3o0j4g0BOJ9kx7/FV3eynbzqc5dH9OEp8dvWBOq\napKC6GxsYnTKX9KE7tDC7UAHROAxV5/qLNv8KJZSqsdB4nlPNUFqzpAZHVlzmMMM\nz1KqNNSK3F0ZEEwn6f8Jb4kgK+qfGfU9WFkhp1GSwDK/7k/3EGDQRTs3qts1k5NQ\n7DGLTX4PyfJbpMPP1JFboahoSN6TkYvNKRG6WUBtW6jKqqXJPtKowU9H76NG/BOr\n7OrRAuitUy1/UnS91WkVHi4lGndmwenGIagmmW1ewT06M++RVBSlNZXtFvz2540C\nAwEAAaMhMB8wHQYDVR0OBBYEFEMEVsRz0vAu51x15LYY9bssZduHMA0GCSqGSIb3\nDQEBCwUAA4IBAQATFjwbhsPMBMBfnK1WKZ4qzW+0PieH5vFbV57bULkUaI6p0zSO\njQvOh3H8FRI06MaOolr40N/Mj/BkYjbYmYnSRTttRN5msgx6gcA+vUeo/j3ui3kI\nRD8NZjrwrFLfO3GsrfMnDzZWI2dNHjjAH3AI6gm5i7jiHk1FBFil1xYWwl7mRVpD\nEkkJHM4ET5jBIn01z01COiRZsggEbLDhLyCrwWT8i+8pnHADmlmHPjMDcX3oDqL6\nVRyk35BUG79ZZ5nbyMOBrV8znhTES1tb2rj1+RyAf8Yf9g4dpOvPGyXsvts4EIHu\nB0FZ0OJPxmYCstCcHZJc4oDZisF9OpFZyTyd\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "stdlib-integration-tests/tcp/tests/tcp_tests.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/test;\nimport ballerina/io;\nimport ballerina/tcp;\n\n@test:Config {}\nfunction testClientEcho() returns  @tainted error? {\n    tcp:Client socketClient = check new (\"localhost\", PORT1);\n\n    string msg = \"Hello Ballerina Echo from client\";\n    byte[] msgByteArray = msg.toBytes();\n    check  socketClient->writeBytes(msgByteArray);\n\n    readonly & byte[] receivedData = check socketClient->readBytes();\n    test:assertEquals(string:fromBytes(receivedData), msg, \"Found unexpected output\");\n\n    return socketClient->close();\n}\n\n@test:Config {\n    dependsOn: [testClientEcho]\n}\nfunction testClientReadTimeout() returns  @tainted error? {\n    tcp:Client socketClient = check new (\"localhost\", PORT2, timeout = 1);\n\n    string msg = \"Do not reply\";\n    byte[] msgByteArray = msg.toBytes();\n    check  socketClient->writeBytes(msgByteArray);\n\n    tcp:Error|(readonly & byte[]) res = socketClient->readBytes();\n    if (res is (readonly & byte[])) {\n        io:println(res.length());\n        test:assertFail(msg = \"Read timeout test failed\");\n    }\n    // print expected timeout error\n    io:println(res);\n\n    return socketClient->close();\n}\n\n@test:Config {\n    dependsOn: [testClientReadTimeout]\n}\nfunction testServerAlreadyClosed() returns  @tainted error? {\n    tcp:Client socketClient = check new (\"localhost\", PORT3, timeout = 1);\n\n    tcp:Error|(readonly & byte[]) res = socketClient->readBytes();\n    if (res is (readonly & byte[])) {\n        io:println(res.length());\n        test:assertFail(msg = \"Test for server already disconnected failed\");\n    }\n    // print expected timeout error\n    io:println(res);\n\n    return socketClient->close();\n}\n\n@test:Config {dependsOn: [testServerAlreadyClosed]}\nfunction testSecureListenerWithSecureClient() returns @tainted error? {\n    tcp:Client socketClient = check new (\"localhost\", PORT4, secureSocket = {\n        cert: certPath,\n        protocol: {\n            name: tcp:TLS,\n            versions: [\"TLSv1.2\", \"TLSv1.1\"]\n        },\n        ciphers: [\"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA\"]\n    });\n\n    string msg = \"Hello Ballerina Echo from secure client\";\n    byte[] msgByteArray = msg.toBytes();\n    check socketClient->writeBytes(msgByteArray);\n\n    readonly & byte[] receivedData = check socketClient->readBytes();\n    test:assertEquals('string:fromBytes(receivedData), msg, \"Found unexpected output\");\n\n    return socketClient->close();\n}\n"
  },
  {
    "path": "stdlib-integration-tests/transaction/tests/xa_transactions_test.bal",
    "content": "// Copyright (c) 2020-2024, WSO2 LLC. (https://www.wso2.com).\n//\n// WSO2 LLC. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/sql;\nimport ballerina/test;\n\nimport ballerinax/java.jdbc;\n\nstring xaDatasourceName = \"org.h2.jdbcx.JdbcDataSource\";\n\n@test:Config {\n}\nfunction testXATransactions() returns error? {\n    string str = \"\";\n\n    jdbc:Client dbClient1 = check new (url = \"jdbc:h2:file:./xa-transactions/testdb1\",\n        user = \"test\", password = \"test\", options = {datasourceName: xaDatasourceName}\n    );\n\n    jdbc:Client dbClient2 = check new (url = \"jdbc:h2:file:./xa-transactions/testdb2\",\n        user = \"test\", password = \"test\", options = {datasourceName: xaDatasourceName}\n    );\n\n    _ = check dbClient1->execute(`CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INT, NAME VARCHAR(30))`);\n    _ = check dbClient2->execute(`CREATE TABLE IF NOT EXISTS SALARY (ID INT, \"VALUE\" FLOAT)`);\n\n    transaction {\n        str += \"transaction started\";\n\n        _ = check dbClient1->execute(`INSERT INTO EMPLOYEE VALUES (1, 'John')`);\n        _ = check dbClient2->execute(`INSERT INTO SALARY VALUES (1, 20000.00)`);\n\n        var commitResult = commit;\n        if commitResult is () {\n            str += \" -> transaction committed\";\n        } else {\n            str += \" -> transaction failed\";\n        }\n        str += \" -> transaction ended.\";\n    }\n\n    test:assertEquals(str, \"transaction started -> transaction committed -> transaction ended.\");\n\n    // Verify that the data was inserted successfully to both databases\n    sql:ExecutionResult employeeResult = check dbClient1->queryRow(`SELECT * FROM EMPLOYEE WHERE ID = 1`);\n    sql:ExecutionResult salaryResult = check dbClient2->queryRow(`SELECT * FROM SALARY WHERE ID = 1`);\n    json employeeResultJson = employeeResult.toJson();\n    json salaryResultJson = salaryResult.toJson();\n\n    test:assertEquals(employeeResultJson.ID, 1);\n    test:assertEquals(employeeResultJson.NAME, \"John\");\n    test:assertEquals(salaryResultJson.ID, 1);\n    test:assertEquals(salaryResultJson.VALUE, 20000.00);\n\n    checkpanic dbClient1.close();\n    checkpanic dbClient2.close();\n}\n"
  },
  {
    "path": "stdlib-integration-tests/udp/tests/mock_servers.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/log;\nimport ballerina/udp;\n\nconst int PORT1 = 9001;\n\nmap<string> QuestionBank = {\n    \"hi\": \"hi there!\",\n    \"who are you?\": \"I'm a ballerina bot\"\n};\n\nservice on new udp:Listener(PORT1) {\n\n remote function onDatagram(readonly & udp:Datagram datagram, udp:Caller caller ) \n        returns udp:Datagram|udp:Error? {\n            string|error request = string:fromBytes(datagram.data);\n        if (request is string && QuestionBank.hasKey(request)) {\n            udp:Datagram|error response = datagram.cloneWithType(udp:Datagram);\n            if (response is error) {\n                return datagram;\n            } else {\n                response.data = QuestionBank.get(request).toBytes();\n                check caller->sendDatagram(response);\n            }   \n        } else {\n            return datagram;\n        }\n    }\n\n    remote function onError(udp:Error err) {\n        log:printError(\"An error occurred\", 'error = err);\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/udp/tests/udp_tests.bal",
    "content": "// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/log;\nimport ballerina/test;\nimport ballerina/udp;\n\n@test:Config {}\nfunction testConnectionlessClient() returns error? {\n    udp:Client socketClient = check new;\n    string msg = \"hi\";\n    string expectedResponseString = \"hi there!\";\n\n    var sendResult = check socketClient->sendDatagram({\n        data: msg.toBytes(),\n        remoteHost: \"localhost\",\n        remotePort: PORT1\n    });\n    log:printInfo(\"Datagram was sent to the remote host.\");\n\n    readonly & udp:Datagram result = check socketClient->receiveDatagram();\n    test:assertEquals(string:fromBytes(result.data), expectedResponseString, \"Found unexpected output\");\n    check socketClient->close();\n}\n\n@test:Config {}\nfunction testConnectClient() returns error? {\n    udp:ConnectClient socketClient = check new (\"localhost\", PORT1);\n\n    string msg = \"who are you?\";\n    string expectedResponseString = \"I'm a ballerina bot\";\n\n\n    check socketClient->writeBytes(msg.toBytes());\n    log:printInfo(\"Datagram was sent to the remote host.\");\n\n    readonly & byte[] result = check socketClient->readBytes();\n    test:assertEquals(string:fromBytes(result), expectedResponseString, \"Found unexpected output\");\n\n    check socketClient->close();\n}\n\n@test:Config {}\nisolated function testConnectClientReadTimeOut() returns error? {\n    udp:ConnectClient socketClient = check new (\"localhost\", 48830, localHost = \"localhost\", timeout = 1);\n\n    var result = socketClient->readBytes();\n    if (result is byte[]) {\n        test:assertFail(msg = \"No UDP service running on localhost:48830, no result should be returned\");\n    } else {\n        log:printInfo(result.message());\n    }\n\n    check socketClient->close();\n}\n"
  },
  {
    "path": "stdlib-integration-tests/url/tests/url_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/test;\nimport ballerina/url;\n\n@test:Config {}\npublic function testUrlEncodingAndDecoding() {\n    string input = \"http://localhost:9090/echoService?type=string&value=hello world\";\n    string output = \"http%3A%2F%2Flocalhost%3A9090%2FechoService%3Ftype%3Dstring%26value%3Dhello%20world\";\n    string|url:Error encodedResult = url:encode(input, \"UTF-8\");\n    if (encodedResult is string) {\n        test:assertEquals(encodedResult, output);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n\n    string|url:Error decodedResult = url:decode(<string>output, \"UTF-8\");\n    if (decodedResult is string) {\n        test:assertEquals(decodedResult, input);\n    } else {\n        test:assertFail(msg = \"Test Failed!\");\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websocket/tests/web_socket_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (//www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// //www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/lang.runtime as runtime;\nimport ballerina/test;\nimport ballerina/http;\nimport ballerina/websocket;\n\nservice /onTextString on new websocket:Listener(21003) {\n   resource isolated function get .(http:Request req) returns websocket:Service|websocket:Error {\n       return new WsService1();\n   }\n}\n\nservice class WsService1 {\n  *websocket:Service;\n  remote isolated function onMessage(websocket:Caller caller, string data) returns error? {\n      check caller->writeMessage(data);\n  }\n}\n\n// Tests string support for writeString and onString\n@test:Config {}\npublic function testWebsocketString() returns websocket:Error? {\n    websocket:Client wsClient = check new (\"ws://localhost:21003/onTextString\");\n    check wsClient->writeMessage(\"Hi\");\n    runtime:sleep(5);\n    string data = check wsClient->readTextMessage();\n    test:assertEquals(data, \"Hi\", msg = \"Failed pushtext\");\n    return wsClient->close(statusCode = 1000, reason = \"Close the connection\", timeout = 180);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub/tests/web_sub_test.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/http;\nimport ballerina/websubhub;\nimport ballerina/test;\n\npublic function startHub() returns string {\n    io:println(\"Starting up the Ballerina Hub Service\");\n    string resultString = \"\";\n    websubhub:Hub webSubHub;\n\n    var result = websubhub:startHub(new http:Listener(9191), \"/websub\", \"/hub\");\n    if (result is websubhub:Hub) {\n        webSubHub = result;\n    } else if (result is websubhub:HubStartedUpError) {\n        webSubHub = result.startedUpHub;\n    } else {\n        resultString = result.message();\n        io:println(\"Hub start error:\" + result.message());\n        return resultString;\n    }\n    var registrationResponse = webSubHub.registerTopic(\"http://websubpubtopic.com\");\n    if (registrationResponse is error) {\n        resultString = resultString + registrationResponse.message();\n        io:println(\"Error occurred registering topic: \" +\n                                registrationResponse.message());\n    } else {\n        resultString = resultString + \"Topic registration successful!\";\n        io:println(\"Topic registration successful!\");\n    }\n\n    io:println(\"Publishing update to internal Hub\");\n    var publishResponse = webSubHub.publishUpdate(\"http://websubpubtopic.com\",\n        {\"action\": \"publish\", \"mode\": \"internal-hub\"});\n\n    if (publishResponse is error) {\n        resultString = resultString + publishResponse.message();\n        io:println(\"Error notifying hub: \" + publishResponse.message());\n    } else {\n        resultString = resultString + \"Update notification successful!\";\n        io:println(\"Update notification successful!\");\n    }\n\n    return resultString;\n}\n\n@test:Config{}\npublic function testStartHubAndPublish() {\n    string result = startHub();\n    io:println(result);\n    test:assertEquals(result, \"Topic registration successful!Update notification successful!\",\n                msg = \"Error starting the hub\");\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-advance/tests/constants.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\n// Integration tests constants\nconst string WEBSUB_PERSISTENCE_TOPIC_ONE = \"http://one.persistence.topic.com\";\nconst string WEBSUB_PERSISTENCE_TOPIC_TWO = \"http://two.persistence.topic.com\";\nconst string WEBSUB_TOPIC_ONE = \"http://one.websub.topic.com\";\n\nconst string ID_NOTIFICATION_ONE = \"NotificationOne\";\nconst string ID_NOTIFICATION_FOUR = \"NotificationFour\";\n\nconst string NOTIFICATION_ONE = \"WebSub Notification Received by One: {\\\"mode\\\":\\\"internal\\\", \\\"content_type\\\":\\\"json\\\"}\";\nconst string NOTIFICATION_FOUR = \"WebSub Notification Received by Four: {\\\"mode\\\":\\\"remote\\\", \\\"content_type\\\":\\\"xml\\\"}\";\n\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-advance/tests/test_subscribers_at_basic_auth_secured_hub.bal",
    "content": "// // Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n// //\n// // WSO2 Inc. licenses this file to you under the Apache License,\n// // Version 2.0 (the \"License\"); you may not use this file except\n// // in compliance with the License.\n// // You may obtain a copy of the License at\n// //\n// // http://www.apache.org/licenses/LICENSE-2.0\n// //\n// // Unless required by applicable law or agreed to in writing,\n// // software distributed under the License is distributed on an\n// // \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// // KIND, either express or implied.  See the License for the\n// // specific language governing permissions and limitations\n// // under the License.\n\n// import ballerina/auth;\n// import ballerina/http;\n// import ballerina/io;\n// import ballerina/lang.runtime as runtime;\n// import ballerina/test;\n// import ballerina/log;\n// import ballerina/websub;\n\n// auth:InboundBasicAuthProvider basicAuthProvider = new;\n// http:BasicAuthHandler basicAuthHandler = new(basicAuthProvider);\n\n// websub:Hub webSubHub = startHubAndRegisterTopic();\n\n// listener http:Listener publisherServiceEP = new http:Listener(23080);\n\n// http:BasicAuthHandler outboundBasicAuthHandler = new(new auth:OutboundBasicAuthProvider({\n//                                                          username: \"anne\",\n//                                                          password: \"abc\"\n//                                                      }));\n\n// websub:PublisherClient websubHubClientEP = new (webSubHub.publishUrl, {\n//     auth: {\n//         authHandler: outboundBasicAuthHandler\n//     },\n//     secureSocket: {\n//         trustStore: {\n//             path: \"tests/resources/security/ballerinaTruststore.p12\",\n//             password: \"ballerina\"\n//         }\n//     }\n// });\n\n// http:BasicAuthHandler authnFailingHandler = new(new auth:OutboundBasicAuthProvider({\n//                                                          username: \"anne\",\n//                                                          password: \"cba\"\n//                                                }));\n\n// websub:PublisherClient authnFailingClient = new (webSubHub.publishUrl, {\n//     auth: {\n//         authHandler: authnFailingHandler\n//     },\n//     secureSocket: {\n//         trustStore: {\n//             path: \"tests/resources/security/ballerinaTruststore.p12\",\n//             password: \"ballerina\"\n//         }\n//     }\n// });\n\n// http:BasicAuthHandler authzFailingHandler = new(new auth:OutboundBasicAuthProvider({\n//                                                          username: \"peter\",\n//                                                          password: \"pqr\"\n//                                                }));\n\n// websub:PublisherClient authzFailingClient = new (webSubHub.publishUrl, {\n//     auth: {\n//         authHandler: authzFailingHandler\n//     },\n//     secureSocket: {\n//         trustStore: {\n//             path: \"tests/resources/security/ballerinaTruststore.p12\",\n//             password: \"ballerina\"\n//         }\n//     }\n// });\n\n// service publisher on publisherServiceEP {\n//     @http:ResourceConfig {\n//         methods: [\"GET\", \"HEAD\"]\n//     }\n//     resource function discover(http:Caller caller, http:Request req) {\n//         http:Response response = new;\n//         // Add a link header indicating the hub and topic\n//         websub:addWebSubLinkHeader(response, [webSubHub.subscriptionUrl], WEBSUB_PERSISTENCE_TOPIC_ONE);\n//         var err = caller->accepted(response);\n//         if (err is error) {\n//             log:printError(\"Error responding on discovery\", err = err);\n//         }\n//     }\n\n//     @http:ResourceConfig {\n//         methods: [\"POST\"],\n//         path: \"/notify/{subscriber}\"\n//     }\n//     resource function notify(http:Caller caller, http:Request req, string subscriber) {\n//         var payload = req.getJsonPayload();\n//         if (payload is error) {\n//             panic <error> payload;\n//         }\n\n//         checkSubscriberAvailability(WEBSUB_PERSISTENCE_TOPIC_ONE, \"http://localhost:\" + subscriber + \"/websub\");\n//         var err = webSubHub.publishUpdate(WEBSUB_PERSISTENCE_TOPIC_ONE, <@untainted> <json> payload);\n//         if (err is error) {\n//             log:printError(\"Error publishing update directly\", err = err);\n//         }\n\n//         http:Response response = new;\n//         err = caller->accepted(response);\n//         if (err is error) {\n//             log:printError(\"Error responding on notify request\", err = err);\n//         }\n//     }\n// }\n\n// service publisherTwo on publisherServiceEP {\n//     @http:ResourceConfig {\n//         methods: [\"GET\", \"HEAD\"]\n//     }\n//     resource function discover(http:Caller caller, http:Request req) {\n//         http:Response response = new;\n//         // Add a link header indicating the hub and topic\n//         websub:addWebSubLinkHeader(response, [webSubHub.subscriptionUrl], WEBSUB_PERSISTENCE_TOPIC_TWO);\n//         var err = caller->accepted(response);\n//         if (err is error) {\n//             log:printError(\"Error responding on discovery\", err = err);\n//         }\n//     }\n\n//     @http:ResourceConfig {\n//         methods: [\"POST\"]\n//     }\n//     resource function notify(http:Caller caller, http:Request req) {\n//         var payload = req.getJsonPayload();\n//         if (payload is error) {\n//             panic <error> payload;\n//         }\n\n//         checkSubscriberAvailability(WEBSUB_PERSISTENCE_TOPIC_TWO, \"http://localhost:23383/websubTwo\");\n//         var err = webSubHub.publishUpdate(WEBSUB_PERSISTENCE_TOPIC_TWO, <@untainted> <json> payload);\n//         if (err is error) {\n//             log:printError(\"Error publishing update directly\", err = err);\n//         }\n\n//         http:Response response = new;\n//         err = caller->accepted(response);\n//         if (err is error) {\n//             log:printError(\"Error responding on notify request\", err = err);\n//         }\n//     }\n// }\n\n// service publisherThree on publisherServiceEP {\n//     @http:ResourceConfig {\n//         methods: [\"GET\", \"HEAD\"]\n//     }\n//     resource function discover(http:Caller caller, http:Request req) {\n//         http:Response response = new;\n//         // Add a link header indicating the hub and topic\n//         websub:addWebSubLinkHeader(response, [webSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n//         var err = caller->accepted(response);\n//         if (err is error) {\n//             log:printError(\"Error responding on discovery\", err = err);\n//         }\n//     }\n\n//     @http:ResourceConfig {\n//         methods: [\"POST\"]\n//     }\n//     resource function notify(http:Caller caller, http:Request req) {\n//         var payload = req.getJsonPayload();\n//         if (payload is error) {\n//             panic <error> payload;\n//         }\n//         checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:23484/websubFour\");\n\n//         string publishErrorMessagesConcatenated = \"\";\n\n//         var err = websubHubClientEP->publishUpdate(WEBSUB_TOPIC_ONE, <@untainted> <json> payload);\n//         if (err is error) {\n//             publishErrorMessagesConcatenated += err.message();\n//             log:printError(\"Error publishing update remotely\", err = err);\n//         }\n\n//         err = authnFailingClient->publishUpdate(WEBSUB_TOPIC_ONE, <@untainted> <json> payload);\n//         if (err is error) {\n//             publishErrorMessagesConcatenated += err.message();\n//             log:printError(\"Error publishing update remotely\", err = err);\n//         }\n\n//         err = authzFailingClient->publishUpdate(WEBSUB_TOPIC_ONE, <@untainted> <json> payload);\n//         if (err is error) {\n//             publishErrorMessagesConcatenated += err.message();\n//             log:printError(\"Error publishing update remotely\", err = err);\n//         }\n\n//         err = caller->accepted(<@untainted> publishErrorMessagesConcatenated);\n//         if (err is error) {\n//             log:printError(\"Error responding on notify request\", err = err);\n//         }\n//     }\n// }\n\n// service helperService on publisherServiceEP {\n//     @http:ResourceConfig {\n//         methods: [\"POST\"]\n//     }\n//     resource function restartHub(http:Caller caller, http:Request req) {\n//         checkpanic webSubHub.stop();\n//         webSubHub = startHubAndRegisterTopic();\n//         checkpanic caller->accepted();\n//     }\n// }\n\n// function startHubAndRegisterTopic() returns websub:Hub {\n//     websub:Hub internalHub = startWebSubHub();\n//     var err = internalHub.registerTopic(WEBSUB_PERSISTENCE_TOPIC_ONE);\n//     if (err is error) {\n//         log:printError(\"Error registering topic\", err = err);\n//     }\n//     err = internalHub.registerTopic(WEBSUB_PERSISTENCE_TOPIC_TWO);\n//     if (err is error) {\n//         log:printError(\"Error registering topic\", err = err);\n//     }\n//     err = internalHub.registerTopic(WEBSUB_TOPIC_ONE);\n//     if (err is error) {\n//         log:printError(\"Error registering topic\", err = err);\n//     }\n//     return internalHub;\n// }\n\n// function startWebSubHub() returns websub:Hub {\n//     var result = websub:startHub(new http:Listener(23192, config =  {\n//                 auth: {\n//                     authHandlers: [basicAuthHandler]\n//                 },\n//                 secureSocket: {\n//                     keyStore: {\n//                         path: \"tests/resources/security/ballerinaKeystore.p12\",\n//                         password: \"ballerina\"\n//                     },\n//                     trustStore: {\n//                         path: \"tests/resources/security/ballerinaTruststore.p12\",\n//                         password: \"ballerina\"\n//                     }\n//                 }\n//             }), \"/websub\", \"/hub\",\n//                 serviceAuth = {enabled:true},\n//                 subscriptionResourceAuth = {enabled:true, scopes:[\"subscribe\"]},\n//                 publisherResourceAuth = {enabled:true, scopes:[\"publish\"]},\n//                 hubConfiguration = { remotePublish : { enabled : true }}\n//     );\n//     if (result is websub:Hub) {\n//         return result;\n//     } else if (result is websub:HubStartedUpError) {\n//         return result.startedUpHub;\n//     } else {\n//         panic result;\n//     }\n// }\n\n// function checkSubscriberAvailability(string topic, string callback) {\n//     int count = 0;\n//     boolean subscriberAvailable = false;\n//     while (!subscriberAvailable && count < 60) {\n//         websub:SubscriberDetails[] topicDetails = webSubHub.getSubscribers(topic);\n//         if (isSubscriberAvailable(topicDetails, callback)) {\n//             return;\n//         }\n//         runtime:sleep(1);\n//         count += 1;\n//     }\n// }\n\n// function isSubscriberAvailable(websub:SubscriberDetails[] topicDetails, string callback) returns boolean {\n//     foreach var detail in topicDetails {\n//         if (detail.callback == callback) {\n//             return true;\n//         }\n//     }\n//     return false;\n// }\n\n// listener websub:Listener websubEP = new websub:Listener(23484);\n// auth:OutboundBasicAuthProvider basicAuthProvider1 = new({\n//     username: \"peter\",\n//     password: \"pqr\"\n// });\n\n// http:BasicAuthHandler basicAuthHandler1 = new(basicAuthProvider1);\n\n// @websub:SubscriberServiceConfig {\n//     path: \"/websub\",\n//     subscribeOnStartUp: true,\n//     target: \"http://localhost:23080/publisher/discover\",\n//     leaseSeconds: 3600,\n//     secret: \"Kslk30SNF2AChs2\",\n//     hubClientConfig: {\n//         auth: { authHandler: basicAuthHandler1 },\n//         secureSocket: {\n//             trustStore: {\n//                 path: \"tests/resources/security/ballerinaTruststore.p12\",\n//                 password: \"ballerina\"\n//             }\n//         }\n//     }\n// }\n// service websubSubscriber on websubEP {\n//     resource function onNotification (websub:Notification notification) returns @tainted error? {\n//         json payload = check notification.getJsonPayload();\n//         io:println(\"WebSub Notification Received by One: \" + <@untainted>payload.toJsonString());\n//         storeOutput(ID_NOTIFICATION_ONE, \"WebSub Notification Received by One: \" + <@untainted>payload.toJsonString());\n//     }\n// }\n\n// auth:OutboundBasicAuthProvider basicAuthProvider2 = new({\n//     username: \"tom\",\n//     password: \"4321\"\n// });\n\n// http:BasicAuthHandler basicAuthHandler2 = new(basicAuthProvider2);\n\n// @websub:SubscriberServiceConfig {\n//     path: \"/websubTwo\",\n//     subscribeOnStartUp: true,\n//     target: \"http://localhost:23080/publisherTwo/discover\",\n//     leaseSeconds: 1200,\n//     hubClientConfig: {\n//         auth: { authHandler: basicAuthHandler2 },\n//         secureSocket: {\n//             trustStore: {\n//                 path: \"tests/resources/security/ballerinaTruststore.p12\",\n//                 password: \"ballerina\"\n//             }\n//         }\n//     }\n// }\n// service websubSubscriberTwo on websubEP {\n//     resource function onNotification (websub:Notification notification) returns @tainted error? {\n//         json payload = check notification.getJsonPayload();\n//         io:println(\"WebSub Notification Received by Two: \" + payload.toJsonString());\n//     }\n// }\n\n// auth:OutboundBasicAuthProvider basicAuthProvider3 = new({\n//     username: \"mary\",\n//     password: \"xyz\"\n// });\n\n// http:BasicAuthHandler basicAuthHandler3 = new(basicAuthProvider3);\n\n// @websub:SubscriberServiceConfig {\n//     path: \"/websubThree\",\n//     subscribeOnStartUp: true,\n//     target: \"http://localhost:23080/publisher/discover\",\n//     leaseSeconds: 1200,\n//     hubClientConfig: {\n//         auth: { authHandler: basicAuthHandler3 },\n//         secureSocket: {\n//             trustStore: {\n//                 path: \"tests/resources/security/ballerinaTruststore.p12\",\n//                 password: \"ballerina\"\n//             }\n//         }\n//     }\n// }\n// service websubSubscriberThree on websubEP {\n//     resource function onNotification (websub:Notification notification) returns @tainted error? {\n//         json payload = check notification.getJsonPayload();\n//         io:println(\"WebSub Notification Received by Three: \" + payload.toJsonString());\n//     }\n// }\n\n// auth:OutboundBasicAuthProvider basicAuthProvider4 = new({\n//     username: \"tom\",\n//     password: \"1234\"\n// });\n\n// http:BasicAuthHandler basicAuthHandler4 = new(basicAuthProvider4);\n\n// @websub:SubscriberServiceConfig {\n//     path: \"/websubFour\",\n//     target: \"http://localhost:23080/publisherThree/discover\",\n//     leaseSeconds: 1200,\n//     hubClientConfig: {\n//         auth: { authHandler: basicAuthHandler4 },\n//         secureSocket: {\n//             trustStore: {\n//                 path: \"tests/resources/security/ballerinaTruststore.p12\",\n//                 password: \"ballerina\"\n//             }\n//         }\n//     }\n// }\n// service websubSubscriberFour on websubEP {\n//     resource function onNotification (websub:Notification notification) returns @tainted error? {\n//         json payload = check notification.getJsonPayload();\n//         io:println(\"WebSub Notification Received by Four: \" + <@untainted>payload.toJsonString());\n//         storeOutput(ID_NOTIFICATION_FOUR, \"WebSub Notification Received by Four: \" + <@untainted>payload.toJsonString());\n//     }\n// }\n\n// @test:Config{}\n// function testDiscoveryAndIntentVerification() {\n//     http:Client clientEndpoint = new (\"http://localhost:23080\");\n//     json jsonPayload = {mode: \"internal\", content_type: \"json\"};\n//     http:Request req = new;\n//     req.addHeader(http:CONTENT_TYPE, \"application/json\");\n//     req.setJsonPayload(jsonPayload);\n//     var response = clientEndpoint->post(\"/publisher/notify/23484\", req);\n//     runtime:sleep(10);\n//     test:assertEquals(fetchOutput(ID_NOTIFICATION_ONE), NOTIFICATION_ONE, msg = \"Response code mismatched\");\n// }\n\n// @test:Config{\n//     dependsOn: [testDiscoveryAndIntentVerification]\n// }\n// function testContentReceipt() {\n//     http:Client clientEndpoint = new (\"http://localhost:23080\");\n//     json jsonPayload = {mode: \"remote\", content_type: \"xml\"};\n//     http:Request req = new;\n//     req.addHeader(http:CONTENT_TYPE, \"application/json\");\n//     req.setJsonPayload(jsonPayload);\n//     var response = clientEndpoint->post(\"/publisherThree/notify\", req);\n//     runtime:sleep(10);\n//     test:assertEquals(fetchOutput(ID_NOTIFICATION_FOUR), NOTIFICATION_FOUR, msg = \"Response code mismatched\");\n// }\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-advance/tests/test_subscribers_at_persistence_enabled_hub.bal",
    "content": "//// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n////\n//// WSO2 Inc. licenses this file to you under the Apache License,\n//// Version 2.0 (the \"License\"); you may not use this file except\n//// in compliance with the License.\n//// You may obtain a copy of the License at\n////\n//// http://www.apache.org/licenses/LICENSE-2.0\n////\n//// Unless required by applicable law or agreed to in writing,\n//// software distributed under the License is distributed on an\n//// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n//// KIND, either express or implied.  See the License for the\n//// specific language governing permissions and limitations\n//// under the License.\n//\n//import ballerina/auth;\n//import ballerina/io;\n//import ballerina/http;\n//\n//listener Listener persistenceWebsubEP = new Listener(23383);\n//\n//auth:OutboundBasicAuthProvider persistenceBasicAuthProvider = new({\n//    username: \"tom\",\n//    password: \"1234\"\n//});\n//\n//http:BasicAuthHandler persistenceBasicAuthHandler = new(persistenceBasicAuthProvider);\n//\n//@SubscriberServiceConfig {\n//    path: \"/websub\",\n//    target: \"http://localhost:23080/publisher/discover\",\n//    leaseSeconds: 3600,\n//    secret: \"Kslk30SNF2AChs2\",\n//    hubClientConfig: {\n//        auth: { authHandler: persistenceBasicAuthHandler }\n//    }\n//}\n//service persistenceWebsubSubscriber on persistenceWebsubEP {\n//    resource function onNotification (Notification notification) returns @tainted error? {\n//        json payload = check notification.getJsonPayload();\n//        io:println(\"WebSub Notification Received by One: \" + payload.toJsonString());\n//    }\n//}\n//\n//@SubscriberServiceConfig {\n//    path: \"/websubTwo\",\n//    subscribeOnStartUp: true,\n//    target: \"http://localhost:23080/publisherTwo/discover\",\n//    leaseSeconds: 1200,\n//    hubClientConfig: {\n//        auth: { authHandler: persistenceBasicAuthHandler }\n//    }\n//}\n//service persistenceWebsubSubscriberTwo on persistenceWebsubEP {\n//    resource function onNotification (Notification notification) returns @tainted error? {\n//        json payload = check notification.getJsonPayload();\n//        io:println(\"WebSub Notification Received by Two: \" + payload.toJsonString());\n//    }\n//}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-advance/tests/utils.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nmap<(anydata|error)> outputs = {};\n\npublic function storeOutput(string key, any|error... s) {\n    any|error statusCode = s[0];\n    outputs[key] = statusCode is error ? statusCode.toString() : statusCode.toString();\n}\n\npublic function fetchOutput(string key) returns (anydata|error) {\n    return outputs[key];\n}\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/01_websub_publisher.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/io;\nimport ballerina/log;\nimport ballerina/lang.runtime as runtime;\nimport ballerina/websubhub;\n\nboolean remoteTopicRegistered = false;\n\nwebsubhub:Hub webSubHub = startHubAndRegisterTopic();\n\nwebsubhub:PublisherClient websubHubClientEP = new (webSubHub.publishUrl);\n\nlistener http:Listener publisherServiceEP = new http:Listener(23080);\n\nservice /publisher on publisherServiceEP {\n    resource function get discover(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        // Add a link header indicating the hub and topic\n        websubhub:addWebSubLinkHeader(response, [webSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n        var err = caller->accepted(response);\n        if (err is error) {\n            log:printError(\"Error responding on ordering\", err = err);\n        }\n    }\n\n    resource function post notify/[string subscriber](http:Caller caller, http:Request req) {\n        remoteRegisterTopic();\n        json jsonPayload = <json> checkpanic req.getJsonPayload();\n        json jsonMode = <json> checkpanic jsonPayload.mode;\n        string mode = jsonMode.toJsonString();\n        json jsonContentType = <json> checkpanic jsonPayload.content_type;\n        string contentType = jsonContentType.toJsonString();\n\n        var err = caller->accepted();\n        if (err is error) {\n            log:printError(\"Error responding on notify request\", err = err);\n        }\n\n        if (subscriber != \"skip_subscriber_check\") {\n            checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:\" + subscriber + \"/websub\");\n            checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:\" + subscriber +\n                    \"/subscriberWithNoPathInAnnot\");\n            checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:\" + subscriber + \"/websubThree?topic=\" +\n                    WEBSUB_TOPIC_ONE + \"&fooVal=barVal\");\n        }\n\n        if (mode == \"internal\") {\n            var result = webSubHub.publishUpdate(WEBSUB_TOPIC_ONE, getPayloadContent(contentType, mode));\n            if (result is error) {\n                log:printError(\"Error publishing update directly\", err = result);\n            }\n        } else {\n            var result = websubHubClientEP->publishUpdate(WEBSUB_TOPIC_ONE, getPayloadContent(contentType, mode));\n            if (result is error) {\n                log:printError(\"Error publishing update remotely\", err = result);\n            }\n        }\n    }\n\n    resource function get topicInfo(http:Caller caller, http:Request req) {\n        if (req.hasHeader(\"x-topic\")) {\n            string topicName = req.getHeader(\"x-topic\");\n            websubhub:SubscriberDetails[] details = webSubHub.getSubscribers(topicName);\n            var err = caller->respond(details.toString());\n            if (err is error) {\n                log:printError(\"Error responding on topicInfo request\", err = err);\n            }\n        } else {\n            map<string> allTopics = {};\n            int index=1;\n            string [] availableTopics = webSubHub.getAvailableTopics();\n            foreach var topic in availableTopics {\n                allTopics[\"Topic_\" + index.toString()] = topic;\n                index += 1;\n            }\n            json j = <json> checkpanic allTopics.cloneWithType(JsonTypedesc);\n            var err = caller->respond(j);\n            if (err is error) {\n                log:printError(\"Error responding on topicInfo request\", err = err);\n            }\n        }\n    }\n\n    resource function get unsubscribe(http:Caller caller, http:Request req) returns error? {\n        check webSubHub.removeSubscription(\"http://one.websub.topic.com\",\n                                           \"http://localhost:23181/websubThree?topic=http://one.websub.topic.com&fooVal=barVal\");\n        var err = caller->respond(\"unsubscription successful\");\n        if (err is error) {\n            log:printError(\"Error responding on unsubscription request\", err = err);\n        }\n    }\n}\n\nservice /publisherTwo on publisherServiceEP {\n    resource function get discover(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        // Add a link header indicating the hub and topic\n        websubhub:addWebSubLinkHeader(response, [webSubHub.subscriptionUrl], WEBSUB_TOPIC_FOUR);\n        var err = caller->accepted(response);\n        if (err is error) {\n            log:printError(\"Error responding on ordering\", err = err);\n        }\n    }\n\n    resource function post notify(http:Caller caller, http:Request req) {\n        checkSubscrberAvailabilityAndPublishDirectly(WEBSUB_TOPIC_THREE, \"http://localhost:23383/websub\",\n                                                     {\"action\":\"publish\",\"mode\":\"internal-hub\"});\n        checkSubscrberAvailabilityAndPublishDirectly(WEBSUB_TOPIC_FOUR, \"http://localhost:23383/websubTwo\",\n                                                     {\"action\":\"publish\",\"mode\":\"internal-hub-two\"});\n\n        var err = caller->accepted();\n        if (err is error) {\n            log:printError(\"Error responding on notify request\", err = err);\n        }\n    }\n}\n\nservice /contentTypePublisher on publisherServiceEP {\n    resource function post notify/[string port](http:Caller caller, http:Request req) {\n        json jsonPayload = <json> checkpanic req.getJsonPayload();\n        json jsonMode = <json> checkpanic jsonPayload.mode;\n        string mode = jsonMode.toJsonString();\n        json jsonContentType = <json> checkpanic jsonPayload.content_type;\n        string contentType = jsonContentType.toJsonString();\n\n        var err = caller->accepted();\n        if (err is error) {\n            log:printError(\"Error responding on notify request\", err = err);\n        }\n\n        if (port != \"skip_subscriber_check\") {\n            checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:\" + port + \"/websub\");\n            checkSubscriberAvailability(WEBSUB_TOPIC_ONE, \"http://localhost:\" + port + \"/websubTwo\");\n        }\n\n        if (mode == \"internal\") {\n            var result = webSubHub.publishUpdate(WEBSUB_TOPIC_ONE, getPayloadContent(contentType, mode));\n            if (result is error) {\n                log:printError(\"Error publishing update directly\", err = result);\n            }\n        } else {\n            var result = websubHubClientEP->publishUpdate(WEBSUB_TOPIC_ONE, getPayloadContent(contentType, mode));\n            if (result is error) {\n                log:printError(\"Error publishing update remotely\", err = result);\n            }\n        }\n    }\n}\n\nfunction checkSubscrberAvailabilityAndPublishDirectly(string topic, string subscriber, json payload) {\n    checkSubscriberAvailability(topic, subscriber);\n    var err = webSubHub.publishUpdate(topic, payload);\n    if (err is error) {\n        log:printError(\"Error publishing update directly\", err = err);\n    }\n}\n\nfunction startHubAndRegisterTopic() returns websubhub:Hub {\n    websubhub:Hub internalHub = startWebSubHub();\n    var err = internalHub.registerTopic(WEBSUB_TOPIC_ONE);\n    if (err is error) {\n        log:printError(\"Error registering topic directly\", err = err);\n    }\n    err = internalHub.registerTopic(WEBSUB_TOPIC_THREE);\n    if (err is error) {\n        log:printError(\"Error registering topic directly\", err = err);\n    }\n    err = internalHub.registerTopic(WEBSUB_TOPIC_FOUR);\n    if (err is error) {\n        log:printError(\"Error registering topic directly\", err = err);\n    }\n    err = internalHub.registerTopic(WEBSUB_TOPIC_FIVE);\n    if (err is error) {\n        log:printError(\"Error registering topic directly\", err = err);\n    }\n    err = internalHub.registerTopic(WEBSUB_TOPIC_SIX);\n    if (err is error) {\n        log:printError(\"Error registering topic directly\", err = err);\n    }\n    return internalHub;\n}\n\nfunction startWebSubHub() returns websubhub:Hub {\n    var result = websubhub:startHub(new http:Listener(23191), \"/websub\", \"/hub\",\n                                 hubConfiguration = { remotePublish : { enabled : true }});\n    if (result is websubhub:Hub) {\n        return result;\n    } else if (result is websubhub:HubStartedUpError) {\n        return result.startedUpHub;\n    } else {\n        panic result;\n    }\n}\n\nfunction remoteRegisterTopic()  {\n    if (remoteTopicRegistered) {\n        return;\n    }\n    var err = websubHubClientEP->registerTopic(WEBSUB_TOPIC_TWO);\n    if (err is error) {\n        log:printError(\"Error registering topic remotely\", err = err);\n    }\n    remoteTopicRegistered = true;\n}\n\nfunction getPayloadContent(string contentType, string mode) returns string|xml|json|byte[]|io:ReadableByteChannel {\n    string errorMessage = \"unknown content type\";\n    if (contentType == \"\" || contentType == \"json\") {\n        if (mode == \"internal\") {\n            json j = {\"action\":\"publish\",\"mode\":\"internal-hub\"};\n            return j;\n        }\n        json k = {\"action\":\"publish\",\"mode\":\"remote-hub\"};\n        return k;\n    } else if (contentType == \"string\") {\n        if (mode == \"internal\") {\n            return \"Text update for internal Hub\";\n        }\n        return \"Text update for remote Hub\";\n    } else if (contentType == \"xml\") {\n        if (mode == \"internal\") {\n            return xml `<websub><request>Notification</request><type>Internal</type></websub>`;\n        }\n        return xml `<websub><request>Notification</request><type>Remote</type></websub>`;\n    } else if (contentType == \"byte[]\" || contentType == \"io:ReadableByteChannel\") {\n        errorMessage = \"content type \" + contentType + \" not yet supported with WebSub tests\";\n    }\n    error e = error(errorMessage);\n    panic e;\n}\n\nfunction checkSubscriberAvailability(string topic, string callback) {\n    int count = 0;\n    boolean subscriberAvailable = false;\n    while (!subscriberAvailable && count < 60) {\n        websubhub:SubscriberDetails[] topicDetails = webSubHub.getSubscribers(topic);\n        if (isSubscriberAvailable(topicDetails, callback)) {\n            return;\n        }\n        runtime:sleep(1);\n        count += 1;\n    }\n}\n\nfunction isSubscriberAvailable(websubhub:SubscriberDetails[] topicDetails, string callback) returns boolean {\n    foreach var detail in topicDetails {\n        if (detail.callback == callback) {\n            return true;\n        }\n    }\n    return false;\n}\n\ntype JsonTypedesc typedesc<json>;\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/02_redirection_publishers.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/log;\nimport ballerina/websubhub;\n\nlistener http:Listener publisherServiceEPTwo = new http:Listener(23081);\n\nservice /original on publisherServiceEPTwo {\n    resource function get one(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        checkpanic caller->redirect(res, http:REDIRECT_MOVED_PERMANENTLY_301, [\"http://localhost:23081/redirected/one\"]);\n    }\n\n    resource function get two(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        checkpanic caller->redirect(res, http:REDIRECT_FOUND_302, [\"http://localhost:23081/redirected/two\"]);\n    }\n}\n\nservice /redirected on publisherServiceEPTwo {\n    resource function get one(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        websubhub:addWebSubLinkHeader(res, [\"http://localhost:23081/hub/one\"], WEBSUB_TOPIC_FIVE);\n        var err = caller->respond(res);\n        if (err is error) {\n            log:printError(\"Error sending response\", err = err);\n        } else {\n            storeOutput(ID_REDIRECT_SUBSCRIBER_ONE_LOG, REDIRECT_SUBSCRIBER_ONE_LOG);\n        }\n    }\n\n    resource function get two(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        websubhub:addWebSubLinkHeader(res, [\"http://localhost:23081/hub/two\"], WEBSUB_TOPIC_SIX);\n        var err = caller->respond(res);\n        if (err is error) {\n            log:printError(\"Error sending response\", err = err);\n        } else {\n            storeOutput(ID_REDIRECT_SUBSCRIBER_TWO_LOG, REDIRECT_SUBSCRIBER_TWO_LOG);\n        }\n    }\n}\n\nservice /hub on publisherServiceEPTwo {\n    resource function get one(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        checkpanic caller->redirect(res, http:REDIRECT_TEMPORARY_REDIRECT_307, [\"http://localhost:23191/websub/hub\"]);\n    }\n\n    resource function get two(http:Caller caller, http:Request req) {\n        http:Response res = new;\n        checkpanic caller->redirect(res, http:REDIRECT_PERMANENT_REDIRECT_308, [\"http://localhost:23191/websub/hub\"]);\n    }\n}\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/constants.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\n// Integration tests constants\nconst string CUSTOM_SUB_MOCK_HEADER = \"MockHeader\";\nconst string MOCK_HEADER = \"MockHeader\";\nconst string CONTENT_TYPE_JSON = \"application/json\";\nconst string CONTENT_TYPE_FORM_URL_ENCODED = \"application/x-www-form-urlencoded\";\nconst string HUB_MODE_INTERNAL = \"internal\";\nconst string HUB_MODE_REMOTE = \"remote\";\nconst string TYPE_JSON = \"json\";\nconst string TYPE_XML = \"xml\";\nconst string TYPE_STRING = \"string\";\nconst string SKIP_SUBSCRIBER_CHECK = \"skip_subscriber_check\";\nconst string COMMON_PATH = \"/contentTypePublisher/notify/\";\n\nconst string WEBSUB_TOPIC_ONE = \"http://one.websub.topic.com\";\nconst string WEBSUB_TOPIC_TWO = \"http://two.websub.topic.com\";\nconst string WEBSUB_TOPIC_THREE = \"http://three.websub.topic.com\";\nconst string WEBSUB_TOPIC_FOUR = \"http://four.websub.topic.com\";\nconst string WEBSUB_TOPIC_FIVE = \"http://one.redir.topic.com\";\nconst string WEBSUB_TOPIC_SIX = \"http://two.redir.topic.com\";\n\nconst string HEADER_ACCEPT = \"Accept\";\nconst string HEADER_ACCEPT_LANGUAGE = \"Accept-Language\";\nconst string ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY = \"MatchingAcceptAndAcceptLanguageHeaderArray\";\nconst string ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS = \"MatchingAcceptAndAcceptLanguageHeaders\";\nconst string ID_MATCH_ACCEPT_HEADER = \"MatchingAcceptHeader\";\nconst string ID_MATCH_ACCEPT_LANGUAGE_HEADER = \"MatchingAcceptLanguageHeader\";\nconst string ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY = \"MisMatchingAcceptAcceptLanguageHeaderArray\";\nconst string ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS = \"MisMatchingAcceptAndAcceptLanguageHeaders\";\nconst string ID_MISMATCH_ACCEPT_HEADER = \"MisMathingAcceptHeader\";\nconst string ID_MISMATCH_ACCEPT_LANGUAGE_HEADER = \"MisMatchingAcceptLanguageHeader\";\nconst string ID_MISSING_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS = \"MissingAcceptAndAcceptLanguageHeaders\";\nconst string LANGUAGE_TYPE_DE = \"de-DE\";\nconst string RESPONSE_CODE_ACCEPTED = \"202\";\nconst string RESPONSE_CODE_NOT_ACCEPTABLE = \"406\";\nconst string RESPONSE_CODE_INTERNAL_SERVER_ERROR = \"500\";\n\nconst string ID_INTENT_VER_REQ_RECEIVED_LOG = \"IntentVerificationInvocation\";\nconst string ID_BY_KEY_CREATED_LOG = \"DispatchingByKeyCreated\";\nconst string ID_BY_KEY_FEATURE_LOG = \"DispatchingByKeyFeatured\";\nconst string ID_BY_HEADER_ISSUE_LOG = \"DispatchingByHeaderIssue\";\nconst string ID_BY_HEADER_COMMIT_LOG = \"DispatchingByHeaderCommit\";\nconst string ID_BY_HEADER_AND_PAYLOAD_ISSUE_CREATED_LOG = \"DispatchingByHeaderAndPayloadKeyCreated\";\nconst string ID_BY_HEADER_AND_PAYLOAD_FEATURE_PULL_LOG = \"DispatchingByHeaderAndPayloadKeyFeature\";\nconst string ID_BY_HEADER_AND_PAYLOAD_HEADER_ONLY_LOG = \"DispatchingByHeaderAndPayloadKeyForOnlyHeader\";\nconst string ID_BY_HEADER_AND_PAYLOAD_KEY_ONLY_LOG = \"DispatchingByHeaderAndPayloadKeyForOnlyKey\";\nconst string ID_REDIRECT_SUBSCRIBER_ONE_LOG = \"RedirectSubscriberOneLog\";\nconst string ID_REDIRECT_SUBSCRIBER_TWO_LOG = \"RedirectSubscriberTwoLog\";\nconst string ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"InternalHubNotificationSubscriberOne\";\nconst string ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"InternalHubNotificationSubscriberTwo\";\nconst string ID_EXPLICIT_INTENT_VERIFICATION_LOG = \"SubscriptionAndExplicitIntentVerification\";\nconst string ID_HUB_NOTIFICATION_LOG = \"InternalAndRemoteHubNotification\";\nconst string ID_HUB_NOTIFICATION_LOG_TWO = \"InternalAndRemoteHubNotificationTwo\";\nconst string ID_QUERY_PARAM_LOG = \"ContentReceiptForCallbackWithQueryParams\";\n\nconst string ID_TEXT_SUBSCRIBER_ONE = \"ContentTypeSubscriberOneText\";\nconst string ID_XML_SUBSCRIBER_ONE = \"ContentTypeSubscriberOneXml\";\nconst string ID_JSON_SUBSCRIBER_ONE = \"ContentTypeSubscriberOneJson\";\nconst string ID_TEXT_SUBSCRIBER_TWO = \"ContentTypeSubscriberTwoText\";\nconst string ID_XML_SUBSCRIBER_TWO = \"ContentTypeSubscriberTwoXml\";\nconst string ID_JSON_SUBSCRIBER_TWO = \"ContentTypeSubscriberTwoJson\";\n\nconst string INTENT_VER_REQ_RECEIVED_LOG = \"Intent verification request received\";\nconst string BY_KEY_CREATED_LOG = \"Created Notification Received, action: created\";\nconst string BY_KEY_FEATURE_LOG = \"Feature Notification Received, domain: feature\";\nconst string BY_HEADER_ISSUE_LOG = \"Issue Notification Received, header value: issue action: deleted\";\nconst string BY_HEADER_COMMIT_LOG = \"Commit Notification Received, header value: commit action: created\";\nconst string BY_HEADER_AND_PAYLOAD_ISSUE_CREATED_LOG = \"Issue Created Notification Received, header value: issue action: created\";\nconst string BY_HEADER_AND_PAYLOAD_FEATURE_PULL_LOG = \"Feature Pull Notification Received, header value: pull domain: feature\";\nconst string BY_HEADER_AND_PAYLOAD_HEADER_ONLY_LOG = \"HeaderOnly Notification Received, header value: headeronly action: header_only\";\nconst string BY_HEADER_AND_PAYLOAD_KEY_ONLY_LOG = \"KeyOnly Notification Received, header value: key_only action: keyonly\";\nconst string REDIRECT_SUBSCRIBER_ONE_LOG = \"Successful redirect subscriber one\";\nconst string REDIRECT_SUBSCRIBER_TWO_LOG = \"Successful redirect subscriber two\";\nconst string INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"WebSub Notification Received by One: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub\\\"}\";\nconst string INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"WebSub Notification Received by Two: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub-two\\\"}\";\nconst string EXPLICIT_INTENT_VERIFICATION_LOG = \"Intent verified explicitly for subscription change request\";\nconst string INTERNAL_HUB_NOTIFICATION_LOG = \"WebSub Notification Received: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub\\\"}\";\nconst string REMOTE_HUB_NOTIFICATION_LOG = \"WebSub Notification Received: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"remote-hub\\\"}\";\nconst string INTERNAL_HUB_NOTIFICATION_LOG_TWO = \"WebSub Notification Received by Two: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub\\\"}\";\nconst string REMOTE_HUB_NOTIFICATION_LOG_TWO = \"WebSub Notification Received by Two: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"remote-hub\\\"}\";\nconst string QUERY_PARAM_LOG = \"Query Params: {\\\"fooVal\\\":[\\\"barVal\\\"],\\\"topic\\\":[\\\"http://one.websub.topic.com\\\"]}\";\n\nconst string XML_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"XML WebSub Notification Received by websubSubscriber: <websub><request>Notification</request><type>Internal</type></websub>\";\nconst string TEXT_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"Text WebSub Notification Received by websubSubscriber: Text update for internal Hub\";\nconst string JSON_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"JSON WebSub Notification Received by websubSubscriber: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub\\\"}\";\nconst string XML_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"XML WebSub Notification Received by websubSubscriberTwo: <websub><request>Notification</request><type>Internal</type></websub>\";\nconst string TEXT_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"Text WebSub Notification Received by websubSubscriberTwo: Text update for internal Hub\";\nconst string JSON_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"JSON WebSub Notification Received by websubSubscriberTwo: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"internal-hub\\\"}\";\nconst string XML_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"XML WebSub Notification Received by websubSubscriber: <websub><request>Notification</request><type>Remote</type></websub>\";\nconst string TEXT_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"Text WebSub Notification Received by websubSubscriber: Text update for remote Hub\";\nconst string JSON_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG = \"JSON WebSub Notification Received by websubSubscriber: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"remote-hub\\\"}\";\nconst string XML_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"XML WebSub Notification Received by websubSubscriberTwo: <websub><request>Notification</request><type>Remote</type></websub>\";\nconst string TEXT_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"Text WebSub Notification Received by websubSubscriberTwo: Text update for remote Hub\";\nconst string JSON_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG = \"JSON WebSub Notification Received by websubSubscriberTwo: {\\\"action\\\":\\\"publish\\\", \\\"mode\\\":\\\"remote-hub\\\"}\";\n\nconst string WEBSUB_PERSISTENCE_TOPIC_ONE = \"http://one.persistence.topic.com\";\nconst string WEBSUB_PERSISTENCE_TOPIC_TWO = \"http://two.persistence.topic.com\";\n\nconst string ID_NOTIFICATION_ONE = \"NotificationOne\";\nconst string ID_NOTIFICATION_FOUR = \"NotificationFour\";\n\nconst string NOTIFICATION_ONE = \"WebSub Notification Received by One: {\\\"mode\\\":\\\"internal\\\", \\\"content_type\\\":\\\"json\\\"}\";\nconst string NOTIFICATION_FOUR = \"WebSub Notification Received by Four: {\\\"mode\\\":\\\"remote\\\", \\\"content_type\\\":\\\"xml\\\"}\";\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_content_negotiation.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/log;\nimport ballerina/stringutils;\nimport ballerina/test;\nimport ballerina/websub;\nimport ballerina/websubhub;\n\nwebsubhub:Hub WebSubHub = startHubAndRegisterTopic();\nlistener http:Listener publisherServiceEPOne = new http:Listener(24080);\nlistener websub:Listener websubSubscriberEPOne = new websub:Listener(24081);\nlistener websub:Listener websubSubscriberEPTwo = new websub:Listener(24082);\nlistener websub:Listener websubSubscriberEPThree = new websub:Listener(24083);\nlistener websub:Listener websubSubscriberEPFour = new websub:Listener(24084);\nlistener websub:Listener websubSubscriberEPFive = new websub:Listener(24085);\nlistener websub:Listener websubSubscriberEPSix = new websub:Listener(24086);\nlistener websub:Listener websubSubscriberEPSeven = new websub:Listener(24087);\nlistener websub:Listener websubSubscriberEPEight = new websub:Listener(24088);\nlistener websub:Listener websubSubscriberEPNine = new websub:Listener(24089);\n\nservice /publisherService on publisherServiceEPOne {\n    resource function get withAcceptAndAcceptLanguageHeaderArray(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        if (!(req.hasHeader(HEADER_ACCEPT) && req.hasHeader(HEADER_ACCEPT_LANGUAGE))) {\n            response.statusCode = 500;\n            var result = caller->respond(response);\n            log:printError(\"Error responding\", err = result);\n            storeOutput(ID_MISSING_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS, response.statusCode);\n        } else {\n            string mediaType = req.getHeader(HEADER_ACCEPT);\n            string languageType = req.getHeader(HEADER_ACCEPT_LANGUAGE);\n            if (stringutils:contains(mediaType, CONTENT_TYPE_JSON) && stringutils:contains(languageType, LANGUAGE_TYPE_DE)) {\n                websubhub:addWebSubLinkHeader(response, [WebSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n                response.statusCode = 202;\n                var result = caller->respond(response);\n                storeOutput(ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY, response.statusCode);\n                if (result is error) {\n                    log:printError(\"Error responding\", err = result);\n                }\n            } else {\n                response.statusCode = 406;\n                var result = caller->respond(response);\n                log:printError(\"Error responding\", err = result);\n                storeOutput(ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY, response.statusCode);\n            }\n        }\n    }\n\n    resource function get withAcceptAndAcceptLanguageHeaders(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        if (!(req.hasHeader(HEADER_ACCEPT) && req.hasHeader(HEADER_ACCEPT_LANGUAGE))) {\n            response.statusCode = 500;\n            var result = caller->respond(response);\n            log:printError(\"Error responding\", err = result);\n            storeOutput(ID_MISSING_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS, response.statusCode);\n        } else {\n             string mediaType = req.getHeader(HEADER_ACCEPT);\n             string languageType = req.getHeader(HEADER_ACCEPT_LANGUAGE);\n             if (mediaType == CONTENT_TYPE_JSON && languageType == LANGUAGE_TYPE_DE) {\n                 websubhub:addWebSubLinkHeader(response, [WebSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n                 response.statusCode = 202;\n                 var result = caller->respond(response);\n                 storeOutput(ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS, response.statusCode);\n                 if (result is error) {\n                     log:printError(\"Error responding\", err = result);\n                 }\n             } else {\n                response.statusCode = 406;\n                var result = caller->respond(response);\n                log:printError(\"Error responding\", err = result);\n                storeOutput(ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS, response.statusCode);\n            }\n        }\n    }\n\n    resource function get withAcceptHeader(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        string mediaType = req.getHeader(HEADER_ACCEPT);\n        if (mediaType == CONTENT_TYPE_JSON) {\n            websubhub:addWebSubLinkHeader(response, [WebSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n            response.statusCode = 202;\n            var result = caller->respond(response);\n            storeOutput(ID_MATCH_ACCEPT_HEADER, response.statusCode);\n            if (result is error) {\n                log:printError(\"Error responding\", err = result);\n            }\n        } else {\n            response.statusCode = 406;\n            var result = caller->respond(response);\n            log:printError(\"Error responding\", err = result);\n            storeOutput(ID_MISMATCH_ACCEPT_HEADER, response.statusCode);\n        }\n    }\n\n    resource function get withAcceptLanguageHeader(http:Caller caller, http:Request req) {\n        http:Response response = new;\n        string languageType = req.getHeader(HEADER_ACCEPT_LANGUAGE);\n        if (languageType == LANGUAGE_TYPE_DE) {\n            websubhub:addWebSubLinkHeader(response, [WebSubHub.subscriptionUrl], WEBSUB_TOPIC_ONE);\n            response.statusCode = 202;\n            var result = caller->respond(response);\n            storeOutput(ID_MATCH_ACCEPT_LANGUAGE_HEADER, response.statusCode);\n            if (result is error) {\n                log:printError(\"Error responding\", err = result);\n            }\n        } else {\n            response.statusCode = 406;\n            var result = caller->respond(response);\n            log:printError(\"Error responding\", err = result);\n            storeOutput(ID_MISMATCH_ACCEPT_LANGUAGE_HEADER, response.statusCode);\n        }\n    }\n}\n\n// do nothing for every onNotification functions.Just for SubscriberServiceConfig annotation.Testing for new fields\n// of SubscriberServiceConfig annotation is done by checking status code of response from initial discovery request\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptAndAcceptLanguageHeaderArray\",\n    accept: [\"application/json\", \"application/xml\", \"text/html\"],\n    acceptLanguage: [\"de-DE\", \"de-US\"],\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMatchingAcceptAndAcceptLanguageHeaderArray on websubSubscriberEPEight {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptAndAcceptLanguageHeaderArray\",\n    accept: [\"text/csv\", \"text/plain\"],\n    acceptLanguage: [\"en-US\", \"en-CA\"],\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMisMatchingAcceptAndAcceptLanguageHeaderArray on websubSubscriberEPNine {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptAndAcceptLanguageHeaders\",\n    accept: \"application/json\",\n    acceptLanguage: \"de-DE\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMatchingAcceptAndAcceptLanguageHeaders on websubSubscriberEPOne {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptAndAcceptLanguageHeaders\",\n    accept: \"text/html\",\n    acceptLanguage: \"de-US\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMisMatchingAcceptAndAcceptLanguageHeaders on websubSubscriberEPTwo {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptHeader\",\n    accept: \"application/json\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMatchingAcceptHeader on websubSubscriberEPThree {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptHeader\",\n    accept: \"text/html\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMisMatchingAcceptHeader on websubSubscriberEPFour {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptLanguageHeader\",\n    acceptLanguage: \"de-DE\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMatchingAcceptLanguageHeader on websubSubscriberEPFive {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptLanguageHeader\",\n    acceptLanguage: \"de-US\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMisMatchingAcceptLanguageHeader on websubSubscriberEPSix {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp: true,\n    target: \"http://localhost:24080/publisherService/withAcceptAndAcceptLanguageHeaders\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subcriberMissingAcceptAndAcceptLanguageHeaders on websubSubscriberEPSeven {\n    remote function onNotification(websub:Notification notification) {}\n}\n\n@test:Config {}\nfunction testMatchingAcceptAndAcceptLanguageHeaderArray() {\n    test:assertEquals(fetchOutput(ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY), RESPONSE_CODE_ACCEPTED);\n}\n\n@test:Config {}\nfunction testMisMatchingAcceptAndAcceptLanguageHeaderArray() {\n    test:assertEquals(fetchOutput(ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADER_ARRAY), RESPONSE_CODE_NOT_ACCEPTABLE);\n}\n\n@test:Config {}\nfunction testMatchingAcceptAndAcceptLanguageHeaders() {\n    test:assertEquals(fetchOutput(ID_MATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS), RESPONSE_CODE_ACCEPTED);\n}\n\n@test:Config {}\nfunction testMisMatchingAcceptAndAcceptLanguageHeaders() {\n    test:assertEquals(fetchOutput(ID_MISMATCH_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS), RESPONSE_CODE_NOT_ACCEPTABLE);\n}\n\n@test:Config {}\nfunction testMatchingAcceptHeader() {\n    test:assertEquals(fetchOutput(ID_MATCH_ACCEPT_HEADER), RESPONSE_CODE_ACCEPTED);\n}\n\n@test:Config {}\nfunction testMisMatchingAcceptHeader() {\n    test:assertEquals(fetchOutput(ID_MISMATCH_ACCEPT_HEADER), RESPONSE_CODE_NOT_ACCEPTABLE);\n}\n\n@test:Config {}\nfunction testMatchingAcceptLanguageHeader() {\n    test:assertEquals(fetchOutput(ID_MATCH_ACCEPT_LANGUAGE_HEADER), RESPONSE_CODE_ACCEPTED);\n}\n\n@test:Config {}\nfunction testMisMatchingAcceptLanguageHeader() {\n    test:assertEquals(fetchOutput(ID_MISMATCH_ACCEPT_LANGUAGE_HEADER), RESPONSE_CODE_NOT_ACCEPTABLE);\n}\n\n@test:Config {}\nfunction testMissingAcceptAndAcceptLanguageHeaders() {\n    test:assertEquals(fetchOutput(ID_MISSING_ACCEPT_AND_ACCEPT_LANGUAGE_HEADERS), RESPONSE_CODE_INTERNAL_SERVER_ERROR);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_custom_subscribers.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/test;\nimport ballerina/http;\nimport ballerina/websub;\n\npublic type CustomSubWebhookListenerConf record {\n    string host = \"\";\n};\n\npublic type CustomSubMockActionEvent record {|\n    string action;\n|};\n\npublic type CustomSubMockDomainEvent record {|\n    string domain;\n|};\n\n@websub:SubscriberServiceConfig {}\nservice websub:SubscriberService /key on new CustomSubWebhookServerForPayload(23585) {\n    remote function onIntentVerification(websub:Caller caller, websub:IntentVerificationRequest verRequest) {\n        storeOutput(ID_INTENT_VER_REQ_RECEIVED_LOG, \"Intent verification request received\");\n        checkpanic caller->accepted();\n    }\n\n    remote function onCreated(websub:Notification notification, CustomSubMockActionEvent event) {\n        storeOutput(ID_BY_KEY_CREATED_LOG,  \"Created Notification Received, action: \" + <@untainted>event.action);\n    }\n\n    remote function onFeature(websub:Notification notification, CustomSubMockDomainEvent event) {\n        storeOutput(ID_BY_KEY_FEATURE_LOG, \"Feature Notification Received, domain: \" +  <@untainted>event.domain);\n    }\n\n    remote function onStatus(websub:Notification notification, CustomSubMockActionEvent event) {\n        // do nothing - test start up\n    }\n}\n\n@websub:SubscriberServiceConfig {}\nservice websub:SubscriberService /header on new CustomSubWebhookServerForHeader(23686) {\n    remote function onIssue(websub:Notification notification, CustomSubMockActionEvent event) {\n        string msg = \"Issue Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n                                 \" action: \" +  <@untainted>event.action;\n        storeOutput(ID_BY_HEADER_ISSUE_LOG, msg);\n    }\n\n    remote function onCommit(websub:Notification notification, CustomSubMockActionEvent event) {\n        string msg = \"Commit Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n                                 \" action: \" + <@untainted>event.action;\n        storeOutput(ID_BY_HEADER_COMMIT_LOG, msg);\n    }\n\n    remote function onStatus(websub:Notification notification, CustomSubMockActionEvent event) {\n        // do nothing - test start up\n    }\n}\n\n@websub:SubscriberServiceConfig {}\nservice websub:SubscriberService /headerAndPayload on new CustomSubWebhookServerForHeaderAndPayload(23787) {\n    remote function onIssueCreated(websub:Notification notification, CustomSubMockActionEvent event) {\n        string msg = \"Issue Created Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n            \" action: \" +  <@untainted>event.action;\n        storeOutput(ID_BY_HEADER_AND_PAYLOAD_ISSUE_CREATED_LOG, msg);\n\n    }\n\n    remote function onFeaturePull(websub:Notification notification, CustomSubMockDomainEvent event) {\n        string msg = \"Feature Pull Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n            \" domain: \" +  <@untainted>event.domain;\n        storeOutput(ID_BY_HEADER_AND_PAYLOAD_FEATURE_PULL_LOG, msg);\n    }\n\n    remote function onHeaderOnly(websub:Notification notification, CustomSubMockActionEvent event) {\n        string msg = \"HeaderOnly Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n            \" action: \" +  <@untainted>event.action;\n        storeOutput(ID_BY_HEADER_AND_PAYLOAD_HEADER_ONLY_LOG, msg);\n    }\n\n    remote function onKeyOnly(websub:Notification notification, CustomSubMockActionEvent event) {\n        string msg = \"KeyOnly Notification Received, header value: \" + <@untainted>notification.getHeader(CUSTOM_SUB_MOCK_HEADER) +\n            \" action: \" +  <@untainted>event.action;\n        storeOutput(ID_BY_HEADER_AND_PAYLOAD_KEY_ONLY_LOG, msg);\n    }\n\n    remote function onStatus(websub:Notification notification, CustomSubMockActionEvent event) {\n        // do nothing - test start up\n    }\n}\n\n/////////////////// Specific Webhook for dispatching by key ///////////////////\npublic class CustomSubWebhookServerForPayload {\n\n    private websub:Listener websubListener;\n\n    public function init(int port, CustomSubWebhookListenerConf? config = ()) {\n        websub:ExtensionConfig extensionConfig = {\n            topicIdentifier: websub:TOPIC_ID_PAYLOAD_KEY,\n            payloadKeyResourceMap: {\n                \"action\" : {\n                    \"created\" : [\"onCreated\", CustomSubMockActionEvent],\n                    \"deleted\" : [\"onDeleted\", CustomSubMockActionEvent],\n                    \"statuscheck\" : [\"onStatus\", CustomSubMockActionEvent]\n                },\n                \"domain\" : {\n                    \"issue\" : [\"onIssue\", CustomSubMockDomainEvent],\n                    \"feature\" : [\"onFeature\", CustomSubMockDomainEvent]\n                }\n            }\n        };\n        string host = config is () ? \"\" : config.host;\n        websub:SubscriberListenerConfiguration sseConfig = {\n            host: host,\n            extensionConfig: extensionConfig\n        };\n        self.websubListener = new(port, sseConfig);\n    }\n\n    public function attach(websub:SubscriberService s, string[]|string? name = ()) returns error? {\n        return self.websubListener.attach(s, name);\n    }\n\n    public function detach(websub:SubscriberService s) returns error? {\n        return self.websubListener.detach(s);\n    }\n\n    public function 'start() returns error? {\n        return self.websubListener.'start();\n    }\n\n    public function gracefulStop() returns error? {\n        return ();\n    }\n\n    public function immediateStop() returns error? {\n        return self.websubListener.immediateStop();\n    }\n}\n\n/////////////////// Specific Webhook for dispatching by header ///////////////////\npublic class CustomSubWebhookServerForHeader {\n\n    private websub:Listener websubListener;\n\n    public function init(int port, CustomSubWebhookListenerConf? config = ()) {\n        websub:ExtensionConfig extensionConfig = {\n            topicIdentifier: websub:TOPIC_ID_HEADER,\n            topicHeader: CUSTOM_SUB_MOCK_HEADER,\n            headerResourceMap: {\n                \"issue\" : [\"onIssue\", CustomSubMockActionEvent],\n                \"commit\" : [\"onCommit\", CustomSubMockActionEvent],\n                \"status\" : [\"onStatus\", CustomSubMockActionEvent]\n            }\n        };\n        string host = config is () ? \"\" : config.host;\n        websub:SubscriberListenerConfiguration sseConfig = {\n            host: host,\n            extensionConfig: extensionConfig\n        };\n        self.websubListener = new(port, sseConfig);\n    }\n\n    public function attach(websub:SubscriberService s, string[]|string? name = ()) returns error? {\n        return self.websubListener.attach(s, name);\n    }\n\n    public function detach(websub:SubscriberService s) returns error? {\n        return self.websubListener.detach(s);\n    }\n\n    public function 'start() returns error? {\n        return self.websubListener.'start();\n    }\n\n    public function gracefulStop() returns error? {\n        return ();\n    }\n\n    public function immediateStop() returns error? {\n        return self.websubListener.immediateStop();\n    }\n}\n\n/////////////////// Specific Webhook for dispatching by header and payload ///////////////////\npublic class CustomSubWebhookServerForHeaderAndPayload {\n\n    private websub:Listener websubListener;\n\n    public function init(int port, CustomSubWebhookListenerConf? config = ()) {\n        websub:ExtensionConfig extensionConfig = {\n            topicIdentifier: websub:TOPIC_ID_HEADER_AND_PAYLOAD,\n            topicHeader: CUSTOM_SUB_MOCK_HEADER,\n            headerResourceMap: {\n                \"headeronly\" : [\"onHeaderOnly\", CustomSubMockActionEvent],\n                \"status\" : [\"onStatus\", CustomSubMockActionEvent]\n            },\n            payloadKeyResourceMap: {\n                \"action\" : {\n                    \"keyonly\" : [\"onKeyOnly\", CustomSubMockActionEvent]\n                },\n                \"domain\" : {\n                    \"domainkeyonly\" : [\"onDomainKeyOnly\", CustomSubMockDomainEvent]\n                }\n            },\n            headerAndPayloadKeyResourceMap: {\n                \"issue\" : {\n                    \"action\" : {\n                        \"created\" : [\"onIssueCreated\", CustomSubMockActionEvent],\n                        \"deleted\" : [\"onIssueDeleted\", CustomSubMockActionEvent]\n                    }\n                },\n                \"pull\" : {\n                    \"domain\" : {\n                        \"bugfix\" : [\"onBugFixPull\", CustomSubMockDomainEvent],\n                        \"feature\" : [\"onFeaturePull\", CustomSubMockDomainEvent]\n                    }\n                }\n            }\n        };\n        string host = config is () ? \"\" : config.host;\n        websub:SubscriberListenerConfiguration sseConfig = {\n            host: host,\n            extensionConfig: extensionConfig\n        };\n        self.websubListener = new(port, sseConfig);\n    }\n\n    public function attach(websub:SubscriberService s, string[]|string? name = ()) returns error? {\n        return self.websubListener.attach(s, name);\n    }\n\n    public function detach(websub:SubscriberService s) returns error? {\n        return self.websubListener.detach(s);\n    }\n\n    public function 'start() returns error? {\n        return self.websubListener.'start();\n    }\n\n    public function gracefulStop() returns error? {\n        return ();\n    }\n\n    public function immediateStop() returns error? {\n        return self.websubListener.immediateStop();\n    }\n}\n\n@test:Config {}\nfunction testOnIntentVerificationInvocation() {\n    http:Client clientEndpoint = new (\"http://localhost:23585\");\n    var response = clientEndpoint->get(\"/key\");\n    test:assertEquals(fetchOutput(ID_INTENT_VER_REQ_RECEIVED_LOG), INTENT_VER_REQ_RECEIVED_LOG);\n}\n\n@test:Config {\n    dependsOn: [testOnIntentVerificationInvocation]\n}\nfunction testDispatchingByKey() {\n    http:Client clientEndpoint = new (\"http://localhost:23585\");\n    json jsonPayload1 = {action: \"created\"};\n    json jsonPayload2 = {domain: \"feature\"};\n    http:Request req1 = new;\n    req1.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req1.setJsonPayload(jsonPayload1);\n    http:Request req2 = new;\n    req2.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req2.setJsonPayload(jsonPayload2);\n\n    var response = clientEndpoint->post(\"/key\", req1);\n    HttpResponseDetails responseDetails = fetchHttpResponse(response);\n    test:assertEquals(responseDetails.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_KEY_CREATED_LOG), BY_KEY_CREATED_LOG);\n\n    response = clientEndpoint->post(\"/key\", req2);\n    responseDetails = fetchHttpResponse(response);\n    test:assertEquals(responseDetails.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_KEY_FEATURE_LOG), BY_KEY_FEATURE_LOG);\n}\n\n@test:Config {\n    dependsOn: [testDispatchingByKey],\n    enable:false\n}\nfunction testDispatchingByHeader() {\n    http:Client clientEndpoint = new (\"http://localhost:23686\");\n    json jsonPayload1 = {action: \"deleted\"};\n    json jsonPayload2 = {action: \"created\"};\n    http:Request req1 = new;\n    req1.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req1.addHeader(CUSTOM_SUB_MOCK_HEADER, \"issue\");\n    req1.setJsonPayload(jsonPayload1);\n    http:Request req2 = new;\n    req2.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req2.addHeader(CUSTOM_SUB_MOCK_HEADER, \"commit\");\n    req2.setJsonPayload(jsonPayload2);\n\n    var response1 = clientEndpoint->post(\"/header\", req1);\n    HttpResponseDetails responseDetails1 = fetchHttpResponse(response1);\n    test:assertEquals(responseDetails1.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_ISSUE_LOG), BY_HEADER_ISSUE_LOG);\n\n    var response2 = clientEndpoint->post(\"/header\", req2);\n    HttpResponseDetails responseDetails2 = fetchHttpResponse(response2);\n    test:assertEquals(responseDetails2.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_COMMIT_LOG), BY_HEADER_COMMIT_LOG);\n}\n\n@test:Config {enable: false}\nfunction testDispatchingByHeaderAndPayloadKey() {\n    http:Client clientEndpoint = new (\"http://localhost:23787\");\n    json jsonPayload1 = {action: \"created\"};\n    json jsonPayload2 = {domain: \"feature\"};\n    http:Request req1 = new;\n    req1.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req1.addHeader(CUSTOM_SUB_MOCK_HEADER, \"issue\");\n    req1.setJsonPayload(jsonPayload1);\n    http:Request req2 = new;\n    req2.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req2.addHeader(CUSTOM_SUB_MOCK_HEADER, \"pull\");\n    req2.setJsonPayload(jsonPayload2);\n\n    var response1 = clientEndpoint->post(\"/headerAndPayload\", req1);\n    HttpResponseDetails responseDetails1 = fetchHttpResponse(response1);\n    test:assertEquals(responseDetails1.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_AND_PAYLOAD_ISSUE_CREATED_LOG), BY_HEADER_AND_PAYLOAD_ISSUE_CREATED_LOG);\n\n    var response2 = clientEndpoint->post(\"/headerAndPayload\", req2);\n    HttpResponseDetails responseDetails2 = fetchHttpResponse(response2);\n    test:assertEquals(responseDetails2.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_AND_PAYLOAD_FEATURE_PULL_LOG), BY_HEADER_AND_PAYLOAD_FEATURE_PULL_LOG);\n}\n\n@test:Config {enable: false}\nfunction testDispatchingByHeaderAndPayloadKeyForOnlyHeader() {\n    http:Client clientEndpoint = new (\"http://localhost:23787\");\n    json jsonPayload = {action: \"header_only\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.addHeader(CUSTOM_SUB_MOCK_HEADER, \"headeronly\");\n    req.setJsonPayload(jsonPayload);\n\n    var response = clientEndpoint->post(\"/headerAndPayload\", req);\n    HttpResponseDetails responseDetails = fetchHttpResponse(response);\n    test:assertEquals(responseDetails.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_AND_PAYLOAD_HEADER_ONLY_LOG), BY_HEADER_AND_PAYLOAD_HEADER_ONLY_LOG);\n}\n\n@test:Config {\n    dependsOn: [testDispatchingByHeaderAndPayloadKeyForOnlyHeader],\n    enable:false\n}\nfunction testDispatchingByHeaderAndPayloadKeyForOnlyKey() {\n    http:Client clientEndpoint = new (\"http://localhost:23787\");\n    json jsonPayload = {action: \"keyonly\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.addHeader(CUSTOM_SUB_MOCK_HEADER, \"key_only\");\n    req.setJsonPayload(jsonPayload);\n\n    var response = clientEndpoint->post(\"/headerAndPayload\", req);\n    HttpResponseDetails responseDetails = fetchHttpResponse(response);\n    test:assertEquals(responseDetails.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    test:assertEquals(fetchOutput(ID_BY_HEADER_AND_PAYLOAD_KEY_ONLY_LOG), BY_HEADER_AND_PAYLOAD_KEY_ONLY_LOG);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_different_content_type_subscribers.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/mime;\nimport ballerina/test;\nimport ballerina/lang.runtime as runtime;\nimport ballerina/http;\nimport ballerina/websub;\n\nlistener websub:Listener websubDifContentTypeEP = new websub:Listener(23282);\n\n@websub:SubscriberServiceConfig {\n    target: [\"http://localhost:23191/websub/hub\", \"http://one.websub.topic.com\"],\n    leaseSeconds: 3000,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /websub on websubDifContentTypeEP {\n    remote function onNotification (websub:Notification notification) {\n        if (notification.getContentType() == mime:TEXT_PLAIN) {\n            var payload = notification.getTextPayload();\n            if (payload is string) {\n                storeOutput(ID_TEXT_SUBSCRIBER_ONE, \"Text WebSub Notification Received by websubSubscriber: \" + <@untainted>payload);\n            } else {\n                panic payload;\n            }\n        } else if (notification.getContentType() == mime:APPLICATION_XML) {\n            var payload = notification.getXmlPayload();\n            if (payload is xml) {\n                storeOutput(ID_XML_SUBSCRIBER_ONE, \"XML WebSub Notification Received by websubSubscriber: \" + <@untainted>payload.toString());\n            } else {\n                panic payload;\n            }\n        } else if (notification.getContentType() == mime:APPLICATION_JSON) {\n            var payload = notification.getJsonPayload();\n            if (payload is json) {\n                storeOutput(ID_JSON_SUBSCRIBER_ONE, \"JSON WebSub Notification Received by websubSubscriber: \" + <@untainted>payload.toJsonString());\n            } else {\n                panic payload;\n            }\n        }\n    }\n}\n\n@websub:SubscriberServiceConfig {\n    path:\"/websubTwo\",\n    subscribeOnStartUp:true,\n    target: [\"http://localhost:23191/websub/hub\", \"http://one.websub.topic.com\"],\n    leaseSeconds: 1000\n}\nservice websub:SubscriberService /websubTwo on websubDifContentTypeEP {\n    remote function onNotification (websub:Notification notification) {\n        if (notification.getContentType() == mime:TEXT_PLAIN) {\n            var payload = notification.getTextPayload();\n            if (payload is string) {\n                storeOutput(ID_TEXT_SUBSCRIBER_TWO, \"Text WebSub Notification Received by websubSubscriberTwo: \" + <@untainted>payload);\n            } else {\n                panic payload;\n            }\n        } else if (notification.getContentType() == mime:APPLICATION_XML) {\n            var payload = notification.getXmlPayload();\n            if (payload is xml) {\n                storeOutput(ID_XML_SUBSCRIBER_TWO, \"XML WebSub Notification Received by websubSubscriberTwo: \" + <@untainted>payload.toString());\n            } else {\n                panic payload;\n            }\n        } else if (notification.getContentType() == mime:APPLICATION_JSON) {\n            var payload = notification.getJsonPayload();\n            if (payload is json) {\n                storeOutput(ID_JSON_SUBSCRIBER_TWO, \"JSON WebSub Notification Received by websubSubscriberTwo: \" + <@untainted>payload.toJsonString());\n            } else {\n                panic payload;\n            }\n        }\n    }\n}\n\n@test:Config {\n    dependsOn: [testUnsubscription]\n}\nfunction testTextContentReceiptForInternalHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + \"23282\", HUB_MODE_INTERNAL, TYPE_STRING);\n    runtime:sleep(5);\n    test:assertEquals(fetchOutput(ID_TEXT_SUBSCRIBER_ONE), TEXT_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_TEXT_SUBSCRIBER_TWO), TEXT_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\n@test:Config {\n    dependsOn: [testTextContentReceiptForInternalHub]\n}\nfunction testTextContentReceiptForRemoteHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + SKIP_SUBSCRIBER_CHECK, HUB_MODE_REMOTE, TYPE_STRING);\n    runtime:sleep(5);\n    test:assertEquals(fetchOutput(ID_TEXT_SUBSCRIBER_ONE), TEXT_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_TEXT_SUBSCRIBER_TWO), TEXT_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\n@test:Config {\n    dependsOn: [testTextContentReceiptForRemoteHub]\n}\nfunction testXmlContentReceiptForInternalHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + SKIP_SUBSCRIBER_CHECK, HUB_MODE_INTERNAL, TYPE_XML);\n    runtime:sleep(5);\n    test:assertEquals(fetchOutput(ID_XML_SUBSCRIBER_ONE), XML_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_XML_SUBSCRIBER_TWO), XML_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\n@test:Config {\n    dependsOn: [testXmlContentReceiptForInternalHub]\n}\nfunction testXmlContentReceiptForRemoteHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + SKIP_SUBSCRIBER_CHECK, HUB_MODE_REMOTE, TYPE_XML);\n    runtime:sleep(5);\n    test:assertEquals(fetchOutput(ID_XML_SUBSCRIBER_ONE), XML_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_XML_SUBSCRIBER_TWO), XML_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\n@test:Config {\n    dependsOn: [testXmlContentReceiptForRemoteHub]\n}\nfunction testJsonContentReceiptForInternalHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + SKIP_SUBSCRIBER_CHECK, HUB_MODE_INTERNAL, TYPE_JSON);\n    runtime:sleep(10);\n    test:assertEquals(fetchOutput(ID_JSON_SUBSCRIBER_ONE), JSON_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_JSON_SUBSCRIBER_TWO), JSON_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\n@test:Config {\n    dependsOn: [testJsonContentReceiptForInternalHub]\n}\nfunction testJsonContentReceiptForRemoteHub() {\n    sendSubscriptionAndIntentVerificationRequest(COMMON_PATH + SKIP_SUBSCRIBER_CHECK, HUB_MODE_REMOTE, TYPE_JSON);\n    runtime:sleep(10);\n    test:assertEquals(fetchOutput(ID_JSON_SUBSCRIBER_ONE), JSON_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_JSON_SUBSCRIBER_TWO), JSON_REMOTE_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n\nfunction sendSubscriptionAndIntentVerificationRequest (string path, string mode, string contentType) {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    json jsonPayload = {mode: mode, content_type: contentType};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.setJsonPayload(jsonPayload);\n    var response = clientEndpoint->post(path, req);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_multiple_subscribers.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/test;\nimport ballerina/lang.runtime as runtime;\nimport ballerina/websub;\n\nlistener websub:Listener multipleSubTestWebsubEP = new websub:Listener(23383);\n\n// Following listner has no services attached with and it should not fail the listener start\nlistener websub:Listener websubEndPointWithNoAttachedServices = new websub:Listener(23384);\n\n@websub:SubscriberServiceConfig {\n    target: [\"http://localhost:23191/websub/hub\", \"http://three.websub.topic.com\"],\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /websub on multipleSubTestWebsubEP {\n    remote function onNotification (websub:Notification notification) {\n        var payload = notification.getJsonPayload();\n        if (payload is json) {\n            storeOutput(ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG, \"WebSub Notification Received by One: \" + <@untainted>payload.toJsonString());\n        } else {\n            panic payload;\n        }\n    }\n}\n\n@websub:SubscriberServiceConfig {\n    target: \"http://localhost:23080/publisherTwo/discover\",\n    leaseSeconds: 1200,\n    secret: \"SwklSSf42DLA\"\n}\nservice websub:SubscriberService /websubTwo on multipleSubTestWebsubEP {\n    remote function onNotification (websub:Notification notification) {\n        var payload = notification.getJsonPayload();\n        if (payload is json) {\n            storeOutput(ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG, \"WebSub Notification Received by Two: \" + <@untainted>payload.toJsonString());\n        } else {\n            panic payload;\n        }\n    }\n}\n\n@test:Config {\n    dependsOn: [testJsonContentReceiptForRemoteHub],\n    enable: false\n}\nfunction testContentReceipt() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    json jsonPayload = {mode: \"internal\", content_type: \"json\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.setJsonPayload(jsonPayload);\n\n    var response = clientEndpoint->post(\"/publisherTwo/notify\", req);\n    runtime:sleep(5);\n    test:assertEquals(fetchOutput(ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG), INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_ONE_LOG);\n    test:assertEquals(fetchOutput(ID_INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG), INTERNAL_HUB_NOTIFICATION_SUBSCRIBER_TWO_LOG);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_redirected_subscribers.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/test;\nimport ballerina/websub;\n\nlistener websub:Listener redirectWebsubEP = new websub:Listener(23484);\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp:true,\n    target: \"http://localhost:23081/original/one\",\n    leaseSeconds: 3600,\n    secret: \"Kslk30SNF2AChs2\",\n    publisherClientConfig: { followRedirects: {\n            enabled: true\n        }\n    },\n    hubClientConfig: { followRedirects: {\n            enabled: true\n        }\n    }\n}\nservice websub:SubscriberService /websub on redirectWebsubEP {\n    remote function onNotification (websub:Notification notification) {\n        var payload = notification.getJsonPayload();\n        if (payload is json) {\n            io:println(\"WebSub Notification Received: \" + payload.toJsonString());\n        } else {\n            panic payload;\n        }\n    }\n}\n\n@websub:SubscriberServiceConfig {\n    target: \"http://localhost:23081/original/two\",\n    leaseSeconds: 1200,\n    secret: \"SwklSSf42DLA\",\n    publisherClientConfig: { followRedirects: {\n            enabled: true\n        }\n    },\n    hubClientConfig: { followRedirects: {\n            enabled: true\n        }\n    }\n}\nservice websub:SubscriberService /websubTwo on redirectWebsubEP {\n    remote function onNotification (websub:Notification notification) {\n        var payload = notification.getJsonPayload();\n        if (payload is json) {\n            io:println(\"WebSub Notification Received: \" + payload.toJsonString());\n        } else {\n            panic payload;\n        }\n    }\n}\n\n@test:Config {\n    dependsOn: [testJsonContentReceiptForRemoteHub],\n    enable: false\n}\nfunction testTopicMovedPermanentlyAndHubTemporaryRedirect() {\n    test:assertEquals(fetchOutput(ID_REDIRECT_SUBSCRIBER_ONE_LOG), REDIRECT_SUBSCRIBER_ONE_LOG);\n}\n\n@test:Config {\n    dependsOn: [testJsonContentReceiptForRemoteHub],\n    enable: false\n}\nfunction testTopicRedirectFoundAndHubPermanentRedirect() {\n    test:assertEquals(fetchOutput(ID_REDIRECT_SUBSCRIBER_TWO_LOG), REDIRECT_SUBSCRIBER_TWO_LOG);\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_subscriber.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/http;\nimport ballerina/lang.runtime as runtime;\nimport ballerina/stringutils;\nimport ballerina/test;\nimport ballerina/websub;\n\nlistener websub:Listener websubEP = new websub:Listener(23181, { host: \"0.0.0.0\" });\n\n@websub:SubscriberServiceConfig {\n    subscribeOnStartUp:true,\n    target: [\"http://localhost:23191/websub/hub\", \"http://one.websub.topic.com\"]\n}\nservice websub:SubscriberService /websub on websubEP {\n    remote function onNotification (websub:Notification notification) {\n        json payload = <json> checkpanic notification.getJsonPayload();\n        storeOutput(ID_HUB_NOTIFICATION_LOG, \"WebSub Notification Received: \" + <@untainted>payload.toJsonString());\n        io:println(\"WebSub Notification Received: \" + <@untainted>payload.toJsonString());\n    }\n}\n\n@websub:SubscriberServiceConfig {\n    target: [\"http://localhost:23191/websub/hub\", \"http://one.websub.topic.com\"],\n    leaseSeconds: 3650,\n    secret: \"Kslk30SNF2AChs2\"\n}\nservice websub:SubscriberService /subscriberWithNoPathInAnnot on websubEP {\n    remote function onIntentVerification (websub:Caller caller, websub:IntentVerificationRequest request) {\n        http:Response response = request.buildSubscriptionVerificationResponse(\"http://one.websub.topic.com\");\n        if (response.statusCode == 202) {\n            storeOutput(ID_EXPLICIT_INTENT_VERIFICATION_LOG, \"Intent verified explicitly for subscription change request\");\n        } else {\n            io:println(\"Intent verification denied explicitly for subscription change request\");\n        }\n        var result = caller->respond(<@untainted> response);\n        if (result is error) {\n            io:println(\"Error responding to intent verification request: \", result);\n        }\n    }\n\n    remote function onNotification (websub:Notification notification) {\n        string payload = <string> checkpanic notification.getTextPayload();\n        storeOutput(ID_HUB_NOTIFICATION_LOG_TWO, \"WebSub Notification Received by Two: \" + <@untainted>payload);\n        io:println(\"WebSub Notification Received by Two: \" + <@untainted>payload);\n    }\n}\n\nstring subscriberThreeTopic = \"http://one.websub.topic.com\";\n\n@websub:SubscriberServiceConfig {\n    path:\"/websubThree\",\n    subscribeOnStartUp:true,\n    target: [\"http://localhost:23191/websub/hub\", subscriberThreeTopic],\n    leaseSeconds: 300,\n    callback: \"http://localhost:23181/websubThree?topic=\" + subscriberThreeTopic + \"&fooVal=barVal\",\n    secret: \"Xaskdnfe234\"\n}\nservice websub:SubscriberService /websubThree on websubEP {\n    remote function onNotification (websub:Notification notification) {\n        string payload = <string> checkpanic notification.getTextPayload();\n        io:println(\"WebSub Notification Received by Three: \", payload);\n        io:println(\"Query Params: \", notification.getQueryParams());\n        storeOutput(ID_QUERY_PARAM_LOG, \"Query Params: \" + <@untainted>notification.getQueryParams().toString());\n    }\n}\n\n@test:Config {}\nfunction testSubscriptionAndAutomaticIntentVerification() {\n    test:assertEquals(fetchOutput(ID_EXPLICIT_INTENT_VERIFICATION_LOG), EXPLICIT_INTENT_VERIFICATION_LOG);\n}\n\n@test:Config {\n    dependsOn: [testSubscriptionAndAutomaticIntentVerification]\n}\nfunction testContentInternalHubNotification() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    json jsonPayload = {mode: \"internal\", content_type: \"json\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.setJsonPayload(jsonPayload);\n    var response = clientEndpoint->post(\"/publisher/notify/23181\", req);\n    runtime:sleep(5);\n\n    test:assertEquals(fetchOutput(ID_HUB_NOTIFICATION_LOG), INTERNAL_HUB_NOTIFICATION_LOG);\n    test:assertEquals(fetchOutput(ID_HUB_NOTIFICATION_LOG_TWO), INTERNAL_HUB_NOTIFICATION_LOG_TWO);\n}\n\n@test:Config {\n    dependsOn: [testContentInternalHubNotification]\n}\nfunction testContentRemoteHubNotification() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    json jsonPayload = {mode: \"remote\", content_type: \"json\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.setJsonPayload(jsonPayload);\n    var response = clientEndpoint->post(\"/publisher/notify/23181\", req);\n    runtime:sleep(5);\n\n    test:assertEquals(fetchOutput(ID_HUB_NOTIFICATION_LOG), REMOTE_HUB_NOTIFICATION_LOG);\n    test:assertEquals(fetchOutput(ID_HUB_NOTIFICATION_LOG_TWO), REMOTE_HUB_NOTIFICATION_LOG_TWO);\n}\n\n@test:Config {\n    dependsOn: [testContentRemoteHubNotification]\n}\nfunction testContentReceiptForCallbackWithQueryParams() {\n    test:assertEquals(fetchOutput(ID_QUERY_PARAM_LOG), QUERY_PARAM_LOG);\n}\n\n@test:Config {\n    dependsOn: [testContentReceiptForCallbackWithQueryParams]\n}\nfunction testRemoteTopicRegistration() {\n    http:Client clientEndpoint = new (\"http://localhost:23191\");\n    http:Request req = new;\n    req.setPayload(\"hub.mode=subscribe&hub.topic=http%3A//two.websub.topic.com&hub.callback=http%3A//localhost%3A23181/websub\");\n    var s = req.setContentType(CONTENT_TYPE_FORM_URL_ENCODED);\n    req.addHeader(http:CONTENT_TYPE, \"application/x-www-form-urlencoded\");\n    var response = clientEndpoint->post(\"/websub/hub\", req);\n    if (response is http:Response) {\n        test:assertEquals(response.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    } else {\n       test:assertFail(msg = \"Unexpected response\");\n    }\n}\n\n@test:Config {\n    dependsOn: [testRemoteTopicRegistration]\n}\nfunction testSubscriberDetailsRetrievalFromHub() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    http:Request req = new;\n    req.setHeader(\"x-topic\", \"http://one.websub.topic.com\");\n    req.setHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    var response = clientEndpoint->get(\"/publisher/topicInfo\", req);\n    HttpResponseDetails httpResponseDetails = fetchHttpResponse(response);\n    test:assertEquals(httpResponseDetails.statusCode, http:STATUS_OK);\n    test:assertTrue(stringutils:contains(httpResponseDetails.responseMessage, \"\\\"callback\\\":\\\"http://localhost:23181/websub\\\"\"));\n    test:assertTrue(\n        stringutils:contains(httpResponseDetails.responseMessage,\n        \"\\\"callback\\\":\\\"http://localhost:23181/subscriberWithNoPathInAnnot\\\"\")\n    );\n    test:assertTrue(\n        stringutils:contains(httpResponseDetails.responseMessage,\n        \"\\\"callback\\\":\\\"http://localhost:23181/websubThree?topic=http://one.websub.topic.com&fooVal=barVal\\\"\")\n    );\n}\n\n@test:Config {\n    dependsOn: [testSubscriberDetailsRetrievalFromHub]\n}\nfunction testAvailableTopicsRetrievalFromHub() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    http:Request req = new;\n    var response = clientEndpoint->get(\"/publisher/topicInfo\", req);\n\n    HttpResponseDetails httpResponseDetails = fetchHttpResponse(response);\n    io:println(httpResponseDetails);\n    string expectedData = \"{\\\"Topic_1\\\":\\\"http://one.websub.topic.com\\\", \" +\n                           \"\\\"Topic_2\\\":\\\"http://three.websub.topic.com\\\", \\\"Topic_3\\\":\\\"http://four.websub.topic.com\\\", \" +\n                           \"\\\"Topic_4\\\":\\\"http://one.redir.topic.com\\\", \\\"Topic_5\\\":\\\"http://two.redir.topic.com\\\", \" +\n                           \"\\\"Topic_6\\\":\\\"http://two.websub.topic.com\\\"}\";\n    test:assertEquals(httpResponseDetails.statusCode, http:STATUS_OK);\n    test:assertEquals(httpResponseDetails.responseMessage, expectedData);\n}\n\n@test:Config {\n    before: sendUnsubscription,\n    dependsOn: [testAvailableTopicsRetrievalFromHub]\n}\nfunction testUnsubscription() {\n    http:Client clientEndpoint = new (\"http://localhost:23080\");\n    var response = clientEndpoint->get(\"/publisher/unsubscribe\");\n    HttpResponseDetails responseDetails = fetchHttpResponse(response);\n    test:assertEquals(responseDetails.responseMessage, \"unsubscription successful\", msg = \"Mismatched\");\n\n    json jsonPayload = {mode: \"internal\", content_type: \"json\"};\n    http:Request req = new;\n    req.addHeader(http:CONTENT_TYPE, CONTENT_TYPE_JSON);\n    req.setJsonPayload(jsonPayload);\n    var postResponse = clientEndpoint->post(\"/publisher/notify/skip_subscriber_check\", req);\n    runtime:sleep(5);\n    if (postResponse is http:Response) {\n        test:assertEquals(postResponse.statusCode, http:STATUS_ACCEPTED, msg = \"Response code mismatched\");\n    } else {\n        test:assertFail(msg = \"Unexpected response\");\n    }\n\n}\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_subscriber_startup.bal",
    "content": "// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\nimport ballerina/log;\nimport ballerina/test;\nimport ballerina/io;\nimport ballerina/config;\nimport ballerina/websub;\nimport ballerina/websubhub;\n\nlistener http:Listener testSubscriber = new(23386);\nlistener http:Listener testHub = new(23190);\n\nservice websub:SubscriberService /subscriber on testSubscriber {\n    resource function get 'start(http:Caller caller, http:Request request) returns error? {\n\n        websub:Listener l1 = new(23387);\n        websub:Listener l2 = new(23387);\n\n        string responseMsg = \"\";\n        var l1Error = l1.'start();\n        if (l1Error is error) {\n            log:printError(\"listener_1 has not started\");\n            string errMsg = l1Error.message();\n            return caller->respond(errMsg);\n        }\n        log:print(\"listener_1 has started\");\n\n        var l2Error = l2.'start();\n        if (l2Error is error) {\n            log:printError(\"listener_2 has not started\");\n            responseMsg = l2Error.message();\n        } else {\n            responseMsg = \"listener_2 has started\";\n        }\n        l1Error = l1.gracefulStop();\n        l2Error = l2.gracefulStop();\n\n        return caller->respond(responseMsg);\n    }\n}\n\nservice /startupHub on testHub {\n    resource function get startup(http:Caller caller, http:Request request) returns error? {\n        http:Listener lis0 = new (23391);\n        http:Listener lis1 = new (23392);\n        websubhub:Hub|websubhub:HubStartedUpError|websubhub:HubStartupError res =\n            websubhub:startHub(lis0, \"/websub\", \"/hub\", \"/pub\", publicUrl = \"https://localhost:23391\");\n\n        if (res is websubhub:Hub) {\n            if (res.publishUrl != \"https://localhost:23391/websub/pub\" ||\n                    res.subscriptionUrl != \"https://localhost:23391/websub/hub\") {\n                return caller->respond(\"invalid publishUrl and subscriptionUrl\");\n            }\n        } else {\n            io:println(res);\n            return caller->respond(\"hub(lis0) start up error\");\n        }\n\n        // testHubStartUpWhenStarted\n        websubhub:Hub|websubhub:HubStartedUpError|websubhub:HubStartupError res2 = websubhub:startHub(lis1);\n\n        if !(res2 is websubhub:HubStartedUpError) || res2.startedUpHub !== res {\n            return caller->respond(\"seperate hub(lis1) has started\");\n        }\n\n        // testHubShutdownAndStart\n        websubhub:Hub hub = <websubhub:Hub> checkpanic res;\n        error? err = hub.stop();\n        if (err is error) {\n            io:println(err);\n            return caller->respond(\"hub(lis0) stop error\");\n        }\n\n        http:Listener lis2 = new (23393);\n        res2 = websubhub:startHub(lis2);\n        if res2 is websubhub:Hub {\n            string responseMsg = res2.publishUrl == \"http://localhost:23393/publish\" && res2.subscriptionUrl ==\n                            \"http://localhost:23393/\" ? \"hub(lis2) start successfully\" :\n                            \"incorrect hub(lis2) has started\";\n            err = res2.stop();\n            return caller->respond(responseMsg);\n        }\n        return caller->respond(\"hub(lis2) start up error\");\n    }\n\n    resource function get testPublisherAndSubscriptionInvalidSameResourcePath(http:Caller caller, http:Request request)\n                                                                                                    returns error? {\n        http:Listener lis = new (23394);\n        websubhub:Hub|websubhub:HubStartedUpError|websubhub:HubStartupError res =\n            websubhub:startHub(lis, \"/websub\", \"/hub\", \"/hub\");\n\n        var err = lis.gracefulStop();\n\n        if (res is websubhub:HubStartupError) {\n            return caller->respond(res.message());\n        }\n        return caller->respond(\"Unexpected result\");\n    }\n}\n\n@test:Config {\n    //dependsOn: [testJsonContentReceiptForRemoteHub]\n}\nfunction testMultipleSubscribersStartUpInSamePort() {\n    http:Client clientEndpoint = new (\"http://0.0.0.0:23386\");\n    var response = clientEndpoint->get(\"/subscriber/start\");\n    HttpResponseDetails responseDetails = fetchHttpResponse(response);\n\n    test:assertEquals(responseDetails.statusCode, http:STATUS_OK, msg = \"Response code mismatched\");\n    string expectedResponseMsg = \"failed to start server connector '0.0.0.0:23387': Address already in use: bind\";\n    if (config:getAsString(\"OS_TYPE\") == \"windows\") {\n        test:assertEquals(responseDetails.responseMessage, expectedResponseMsg);\n    } else {\n        expectedResponseMsg = \"failed to start server connector '0.0.0.0:23387': Address already in use\";\n        test:assertEquals(responseDetails.responseMessage, expectedResponseMsg);\n    }\n}\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/test_unsubscription_client.bal",
    "content": "// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/io;\nimport ballerina/lang.runtime as runtime;\nimport ballerina/websub;\n\nfunction sendUnsubscription() {\n    // This is the client used to send subscription and unsubscription requests.\n    websub:SubscriptionClient websubHubUnsubscribeClientEP = new (\"http://localhost:23191/websub/hub\");\n\n    // Send unsubscription request for the subscriber service.\n    websub:SubscriptionChangeRequest unsubscriptionRequest = {\n        topic: \"http://one.websub.topic.com\",\n        callback: \"http://localhost:23181/websub\"\n    };\n\n    var response = websubHubUnsubscribeClientEP->unsubscribe(unsubscriptionRequest);\n    if (response is websub:SubscriptionChangeResponse) {\n        io:println(\"Unsubscription Request successful at Hub [\" + response.hub + \"] for Topic [\" +\n                        response.topic + \"]\");\n    } else {\n        io:println(\"Error occurred with Unsubscription Request: \", response.cause());\n    }\n\n    // Confirm unsubscription - no notifications should be received.\n    runtime:sleep(5);\n}\n\n\n"
  },
  {
    "path": "stdlib-integration-tests/websub-generic/tests/utils.bal",
    "content": "// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n//\n// WSO2 Inc. licenses this file to you under the Apache License,\n// Version 2.0 (the \"License\"); you may not use this file except\n// in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\nimport ballerina/http;\n\ntype HttpResponseDetails record {\n    int statusCode;\n    string responseMessage;\n};\n\nmap<(anydata|error)> outputs = {};\n\npublic function storeOutput(string key, any|error... s) {\n    any|error statusCode = s[0];\n    outputs[key] = statusCode is error ? statusCode.toString() : statusCode.toString();\n}\n\npublic function fetchOutput(string key) returns (anydata|error) {\n    return outputs[key];\n}\n\nfunction fetchHttpResponse(http:Response|http:PayloadType|error response) returns HttpResponseDetails {\n    string responseMessage = \"\";\n    int statusCode = -1;\n    if (response is http:Response) {\n        statusCode = response.statusCode;\n        var msg = response.getTextPayload();\n        if (msg is string) {\n            responseMessage = msg;\n        } else {\n            responseMessage = \"Invalid payload received\";\n        }\n    } else {\n        responseMessage = \"Error when calling the backend\";\n    }\n    HttpResponseDetails httpResponseDetails = {\n        statusCode: statusCode,\n        responseMessage: responseMessage\n    };\n    return httpResponseDetails;\n}\n\n"
  }
]