├── .devcontainer ├── Dockerfile ├── devcontainer.json └── env-compose.yaml ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ ├── proposal.md │ └── question.md ├── pull_request_template.md └── workflows │ └── test.yaml ├── .gitignore ├── .vscode └── settings.json ├── CONTRIBUTING.MD ├── LICENSE ├── README.md ├── analysis_options.yaml ├── codecov ├── daprdocs ├── README.md └── content │ └── en │ ├── dart-sdk-contributing │ └── dart-contributing.md │ └── dart-sdk-docs │ ├── _index.md │ ├── dapr-client │ └── _index.md │ └── dapr-server │ └── _index.md ├── infrastructure └── gh_actions_components │ ├── client │ ├── bindings-mqtt.yaml │ ├── pubsub-redis.yaml │ ├── secret-envvars.yaml │ └── state-redis.yaml │ └── server │ ├── bindings-mqtt.yaml │ └── pubsub-redis.yaml ├── melos.yaml ├── melos_dapr_dart_sdk.iml └── packages ├── dapr_client ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example │ ├── dapr_client_example.dart │ ├── secrets_management │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── bin │ │ │ └── secrets_management.dart │ │ ├── components │ │ │ ├── local_secrets.json │ │ │ └── secrets_local.yaml │ │ ├── melos_secrets_management.iml │ │ └── pubspec.yaml │ └── state_management │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── bin │ │ └── state_management.dart │ │ ├── components │ │ └── state-redis.yaml │ │ ├── melos_state_management.iml │ │ └── pubspec.yaml ├── lib │ ├── dapr_client.dart │ └── src │ │ ├── abstractions │ │ ├── client.dart │ │ ├── client_actor.dart │ │ ├── client_binding.dart │ │ ├── client_invoker.dart │ │ ├── client_pubsub.dart │ │ ├── client_secrets.dart │ │ └── client_state.dart │ │ └── implementations │ │ ├── dapr_client.dart │ │ ├── grpc │ │ ├── grpc_binding.dart │ │ ├── grpc_client.dart │ │ ├── grpc_invoker.dart │ │ ├── grpc_pub_sub.dart │ │ ├── grpc_secret.dart │ │ └── grpc_state.dart │ │ └── http │ │ ├── http_binding.dart │ │ ├── http_client.dart │ │ ├── http_invoker.dart │ │ ├── http_pub_sub.dart │ │ ├── http_secret.dart │ │ └── http_state.dart ├── melos_dapr_client.iml ├── pubspec.yaml └── test │ ├── components │ ├── bindings-mqtt.yaml │ ├── pubsub-redis.yaml │ ├── secret-envvars.yaml │ └── state-redis.yaml │ ├── e2e │ ├── grpc │ │ └── grpc_test.dart │ └── http │ │ └── http_test.dart │ └── unit │ ├── dapr_client_test.dart │ └── env_defaults │ └── dapr_client_env_test.dart ├── dapr_common ├── .gitignore ├── CHANGELOG.md ├── README.md ├── analysis_options.yaml ├── example │ └── dapr_common_example.dart ├── lib │ ├── dapr_common.dart │ └── src │ │ ├── config │ │ └── dapr_config_constants.dart │ │ ├── enum │ │ ├── communication_protocol.dart │ │ ├── http_method.dart │ │ └── state_option_enums.dart │ │ ├── mocks │ │ ├── http_mocks.dart │ │ └── http_mocks.mocks.dart │ │ ├── models │ │ ├── client │ │ │ ├── client_type_definitions.dart │ │ │ └── generated │ │ │ │ ├── actor_models.dart │ │ │ │ ├── actor_models.freezed.dart │ │ │ │ ├── actor_models.g.dart │ │ │ │ ├── bindings_models.dart │ │ │ │ ├── bindings_models.freezed.dart │ │ │ │ ├── bindings_models.g.dart │ │ │ │ ├── pub_sub_models.dart │ │ │ │ ├── pub_sub_models.freezed.dart │ │ │ │ ├── pub_sub_models.g.dart │ │ │ │ ├── secret_models.dart │ │ │ │ ├── secret_models.freezed.dart │ │ │ │ ├── secret_models.g.dart │ │ │ │ ├── state_models.dart │ │ │ │ ├── state_models.freezed.dart │ │ │ │ └── state_models.g.dart │ │ └── server │ │ │ ├── generated │ │ │ ├── bindings_models.dart │ │ │ ├── bindings_models.freezed.dart │ │ │ ├── bindings_models.g.dart │ │ │ ├── invoker_models.dart │ │ │ ├── invoker_models.freezed.dart │ │ │ ├── invoker_models.g.dart │ │ │ ├── pub_sub_models.dart │ │ │ ├── pub_sub_models.freezed.dart │ │ │ └── pub_sub_models.g.dart │ │ │ └── server_type_definitions.dart │ │ └── utils │ │ └── utils.dart ├── melos_dapr_common.iml ├── pubspec.yaml └── test │ └── dapr_common_test.dart ├── dapr_proto ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example │ └── dapr_proto_example.dart ├── lib │ ├── dapr_proto.dart │ └── src │ │ └── proto │ │ ├── dapr │ │ └── proto │ │ │ ├── common │ │ │ └── v1 │ │ │ │ ├── common.pb.dart │ │ │ │ ├── common.pbenum.dart │ │ │ │ ├── common.pbjson.dart │ │ │ │ └── common.proto │ │ │ └── runtime │ │ │ └── v1 │ │ │ ├── appcallback.pb.dart │ │ │ ├── appcallback.pbenum.dart │ │ │ ├── appcallback.pbgrpc.dart │ │ │ ├── appcallback.pbjson.dart │ │ │ ├── appcallback.proto │ │ │ ├── dapr.pb.dart │ │ │ ├── dapr.pbenum.dart │ │ │ ├── dapr.pbgrpc.dart │ │ │ ├── dapr.pbjson.dart │ │ │ └── dapr.proto │ │ └── google │ │ └── protobuf │ │ ├── any.pb.dart │ │ ├── any.pbenum.dart │ │ ├── any.pbjson.dart │ │ ├── any.proto │ │ ├── empty.pb.dart │ │ ├── empty.pbenum.dart │ │ ├── empty.pbjson.dart │ │ └── empty.proto ├── melos_dapr_proto.iml ├── pubspec.yaml ├── scripts │ └── sh │ │ └── update_dapr_grpc.sh └── test │ └── dapr_proto_test.dart └── dapr_server ├── .gitignore ├── CHANGELOG.md ├── README.md ├── analysis_options.yaml ├── example ├── dapr_server_example.dart └── service_invoker │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── analysis_options.yaml │ ├── bin │ └── service_invoker.dart │ ├── melos_service_invoker.iml │ └── pubspec.yaml ├── lib ├── dapr_server.dart └── src │ ├── abstractions │ ├── server.dart │ ├── server_actor.dart │ ├── server_binding.dart │ ├── server_invoker.dart │ └── server_pub_sub.dart │ ├── exceptions │ └── dapr_server_exceptions.dart │ └── implementations │ ├── dapr_server.dart │ ├── grpc │ ├── grpc_binding.dart │ ├── grpc_invoker.dart │ ├── grpc_pubsub.dart │ ├── grpc_server.dart │ └── grpc_server_impl.dart │ └── http │ ├── http_bindings.dart │ ├── http_invoker.dart │ ├── http_pub_sub.dart │ ├── http_server.dart │ └── http_server_impl.dart ├── melos_dapr_server.iml ├── pubspec.yaml └── test ├── components ├── bindings-mqtt.yaml └── pubsub-redis.yaml ├── grpc └── grpc_test.dart └── http └── http_test.dart /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM dart:stable 2 | 3 | # Avoid warnings by switching to noninteractive 4 | ENV DEBIAN_FRONTEND=noninteractive 5 | 6 | # This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" 7 | # property in devcontainer.json to use it. On Linux, the container user's GID/UIDs 8 | # will be updated to match your local UID/GID (when using the dockerFile property). 9 | # See https://aka.ms/vscode-remote/containers/non-root-user for details. 10 | ARG USERNAME=vscode 11 | ARG USER_UID=1000 12 | ARG USER_GID=$USER_UID 13 | 14 | # Configure apt and install packages 15 | RUN apt-get update \ 16 | && apt-get -y install --no-install-recommends apt-utils dialog wget curl 2>&1 \ 17 | # 18 | # Install Docker CE CLI 19 | && apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common lsb-release \ 20 | && curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT) \ 21 | && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" \ 22 | && apt-get update \ 23 | && apt-get install -y docker-ce-cli \ 24 | # 25 | # Install Dapr CLI and initialize it in slim mode. 26 | && wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash \ 27 | # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. 28 | && groupadd --gid $USER_GID $USERNAME \ 29 | && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ 30 | # 31 | # Install protobuf compiler 32 | && apt install -y protobuf-compiler \ 33 | # 34 | # [Optional] Add sudo support for the non-root user 35 | && apt-get install -y sudo \ 36 | && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ 37 | && chmod 0440 /etc/sudoers.d/$USERNAME \ 38 | # 39 | # Clean up 40 | && apt-get autoremove -y \ 41 | && apt-get clean -y \ 42 | && rm -rf /var/lib/apt/lists/* \ 43 | # 44 | # Install Melos 45 | && dart pub global activate melos \ 46 | && dart pub global activate protoc_plugin \ 47 | && dart pub global activate coverage 48 | # 49 | # CirusCi flutter image sets the user name to cirus ci 50 | # Clearing it to ensure the commit goes under the correct name. 51 | # && git config --global --unset user.name \ 52 | # && git config --global --unset user.email 53 | # Setup pub bin cache in the path. 54 | # Need to find if this is the correct way to set melos in path. 55 | ENV PATH ${PATH}:/root/.pub-cache/bin 56 | 57 | # Switch back to dialog for any ad-hoc use of apt-get 58 | ENV DEBIAN_FRONTEND=dialog -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/vscode-remote/devcontainer.json. 2 | { 3 | "name": "Dapr - DART SDK", 4 | // "context": "..", 5 | // "dockerFile": "Dockerfile", 6 | "dockerComposeFile": [ 7 | "env-compose.yaml" 8 | ], 9 | "service": "dart-sdk-dev-env", 10 | // Set *default* container specific settings.json values on container create. 11 | "settings": { 12 | "terminal.integrated.profiles.linux": { 13 | "bash": { 14 | "path": "bash" 15 | }, 16 | "zsh": { 17 | "path": "zsh" 18 | }, 19 | "fish": { 20 | "path": "fish" 21 | }, 22 | "tmux": { 23 | "path": "tmux", 24 | "icon": "terminal-tmux" 25 | }, 26 | "pwsh": { 27 | "path": "pwsh", 28 | "icon": "terminal-powershell" 29 | } 30 | }, 31 | "terminal.integrated.defaultProfile.linux": "bash", 32 | }, 33 | // Add the IDs of extensions you want installed when the container is created. 34 | "extensions": [ 35 | "ms-azuretools.vscode-dapr", 36 | "ms-azuretools.vscode-docker", 37 | "Dart-Code.dart-code", 38 | "Dart-Code.flutter", 39 | "blaxou.freezed", 40 | "zxh404.vscode-proto3", 41 | ], 42 | // "mounts": [ 43 | // "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", 44 | // ], 45 | "workspaceFolder": "/workspace", 46 | // All dart, flutter packages in this repository is maintained using melos. 47 | // See : https://melos.invertase.dev/ 48 | // Melos is installed as part of Docker setup. See Dockerfile. 49 | // This command installs melos and bootstraps all the packages by run pub get on all the dart packages. 50 | "postAttachCommand": "dapr init --network dart_net && melos bootstrap && docker rename dapr_redis_dart_net dapr_redis", 51 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 52 | // "forwardPorts": [], 53 | // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. 54 | // "remoteUser": "vscode", 55 | "remoteEnv": { 56 | "CLNT_COMP_DIR": "./test/components", 57 | "SRV_COMP_DIR": "./test/components", 58 | } 59 | } -------------------------------------------------------------------------------- /.devcontainer/env-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | ############################### 5 | ## Redis state store service 6 | ############################### 7 | # redis: 8 | # container_name: "test-redis" 9 | # image: "redis:alpine" 10 | # ports: 11 | # - "6380:6379" 12 | # networks: 13 | # - dart-sdk-network 14 | ############################################# 15 | ## Mosquitto MQTT message broker for bindings 16 | ############################################# 17 | # mosquitto: 18 | # container_name: "test-mosquitto" 19 | # image: "eclipse-mosquitto" 20 | # ports: 21 | # - "1883:1883" 22 | # - "9000:9001" 23 | # volumes: 24 | # - type: bind 25 | # source: ../infrastructure/mosquitto.conf 26 | # target: /mosquitto/config/mosquitto.conf 27 | # networks: 28 | # - dart-sdk-network 29 | ################################### 30 | ## Rabitt MQ 31 | ################################### 32 | rabbitmq: 33 | image: rabbitmq:3-management-alpine 34 | container_name: 'dapr_rabbitmq' 35 | ports: 36 | - 5672:5672 37 | - 15672:15672 38 | networks: 39 | - dart_net 40 | ############################ 41 | ## Dapr placement service 42 | ############################ 43 | # placement: 44 | # container_name: "test-dapr-placement" 45 | # image: "daprio/dapr" 46 | # command: ["./placement", "-port", "50006"] 47 | # ports: 48 | # - "50006:50006" 49 | # networks: 50 | # - dart-sdk-network 51 | ################################### 52 | ## 53 | ## Dapr dart-sdk dev environment 54 | ## 55 | ## Builds the environtment from 56 | ## the Dockerfile in this directory 57 | ################################### 58 | dart-sdk-dev-env: 59 | container_name: "dart-sdk-dev-env" 60 | build: 61 | context: . 62 | dockerfile: Dockerfile 63 | volumes: 64 | # Forwards the local Docker socket to the container. 65 | - /var/run/docker.sock:/var/run/docker.sock 66 | # Update this to wherever you want VS Code to mount the folder of your project 67 | - ..:/workspace:cached 68 | # Overrides default command so things don't shut down after the process ends. 69 | # entrypoint: /usr/local/share/docker-init.sh 70 | command: sleep infinity 71 | networks: 72 | - dart_net 73 | # volumes: 74 | networks: 75 | dart_net: 76 | name: "dart_net" 77 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a bug in dapr dart sdk 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Sdk version & Dapr Version** 14 | 15 | **Steps to reproduce the problem** 16 | 17 | **Expected behavior** 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Raise a feature request for dart-sdk 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the feature you'd like** 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Proposal 3 | about: Create a technical proposal for dart-sdk 4 | title: '' 5 | labels: proposal 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the proposal** 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question related to dart-sdk 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe your question** 11 | 12 | **Steps to reproduce if applicable** 13 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | _Please explain the changes you've made_ 4 | 5 | ## Issue reference 6 | 7 | We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation. 8 | 9 | Please reference the issue this PR will close: #_[issue number]_ 10 | 11 | ## Checklist 12 | 13 | Please make sure you've completed the relevant tasks for this PR, out of the following list: 14 | 15 | * [ ] Code compiles correctly 16 | * [ ] Created/updated tests 17 | * [ ] Extended the documentation 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: E2E & unit tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - release-* 8 | tags: 9 | - v* 10 | pull_request: 11 | branches: 12 | - main 13 | - release-* 14 | 15 | jobs: 16 | run-all-tests: 17 | runs-on: ubuntu-latest 18 | env: 19 | DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/master/install/install.sh 20 | SRV_COMP_DIR: ../../infrastructure/gh_actions_components/server 21 | CLNT_COMP_DIR: ../../infrastructure/gh_actions_components/client 22 | services: 23 | dapr_rabbitmq: 24 | image: rabbitmq:3-management-alpine 25 | ports: 26 | - 5672:5672 27 | - 15672:15672 28 | steps: 29 | - uses: actions/checkout@v2 30 | 31 | - name: Dapr - Install CLI 32 | run: wget -q ${{ env.DAPR_INSTALL_URL }} -O - | /bin/bash -s ${{ env.DAPR_CLI_VER }} 33 | 34 | - name: Dapr - Initialize 35 | run: dapr init 36 | 37 | # - name: Run RabbitMQ container 38 | # run: docker run -d -p 5672:5672 --name dapr_rabbitmq rabbitmq:3-management-alpine 39 | - name: List docker containers 40 | run: docker ps 41 | 42 | - name: Install dart 43 | uses: dart-lang/setup-dart@v1 44 | with: 45 | sdk: stable 46 | 47 | - name: Install Melos 48 | run: dart pub global activate melos 49 | 50 | - name: Install coverage package for dart 51 | run: dart pub global activate coverage 52 | 53 | - name: Install jq for processing json in terminal 54 | run: | 55 | sudo apt-get update -y 56 | sudo apt-get install -y jq 57 | 58 | - name: Run client unit tests 59 | run: | 60 | melos run test:client:unit 61 | 62 | - name: Run client http e2e tests 63 | run: | 64 | melos run test:client:e2e:http 65 | export test_result=$(tail -1 packages/dapr_client/test/reports/tests_client_http.json) 66 | if $(echo $test_result | jq '.success') == true; then 67 | echo "No error found: All tests passed"; 68 | else 69 | echo "Some test have failed. Pleas verify the logs" 70 | exit 1; 71 | fi 72 | 73 | - name: Run client grpc e2e tests 74 | run: | 75 | melos run test:client:e2e:grpc | tee cln_grpc.txt 76 | export test_result=$(tail -1 packages/dapr_client/test/reports/tests_client_grpc.json) 77 | if $(echo $test_result | jq '.success') == true; then 78 | echo "No error found: All tests passed"; 79 | else 80 | echo "Some test have failed. Pleas verify the logs" 81 | exit 1; 82 | fi 83 | 84 | - name: Run server http e2e tests 85 | run: | 86 | melos run test:server:e2e:http | tee srv_http.txt 87 | export test_result=$(tail -1 packages/dapr_server/test/reports/tests_server_http.json) 88 | if $(echo $test_result | jq '.success') == true; then 89 | echo "No error found: All tests passed"; 90 | else 91 | echo "Some test have failed. Pleas verify the logs" 92 | exit 1; 93 | fi 94 | 95 | - name: Run server grpc e2e tests 96 | run: | 97 | melos run test:server:e2e:grpc | tee srv_grpc.txt 98 | export test_result=$(tail -1 packages/dapr_server/test/reports/tests_server_grpc.json) 99 | if $(echo $test_result | jq '.success') == true; then 100 | echo "No error found: All tests passed"; 101 | else 102 | echo "Some test have failed. Pleas verify the logs" 103 | exit 1; 104 | fi 105 | 106 | - name: Upload coverage to Codecov 107 | uses: codecov/codecov-action@v2 108 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # Remove coverage files from tracking. 4 | coverage 5 | coverage.lcov 6 | demo_shef_server 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "dapr", 4 | "lcov" 5 | ] 6 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![melos](https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square)](https://github.com/invertase/melos) 2 | [![codecov](https://codecov.io/gh/Abhilash-Chandran/dart-sdk/branch/master/graph/badge.svg?token=F3XOQ7UGXE)](https://codecov.io/gh/Abhilash-Chandran/dart-sdk) 3 | [![E2E & unit tests](https://github.com/Abhilash-Chandran/dart-sdk/actions/workflows/test.yaml/badge.svg)](https://github.com/Abhilash-Chandran/dart-sdk/actions/workflows/test.yaml) 4 | 5 | # Dapr dart sdk 6 | 7 | Welcome to the dart-sdk for dapr. This repository aims to provide and maintain the dart packages required to interact with dapr sidecar. 8 | 9 | ## What is Dapr? 10 | [Dapr](https://dapr.io/) is an API to build & maintain, portable and reliable microservices. 11 | It allows developers to build microservices that can inteface with a plethora of external services, through a set of standardised APIs. 12 | Using Dapr allows developers to focus on the core business logic instead of dealing with the SDKs required to connect with theses external services. 13 | 14 | Dapr enables this interfacing by defining a set of standard components namely building blocks each of which handle different core logic that a microservice would require to handle. This is achieved using a sidecar architecture in which the sidecar runs alongside your service or web app and enables interacting with external services through this sidecar. 15 | 16 | To learn more about Dapr head over to docs section at [https://dapr.io/](https://dapr.io/) 17 | 18 | 19 | ## What does this SDK offer? 20 | 21 | The Dart-sdk offers two main packages namely [dapr_client](packages/dapr_client/README.md) and [dapr_server](packages/dapr_server/README.md) which provides api's to interact with a dapr_sidercar. 22 | 23 | When using Dapr there are two main use cases. 24 | 25 | 1. An application interacting with the Dapr sidecar to invoke, publish or retrieve state. 26 | 27 | * [dapr_client](packages/dapr_client/README.md) eases this process by providing a unified api to interact with all the building blocks a sidecar offers. 28 | 29 | 2. An application which can be invoked by external services, which listens to a published message to take corresponding action. 30 | 31 | * [dapr_server](packages/dapr_server/README.md) eases this process by providing APIs to write daperised services which confirm to the required specification. 32 | 33 | The image below depicts both these use cases. 34 | 35 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | linter: 2 | rules: 3 | - prefer_relative_imports -------------------------------------------------------------------------------- /codecov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapr-sandbox/dart-sdk/e8710adb2e71fceb4798d809d92bef1ba8495969/codecov -------------------------------------------------------------------------------- /daprdocs/README.md: -------------------------------------------------------------------------------- 1 | # Dapr Dart SDK documentation 2 | 3 | This page covers how the documentation is structured for the Dapr Dart SDK 4 | 5 | ## Dapr Docs 6 | 7 | All Dapr documentation is hosted at [docs.dapr.io](https://docs.dapr.io), including the docs for the [Dart SDK](https://docs.dapr.io/developing-applications/sdks/dart/). Head over there if you want to read the docs. 8 | 9 | ### Dart SDK docs source 10 | 11 | Although the docs site code and content is in the [docs repo](https://github.com/dapr/docs), the 12 | Dart SDK content and images are within the `content` and `static` directories, respectively. 13 | 14 | This allows separation of roles and expertise between maintainers, and makes it easy to find the docs files you are looking for. 15 | 16 | ## Writing Dart SDK docs 17 | 18 | To get up and running to write Dart SDK docs, visit the [docs repo](https://github.com/dapr/docs) to initialize your environment. It will clone both the docs repo and this repo, so you can make changes and see it rendered within the site instantly, as well as commit and PR into this repo. 19 | 20 | Make sure to read the [docs contributing guide](https://docs.dapr.io/contributing/contributing-docs/) for information on style/semantics/etc. 21 | 22 | ## Docs architecture 23 | 24 | The docs site is built on [Hugo](https://gohugo.io), which lives in the docs repo. This repo is setup as a git submodule so that when the repo is cloned and initialized, the javascript-sdk repo, along with the docs, are cloned as well. 25 | 26 | Then, in the Hugo configuration file, the `daprdocs/content` and `daprdocs/static` directories are redirected to the `daprdocs/developing-applications/sdks/dart` and `static/dart` directories, respectively. Thus, all the content within this repo is folded into the main docs site. 27 | -------------------------------------------------------------------------------- /daprdocs/content/en/dart-sdk-docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: docs 3 | title: "Dapr Dart SDK" 4 | linkTitle: "Dart" 5 | weight: 1000 6 | description: Dart SDK packages for developing Dapr applications 7 | no_list: true 8 | --- 9 | 10 | A Dart-sdk to help write Dapr application in dart. The sdk provides two set of 11 | packages namely `dapr_client` and `dapr_server`. 12 | 13 | {{< cardpane >}} 14 | {{< card title="**Client**">}} 15 | Use the Dapr Client dart sdk for invoking public Dapr APIs 16 | 17 | [**Learn more about the Dart client sdk**]({{< ref dapr-client >}}) 18 | {{< /card >}} 19 | {{< card title="**Service**">}} 20 | Use the Dart Server (Callback) sdk to create services that will be invoked by Dapr. 21 | 22 | [**Learn more about the Dart server (Callback) sdk**]({{< ref dapr-server >}}) 23 | {{< /card >}} 24 | {{< /cardpane >}} 25 | -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/client/bindings-mqtt.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/rabbitmq/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: binding-rabbit 6 | namespace: default 7 | spec: 8 | type: bindings.rabbitmq 9 | version: v1 10 | metadata: 11 | - name: consumerID 12 | value: "{uuid}" 13 | - name: host 14 | value: "amqp://guest:guest@localhost:5672" 15 | - name: queueName 16 | value: "test-queue" 17 | - name: qos 18 | value: 1 19 | - name: retain 20 | value: "false" 21 | - name: cleanSession 22 | value: "false" 23 | -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/client/pubsub-redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: pubsub-redis 5 | namespace: default 6 | spec: 7 | type: pubsub.redis 8 | version: v1 9 | metadata: 10 | - name: redisHost 11 | value: localhost:6379 12 | - name: redisPassword 13 | value: "" 14 | - name: consumerID 15 | value: "myGroup" 16 | - name: enableTLS 17 | value: "false" -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/client/secret-envvars.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: secret-envvars 5 | namespace: default 6 | spec: 7 | type: secretstores.local.env 8 | version: v1 9 | metadata: -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/client/state-redis.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/redis/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: state-redis 6 | namespace: default 7 | spec: 8 | type: state.redis 9 | version: v1 10 | metadata: 11 | - name: redisHost 12 | value: localhost:6379 13 | - name: redisPassword 14 | value: "" 15 | - name: enableTLS 16 | value: "false" 17 | - name: failover 18 | value: "false" 19 | - name: actorStateStore 20 | value: "true" -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/server/bindings-mqtt.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/rabbitmq/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: binding-rabbit 6 | namespace: default 7 | spec: 8 | type: bindings.rabbitmq 9 | version: v1 10 | metadata: 11 | - name: consumerID 12 | value: "{uuid}" 13 | - name: host 14 | value: "amqp://guest:guest@localhost:5672" 15 | - name: queueName 16 | value: "test-queue" 17 | - name: qos 18 | value: 1 19 | - name: retain 20 | value: "false" 21 | - name: cleanSession 22 | value: "false" 23 | -------------------------------------------------------------------------------- /infrastructure/gh_actions_components/server/pubsub-redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: pubsub-redis 5 | namespace: default 6 | spec: 7 | type: pubsub.redis 8 | version: v1 9 | metadata: 10 | - name: redisHost 11 | value: localhost:6379 12 | - name: redisPassword 13 | value: "" 14 | - name: consumerID 15 | value: "myGroup" 16 | - name: enableTLS 17 | value: "false" -------------------------------------------------------------------------------- /melos_dapr_dart_sdk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/dapr_client/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build outputs. 6 | build/ 7 | 8 | # Omit committing pubspec.lock for library packages; see 9 | # https://dart.dev/guides/libraries/private-files#pubspeclock. 10 | pubspec.lock 11 | 12 | # ignore test reports directory 13 | test/reports -------------------------------------------------------------------------------- /packages/dapr_client/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | - Initial version. 4 | - Client sdk for State and Secrete management API is ready for use. 5 | -------------------------------------------------------------------------------- /packages/dapr_client/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Abhilash Chandran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/dapr_client/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | analyzer: 23 | exclude: 24 | - lib/src/models/generated/**.g.dart 25 | - lib/src/models/generated/**.freezed.dart 26 | 27 | # For more information about the core and recommended set of lints, see 28 | # https://dart.dev/go/core-lints 29 | 30 | # For additional information about configuring this file, see 31 | # https://dart.dev/guides/language/analysis-options 32 | -------------------------------------------------------------------------------- /packages/dapr_client/example/dapr_client_example.dart: -------------------------------------------------------------------------------- 1 | void main(List args) { 2 | 3 | } -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build output. 6 | build/ 7 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version. 4 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/README.md: -------------------------------------------------------------------------------- 1 | A simple command-line application. 2 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | # analyzer: 23 | # exclude: 24 | # - path/to/excluded/files/** 25 | 26 | # For more information about the core and recommended set of lints, see 27 | # https://dart.dev/go/core-lints 28 | 29 | # For additional information about configuring this file, see 30 | # https://dart.dev/guides/language/analysis-options 31 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/bin/secrets_management.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/dapr_client.dart'; 2 | 3 | void main(List arguments) async { 4 | // Defaults to http protocol 5 | final daprClient = DaprClient(daprPort: 3500); 6 | 7 | // Switch to grpc by changing the commmunication protocol. 8 | // final daprClient = DaprClient( 9 | // daprPort: 50000, communicationProtocol: CommunicationProtocol.grpc); 10 | 11 | // Fetch the secret from local store. 12 | final mySecret = await daprClient.secret 13 | .get(secretStoreName: 'secret-local', key: 'my-secret'); 14 | 15 | print("================"); 16 | print('My secret is $mySecret'); 17 | print("================"); 18 | 19 | // Fetch the bulk secret from local store. 20 | final myBulkSecret = 21 | await daprClient.secret.getBulk(secretStoreName: 'secret-local'); 22 | 23 | print("================"); 24 | print('My secret is $myBulkSecret'); 25 | print("================"); 26 | } 27 | 28 | // dapr run --app-id myapp --dapr-http-port 3500 --dapr-grpc-port 50000 --components-path ./components dart run -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/components/local_secrets.json: -------------------------------------------------------------------------------- 1 | { 2 | "my-secret": "I'm Batman", 3 | "secret_2": { 4 | "friend_1": "Christopher Nolan", 5 | "enemy_1": "Joker" 6 | } 7 | } -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/components/secrets_local.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: secret-local 5 | namespace: default 6 | spec: 7 | type: secretstores.local.file 8 | version: v1 9 | metadata: 10 | - name: secretsFile 11 | value: components/local_secrets.json 12 | - name: nestedSeparator 13 | value: ":" 14 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/melos_secrets_management.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_client/example/secrets_management/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: secrets_management 2 | description: A simple command-line application. 3 | version: 1.0.0 4 | # homepage: https://www.example.com 5 | publish_to: none 6 | 7 | environment: 8 | sdk: ">=2.14.4 <3.0.0" 9 | 10 | dependencies: 11 | # dapr_client: 0.1.0 12 | dapr_client: 13 | path: "../../" 14 | 15 | dev_dependencies: 16 | lints: ^1.0.0 17 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build output. 6 | build/ 7 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version. 4 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/README.md: -------------------------------------------------------------------------------- 1 | A simple command-line application. 2 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | # analyzer: 23 | # exclude: 24 | # - path/to/excluded/files/** 25 | 26 | # For more information about the core and recommended set of lints, see 27 | # https://dart.dev/go/core-lints 28 | 29 | # For additional information about configuring this file, see 30 | # https://dart.dev/guides/language/analysis-options 31 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/bin/state_management.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/dapr_client.dart'; 2 | 3 | void main(List arguments) async { 4 | final daprClient = DaprClient(daprPort: 3500); 5 | 6 | // Save a new state 7 | await daprClient.state.save( 8 | storeName: "state-redis", 9 | stateObjects: [SaveStateItem(key: 'key-1', value: 'value-1')], 10 | ); 11 | 12 | // Save additional key value pairs 13 | await daprClient.state.save( 14 | storeName: "state-redis", 15 | stateObjects: [ 16 | SaveStateItem(key: 'key-2', value: 'value-2'), 17 | SaveStateItem(key: 'key-3', value: 'value-3'), 18 | ], 19 | ); 20 | 21 | // Retrieve and print an existing state. 22 | final stateKey2 = 23 | await daprClient.state.get(storeName: 'state-redis', key: 'key-2'); 24 | 25 | print("======================================"); 26 | print("State value for key-2 is $stateKey2"); 27 | print("======================================"); 28 | 29 | // Fetch bulk state key-value pairs. 30 | final allKeys = await daprClient.state 31 | .getBulk(storeName: 'state-redis', keys: ['key-1', 'key-3']); 32 | 33 | print("======================================"); 34 | print("Bulk Key value pair is is $allKeys"); 35 | print("======================================"); 36 | 37 | // Perform transactions on state store 38 | await daprClient.state.transaction(storeName: 'state-redis', operations: [ 39 | StateOperation( 40 | operation: 'upsert', 41 | request: StateOperationRequest(key: 'key-1', value: 'updated-value-1'), 42 | ), 43 | StateOperation( 44 | operation: 'upsert', 45 | request: StateOperationRequest(key: 'key-2', value: 'updated-value-2'), 46 | ), 47 | StateOperation( 48 | operation: 'delete', 49 | request: StateOperationRequest(key: 'key-3'), 50 | ), 51 | ]); 52 | 53 | // verify the transaction result 54 | final allKeys2 = await daprClient.state 55 | .getBulk(storeName: 'state-redis', keys: ['key-1', 'key-2']); 56 | print("======================================"); 57 | print("Bulk Key value pair is is $allKeys2"); 58 | print("======================================"); 59 | 60 | // delete existing key-value pairs 61 | await daprClient.state.delete(storeName: 'state-redis', key: 'key-1'); 62 | await daprClient.state.delete(storeName: 'state-redis', key: 'key-2'); 63 | } 64 | 65 | 66 | // dapr run --app-id myapp --dapr-http-port 3500 --dapr-grpc-port 50000 --components-path ./components dart run -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/components/state-redis.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/redis/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: state-redis 6 | namespace: default 7 | spec: 8 | type: state.redis 9 | version: v1 10 | metadata: 11 | - name: redisHost 12 | value: dapr_redis:6379 13 | - name: redisPassword 14 | value: "" 15 | - name: enableTLS 16 | value: "false" 17 | - name: failover 18 | value: "false" 19 | - name: actorStateStore 20 | value: "true" -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/melos_state_management.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_client/example/state_management/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: state_management 2 | description: A simple command-line application. 3 | version: 1.0.0 4 | # homepage: https://www.example.com 5 | 6 | publish_to: none 7 | environment: 8 | sdk: ">=2.14.4 <3.0.0" 9 | 10 | dependencies: 11 | # dapr_client: 0.1.0 12 | dapr_client: 13 | path: "../../" 14 | 15 | dev_dependencies: 16 | lints: ^1.0.0 17 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/dapr_client.dart: -------------------------------------------------------------------------------- 1 | /// Support for doing something awesome. 2 | /// 3 | /// More dartdocs go here. 4 | library dapr_client; 5 | 6 | export 'src/implementations/dapr_client.dart'; 7 | export 'package:dapr_common/dapr_common.dart'; 8 | 9 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | /// An abstract client which exposes client related information. 4 | /// 5 | /// Will be implemented by the respective clients such as [HttpClient] and [GrpcClient]. 6 | abstract class Client { 7 | T get client; 8 | String get clientHost; 9 | int get clientPort; 10 | CommunicationProtocol get communicationProtocol; 11 | } 12 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_actor.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | abstract class ClientActor { 4 | /// The client for the chose protocol. 5 | T get client; 6 | 7 | /// Based on the following api definition. 8 | /// 9 | /// https://docs.dapr.io/reference/api/actors_api/#invoke-actor-method 10 | /// 11 | Future invoke({ 12 | HttpMethod method, 13 | String actorType, 14 | String actorId, 15 | String methodName, 16 | dynamic body, 17 | }); 18 | 19 | /// Based on the following api definition. 20 | /// 21 | /// https://docs.dapr.io/reference/api/actors_api/#actor-state-transactions 22 | /// 23 | /// Note that this operation is dependant on a using state store component that supports multi-item transactions. 24 | Future stateTransaction({ 25 | String actorType, 26 | String actorId, 27 | List operations, 28 | }); 29 | 30 | /// Based on the following api definition. 31 | /// 32 | /// https://docs.dapr.io/reference/api/actors_api/#get-actor-state 33 | /// 34 | /// TODO: Think about making the return as Union of Map and String. Perhaps 35 | /// using Freezed! 36 | /// 37 | Future> stateGet( 38 | {String actorType, String actorId, String key}); 39 | 40 | /// Based on the following api definition. 41 | /// 42 | /// https://docs.dapr.io/reference/api/actors_api/#create-actor-reminder 43 | /// 44 | Future reminderCreate({ 45 | String actorType, 46 | String actorId, 47 | String name, 48 | }); 49 | 50 | /// Based on the following api definition. 51 | /// 52 | /// https://docs.dapr.io/reference/api/actors_api/#delete-actor-reminder 53 | /// 54 | Future reminderDelete({ 55 | String actorType, 56 | String actorId, 57 | String name, 58 | }); 59 | 60 | /// Based on the following api definition. 61 | /// 62 | /// https://docs.dapr.io/reference/api/actors_api/#create-actor-timer 63 | /// 64 | Future timeerCreate({ 65 | String actorType, 66 | String actorId, 67 | String name, 68 | }); 69 | 70 | /// Based on the following api definition. 71 | /// 72 | /// https://docs.dapr.io/reference/api/actors_api/#delete-actor-timer 73 | /// 74 | Future timerDelete({ 75 | String actorType, 76 | String actorId, 77 | String name, 78 | }); 79 | 80 | /// Based on the following api definition. 81 | /// 82 | /// https://docs.dapr.io/reference/api/actors_api/#get-registered-actors 83 | /// 84 | Future getActors(); 85 | } 86 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | abstract class ClientBinding { 4 | /// The client for the chose protocol. 5 | T get client; 6 | Future send({ 7 | required String bindingName, 8 | required OutputBindingEvent outputBindingEvent, 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | abstract class ClientInvoker { 4 | T get client; 5 | Future invoke({ 6 | required String appId, 7 | required String methodName, 8 | required HttpMethod httpMethod, 9 | Object? data, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_pubsub.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/dapr_client.dart'; 2 | 3 | abstract class ClientPubSub { 4 | /// The client for the chose protocol. 5 | T get client; 6 | Future publish({ 7 | required String pubSubName, 8 | required String topicName, 9 | Object? data, 10 | String contentType, 11 | PublishMetadata metadata, 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_secrets.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | abstract class ClientSecret { 4 | /// The client for the chose protocol. 5 | T get client; 6 | 7 | Future> get({ 8 | required String secretStoreName, 9 | required String key, 10 | Map? metadata, 11 | }); 12 | 13 | Future> getBulk({ 14 | required String secretStoreName, 15 | Map? metadata, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/abstractions/client_state.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:dapr_common/dapr_common.dart'; 3 | 4 | abstract class ClientState { 5 | /// The client for the chose protocol. 6 | T get client; 7 | 8 | Future save({ 9 | required String storeName, 10 | required List stateObjects, 11 | }); 12 | 13 | /// The result can be of any type which is json encodable. 14 | /// So the return cannot be expresed as a String or Map. The current choice 15 | /// without a sealed or union class is to opt for dynamic. 16 | /// 17 | /// TODO: Perhaps a Freezed based Union class could be used. But in that 18 | /// case which types needs to be supported is still a question. 19 | Future get({ 20 | required String storeName, 21 | required String key, 22 | // TODO: add options for passing metadata and state options 23 | // StateOptions? options, 24 | }); 25 | 26 | Future> getBulk({ 27 | required String storeName, 28 | required List keys, 29 | int parallelism = 10, 30 | Map metadata = const {}, 31 | }); 32 | 33 | Future delete({ 34 | required String storeName, 35 | required String key, 36 | // TODO: add options for passing metadata and state options 37 | // StateOptions? options, 38 | }); 39 | 40 | Future transaction({ 41 | required String storeName, 42 | List? operations, 43 | Map? metadata, 44 | }); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/dapr_client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dapr_client/src/abstractions/client_binding.dart'; 4 | import 'package:dapr_client/src/abstractions/client_invoker.dart'; 5 | import 'package:dapr_client/src/abstractions/client_pubsub.dart'; 6 | import 'package:dapr_client/src/implementations/grpc/grpc_binding.dart'; 7 | import 'package:dapr_client/src/implementations/grpc/grpc_invoker.dart'; 8 | import 'package:dapr_client/src/implementations/grpc/grpc_pub_sub.dart'; 9 | import 'package:dapr_client/src/implementations/http/http_binding.dart'; 10 | import 'package:dapr_client/src/implementations/http/http_invoker.dart'; 11 | import 'package:dapr_client/src/implementations/http/http_pub_sub.dart'; 12 | import 'package:dapr_common/dapr_common.dart'; 13 | 14 | import '../abstractions/client.dart'; 15 | import '../abstractions/client_secrets.dart'; 16 | import '../abstractions/client_state.dart'; 17 | 18 | import 'grpc/grpc_client.dart'; 19 | import 'grpc/grpc_state.dart'; 20 | import 'grpc/grpc_secret.dart'; 21 | 22 | import 'http/http_client.dart'; 23 | import 'http/http_secret.dart'; 24 | import 'http/http_state.dart'; 25 | 26 | class DaprClient { 27 | /// Defaults to 127.0.0.1 28 | final String daprHost; 29 | 30 | /// Defaults to the DAPR_HTTP_PORT or DAPR_GRPC_PORT environment variable set 31 | /// by Dapr. 32 | int? _daprPort; 33 | 34 | final CommunicationProtocol communicationProtocol; 35 | late final Client client; 36 | late final ClientState state; 37 | late final ClientSecret secret; 38 | late final ClientBinding binding; 39 | late final ClientInvoker invoker; 40 | late final ClientPubSub pubSub; 41 | DaprClient({ 42 | this.daprHost = DaprConf.defDaprHost, 43 | int? daprPort, 44 | this.communicationProtocol = CommunicationProtocol.http, 45 | }) { 46 | // set default values from configurations if the environment variables is 47 | // not set or the port is not provided. 48 | _daprPort = daprPort ??= int.tryParse(Platform.environment[ 49 | communicationProtocol == CommunicationProtocol.http 50 | ? 'DAPR_HTTP_PORT' 51 | : 'DAPR_GRPC_PORT'] ?? 52 | ''); 53 | _daprPort ??= communicationProtocol == CommunicationProtocol.http 54 | ? DaprConf.defDaprHttpPort 55 | : DaprConf.defDaprGrpcPort; 56 | switch (communicationProtocol) { 57 | case CommunicationProtocol.http: 58 | final _client = 59 | DaprHttpClient(clientHost: daprHost, clientPort: _daprPort!); 60 | client = _client; 61 | state = HttpClientState(client: _client); 62 | secret = HttpClientSecret(client: _client); 63 | binding = HttpClientBinding(client: _client); 64 | pubSub = HttpClientPubSub(client: _client); 65 | invoker = HttpClientInvoker(client: _client); 66 | break; 67 | default: 68 | final _client = 69 | DaprGrpcClient(clientHost: daprHost, clientPort: _daprPort!); 70 | client = _client; 71 | state = GrpcClientState(client: _client); 72 | secret = GrpcClientSecret(client: _client); 73 | binding = GrpcClientBinding(client: _client); 74 | pubSub = GrpcClientPubSub(client: _client); 75 | invoker = GrpcClientInvoker(client: _client); 76 | } 77 | } 78 | 79 | int get daprPort => _daprPort!; 80 | } 81 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_binding.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_client/src/abstractions/client_binding.dart'; 4 | import 'package:dapr_client/src/implementations/grpc/grpc_client.dart'; 5 | import 'package:dapr_common/dapr_common.dart'; 6 | 7 | import 'package:dapr_proto/dapr_proto.dart' as dp; 8 | 9 | class GrpcClientBinding implements ClientBinding { 10 | @override 11 | DaprGrpcClient client; 12 | 13 | /// Note this is DaprClient from the dapr_proto package which enables a 14 | /// client communication with the dapr grpc sidecar server. 15 | late final dp.DaprClient _daprClient; 16 | GrpcClientBinding({required this.client}) { 17 | _daprClient = client.client; 18 | } 19 | 20 | @override 21 | Future send({ 22 | required String bindingName, 23 | required OutputBindingEvent outputBindingEvent, 24 | }) async { 25 | final _invokeBindinRequest = dp.InvokeBindingRequest( 26 | data: utf8.encode(outputBindingEvent.data), 27 | metadata: outputBindingEvent.metadata, 28 | name: bindingName, 29 | operation: outputBindingEvent.operation, 30 | ); 31 | final _result = await _daprClient.invokeBinding(_invokeBindinRequest); 32 | print(_result.toProto3Json()); 33 | return OutputBindingEventResponse( 34 | data: utf8.decode(_result.data), 35 | metadata: _result.metadata, 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_client.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | import 'package:dapr_proto/dapr_proto.dart' as dp; 3 | import 'package:grpc/grpc.dart' as grpc; 4 | 5 | import '../../abstractions/client.dart'; 6 | 7 | /// 8 | /// A grpc client to access Dapr Side Car. 9 | /// 10 | class DaprGrpcClient implements Client { 11 | /// Note this is a DaprClient generated by Grpc compiler tools. 12 | @override 13 | late final dp.DaprClient client; 14 | @override 15 | final String clientHost; 16 | @override 17 | final int clientPort; 18 | @override 19 | final CommunicationProtocol communicationProtocol = 20 | CommunicationProtocol.grpc; 21 | 22 | DaprGrpcClient({ 23 | required this.clientHost, 24 | required this.clientPort, 25 | }) { 26 | // Initialize the grpc client. 27 | // We use the grpc package to handle all the grpc based client calls. 28 | final channel = grpc.ClientChannel( 29 | clientHost, 30 | port: clientPort, 31 | options: grpc.ChannelOptions( 32 | credentials: grpc.ChannelCredentials.insecure(), 33 | ), 34 | ); 35 | 36 | client = dp.DaprClient(channel); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import '../../abstractions/client_invoker.dart'; 4 | import 'grpc_client.dart'; 5 | import 'package:dapr_common/dapr_common.dart'; 6 | import 'package:dapr_proto/dapr_proto.dart' as dp; 7 | 8 | class GrpcClientInvoker implements ClientInvoker { 9 | @override 10 | final DaprGrpcClient client; 11 | late final dp.DaprClient _daprClient; 12 | GrpcClientInvoker({required this.client}) { 13 | _daprClient = client.client; 14 | } 15 | 16 | dp.HTTPExtension_Verb mapToHttpExtensionVerb(HttpMethod httpMethod) { 17 | switch (httpMethod) { 18 | case HttpMethod.post: 19 | return dp.HTTPExtension_Verb.POST; 20 | case HttpMethod.delete: 21 | return dp.HTTPExtension_Verb.DELETE; 22 | case HttpMethod.put: 23 | return dp.HTTPExtension_Verb.PUT; 24 | case HttpMethod.get: 25 | default: 26 | return dp.HTTPExtension_Verb.GET; 27 | } 28 | } 29 | 30 | // TODO: There are so many parameters which are not completely understood. 31 | // This implementation should be revisited. 32 | @override 33 | Future invoke( 34 | {required String appId, 35 | required String methodName, 36 | required HttpMethod httpMethod, 37 | Object? data}) async { 38 | final _jsonEncodedData = 39 | data is String && data.isEmpty ? data : jsonEncode(data); 40 | final _invokeRequest = dp.InvokeRequest( 41 | data: dp.Any( 42 | value: utf8.encode(_jsonEncodedData), 43 | ), 44 | httpExtension: dp.HTTPExtension( 45 | verb: mapToHttpExtensionVerb(httpMethod), 46 | ), 47 | contentType: 'application/json', 48 | method: methodName, 49 | ); 50 | final _invokeServiceRequest = dp.InvokeServiceRequest( 51 | id: appId, 52 | message: _invokeRequest, 53 | ); 54 | var _result = await _daprClient.invokeService( 55 | _invokeServiceRequest, 56 | ); 57 | var _finalResult = utf8.decode(_result.data.value); 58 | return _finalResult; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_pub_sub.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_client/src/abstractions/client_pubsub.dart'; 4 | import 'package:dapr_client/src/implementations/grpc/grpc_client.dart'; 5 | import 'package:dapr_proto/dapr_proto.dart' as dp; 6 | import 'package:dapr_common/dapr_common.dart'; 7 | 8 | typedef ByteArray = List; 9 | 10 | class GrpcClientPubSub implements ClientPubSub { 11 | @override 12 | final DaprGrpcClient client; 13 | 14 | late final dp.DaprClient _daprClient; 15 | GrpcClientPubSub({required this.client}) { 16 | _daprClient = client.client; 17 | } 18 | 19 | @override 20 | Future publish({ 21 | required String pubSubName, 22 | required String topicName, 23 | Object? data, 24 | String contentType = 'application/json', 25 | PublishMetadata metadata = const PublishMetadata(), 26 | }) async { 27 | final _publishEventRequest = dp.PublishEventRequest( 28 | topic: topicName, 29 | pubsubName: pubSubName, 30 | ); 31 | // Update PublishEventRequest request with data if data is not null and its 32 | // content type. 33 | if (data != null) { 34 | switch (data.runtimeType) { 35 | case ByteArray: 36 | _publishEventRequest.data = data as ByteArray; 37 | break; 38 | case String: 39 | _publishEventRequest.data = utf8.encode(data as String); 40 | break; 41 | default: 42 | _publishEventRequest.data = utf8.encode(jsonEncode(data)); 43 | _publishEventRequest.dataContentType = contentType; 44 | break; 45 | } 46 | } 47 | await _daprClient.publishEvent(_publishEventRequest); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_secret.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | import 'package:dapr_proto/dapr_proto.dart' as dp; 3 | 4 | import '../../abstractions/client_secrets.dart'; 5 | import 'grpc_client.dart'; 6 | 7 | class GrpcClientSecret implements ClientSecret { 8 | @override 9 | final DaprGrpcClient client; 10 | 11 | /// Note this is DaprClient from the dapr_proto package which enables a 12 | /// client communication with the dapr grpc sidecar server. 13 | late final dp.DaprClient _daprClient; 14 | GrpcClientSecret({required this.client}) { 15 | _daprClient = client.client; 16 | } 17 | 18 | @override 19 | Future> get({ 20 | required String secretStoreName, 21 | required String key, 22 | Map? metadata, 23 | }) async { 24 | final _getSecretRequest = dp.GetSecretRequest( 25 | key: key, 26 | storeName: secretStoreName, 27 | metadata: metadata, 28 | ); 29 | 30 | final _grpcResponse = await _daprClient.getSecret(_getSecretRequest); 31 | return _grpcResponse.data; 32 | } 33 | 34 | @override 35 | Future> getBulk({ 36 | required String secretStoreName, 37 | Map? metadata, 38 | }) async { 39 | final _getBulkSecretRequest = dp.GetBulkSecretRequest( 40 | storeName: secretStoreName, 41 | ); 42 | final _bulkSecretResponse = 43 | await _daprClient.getBulkSecret(_getBulkSecretRequest); 44 | final _responseBulkSecrets = {}; 45 | for (var bulkSecret in _bulkSecretResponse.data.entries) { 46 | _responseBulkSecrets.putIfAbsent( 47 | bulkSecret.key, 48 | () => SecretResponse( 49 | secrets: bulkSecret.value.secrets, 50 | ), 51 | ); 52 | } 53 | return _responseBulkSecrets; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/grpc/grpc_state.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:dapr_common/dapr_common.dart'; 3 | import 'package:dapr_proto/dapr_proto.dart' as dp; 4 | 5 | import '../../abstractions/client_state.dart'; 6 | import 'grpc_client.dart'; 7 | 8 | class GrpcClientState implements ClientState { 9 | @override 10 | final DaprGrpcClient client; 11 | 12 | /// Note this is DaprClient from the dapr_proto package which enables a 13 | /// client communication with the dapr grpc sidecar server. 14 | late final dp.DaprClient _daprClient; 15 | 16 | GrpcClientState({required this.client}) { 17 | _daprClient = client.client; 18 | } 19 | 20 | @override 21 | Future delete({required String storeName, required String key}) async { 22 | final _deleteStateRequest = dp.DeleteStateRequest( 23 | storeName: storeName, 24 | key: key, 25 | ); 26 | await _daprClient.deleteState(_deleteStateRequest); 27 | } 28 | 29 | @override 30 | Future get({required String storeName, required String key}) async { 31 | final _getStateRequest = dp.GetStateRequest(storeName: storeName, key: key); 32 | final _result = await _daprClient.getState(_getStateRequest); 33 | final _utfDecoded = utf8.decode(_result.data); 34 | late final _jsonResult = _jsonDecodeUtil(_utfDecoded); 35 | return _jsonResult; 36 | } 37 | 38 | @override 39 | Future> getBulk( 40 | {required String storeName, 41 | required List keys, 42 | int parallelism = 10, 43 | Map metadata = const {}}) async { 44 | final _getBulkStateRequest = dp.GetBulkStateRequest( 45 | storeName: storeName, 46 | keys: keys, 47 | parallelism: parallelism, 48 | metadata: metadata, 49 | ); 50 | 51 | final _bulkStateResponse = 52 | await _daprClient.getBulkState(_getBulkStateRequest); 53 | 54 | final _bulkStateResponseItems = _bulkStateResponse.items; 55 | 56 | final _bulkStateItems = []; 57 | for (var res in _bulkStateResponseItems) { 58 | _bulkStateItems.add( 59 | BulkStateItem( 60 | key: res.key, 61 | etag: res.etag, 62 | data: _jsonDecodeUtil( 63 | utf8.decode(res.data), 64 | ), 65 | ), 66 | ); 67 | } 68 | return _bulkStateItems; 69 | } 70 | 71 | @override 72 | Future save({ 73 | required String storeName, 74 | required List stateObjects, 75 | }) async { 76 | final _stateItems = []; 77 | for (var so in stateObjects) { 78 | final _si = dp.StateItem() 79 | ..key = so.key 80 | ..value = utf8.encode( 81 | so.value is Map ? jsonEncode(so.value) : so.value.toString()); 82 | _stateItems.add(_si); 83 | } 84 | final _saveStateRequest = dp.SaveStateRequest( 85 | storeName: storeName, 86 | states: _stateItems, 87 | ); 88 | await _daprClient.saveState(_saveStateRequest); 89 | } 90 | 91 | @override 92 | Future transaction( 93 | {required String storeName, 94 | List? operations, 95 | Map? metadata}) async { 96 | final _transactionalStateOperations = operations 97 | ?.map( 98 | (e) => dp.TransactionalStateOperation( 99 | operationType: e.operation, 100 | request: dp.StateItem( 101 | key: e.request.key, 102 | value: utf8.encode(e.request.value ?? ''), 103 | ), 104 | ), 105 | ) 106 | .toList(); 107 | final _executeStateTransactionRequest = dp.ExecuteStateTransactionRequest( 108 | storeName: storeName, 109 | metadata: metadata, 110 | operations: _transactionalStateOperations, 111 | ); 112 | await _daprClient.executeStateTransaction(_executeStateTransactionRequest); 113 | } 114 | 115 | /// jsonDecode will throw error for a simple string value. 116 | /// Thats why the try catch block allows us to capture the format exception 117 | /// which is raised when pasisng a simple string which is not json decodable. 118 | dynamic _jsonDecodeUtil(String json) { 119 | try { 120 | return jsonDecode(json); 121 | } on FormatException catch (_) { 122 | return json; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_binding.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_client/src/implementations/http/http_client.dart'; 4 | import 'package:dapr_common/dapr_common.dart'; 5 | 6 | import '../../abstractions/client_binding.dart'; 7 | 8 | class HttpClientBinding implements ClientBinding { 9 | @override 10 | final DaprHttpClient client; 11 | HttpClientBinding({required this.client}); 12 | @override 13 | Future send({ 14 | required String bindingName, 15 | required OutputBindingEvent outputBindingEvent, 16 | }) async { 17 | final result = await client.executeDaprApiCall( 18 | apiUrl: '/bindings/$bindingName', 19 | httpMethod: HttpMethod.post, 20 | headers: {'Content-type': 'application/json'}, 21 | body: jsonEncode(outputBindingEvent), 22 | ); 23 | final _body = result.body; 24 | print('Result from Binding response $result'); 25 | return _body.isEmpty ? _body : jsonEncode(_body); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import '../../abstractions/client.dart'; 7 | 8 | /// 9 | /// A http client to access Dapr Side Car. 10 | /// 11 | /// Prefer using grpc client as much as posisble for performance reasons. 12 | /// 13 | /// An ideal use case to use a Http Client is when the app is deployed as web app. 14 | /// 15 | class DaprHttpClient implements Client { 16 | @override 17 | late final http.Client client; 18 | @override 19 | final String clientHost; 20 | @override 21 | final int clientPort; 22 | @override 23 | final CommunicationProtocol communicationProtocol = 24 | CommunicationProtocol.http; 25 | 26 | late final String _daprBaseUrl; 27 | 28 | DaprHttpClient({ 29 | required this.clientHost, 30 | required this.clientPort, 31 | }) { 32 | // Initialize the http client 33 | // The http package handles the browser or io based client automatically 34 | client = http.Client(); 35 | 36 | // Set up the based URL for accesing the Dapr api over http 37 | 38 | var _clientUrl = '$clientHost:$clientPort/${DaprConf.defDaprApiVersion}'; 39 | 40 | // Before assigning, verify if the provided host contains the protocol. 41 | // If not append the http protocol. 42 | if (!_clientUrl.startsWith(RegExp('^(http:)|(https:)'))) { 43 | _clientUrl = 'http://$_clientUrl'; 44 | } 45 | _daprBaseUrl = _clientUrl; 46 | } 47 | 48 | /// Should be used by all the http client api's to form the respective URl's 49 | String get daprBaseUrl => _daprBaseUrl; 50 | 51 | /// Works as the main method to execute all the http calls to the Dapr api. 52 | /// All the internal clients implementing http based api's should use this 53 | /// method. 54 | /// 55 | /// If not possible the reason should be documented in the respective method. 56 | /// 57 | /// Query params should be added to the [apiUrl] by the caller. This is 58 | /// because the specification for query params varies for various building 59 | /// blocks. 60 | /// 61 | /// The types of headers and body is based on the definitions mentioned in 62 | /// the http package from dart. 63 | /// 64 | /// Check this class for the more details. 65 | /// https://github.com/dart-lang/http/blob/master/lib/src/base_client.dart#L20 66 | Future executeDaprApiCall({ 67 | required String apiUrl, 68 | required HttpMethod httpMethod, 69 | Map? headers, 70 | Object? body, 71 | }) async { 72 | String _contentType = 'Content-Type'; 73 | headers ??= {}; 74 | // Set up the content-type for the request if its not already provided. 75 | // Do this only if the body is not null. If the body is null then no need to set the content type in headers. 76 | if (body != null && headers[_contentType] == null) { 77 | if (body is String) { 78 | headers[_contentType] = "text/plain; charset=UTF-8"; 79 | } else if (body is Map) { 80 | headers[_contentType] = "application/json"; 81 | // This needs to be configurable. 82 | body = removeNullsFromMap(body); 83 | body = jsonEncode(body); 84 | } else if (body is List) { 85 | headers[_contentType] = 'application/octet-stream'; 86 | } else { 87 | headers[_contentType] = "text/plain; charset=UTF-8"; 88 | } 89 | } 90 | 91 | // Prepare the daprApiUrl based on the partial path received. 92 | // Here we assume if the [apiUrl] starts with http or https then the provided url is used as it is. 93 | // Otherwise the provided url is partial and hence the base url is appended. 94 | final _finalApiUrl = Uri.parse( 95 | apiUrl.startsWith(RegExp('^(http:)|(https:)')) 96 | ? apiUrl 97 | : '$_daprBaseUrl$apiUrl', 98 | ); 99 | try { 100 | final http.Response response; 101 | // Make the daprApi call based on the method. 102 | switch (httpMethod) { 103 | case HttpMethod.get: 104 | response = await client.get(_finalApiUrl, headers: headers); 105 | break; 106 | case HttpMethod.post: 107 | response = 108 | await client.post(_finalApiUrl, headers: headers, body: body); 109 | 110 | break; 111 | case HttpMethod.put: 112 | response = 113 | await client.put(_finalApiUrl, headers: headers, body: body); 114 | break; 115 | case HttpMethod.delete: 116 | response = 117 | await client.delete(_finalApiUrl, headers: headers, body: body); 118 | break; 119 | default: 120 | response = await client.get(_finalApiUrl, headers: headers); 121 | break; 122 | } 123 | if (response.statusCode >= 400) { 124 | // TODO: Decide how to throw an exception and what information needs to 125 | // be passed. 126 | } 127 | 128 | // Note we do not parse the response here. 129 | // It is the responsibility of the caller to parse the reponse and convert 130 | // it to the internal object types. 131 | return response; 132 | } catch (e) { 133 | print(e); 134 | // TODO: Decide how to throw an exception and what information needs to 135 | // be passed. 136 | throw ''; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/src/abstractions/client_invoker.dart'; 2 | import 'package:dapr_client/src/implementations/http/http_client.dart'; 3 | import 'package:dapr_common/dapr_common.dart'; 4 | 5 | class HttpClientInvoker implements ClientInvoker { 6 | @override 7 | DaprHttpClient client; 8 | 9 | HttpClientInvoker({required this.client}); 10 | @override 11 | Future invoke( 12 | {required String appId, 13 | required String methodName, 14 | required HttpMethod httpMethod, 15 | Object? data}) async { 16 | final _resp = await client.executeDaprApiCall( 17 | apiUrl: '/invoke/$appId/method/$methodName', 18 | httpMethod: httpMethod, 19 | body: data, 20 | ); 21 | final _body = _resp.body; 22 | return _body; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_pub_sub.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | 4 | import 'package:dapr_client/src/abstractions/client_pubsub.dart'; 5 | import 'package:dapr_common/dapr_common.dart'; 6 | import 'http_client.dart'; 7 | 8 | class HttpClientPubSub implements ClientPubSub { 9 | @override 10 | DaprHttpClient client; 11 | HttpClientPubSub({required this.client}); 12 | 13 | @override 14 | Future publish({ 15 | required String pubSubName, 16 | required String topicName, 17 | Object? data, 18 | String contentType = 'application/json', 19 | PublishMetadata metadata = const PublishMetadata(), 20 | }) async { 21 | final dynamic _body; 22 | if (data is String || data is List) { 23 | _body = data; 24 | } else { 25 | _body = jsonEncode(data); 26 | } 27 | await client.executeDaprApiCall( 28 | apiUrl: '/publish/$pubSubName/$topicName${_metaToParams(metadata)}', 29 | httpMethod: HttpMethod.post, 30 | headers: { 31 | 'Content-Type': contentType, 32 | }, 33 | body: _body, 34 | ); 35 | } 36 | 37 | /// Converts the [PublishMetadata] instance to a query param string. 38 | String _metaToParams(PublishMetadata metadata) { 39 | var _mqp = '?metadata.rawPayload=${metadata.rawPayload}'; 40 | 41 | if (metadata.ttlInSeconds != null) { 42 | _mqp += metadata.ttlInSeconds == null 43 | ? '' 44 | : '&metadata.ttlInSeconds=${metadata.ttlInSeconds}'; 45 | } 46 | return _mqp; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_secret.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | 5 | import '../../abstractions/client_secrets.dart'; 6 | import 'http_client.dart'; 7 | 8 | class HttpClientSecret implements ClientSecret { 9 | @override 10 | final DaprHttpClient client; 11 | HttpClientSecret({required this.client}); 12 | 13 | @override 14 | Future> get({ 15 | required String secretStoreName, 16 | required String key, 17 | Map? metadata, 18 | }) async { 19 | final _queryParams = mapToQueryParams(metadata ?? {}); 20 | final result = await client.executeDaprApiCall( 21 | apiUrl: 22 | '/secrets/$secretStoreName/$key${_queryParams.isEmpty ? _queryParams : '?$_queryParams'}', 23 | httpMethod: HttpMethod.get, 24 | ); 25 | final _body = result.body; 26 | return jsonDecode(_body); 27 | } 28 | 29 | @override 30 | Future> getBulk({ 31 | required String secretStoreName, 32 | Map? metadata, 33 | }) async { 34 | final result = await client.executeDaprApiCall( 35 | apiUrl: '/secrets/$secretStoreName/bulk', 36 | httpMethod: HttpMethod.get, 37 | headers: { 38 | 'Content-Type': 'application/json', 39 | }); 40 | final _body = result.body; 41 | final _decodedResponse = jsonDecode(_body) as Map; 42 | final _responseBulkSecrets = {}; 43 | for (var bulkSecret in _decodedResponse.entries) { 44 | _responseBulkSecrets.putIfAbsent( 45 | bulkSecret.key, 46 | () => SecretResponse(secrets: bulkSecret.value as Map), 47 | ); 48 | } 49 | return _responseBulkSecrets; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/dapr_client/lib/src/implementations/http/http_state.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | 5 | import '../../abstractions/client_state.dart'; 6 | import 'http_client.dart'; 7 | 8 | class HttpClientState implements ClientState { 9 | @override 10 | final DaprHttpClient client; 11 | 12 | HttpClientState({required this.client}); 13 | 14 | @override 15 | Future delete({required String storeName, required String key}) async { 16 | await client.executeDaprApiCall( 17 | apiUrl: '/state/$storeName/$key', 18 | httpMethod: HttpMethod.delete, 19 | ); 20 | return; 21 | } 22 | 23 | @override 24 | Future get({required String storeName, required String key}) async { 25 | final _result = await client.executeDaprApiCall( 26 | apiUrl: '/state/$storeName/$key', 27 | httpMethod: HttpMethod.get, 28 | ); 29 | final _body = _result.body; 30 | final finalResult = _body.isEmpty ? _body : jsonDecode(_body); 31 | return finalResult; 32 | } 33 | 34 | @override 35 | Future save( 36 | {required String storeName, 37 | required List stateObjects}) async { 38 | final _result = await client.executeDaprApiCall( 39 | apiUrl: '/state/$storeName', 40 | httpMethod: HttpMethod.post, 41 | headers: { 42 | 'Content-Type': 'application/json', 43 | }, 44 | body: jsonEncode(stateObjects), 45 | ); 46 | final _body = _result.body; 47 | final finalResult = _body.isEmpty ? _body : jsonDecode(_body); 48 | return finalResult; 49 | } 50 | 51 | @override 52 | Future> getBulk({ 53 | required String storeName, 54 | required List keys, 55 | int parallelism = 10, 56 | Map metadata = const {}, 57 | }) async { 58 | try { 59 | final encodedBody = jsonEncode( 60 | { 61 | 'keys': keys, 62 | 'parallelism': parallelism, 63 | }, 64 | ); 65 | // Convert metadata map into query parameters. 66 | final metadataString = mapToQueryParams(metadata); 67 | final _result = await client.executeDaprApiCall( 68 | apiUrl: 69 | '/state/$storeName/bulk${metadataString.isEmpty ? metadataString : '?$metadataString'}', 70 | httpMethod: HttpMethod.post, 71 | headers: { 72 | 'Content-Type': 'application/json', 73 | }, 74 | body: encodedBody, 75 | ); 76 | final _body = _result.body; 77 | // Return an empty array if no values are found for the provided keys. 78 | final bulkStateItems = []; 79 | 80 | // Fill the empty array with [SaveStateItem] objects extracted from the result. 81 | if (_body.isNotEmpty) { 82 | final decodeResult = jsonDecode(_body) as List; 83 | for (var element in decodeResult) { 84 | bulkStateItems.add(BulkStateItem.fromJson(element)); 85 | } 86 | } 87 | return bulkStateItems; 88 | } on Exception catch (e) { 89 | print(e); 90 | return []; 91 | } 92 | } 93 | 94 | @override 95 | Future transaction( 96 | {required String storeName, 97 | List? operations, 98 | Map? metadata}) async { 99 | final encodedBody = jsonEncode( 100 | { 101 | 'operations': operations, 102 | 'metadata': metadata, 103 | }, 104 | ); 105 | await client.executeDaprApiCall( 106 | apiUrl: '/state/$storeName/transaction', 107 | httpMethod: HttpMethod.post, 108 | headers: {'Content-Type': 'application/json'}, 109 | body: encodedBody, 110 | ); 111 | return; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /packages/dapr_client/melos_dapr_client.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_client/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dapr_client 2 | description: A starting point for Dart libraries or applications. 3 | version: 0.0.1 4 | # homepage: https://www.example.com 5 | 6 | environment: 7 | sdk: '>=2.14.4 <3.0.0' 8 | 9 | # Temporary to keep the analyzer happy. 10 | # Remove it once the packages are published. 11 | publish_to: none 12 | 13 | dependencies: 14 | http: ^0.13.4 15 | grpc: ^3.0.2 16 | dapr_proto: ^0.0.3 17 | dapr_common: 18 | path: ../dapr_common 19 | 20 | dev_dependencies: 21 | lints: ^1.0.0 22 | test: ^1.16.0 23 | dapr_server: 24 | path: ../dapr_server 25 | mockito: ^5.0.16 -------------------------------------------------------------------------------- /packages/dapr_client/test/components/bindings-mqtt.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/rabbitmq/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: binding-rabbit 6 | namespace: default 7 | spec: 8 | type: bindings.rabbitmq 9 | version: v1 10 | metadata: 11 | - name: consumerID 12 | value: "{uuid}" 13 | - name: host 14 | value: "amqp://guest:guest@dapr_rabbitmq:5672" 15 | - name: queueName 16 | value: "test-queue" 17 | - name: qos 18 | value: 1 19 | - name: retain 20 | value: "false" 21 | - name: cleanSession 22 | value: "false" -------------------------------------------------------------------------------- /packages/dapr_client/test/components/pubsub-redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: pubsub-redis 5 | namespace: default 6 | spec: 7 | type: pubsub.redis 8 | version: v1 9 | metadata: 10 | - name: redisHost 11 | value: dapr_redis:6379 12 | - name: redisPassword 13 | value: "" 14 | - name: consumerID 15 | value: "myGroup" 16 | - name: enableTLS 17 | value: "false" -------------------------------------------------------------------------------- /packages/dapr_client/test/components/secret-envvars.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: secret-envvars 5 | namespace: default 6 | spec: 7 | type: secretstores.local.env 8 | version: v1 9 | metadata: -------------------------------------------------------------------------------- /packages/dapr_client/test/components/state-redis.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/redis/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: state-redis 6 | namespace: default 7 | spec: 8 | type: state.redis 9 | version: v1 10 | metadata: 11 | - name: redisHost 12 | value: dapr_redis:6379 13 | - name: redisPassword 14 | value: "" 15 | - name: enableTLS 16 | value: "false" 17 | - name: failover 18 | value: "false" 19 | - name: actorStateStore 20 | value: "true" -------------------------------------------------------------------------------- /packages/dapr_client/test/unit/dapr_client_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/dapr_client.dart'; 2 | import 'package:dapr_client/src/implementations/grpc/grpc_client.dart'; 3 | import 'package:dapr_client/src/implementations/http/http_client.dart'; 4 | import 'package:test/test.dart'; 5 | 6 | void main() { 7 | test("Default values for DaprClient", () { 8 | final _defDaprClient = DaprClient(); 9 | expect(_defDaprClient.daprHost, DaprConf.defDaprHost); 10 | expect(_defDaprClient.daprPort, DaprConf.defDaprHttpPort); 11 | expect(_defDaprClient.communicationProtocol, CommunicationProtocol.http); 12 | }); 13 | 14 | test("Default values with grpc protocol", () { 15 | final _defDaprClient = DaprClient( 16 | communicationProtocol: CommunicationProtocol.grpc, 17 | ); 18 | expect(_defDaprClient.daprHost, DaprConf.defDaprHost); 19 | expect(_defDaprClient.daprPort, DaprConf.defDaprGrpcPort); 20 | expect(_defDaprClient.communicationProtocol, CommunicationProtocol.grpc); 21 | }); 22 | 23 | test("Set daprhost, daprPort arguments", () { 24 | final _defDaprClientHttp = DaprClient( 25 | daprHost: 'www.example.com', 26 | daprPort: 8080, 27 | communicationProtocol: CommunicationProtocol.http, 28 | ); 29 | expect(_defDaprClientHttp.daprHost, 'www.example.com'); 30 | expect(_defDaprClientHttp.daprPort, 8080); 31 | expect( 32 | _defDaprClientHttp.communicationProtocol, CommunicationProtocol.http); 33 | final _defDaprClientGrpc = DaprClient( 34 | daprHost: 'www.example.com', 35 | daprPort: 8080, 36 | communicationProtocol: CommunicationProtocol.grpc, 37 | ); 38 | expect(_defDaprClientGrpc.daprHost, 'www.example.com'); 39 | expect(_defDaprClientGrpc.daprPort, 8080); 40 | expect( 41 | _defDaprClientGrpc.communicationProtocol, CommunicationProtocol.grpc); 42 | }); 43 | 44 | test('Ensure protocol based client is created', () { 45 | final _daprClientHttp = DaprClient( 46 | communicationProtocol: CommunicationProtocol.http, 47 | ); 48 | expect(_daprClientHttp.client, isA()); 49 | 50 | final _daprClientGrpc = DaprClient( 51 | communicationProtocol: CommunicationProtocol.grpc, 52 | ); 53 | expect(_daprClientGrpc.client, isA()); 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /packages/dapr_client/test/unit/env_defaults/dapr_client_env_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_client/dapr_client.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | test("Default values from environment variable - http", () async { 6 | // Note: This is set when melos runs this test. 7 | // TODO: Find a programatic way to set environment variable. 8 | int envDaprHttpPort = 3400; 9 | 10 | final _defDaprClient = DaprClient(); 11 | expect(_defDaprClient.daprHost, DaprConf.defDaprHost); 12 | expect(_defDaprClient.daprPort, envDaprHttpPort); 13 | expect(_defDaprClient.communicationProtocol, CommunicationProtocol.http); 14 | }); 15 | test("Default values from environment variable - grpc", () async { 16 | // Note: This is set when melos runs this test. 17 | // TODO: Find a programatic way to set environment variable. 18 | int envDaprGrpcPort = 54000; 19 | 20 | final _defDaprClient = DaprClient( 21 | communicationProtocol: CommunicationProtocol.grpc, 22 | ); 23 | expect(_defDaprClient.daprHost, DaprConf.defDaprHost); 24 | expect(_defDaprClient.daprPort, envDaprGrpcPort); 25 | expect(_defDaprClient.communicationProtocol, CommunicationProtocol.grpc); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /packages/dapr_common/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build outputs. 6 | build/ 7 | 8 | # Omit committing pubspec.lock for library packages; see 9 | # https://dart.dev/guides/libraries/private-files#pubspeclock. 10 | pubspec.lock 11 | -------------------------------------------------------------------------------- /packages/dapr_common/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version. 4 | -------------------------------------------------------------------------------- /packages/dapr_common/README.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | TODO: Put a short description of the package here that helps potential users 15 | know whether this package might be useful for them. 16 | 17 | ## Features 18 | 19 | TODO: List what your package can do. Maybe include images, gifs, or videos. 20 | 21 | ## Getting started 22 | 23 | TODO: List prerequisites and provide or point to information on how to 24 | start using the package. 25 | 26 | ## Usage 27 | 28 | TODO: Include short and useful examples for package users. Add longer examples 29 | to `/example` folder. 30 | 31 | ```dart 32 | const like = 'sample'; 33 | ``` 34 | 35 | ## Additional information 36 | 37 | TODO: Tell users more about the package: where to find more information, how to 38 | contribute to the package, how to file issues, what response they can expect 39 | from the package authors, and more. 40 | -------------------------------------------------------------------------------- /packages/dapr_common/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | analyzer: 23 | exclude: 24 | - "**/*.g.dart" 25 | - "**/*.freezed.dart" 26 | - "**/*.mocks.dart" 27 | 28 | # For more information about the core and recommended set of lints, see 29 | # https://dart.dev/go/core-lints 30 | 31 | # For additional information about configuring this file, see 32 | # https://dart.dev/guides/language/analysis-options 33 | -------------------------------------------------------------------------------- /packages/dapr_common/example/dapr_common_example.dart: -------------------------------------------------------------------------------- 1 | // import 'package:dapr_common/dapr_common.dart'; 2 | 3 | // void main() { 4 | // var awesome = Awesome(); 5 | // print('awesome: ${awesome.isAwesome}'); 6 | // } 7 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/dapr_common.dart: -------------------------------------------------------------------------------- 1 | /// Support for doing something awesome. 2 | /// 3 | /// More dartdocs go here. 4 | library dapr_common; 5 | 6 | /// Exporting the common enumerations 7 | export 'src/enum/communication_protocol.dart'; 8 | export 'src/enum/http_method.dart'; 9 | export 'src/enum/state_option_enums.dart'; 10 | 11 | /// Exporting the common configurations 12 | export 'src/config/dapr_config_constants.dart'; 13 | 14 | /// Export utility methods. 15 | export 'src/utils//utils.dart'; 16 | 17 | /// Export client models 18 | export 'src/models/client/generated/actor_models.dart'; 19 | export 'src/models/client/generated/state_models.dart'; 20 | export 'src/models/client/generated/secret_models.dart'; 21 | export 'src/models/client/generated/bindings_models.dart'; 22 | export 'src/models/client/generated/pub_sub_models.dart'; 23 | export 'src/models/client/client_type_definitions.dart'; 24 | 25 | /// Export server models 26 | export 'src/models/server/generated/invoker_models.dart'; 27 | export 'src/models/server/generated/pub_sub_models.dart'; 28 | export 'src/models/server/generated/bindings_models.dart'; 29 | export 'src/models/server/server_type_definitions.dart'; 30 | 31 | /// Export mock models for testing in other packages. 32 | export 'src/mocks/http_mocks.mocks.dart'; 33 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/config/dapr_config_constants.dart: -------------------------------------------------------------------------------- 1 | import '../../dapr_common.dart'; 2 | 3 | /// 4 | /// ref: https://github.com/dapr/python-sdk/blob/master/dapr/conf/global_settings.py 5 | /// 6 | class DaprConf { 7 | static const String defAppHost = "127.0.0.1"; 8 | static const String defDaprHost = "127.0.0.1"; 9 | static const int defDaprHttpPort = 3500; 10 | static const int defDaprGrpcPort = 50001; 11 | static const String defDaprApiVersion = "v1.0"; 12 | static const CommunicationProtocol defCommunicationProtocol = 13 | CommunicationProtocol.http; 14 | static const int defHttpAppPort = 3000; 15 | static const int defGrpcAppPort = 3010; 16 | static const int defHttpTimeout = 60; 17 | } 18 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/enum/communication_protocol.dart: -------------------------------------------------------------------------------- 1 | /// Communication protocol to be used for communicating with the dapr sidecar process/container. 2 | enum CommunicationProtocol { 3 | http, 4 | grpc, 5 | } 6 | 7 | extension CommunicationProtocolExt on CommunicationProtocol { 8 | String get name => toString().split('.')[1]; 9 | String get nameUpper => toString().toUpperCase().split('.')[1]; 10 | String get nameLower => toString().toLowerCase().split('.')[1]; 11 | } 12 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/enum/http_method.dart: -------------------------------------------------------------------------------- 1 | /// Enum defining the allowed http methods for an Http client 2 | enum HttpMethod { 3 | get, 4 | put, 5 | post, 6 | delete, 7 | } 8 | 9 | extension HttpMethodExt on HttpMethod { 10 | String get name => toString().split('.')[1]; 11 | String get nameUpper => toString().toUpperCase().split('.')[1]; 12 | String get nameLower => toString().toLowerCase().split('.')[1]; 13 | } 14 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/enum/state_option_enums.dart: -------------------------------------------------------------------------------- 1 | /// Consistency mode for Dapr State Api calls 2 | /// 3 | /// https://docs.dapr.io/reference/api/state_api/#consistency 4 | /// 5 | /// TODO: Check how to pass these options to Grpc calls. 6 | enum Consistency { unspecified, eventual, strong } 7 | 8 | /// Concurrency mode for Dapr State Api calls. 9 | /// 10 | /// https://docs.dapr.io/developing-applications/building-blocks/state-management/state-management-overview/#concurrency 11 | /// 12 | /// The name are derived based on the proto definitions. 13 | /// 14 | /// TODO: Check how to convert and pass these options to Grpc calls. 15 | enum Concurrency { unspecified, firstWrite, lastWrite } 16 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/mocks/http_mocks.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | import 'package:mockito/annotations.dart'; 3 | 4 | @GenerateMocks([TestPubSub]) 5 | abstract class TestPubSub { 6 | Future testCallBack(dynamic data); 7 | } 8 | 9 | @GenerateMocks([TestBinding]) 10 | abstract class TestBinding { 11 | Future testCallBack(BindingEvent bindingEvent); 12 | } 13 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/mocks/http_mocks.mocks.dart: -------------------------------------------------------------------------------- 1 | // Mocks generated by Mockito 5.0.16 from annotations 2 | // in dapr_common/src/mocks/http_mocks.dart. 3 | // Do not manually edit this file. 4 | 5 | import 'dart:async' as _i4; 6 | 7 | import 'package:dapr_common/dapr_common.dart' as _i2; 8 | import 'package:dapr_common/src/mocks/http_mocks.dart' as _i3; 9 | import 'package:mockito/mockito.dart' as _i1; 10 | 11 | // ignore_for_file: avoid_redundant_argument_values 12 | // ignore_for_file: avoid_setters_without_getters 13 | // ignore_for_file: comment_references 14 | // ignore_for_file: implementation_imports 15 | // ignore_for_file: invalid_use_of_visible_for_testing_member 16 | // ignore_for_file: prefer_const_constructors 17 | // ignore_for_file: unnecessary_parenthesis 18 | // ignore_for_file: camel_case_types 19 | 20 | class _FakePubSubResponse_0 extends _i1.Fake implements _i2.PubSubResponse {} 21 | 22 | /// A class which mocks [TestPubSub]. 23 | /// 24 | /// See the documentation for Mockito's code generation for more information. 25 | class MockTestPubSub extends _i1.Mock implements _i3.TestPubSub { 26 | MockTestPubSub() { 27 | _i1.throwOnMissingStub(this); 28 | } 29 | 30 | @override 31 | _i4.Future<_i2.PubSubResponse> testCallBack(dynamic data) => 32 | (super.noSuchMethod(Invocation.method(#testCallBack, [data]), 33 | returnValue: 34 | Future<_i2.PubSubResponse>.value(_FakePubSubResponse_0())) 35 | as _i4.Future<_i2.PubSubResponse>); 36 | @override 37 | String toString() => super.toString(); 38 | } 39 | 40 | /// A class which mocks [TestBinding]. 41 | /// 42 | /// See the documentation for Mockito's code generation for more information. 43 | class MockTestBinding extends _i1.Mock implements _i3.TestBinding { 44 | MockTestBinding() { 45 | _i1.throwOnMissingStub(this); 46 | } 47 | 48 | @override 49 | _i4.Future testCallBack(_i2.BindingEvent? bindingEvent) => 50 | (super.noSuchMethod(Invocation.method(#testCallBack, [bindingEvent]), 51 | returnValue: Future.value()) as _i4.Future); 52 | @override 53 | String toString() => super.toString(); 54 | } 55 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/client_type_definitions.dart: -------------------------------------------------------------------------------- 1 | typedef StateMetaData = Map; 2 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/actor_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'actor_models.freezed.dart'; 4 | part 'actor_models.g.dart'; 5 | 6 | @freezed 7 | class ActorTimer with _$ActorTimer { 8 | const factory ActorTimer({ 9 | required Duration period, 10 | Duration? dueTime, 11 | dynamic data, 12 | // TODO: Address the call back after understanding this api properly. 13 | // String callBack, 14 | }) = _ActorTimer; 15 | factory ActorTimer.fromJson(Map json) => 16 | _$ActorTimerFromJson(json); 17 | } 18 | 19 | @freezed 20 | class ActorReminder with _$ActorReminder { 21 | const factory ActorReminder({ 22 | required Duration period, 23 | Duration? dueTime, 24 | dynamic data, 25 | }) = _ActorReminder; 26 | 27 | factory ActorReminder.fromJson(Map json) => 28 | _$ActorReminderFromJson(json); 29 | } 30 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/actor_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'actor_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_ActorTimer _$$_ActorTimerFromJson(Map json) => 10 | _$_ActorTimer( 11 | period: Duration(microseconds: json['period'] as int), 12 | dueTime: json['dueTime'] == null 13 | ? null 14 | : Duration(microseconds: json['dueTime'] as int), 15 | data: json['data'], 16 | ); 17 | 18 | Map _$$_ActorTimerToJson(_$_ActorTimer instance) => 19 | { 20 | 'period': instance.period.inMicroseconds, 21 | 'dueTime': instance.dueTime?.inMicroseconds, 22 | 'data': instance.data, 23 | }; 24 | 25 | _$_ActorReminder _$$_ActorReminderFromJson(Map json) => 26 | _$_ActorReminder( 27 | period: Duration(microseconds: json['period'] as int), 28 | dueTime: json['dueTime'] == null 29 | ? null 30 | : Duration(microseconds: json['dueTime'] as int), 31 | data: json['data'], 32 | ); 33 | 34 | Map _$$_ActorReminderToJson(_$_ActorReminder instance) => 35 | { 36 | 'period': instance.period.inMicroseconds, 37 | 'dueTime': instance.dueTime?.inMicroseconds, 38 | 'data': instance.data, 39 | }; 40 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/bindings_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'bindings_models.g.dart'; 4 | part 'bindings_models.freezed.dart'; 5 | 6 | @freezed 7 | class OutputBindingEvent with _$OutputBindingEvent { 8 | const factory OutputBindingEvent({ 9 | required String data, 10 | @Default({}) Map metadata, 11 | required String operation, 12 | }) = _OutputBindingEvent; 13 | 14 | factory OutputBindingEvent.fromJson(Map json) => 15 | _$OutputBindingEventFromJson(json); 16 | } 17 | 18 | @freezed 19 | class OutputBindingEventResponse with _$OutputBindingEventResponse { 20 | const factory OutputBindingEventResponse({ 21 | required String data, 22 | required Map metadata, 23 | }) = _OutputBindingEventResponse; 24 | 25 | factory OutputBindingEventResponse.fromJson(Map json) => 26 | _$OutputBindingEventResponseFromJson(json); 27 | } 28 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/bindings_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bindings_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_OutputBindingEvent _$$_OutputBindingEventFromJson( 10 | Map json) => 11 | _$_OutputBindingEvent( 12 | data: json['data'] as String, 13 | metadata: (json['metadata'] as Map?)?.map( 14 | (k, e) => MapEntry(k, e as String), 15 | ) ?? 16 | {}, 17 | operation: json['operation'] as String, 18 | ); 19 | 20 | Map _$$_OutputBindingEventToJson( 21 | _$_OutputBindingEvent instance) => 22 | { 23 | 'data': instance.data, 24 | 'metadata': instance.metadata, 25 | 'operation': instance.operation, 26 | }; 27 | 28 | _$_OutputBindingEventResponse _$$_OutputBindingEventResponseFromJson( 29 | Map json) => 30 | _$_OutputBindingEventResponse( 31 | data: json['data'] as String, 32 | metadata: Map.from(json['metadata'] as Map), 33 | ); 34 | 35 | Map _$$_OutputBindingEventResponseToJson( 36 | _$_OutputBindingEventResponse instance) => 37 | { 38 | 'data': instance.data, 39 | 'metadata': instance.metadata, 40 | }; 41 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/pub_sub_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'pub_sub_models.freezed.dart'; 4 | part 'pub_sub_models.g.dart'; 5 | 6 | @freezed 7 | class PublishMetadata with _$PublishMetadata { 8 | const factory PublishMetadata({ 9 | int? ttlInSeconds, 10 | @Default(false) bool rawPayload, 11 | }) = _PublishMetadata; 12 | 13 | factory PublishMetadata.fromJson(Map json) => 14 | _$PublishMetadataFromJson(json); 15 | } 16 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/pub_sub_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pub_sub_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_PublishMetadata _$$_PublishMetadataFromJson(Map json) => 10 | _$_PublishMetadata( 11 | ttlInSeconds: json['ttlInSeconds'] as int?, 12 | rawPayload: json['rawPayload'] as bool? ?? false, 13 | ); 14 | 15 | Map _$$_PublishMetadataToJson(_$_PublishMetadata instance) => 16 | { 17 | 'ttlInSeconds': instance.ttlInSeconds, 18 | 'rawPayload': instance.rawPayload, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/secret_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'secret_models.freezed.dart'; 4 | part 'secret_models.g.dart'; 5 | 6 | @freezed 7 | class SecretResponse with _$SecretResponse { 8 | const factory SecretResponse({ 9 | required Map secrets, 10 | }) = _SecretResponse; 11 | factory SecretResponse.fromJson(Map json) => 12 | _$SecretResponseFromJson(json); 13 | } 14 | 15 | // @freezed 16 | // class BulkSecretResponse with _$BulkSecretResponse { 17 | // const factory BulkSecretResponse({ 18 | // required Map secrets, 19 | // }) = _BulkSecretResponse; 20 | // factory BulkSecretResponse.fromJson(Map json) => 21 | // _$BulkSecretResponseFromJson(json); 22 | // } 23 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/secret_models.freezed.dart: -------------------------------------------------------------------------------- 1 | // coverage:ignore-file 2 | // GENERATED CODE - DO NOT MODIFY BY HAND 3 | // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target 4 | 5 | part of 'secret_models.dart'; 6 | 7 | // ************************************************************************** 8 | // FreezedGenerator 9 | // ************************************************************************** 10 | 11 | T _$identity(T value) => value; 12 | 13 | final _privateConstructorUsedError = UnsupportedError( 14 | 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); 15 | 16 | SecretResponse _$SecretResponseFromJson(Map json) { 17 | return _SecretResponse.fromJson(json); 18 | } 19 | 20 | /// @nodoc 21 | class _$SecretResponseTearOff { 22 | const _$SecretResponseTearOff(); 23 | 24 | _SecretResponse call({required Map secrets}) { 25 | return _SecretResponse( 26 | secrets: secrets, 27 | ); 28 | } 29 | 30 | SecretResponse fromJson(Map json) { 31 | return SecretResponse.fromJson(json); 32 | } 33 | } 34 | 35 | /// @nodoc 36 | const $SecretResponse = _$SecretResponseTearOff(); 37 | 38 | /// @nodoc 39 | mixin _$SecretResponse { 40 | Map get secrets => throw _privateConstructorUsedError; 41 | 42 | Map toJson() => throw _privateConstructorUsedError; 43 | @JsonKey(ignore: true) 44 | $SecretResponseCopyWith get copyWith => 45 | throw _privateConstructorUsedError; 46 | } 47 | 48 | /// @nodoc 49 | abstract class $SecretResponseCopyWith<$Res> { 50 | factory $SecretResponseCopyWith( 51 | SecretResponse value, $Res Function(SecretResponse) then) = 52 | _$SecretResponseCopyWithImpl<$Res>; 53 | $Res call({Map secrets}); 54 | } 55 | 56 | /// @nodoc 57 | class _$SecretResponseCopyWithImpl<$Res> 58 | implements $SecretResponseCopyWith<$Res> { 59 | _$SecretResponseCopyWithImpl(this._value, this._then); 60 | 61 | final SecretResponse _value; 62 | // ignore: unused_field 63 | final $Res Function(SecretResponse) _then; 64 | 65 | @override 66 | $Res call({ 67 | Object? secrets = freezed, 68 | }) { 69 | return _then(_value.copyWith( 70 | secrets: secrets == freezed 71 | ? _value.secrets 72 | : secrets // ignore: cast_nullable_to_non_nullable 73 | as Map, 74 | )); 75 | } 76 | } 77 | 78 | /// @nodoc 79 | abstract class _$SecretResponseCopyWith<$Res> 80 | implements $SecretResponseCopyWith<$Res> { 81 | factory _$SecretResponseCopyWith( 82 | _SecretResponse value, $Res Function(_SecretResponse) then) = 83 | __$SecretResponseCopyWithImpl<$Res>; 84 | @override 85 | $Res call({Map secrets}); 86 | } 87 | 88 | /// @nodoc 89 | class __$SecretResponseCopyWithImpl<$Res> 90 | extends _$SecretResponseCopyWithImpl<$Res> 91 | implements _$SecretResponseCopyWith<$Res> { 92 | __$SecretResponseCopyWithImpl( 93 | _SecretResponse _value, $Res Function(_SecretResponse) _then) 94 | : super(_value, (v) => _then(v as _SecretResponse)); 95 | 96 | @override 97 | _SecretResponse get _value => super._value as _SecretResponse; 98 | 99 | @override 100 | $Res call({ 101 | Object? secrets = freezed, 102 | }) { 103 | return _then(_SecretResponse( 104 | secrets: secrets == freezed 105 | ? _value.secrets 106 | : secrets // ignore: cast_nullable_to_non_nullable 107 | as Map, 108 | )); 109 | } 110 | } 111 | 112 | /// @nodoc 113 | @JsonSerializable() 114 | class _$_SecretResponse implements _SecretResponse { 115 | const _$_SecretResponse({required this.secrets}); 116 | 117 | factory _$_SecretResponse.fromJson(Map json) => 118 | _$$_SecretResponseFromJson(json); 119 | 120 | @override 121 | final Map secrets; 122 | 123 | @override 124 | String toString() { 125 | return 'SecretResponse(secrets: $secrets)'; 126 | } 127 | 128 | @override 129 | bool operator ==(dynamic other) { 130 | return identical(this, other) || 131 | (other.runtimeType == runtimeType && 132 | other is _SecretResponse && 133 | const DeepCollectionEquality().equals(other.secrets, secrets)); 134 | } 135 | 136 | @override 137 | int get hashCode => 138 | Object.hash(runtimeType, const DeepCollectionEquality().hash(secrets)); 139 | 140 | @JsonKey(ignore: true) 141 | @override 142 | _$SecretResponseCopyWith<_SecretResponse> get copyWith => 143 | __$SecretResponseCopyWithImpl<_SecretResponse>(this, _$identity); 144 | 145 | @override 146 | Map toJson() { 147 | return _$$_SecretResponseToJson(this); 148 | } 149 | } 150 | 151 | abstract class _SecretResponse implements SecretResponse { 152 | const factory _SecretResponse({required Map secrets}) = 153 | _$_SecretResponse; 154 | 155 | factory _SecretResponse.fromJson(Map json) = 156 | _$_SecretResponse.fromJson; 157 | 158 | @override 159 | Map get secrets; 160 | @override 161 | @JsonKey(ignore: true) 162 | _$SecretResponseCopyWith<_SecretResponse> get copyWith => 163 | throw _privateConstructorUsedError; 164 | } 165 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/secret_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'secret_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_SecretResponse _$$_SecretResponseFromJson(Map json) => 10 | _$_SecretResponse( 11 | secrets: json['secrets'] as Map, 12 | ); 13 | 14 | Map _$$_SecretResponseToJson(_$_SecretResponse instance) => 15 | { 16 | 'secrets': instance.secrets, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/state_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | import '../../../enum/state_option_enums.dart'; 4 | import '../../../models/client/client_type_definitions.dart'; 5 | 6 | 7 | part 'state_models.freezed.dart'; 8 | part 'state_models.g.dart'; 9 | 10 | /// The definition is based on the options to be passed to save state method 11 | /// of the Dapr State api. 12 | /// 13 | /// https://docs.dapr.io/reference/api/state_api/#request-body 14 | @freezed 15 | class SaveStateItem with _$SaveStateItem { 16 | factory SaveStateItem({ 17 | required String key, 18 | required dynamic value, 19 | String? etag, 20 | // TODO: following fields should be updated after properly understanding 21 | // the api 22 | // 23 | // dynamic? metadata, 24 | // StateOptions options, 25 | }) = _SaveStateItem; 26 | 27 | factory SaveStateItem.fromJson(Map json) => 28 | _$SaveStateItemFromJson(json); 29 | } 30 | 31 | /// The definition is based on the response definition provided in Dapr State management api 32 | /// Check the response section. 33 | /// 34 | /// https://docs.dapr.io/reference/api/state_api/#example-2 35 | @freezed 36 | class BulkStateItem with _$BulkStateItem { 37 | factory BulkStateItem({ 38 | required String key, 39 | required dynamic data, 40 | String? etag, 41 | }) = _BulkStateItem; 42 | 43 | factory BulkStateItem.fromJson(Map json) => 44 | _$BulkStateItemFromJson(json); 45 | } 46 | 47 | @freezed 48 | class StateOptions with _$StateOptions { 49 | const factory StateOptions({ 50 | Concurrency? concurrency, 51 | Consistency? consistency, 52 | }) = _StateOptions; 53 | 54 | factory StateOptions.fromJson(Map json) => 55 | _$StateOptionsFromJson(json); 56 | } 57 | 58 | @freezed 59 | class Etag with _$Etag { 60 | const factory Etag({ 61 | required String value, 62 | }) = _Etag; 63 | factory Etag.fromJson(Map json) => _$EtagFromJson(json); 64 | } 65 | 66 | @freezed 67 | class StateOperation with _$StateOperation { 68 | const factory StateOperation({ 69 | required String operation, 70 | required StateOperationRequest request, 71 | }) = _StateOperation; 72 | factory StateOperation.fromJson(Map json) => 73 | _$StateOperationFromJson(json); 74 | } 75 | 76 | @freezed 77 | class StateOperationRequest with _$StateOperationRequest { 78 | const factory StateOperationRequest({ 79 | required String key, 80 | String? value, 81 | Etag? etag, 82 | StateMetaData? metaData, 83 | StateOptions? options, 84 | }) = _StateOperationRequest; 85 | 86 | factory StateOperationRequest.fromJson(Map json) => 87 | _$StateOperationRequestFromJson(json); 88 | } 89 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/client/generated/state_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'state_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_SaveStateItem _$$_SaveStateItemFromJson(Map json) => 10 | _$_SaveStateItem( 11 | key: json['key'] as String, 12 | value: json['value'], 13 | etag: json['etag'] as String?, 14 | ); 15 | 16 | Map _$$_SaveStateItemToJson(_$_SaveStateItem instance) => 17 | { 18 | 'key': instance.key, 19 | 'value': instance.value, 20 | 'etag': instance.etag, 21 | }; 22 | 23 | _$_BulkStateItem _$$_BulkStateItemFromJson(Map json) => 24 | _$_BulkStateItem( 25 | key: json['key'] as String, 26 | data: json['data'], 27 | etag: json['etag'] as String?, 28 | ); 29 | 30 | Map _$$_BulkStateItemToJson(_$_BulkStateItem instance) => 31 | { 32 | 'key': instance.key, 33 | 'data': instance.data, 34 | 'etag': instance.etag, 35 | }; 36 | 37 | _$_StateOptions _$$_StateOptionsFromJson(Map json) => 38 | _$_StateOptions( 39 | concurrency: 40 | $enumDecodeNullable(_$ConcurrencyEnumMap, json['concurrency']), 41 | consistency: 42 | $enumDecodeNullable(_$ConsistencyEnumMap, json['consistency']), 43 | ); 44 | 45 | Map _$$_StateOptionsToJson(_$_StateOptions instance) => 46 | { 47 | 'concurrency': _$ConcurrencyEnumMap[instance.concurrency], 48 | 'consistency': _$ConsistencyEnumMap[instance.consistency], 49 | }; 50 | 51 | const _$ConcurrencyEnumMap = { 52 | Concurrency.unspecified: 'unspecified', 53 | Concurrency.firstWrite: 'firstWrite', 54 | Concurrency.lastWrite: 'lastWrite', 55 | }; 56 | 57 | const _$ConsistencyEnumMap = { 58 | Consistency.unspecified: 'unspecified', 59 | Consistency.eventual: 'eventual', 60 | Consistency.strong: 'strong', 61 | }; 62 | 63 | _$_Etag _$$_EtagFromJson(Map json) => _$_Etag( 64 | value: json['value'] as String, 65 | ); 66 | 67 | Map _$$_EtagToJson(_$_Etag instance) => { 68 | 'value': instance.value, 69 | }; 70 | 71 | _$_StateOperation _$$_StateOperationFromJson(Map json) => 72 | _$_StateOperation( 73 | operation: json['operation'] as String, 74 | request: StateOperationRequest.fromJson( 75 | json['request'] as Map), 76 | ); 77 | 78 | Map _$$_StateOperationToJson(_$_StateOperation instance) => 79 | { 80 | 'operation': instance.operation, 81 | 'request': instance.request, 82 | }; 83 | 84 | _$_StateOperationRequest _$$_StateOperationRequestFromJson( 85 | Map json) => 86 | _$_StateOperationRequest( 87 | key: json['key'] as String, 88 | value: json['value'] as String?, 89 | etag: json['etag'] == null 90 | ? null 91 | : Etag.fromJson(json['etag'] as Map), 92 | metaData: json['metaData'] as Map?, 93 | options: json['options'] == null 94 | ? null 95 | : StateOptions.fromJson(json['options'] as Map), 96 | ); 97 | 98 | Map _$$_StateOperationRequestToJson( 99 | _$_StateOperationRequest instance) => 100 | { 101 | 'key': instance.key, 102 | 'value': instance.value, 103 | 'etag': instance.etag, 104 | 'metaData': instance.metaData, 105 | 'options': instance.options, 106 | }; 107 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/bindings_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'bindings_models.g.dart'; 4 | part 'bindings_models.freezed.dart'; 5 | 6 | @freezed 7 | class BindingEvent with _$BindingEvent { 8 | const factory BindingEvent({ 9 | required String data, 10 | @Default({}) Map metadata, 11 | }) = _BindingEvent; 12 | 13 | factory BindingEvent.fromJson(Map json) => 14 | _$BindingEventFromJson(json); 15 | } 16 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/bindings_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bindings_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_BindingEvent _$$_BindingEventFromJson(Map json) => 10 | _$_BindingEvent( 11 | data: json['data'] as String, 12 | metadata: json['metadata'] as Map? ?? {}, 13 | ); 14 | 15 | Map _$$_BindingEventToJson(_$_BindingEvent instance) => 16 | { 17 | 'data': instance.data, 18 | 'metadata': instance.metadata, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/invoker_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | import '../../../enum/http_method.dart'; 4 | 5 | part 'invoker_models.freezed.dart'; 6 | part 'invoker_models.g.dart'; 7 | 8 | @freezed 9 | class InvokerCallbackContent with _$InvokerCallbackContent { 10 | const factory InvokerCallbackContent({ 11 | String? body, 12 | Map? query, 13 | InvokerCallbackMetadata? metadata, 14 | }) = _InvokerCallbackContent; 15 | 16 | factory InvokerCallbackContent.fromJson(Map json) => 17 | _$InvokerCallbackContentFromJson(json); 18 | } 19 | 20 | @freezed 21 | class InvokerCallbackMetadata with _$InvokerCallbackMetadata { 22 | const factory InvokerCallbackMetadata({ 23 | String? contentType, 24 | }) = _InvokerCallbackMetadata; 25 | 26 | factory InvokerCallbackMetadata.fromJson(Map json) => 27 | _$InvokerCallbackMetadataFromJson(json); 28 | } 29 | 30 | @freezed 31 | class InvokerCallbackOptions with _$InvokerCallbackOptions { 32 | const factory InvokerCallbackOptions({required HttpMethod method}) = 33 | _InvokerCallbackOptions; 34 | 35 | factory InvokerCallbackOptions.fromJson(Map json) => 36 | _$InvokerCallbackOptionsFromJson(json); 37 | } 38 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/invoker_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'invoker_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_InvokerCallbackContent _$$_InvokerCallbackContentFromJson( 10 | Map json) => 11 | _$_InvokerCallbackContent( 12 | body: json['body'] as String?, 13 | query: (json['query'] as Map?)?.map( 14 | (k, e) => MapEntry(k, e as String), 15 | ), 16 | metadata: json['metadata'] == null 17 | ? null 18 | : InvokerCallbackMetadata.fromJson( 19 | json['metadata'] as Map), 20 | ); 21 | 22 | Map _$$_InvokerCallbackContentToJson( 23 | _$_InvokerCallbackContent instance) => 24 | { 25 | 'body': instance.body, 26 | 'query': instance.query, 27 | 'metadata': instance.metadata, 28 | }; 29 | 30 | _$_InvokerCallbackMetadata _$$_InvokerCallbackMetadataFromJson( 31 | Map json) => 32 | _$_InvokerCallbackMetadata( 33 | contentType: json['contentType'] as String?, 34 | ); 35 | 36 | Map _$$_InvokerCallbackMetadataToJson( 37 | _$_InvokerCallbackMetadata instance) => 38 | { 39 | 'contentType': instance.contentType, 40 | }; 41 | 42 | _$_InvokerCallbackOptions _$$_InvokerCallbackOptionsFromJson( 43 | Map json) => 44 | _$_InvokerCallbackOptions( 45 | method: $enumDecode(_$HttpMethodEnumMap, json['method']), 46 | ); 47 | 48 | Map _$$_InvokerCallbackOptionsToJson( 49 | _$_InvokerCallbackOptions instance) => 50 | { 51 | 'method': _$HttpMethodEnumMap[instance.method], 52 | }; 53 | 54 | const _$HttpMethodEnumMap = { 55 | HttpMethod.get: 'get', 56 | HttpMethod.put: 'put', 57 | HttpMethod.post: 'post', 58 | HttpMethod.delete: 'delete', 59 | }; 60 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/pub_sub_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'pub_sub_models.freezed.dart'; 4 | part 'pub_sub_models.g.dart'; 5 | 6 | @freezed 7 | class PubSubRoute with _$PubSubRoute { 8 | const factory PubSubRoute({ 9 | /// The component name configured in a component yaml file. 10 | @JsonKey(name: 'pubsubname') required String pubSubName, 11 | 12 | /// The name of the topic to Publish/Subscribe to. 13 | required String topic, 14 | 15 | /// The http route name for associated with this topic. 16 | /// 17 | /// This name is primarily used for a Http server where the event from the 18 | /// topic will forwared to this http route built automatically. 19 | required String route, 20 | 21 | /// Metadata to be passed to the dapr. e.g. rawPayload. 22 | /// https://docs.dapr.io/developing-applications/building-blocks/pubsub/pubsub-raw/ 23 | @Default({}) Map metadata, 24 | }) = _PubSubRoute; 25 | 26 | factory PubSubRoute.fromJson(Map json) => 27 | _$PubSubRouteFromJson(json); 28 | } 29 | 30 | @freezed 31 | class PubSubResponse with _$PubSubResponse { 32 | const factory PubSubResponse.success() = Success; 33 | const factory PubSubResponse.drop() = Drop; 34 | const factory PubSubResponse.retry() = Retry; 35 | const factory PubSubResponse.error() = Error; 36 | } 37 | 38 | @freezed 39 | class CloudEvent with _$CloudEvent { 40 | const factory CloudEvent({ 41 | required String id, 42 | required Uri source, 43 | @JsonKey(name: 'specversion') required String specVersion, 44 | required String type, 45 | @JsonKey(name: 'datacontenttype') String? dataContentType, 46 | Object? data, 47 | @JsonKey(name: 'dataschema') Uri? dataSchema, 48 | String? subject, 49 | DateTime? time, 50 | }) = _CloudEvent; 51 | 52 | factory CloudEvent.fromJson(Map json) => 53 | _$CloudEventFromJson(json); 54 | } 55 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/generated/pub_sub_models.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'pub_sub_models.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_PubSubRoute _$$_PubSubRouteFromJson(Map json) => 10 | _$_PubSubRoute( 11 | pubSubName: json['pubsubname'] as String, 12 | topic: json['topic'] as String, 13 | route: json['route'] as String, 14 | metadata: (json['metadata'] as Map?)?.map( 15 | (k, e) => MapEntry(k, e as String), 16 | ) ?? 17 | {}, 18 | ); 19 | 20 | Map _$$_PubSubRouteToJson(_$_PubSubRoute instance) => 21 | { 22 | 'pubsubname': instance.pubSubName, 23 | 'topic': instance.topic, 24 | 'route': instance.route, 25 | 'metadata': instance.metadata, 26 | }; 27 | 28 | _$_CloudEvent _$$_CloudEventFromJson(Map json) => 29 | _$_CloudEvent( 30 | id: json['id'] as String, 31 | source: Uri.parse(json['source'] as String), 32 | specVersion: json['specversion'] as String, 33 | type: json['type'] as String, 34 | dataContentType: json['datacontenttype'] as String?, 35 | data: json['data'], 36 | dataSchema: json['dataschema'] == null 37 | ? null 38 | : Uri.parse(json['dataschema'] as String), 39 | subject: json['subject'] as String?, 40 | time: 41 | json['time'] == null ? null : DateTime.parse(json['time'] as String), 42 | ); 43 | 44 | Map _$$_CloudEventToJson(_$_CloudEvent instance) => 45 | { 46 | 'id': instance.id, 47 | 'source': instance.source.toString(), 48 | 'specversion': instance.specVersion, 49 | 'type': instance.type, 50 | 'datacontenttype': instance.dataContentType, 51 | 'data': instance.data, 52 | 'dataschema': instance.dataSchema?.toString(), 53 | 'subject': instance.subject, 54 | 'time': instance.time?.toIso8601String(), 55 | }; 56 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/models/server/server_type_definitions.dart: -------------------------------------------------------------------------------- 1 | import '../../../dapr_common.dart'; 2 | 3 | typedef BindingCallback = Future Function(BindingEvent data); 4 | typedef PubSubCallback = Future Function(dynamic data); 5 | 6 | typedef InvokerCallback = Future Function(InvokerCallbackContent data); 7 | -------------------------------------------------------------------------------- /packages/dapr_common/lib/src/utils/utils.dart: -------------------------------------------------------------------------------- 1 | Map removeNullsFromMap(Map json) => json 2 | ..removeWhere((String key, dynamic value) => value == null) 3 | ..map((key, value) => MapEntry(key, removeNulls(value))); 4 | 5 | removeNulls(e) => (e is List) 6 | ? removeNullsFromList(e) 7 | : (e is Map ? removeNullsFromMap(e) : e); 8 | 9 | List removeNullsFromList(List list) => list 10 | ..removeWhere((value) => value == null) 11 | ..map((e) => removeNulls(e)).toList(); 12 | 13 | String mapToQueryParams(Map metadataMap) { 14 | var _queryParam = ''; 15 | for (var entry in metadataMap.entries) { 16 | _queryParam += '${entry.key}=${entry.value}&'; 17 | } 18 | return _queryParam.isNotEmpty 19 | ? _queryParam.substring(0, _queryParam.length - 1) 20 | : _queryParam; 21 | } 22 | 23 | Map queryParamStringToMap(String queryParams) { 24 | var _queryParam = {}; 25 | if (queryParams.isNotEmpty) { 26 | final splitByAmpresand = queryParams.split('&'); 27 | for (var qp in splitByAmpresand) { 28 | var splitByEq = qp.split('='); 29 | if (splitByEq.isNotEmpty) { 30 | _queryParam.putIfAbsent(splitByEq[0], () => splitByEq[1]); 31 | } 32 | } 33 | } 34 | return _queryParam; 35 | } 36 | -------------------------------------------------------------------------------- /packages/dapr_common/melos_dapr_common.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_common/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dapr_common 2 | description: A starting point for Dart libraries or applications. 3 | version: 0.0.1 4 | # homepage: https://www.example.com 5 | 6 | environment: 7 | sdk: '>=2.14.4 <3.0.0' 8 | 9 | 10 | dependencies: 11 | freezed_annotation: 12 | json_annotation: ^4.3.0 13 | mockito: ^5.0.16 14 | 15 | dev_dependencies: 16 | lints: ^1.0.0 17 | test: ^1.16.0 18 | build_runner: 19 | freezed: 20 | json_serializable: 21 | -------------------------------------------------------------------------------- /packages/dapr_common/test/dapr_common_test.dart: -------------------------------------------------------------------------------- 1 | // import 'package:dapr_common/dapr_common.dart'; 2 | // import 'package:test/test.dart'; 3 | 4 | // void main() { 5 | // group('A group of tests', () { 6 | // final awesome = Awesome(); 7 | 8 | // setUp(() { 9 | // // Additional setup goes here. 10 | // }); 11 | 12 | // test('First Test', () { 13 | // expect(awesome.isAwesome, isTrue); 14 | // }); 15 | // }); 16 | // } 17 | -------------------------------------------------------------------------------- /packages/dapr_proto/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build outputs. 6 | build/ 7 | 8 | # Omit committing pubspec.lock for library packages; see 9 | # https://dart.dev/guides/libraries/private-files#pubspeclock. 10 | pubspec.lock 11 | -------------------------------------------------------------------------------- /packages/dapr_proto/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.3 2 | 3 | - Export google protobuf stubs. 4 | 5 | ## 0.0.2 6 | 7 | - Updated read me for proper description. 8 | 9 | ## 0.0.1 10 | 11 | - Initial version. 12 | -------------------------------------------------------------------------------- /packages/dapr_proto/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Abhilash Chandran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/dapr_proto/README.md: -------------------------------------------------------------------------------- 1 | # Dapr_proto 2 | 3 | An assiting package for dapr_client package. 4 | 5 | The primary purpose of this package is to provide the Dapr grpc stubs required for implmenting the dapr_client package. 6 | 7 | The package basically generates the dart stubs for dapr and exposes it a separate library. 8 | 9 | Dapr user's doesn't have use this package directly. -------------------------------------------------------------------------------- /packages/dapr_proto/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | linter: 19 | rules: 20 | constant_identifier_names: false 21 | avoid_renaming_method_parameters: false 22 | 23 | analyzer: 24 | exclude: 25 | - "**/*.pb.dart" 26 | 27 | # For more information about the core and recommended set of lints, see 28 | # https://dart.dev/go/core-lints 29 | 30 | # For additional information about configuring this file, see 31 | # https://dart.dev/guides/language/analysis-options 32 | -------------------------------------------------------------------------------- /packages/dapr_proto/example/dapr_proto_example.dart: -------------------------------------------------------------------------------- 1 | // import 'package:dapr_proto/dapr_proto.dart'; 2 | 3 | // void main() { 4 | // var awesome = Awesome(); 5 | // print('awesome: ${awesome.isAwesome}'); 6 | // } 7 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/dapr_proto.dart: -------------------------------------------------------------------------------- 1 | /// Support for doing something awesome. 2 | /// 3 | /// More dartdocs go here. 4 | library dapr_proto; 5 | 6 | /// Export Dapr protobuf stubs 7 | export 'src/proto/dapr/proto/runtime/v1/dapr.pbgrpc.dart'; 8 | export 'src/proto/dapr/proto/runtime/v1/appcallback.pbgrpc.dart'; 9 | export 'src/proto/dapr/proto/common/v1/common.pb.dart'; 10 | export 'src/proto/dapr/proto/runtime/v1/dapr.pb.dart'; 11 | 12 | /// Export google protobuf stubs 13 | export 'src/proto/google/protobuf/empty.pb.dart'; 14 | export 'src/proto/google/protobuf/any.pb.dart'; 15 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/dapr/proto/common/v1/common.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: dapr/proto/common/v1/common.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | // ignore_for_file: UNDEFINED_SHOWN_NAME 9 | import 'dart:core' as $core; 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | class HTTPExtension_Verb extends $pb.ProtobufEnum { 13 | static const HTTPExtension_Verb NONE = HTTPExtension_Verb._( 14 | 0, 15 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 16 | ? '' 17 | : 'NONE'); 18 | static const HTTPExtension_Verb GET = HTTPExtension_Verb._( 19 | 1, 20 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 21 | ? '' 22 | : 'GET'); 23 | static const HTTPExtension_Verb HEAD = HTTPExtension_Verb._( 24 | 2, 25 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 26 | ? '' 27 | : 'HEAD'); 28 | static const HTTPExtension_Verb POST = HTTPExtension_Verb._( 29 | 3, 30 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 31 | ? '' 32 | : 'POST'); 33 | static const HTTPExtension_Verb PUT = HTTPExtension_Verb._( 34 | 4, 35 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 36 | ? '' 37 | : 'PUT'); 38 | static const HTTPExtension_Verb DELETE = HTTPExtension_Verb._( 39 | 5, 40 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 41 | ? '' 42 | : 'DELETE'); 43 | static const HTTPExtension_Verb CONNECT = HTTPExtension_Verb._( 44 | 6, 45 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 46 | ? '' 47 | : 'CONNECT'); 48 | static const HTTPExtension_Verb OPTIONS = HTTPExtension_Verb._( 49 | 7, 50 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 51 | ? '' 52 | : 'OPTIONS'); 53 | static const HTTPExtension_Verb TRACE = HTTPExtension_Verb._( 54 | 8, 55 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 56 | ? '' 57 | : 'TRACE'); 58 | static const HTTPExtension_Verb PATCH = HTTPExtension_Verb._( 59 | 9, 60 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 61 | ? '' 62 | : 'PATCH'); 63 | 64 | static const $core.List values = [ 65 | NONE, 66 | GET, 67 | HEAD, 68 | POST, 69 | PUT, 70 | DELETE, 71 | CONNECT, 72 | OPTIONS, 73 | TRACE, 74 | PATCH, 75 | ]; 76 | 77 | static final $core.Map<$core.int, HTTPExtension_Verb> _byValue = 78 | $pb.ProtobufEnum.initByValue(values); 79 | static HTTPExtension_Verb? valueOf($core.int value) => _byValue[value]; 80 | 81 | const HTTPExtension_Verb._($core.int v, $core.String n) : super(v, n); 82 | } 83 | 84 | class StateOptions_StateConcurrency extends $pb.ProtobufEnum { 85 | static const StateOptions_StateConcurrency CONCURRENCY_UNSPECIFIED = 86 | StateOptions_StateConcurrency._( 87 | 0, 88 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 89 | ? '' 90 | : 'CONCURRENCY_UNSPECIFIED'); 91 | static const StateOptions_StateConcurrency CONCURRENCY_FIRST_WRITE = 92 | StateOptions_StateConcurrency._( 93 | 1, 94 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 95 | ? '' 96 | : 'CONCURRENCY_FIRST_WRITE'); 97 | static const StateOptions_StateConcurrency CONCURRENCY_LAST_WRITE = 98 | StateOptions_StateConcurrency._( 99 | 2, 100 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 101 | ? '' 102 | : 'CONCURRENCY_LAST_WRITE'); 103 | 104 | static const $core.List values = 105 | [ 106 | CONCURRENCY_UNSPECIFIED, 107 | CONCURRENCY_FIRST_WRITE, 108 | CONCURRENCY_LAST_WRITE, 109 | ]; 110 | 111 | static final $core.Map<$core.int, StateOptions_StateConcurrency> _byValue = 112 | $pb.ProtobufEnum.initByValue(values); 113 | static StateOptions_StateConcurrency? valueOf($core.int value) => 114 | _byValue[value]; 115 | 116 | const StateOptions_StateConcurrency._($core.int v, $core.String n) 117 | : super(v, n); 118 | } 119 | 120 | class StateOptions_StateConsistency extends $pb.ProtobufEnum { 121 | static const StateOptions_StateConsistency CONSISTENCY_UNSPECIFIED = 122 | StateOptions_StateConsistency._( 123 | 0, 124 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 125 | ? '' 126 | : 'CONSISTENCY_UNSPECIFIED'); 127 | static const StateOptions_StateConsistency CONSISTENCY_EVENTUAL = 128 | StateOptions_StateConsistency._( 129 | 1, 130 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 131 | ? '' 132 | : 'CONSISTENCY_EVENTUAL'); 133 | static const StateOptions_StateConsistency CONSISTENCY_STRONG = 134 | StateOptions_StateConsistency._( 135 | 2, 136 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 137 | ? '' 138 | : 'CONSISTENCY_STRONG'); 139 | 140 | static const $core.List values = 141 | [ 142 | CONSISTENCY_UNSPECIFIED, 143 | CONSISTENCY_EVENTUAL, 144 | CONSISTENCY_STRONG, 145 | ]; 146 | 147 | static final $core.Map<$core.int, StateOptions_StateConsistency> _byValue = 148 | $pb.ProtobufEnum.initByValue(values); 149 | static StateOptions_StateConsistency? valueOf($core.int value) => 150 | _byValue[value]; 151 | 152 | const StateOptions_StateConsistency._($core.int v, $core.String n) 153 | : super(v, n); 154 | } 155 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/dapr/proto/common/v1/common.proto: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------ 2 | // Copyright (c) Microsoft Corporation and Dapr Contributors. 3 | // Licensed under the MIT License. 4 | // ------------------------------------------------------------ 5 | 6 | syntax = "proto3"; 7 | 8 | package dapr.proto.common.v1; 9 | 10 | import "google/protobuf/any.proto"; 11 | 12 | option csharp_namespace = "Dapr.Client.Autogen.Grpc.v1"; 13 | option java_outer_classname = "CommonProtos"; 14 | option java_package = "io.dapr.v1"; 15 | option go_package = "github.com/dapr/dapr/pkg/proto/common/v1;common"; 16 | 17 | // HTTPExtension includes HTTP verb and querystring 18 | // when Dapr runtime delivers HTTP content. 19 | // 20 | // For example, when callers calls http invoke api 21 | // POST http://localhost:3500/v1.0/invoke//method/?query1=value1&query2=value2 22 | // 23 | // Dapr runtime will parse POST as a verb and extract querystring to quersytring map. 24 | message HTTPExtension { 25 | // Type of HTTP 1.1 Methods 26 | // RFC 7231: https://tools.ietf.org/html/rfc7231#page-24 27 | // RFC 5789: https://datatracker.ietf.org/doc/html/rfc5789 28 | enum Verb { 29 | NONE = 0; 30 | GET = 1; 31 | HEAD = 2; 32 | POST = 3; 33 | PUT = 4; 34 | DELETE = 5; 35 | CONNECT = 6; 36 | OPTIONS = 7; 37 | TRACE = 8; 38 | PATCH = 9; 39 | } 40 | 41 | // Required. HTTP verb. 42 | Verb verb = 1; 43 | 44 | // Optional. querystring represents an encoded HTTP url query string in the following format: name=value&name2=value2 45 | string querystring = 2; 46 | } 47 | 48 | // InvokeRequest is the message to invoke a method with the data. 49 | // This message is used in InvokeService of Dapr gRPC Service and OnInvoke 50 | // of AppCallback gRPC service. 51 | message InvokeRequest { 52 | // Required. method is a method name which will be invoked by caller. 53 | string method = 1; 54 | 55 | // Required. Bytes value or Protobuf message which caller sent. 56 | // Dapr treats Any.value as bytes type if Any.type_url is unset. 57 | google.protobuf.Any data = 2; 58 | 59 | // The type of data content. 60 | // 61 | // This field is required if data delivers http request body 62 | // Otherwise, this is optional. 63 | string content_type = 3; 64 | 65 | // HTTP specific fields if request conveys http-compatible request. 66 | // 67 | // This field is required for http-compatible request. Otherwise, 68 | // this field is optional. 69 | HTTPExtension http_extension = 4; 70 | } 71 | 72 | // InvokeResponse is the response message inclduing data and its content type 73 | // from app callback. 74 | // This message is used in InvokeService of Dapr gRPC Service and OnInvoke 75 | // of AppCallback gRPC service. 76 | message InvokeResponse { 77 | // Required. The content body of InvokeService response. 78 | google.protobuf.Any data = 1; 79 | 80 | // Required. The type of data content. 81 | string content_type = 2; 82 | } 83 | 84 | // StateItem represents state key, value, and additional options to save state. 85 | message StateItem { 86 | // Required. The state key 87 | string key = 1; 88 | 89 | // Required. The state data for key 90 | bytes value = 2; 91 | 92 | // The entity tag which represents the specific version of data. 93 | // The exact ETag format is defined by the corresponding data store. 94 | Etag etag = 3; 95 | 96 | // The metadata which will be passed to state store component. 97 | map metadata = 4; 98 | 99 | // Options for concurrency and consistency to save the state. 100 | StateOptions options = 5; 101 | } 102 | 103 | // Etag represents a state item version 104 | message Etag { 105 | // value sets the etag value 106 | string value = 1; 107 | } 108 | 109 | // StateOptions configures concurrency and consistency for state operations 110 | message StateOptions { 111 | // Enum describing the supported concurrency for state. 112 | enum StateConcurrency { 113 | CONCURRENCY_UNSPECIFIED = 0; 114 | CONCURRENCY_FIRST_WRITE = 1; 115 | CONCURRENCY_LAST_WRITE = 2; 116 | } 117 | 118 | // Enum describing the supported consistency for state. 119 | enum StateConsistency { 120 | CONSISTENCY_UNSPECIFIED = 0; 121 | CONSISTENCY_EVENTUAL = 1; 122 | CONSISTENCY_STRONG = 2; 123 | } 124 | 125 | StateConcurrency concurrency = 1; 126 | StateConsistency consistency = 2; 127 | } 128 | 129 | 130 | // ConfigurationItem represents all the configuration with its name(key). 131 | message ConfigurationItem { 132 | // Required. The name of configuration item 133 | string key = 1; 134 | 135 | // Required. The value of configuration item. 136 | string value = 2; 137 | 138 | // Version is response only and cannot be fetched. Store is not expected to keep all versions available 139 | string version = 3; 140 | 141 | // the metadata which will be passed to/from configuration store component. 142 | map metadata = 4; 143 | } 144 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/dapr/proto/runtime/v1/appcallback.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: dapr/proto/runtime/v1/appcallback.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | // ignore_for_file: UNDEFINED_SHOWN_NAME 9 | import 'dart:core' as $core; 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | class TopicEventResponse_TopicEventResponseStatus extends $pb.ProtobufEnum { 13 | static const TopicEventResponse_TopicEventResponseStatus SUCCESS = 14 | TopicEventResponse_TopicEventResponseStatus._( 15 | 0, 16 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 17 | ? '' 18 | : 'SUCCESS'); 19 | static const TopicEventResponse_TopicEventResponseStatus RETRY = 20 | TopicEventResponse_TopicEventResponseStatus._( 21 | 1, 22 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 23 | ? '' 24 | : 'RETRY'); 25 | static const TopicEventResponse_TopicEventResponseStatus DROP = 26 | TopicEventResponse_TopicEventResponseStatus._( 27 | 2, 28 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 29 | ? '' 30 | : 'DROP'); 31 | 32 | static const $core.List values = 33 | [ 34 | SUCCESS, 35 | RETRY, 36 | DROP, 37 | ]; 38 | 39 | static final $core.Map<$core.int, TopicEventResponse_TopicEventResponseStatus> 40 | _byValue = $pb.ProtobufEnum.initByValue(values); 41 | static TopicEventResponse_TopicEventResponseStatus? valueOf( 42 | $core.int value) => 43 | _byValue[value]; 44 | 45 | const TopicEventResponse_TopicEventResponseStatus._( 46 | $core.int v, $core.String n) 47 | : super(v, n); 48 | } 49 | 50 | class BindingEventResponse_BindingEventConcurrency extends $pb.ProtobufEnum { 51 | static const BindingEventResponse_BindingEventConcurrency SEQUENTIAL = 52 | BindingEventResponse_BindingEventConcurrency._( 53 | 0, 54 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 55 | ? '' 56 | : 'SEQUENTIAL'); 57 | static const BindingEventResponse_BindingEventConcurrency PARALLEL = 58 | BindingEventResponse_BindingEventConcurrency._( 59 | 1, 60 | const $core.bool.fromEnvironment('protobuf.omit_enum_names') 61 | ? '' 62 | : 'PARALLEL'); 63 | 64 | static const $core.List values = 65 | [ 66 | SEQUENTIAL, 67 | PARALLEL, 68 | ]; 69 | 70 | static final $core 71 | .Map<$core.int, BindingEventResponse_BindingEventConcurrency> 72 | _byValue = $pb.ProtobufEnum.initByValue(values); 73 | static BindingEventResponse_BindingEventConcurrency? valueOf( 74 | $core.int value) => 75 | _byValue[value]; 76 | 77 | const BindingEventResponse_BindingEventConcurrency._( 78 | $core.int v, $core.String n) 79 | : super(v, n); 80 | } 81 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/dapr/proto/runtime/v1/dapr.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: dapr/proto/runtime/v1/dapr.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/any.pb.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/any.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | import 'dart:core' as $core; 9 | 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | import 'package:protobuf/src/protobuf/mixins/well_known.dart' as $mixin; 13 | 14 | class Any extends $pb.GeneratedMessage with $mixin.AnyMixin { 15 | static final $pb.BuilderInfo _i = $pb.BuilderInfo( 16 | const $core.bool.fromEnvironment('protobuf.omit_message_names') 17 | ? '' 18 | : 'Any', 19 | package: const $pb.PackageName( 20 | const $core.bool.fromEnvironment('protobuf.omit_message_names') 21 | ? '' 22 | : 'google.protobuf'), 23 | createEmptyInstance: create, 24 | toProto3Json: $mixin.AnyMixin.toProto3JsonHelper, 25 | fromProto3Json: $mixin.AnyMixin.fromProto3JsonHelper) 26 | ..aOS( 27 | 1, 28 | const $core.bool.fromEnvironment('protobuf.omit_field_names') 29 | ? '' 30 | : 'typeUrl') 31 | ..a<$core.List<$core.int>>( 32 | 2, 33 | const $core.bool.fromEnvironment('protobuf.omit_field_names') 34 | ? '' 35 | : 'value', 36 | $pb.PbFieldType.OY) 37 | ..hasRequiredFields = false; 38 | 39 | Any._() : super(); 40 | factory Any({ 41 | $core.String? typeUrl, 42 | $core.List<$core.int>? value, 43 | }) { 44 | final _result = create(); 45 | if (typeUrl != null) { 46 | _result.typeUrl = typeUrl; 47 | } 48 | if (value != null) { 49 | _result.value = value; 50 | } 51 | return _result; 52 | } 53 | factory Any.fromBuffer($core.List<$core.int> i, 54 | [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => 55 | create()..mergeFromBuffer(i, r); 56 | factory Any.fromJson($core.String i, 57 | [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => 58 | create()..mergeFromJson(i, r); 59 | @$core.Deprecated('Using this can add significant overhead to your binary. ' 60 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 61 | 'Will be removed in next major version') 62 | Any clone() => Any()..mergeFromMessage(this); 63 | @$core.Deprecated('Using this can add significant overhead to your binary. ' 64 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 65 | 'Will be removed in next major version') 66 | Any copyWith(void Function(Any) updates) => 67 | super.copyWith((message) => updates(message as Any)) 68 | as Any; // ignore: deprecated_member_use 69 | $pb.BuilderInfo get info_ => _i; 70 | @$core.pragma('dart2js:noInline') 71 | static Any create() => Any._(); 72 | Any createEmptyInstance() => create(); 73 | static $pb.PbList createRepeated() => $pb.PbList(); 74 | @$core.pragma('dart2js:noInline') 75 | static Any getDefault() => 76 | _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 77 | static Any? _defaultInstance; 78 | 79 | @$pb.TagNumber(1) 80 | $core.String get typeUrl => $_getSZ(0); 81 | @$pb.TagNumber(1) 82 | set typeUrl($core.String v) { 83 | $_setString(0, v); 84 | } 85 | 86 | @$pb.TagNumber(1) 87 | $core.bool hasTypeUrl() => $_has(0); 88 | @$pb.TagNumber(1) 89 | void clearTypeUrl() => clearField(1); 90 | 91 | @$pb.TagNumber(2) 92 | $core.List<$core.int> get value => $_getN(1); 93 | @$pb.TagNumber(2) 94 | set value($core.List<$core.int> v) { 95 | $_setBytes(1, v); 96 | } 97 | 98 | @$pb.TagNumber(2) 99 | $core.bool hasValue() => $_has(1); 100 | @$pb.TagNumber(2) 101 | void clearValue() => clearField(2); 102 | 103 | /// Creates a new [Any] encoding [message]. 104 | /// 105 | /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is 106 | /// the fully qualified name of the type of [message]. 107 | static Any pack($pb.GeneratedMessage message, 108 | {$core.String typeUrlPrefix = 'type.googleapis.com'}) { 109 | final result = create(); 110 | $mixin.AnyMixin.packIntoAny(result, message, typeUrlPrefix: typeUrlPrefix); 111 | return result; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/any.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/any.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/any.pbjson.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/any.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package 7 | 8 | import 'dart:core' as $core; 9 | import 'dart:convert' as $convert; 10 | import 'dart:typed_data' as $typed_data; 11 | 12 | @$core.Deprecated('Use anyDescriptor instead') 13 | const Any$json = const { 14 | '1': 'Any', 15 | '2': const [ 16 | const {'1': 'type_url', '3': 1, '4': 1, '5': 9, '10': 'typeUrl'}, 17 | const {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, 18 | ], 19 | }; 20 | 21 | /// Descriptor for `Any`. Decode as a `google.protobuf.DescriptorProto`. 22 | final $typed_data.Uint8List anyDescriptor = $convert.base64Decode( 23 | 'CgNBbnkSGQoIdHlwZV91cmwYASABKAlSB3R5cGVVcmwSFAoFdmFsdWUYAiABKAxSBXZhbHVl'); 24 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/empty.pb.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/empty.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | import 'dart:core' as $core; 9 | 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | class Empty extends $pb.GeneratedMessage { 13 | static final $pb.BuilderInfo _i = $pb.BuilderInfo( 14 | const $core.bool.fromEnvironment('protobuf.omit_message_names') 15 | ? '' 16 | : 'Empty', 17 | package: const $pb.PackageName( 18 | const $core.bool.fromEnvironment('protobuf.omit_message_names') 19 | ? '' 20 | : 'google.protobuf'), 21 | createEmptyInstance: create) 22 | ..hasRequiredFields = false; 23 | 24 | Empty._() : super(); 25 | factory Empty() => create(); 26 | factory Empty.fromBuffer($core.List<$core.int> i, 27 | [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => 28 | create()..mergeFromBuffer(i, r); 29 | factory Empty.fromJson($core.String i, 30 | [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => 31 | create()..mergeFromJson(i, r); 32 | @$core.Deprecated('Using this can add significant overhead to your binary. ' 33 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 34 | 'Will be removed in next major version') 35 | Empty clone() => Empty()..mergeFromMessage(this); 36 | @$core.Deprecated('Using this can add significant overhead to your binary. ' 37 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 38 | 'Will be removed in next major version') 39 | Empty copyWith(void Function(Empty) updates) => 40 | super.copyWith((message) => updates(message as Empty)) 41 | as Empty; // ignore: deprecated_member_use 42 | $pb.BuilderInfo get info_ => _i; 43 | @$core.pragma('dart2js:noInline') 44 | static Empty create() => Empty._(); 45 | Empty createEmptyInstance() => create(); 46 | static $pb.PbList createRepeated() => $pb.PbList(); 47 | @$core.pragma('dart2js:noInline') 48 | static Empty getDefault() => 49 | _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 50 | static Empty? _defaultInstance; 51 | } 52 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/empty.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/empty.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/empty.pbjson.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: google/protobuf/empty.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package 7 | 8 | import 'dart:core' as $core; 9 | import 'dart:convert' as $convert; 10 | import 'dart:typed_data' as $typed_data; 11 | 12 | @$core.Deprecated('Use emptyDescriptor instead') 13 | const Empty$json = const { 14 | '1': 'Empty', 15 | }; 16 | 17 | /// Descriptor for `Empty`. Decode as a `google.protobuf.DescriptorProto`. 18 | final $typed_data.Uint8List emptyDescriptor = 19 | $convert.base64Decode('CgVFbXB0eQ=='); 20 | -------------------------------------------------------------------------------- /packages/dapr_proto/lib/src/proto/google/protobuf/empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "google.golang.org/protobuf/types/known/emptypb"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "EmptyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | option cc_enable_arenas = true; 42 | 43 | // A generic empty message that you can re-use to avoid defining duplicated 44 | // empty messages in your APIs. A typical example is to use it as the request 45 | // or the response type of an API method. For instance: 46 | // 47 | // service Foo { 48 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); 49 | // } 50 | // 51 | // The JSON representation for `Empty` is empty JSON object `{}`. 52 | message Empty {} 53 | -------------------------------------------------------------------------------- /packages/dapr_proto/melos_dapr_proto.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_proto/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dapr_proto 2 | description: An assiting package for dapr_client package. 3 | version: 0.0.3 4 | 5 | homepage: https://abhilash-chandran.com 6 | repository: https://github.com/Abhilash-Chandran/dart-sdk 7 | 8 | environment: 9 | sdk: '>=2.14.4 <3.0.0' 10 | 11 | 12 | dependencies: 13 | protobuf: ^2.0.0 14 | grpc: ^3.0.2 15 | 16 | dev_dependencies: 17 | lints: ^1.0.0 18 | test: ^1.16.0 19 | -------------------------------------------------------------------------------- /packages/dapr_proto/scripts/sh/update_dapr_grpc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') 3 | ARCH=$(uname -m) 4 | 5 | # Proto buf generation 6 | APPCALLBACK="appcallback" 7 | COMMON="common" 8 | DAPR="dapr" 9 | RUNTIME="runtime" 10 | GOOGLE_ANY="runtime" 11 | 12 | # Path to store output 13 | PATH_ROOT=$(pwd) 14 | # PATH_PROTO="$PATH_ROOT/src/grpc" 15 | # PATH_PROTO_DAPR="$PATH_PROTO/dapr/proto" 16 | # SRC="./src/grpc" 17 | 18 | # Http request CLI 19 | HTTP_REQUEST_CLI=curl 20 | 21 | # Make sure curl or wget are installed 22 | prerequisiteCheckHttpRequestCLI() { 23 | if type "curl" > /dev/null; then 24 | HTTP_REQUEST_CLI=curl 25 | elif type "wget" > /dev/null; then 26 | HTTP_REQUEST_CLI=wget 27 | else 28 | echo "Either curl or wget is required" 29 | exit 1 30 | fi 31 | } 32 | 33 | prerequisiteCheckProtobuf() { 34 | if ! type "protoc" > /dev/null; then 35 | echo "protoc is not installed, trying to install" 36 | sudo apt update 37 | sudo apt install -y protobuf-compiler 38 | protoc --version 39 | 40 | prerequisiteCheckProtobuf 41 | else 42 | echo "protoc ($(protoc --version)) installed" 43 | fi 44 | } 45 | 46 | downloadFile() { 47 | SRC=$1 48 | DST=$2 49 | 50 | # Ensure target path exists 51 | mkdir -p $(dirname $DST) 52 | 53 | # Download the file 54 | echo "[$HTTP_REQUEST_CLI] Downloading $1 ..." 55 | if [ "$HTTP_REQUEST_CLI" == "curl" ]; then 56 | curl -SsL "$SRC" -o "$DST" 57 | else 58 | wget -q -P "$SRC" "$DST" 59 | fi 60 | echo "[$HTTP_REQUEST_CLI] Saved to $DST" 61 | } 62 | 63 | generateGrpc() { 64 | PATH_PROTO=$1 65 | PATH_FILE=$2 66 | 67 | echo "[protoc] Generating RPC for $PATH_PROTO/$PATH_FILE" 68 | 69 | # Tools to be installed by npm (see package.json) 70 | # npm install grpc-tools --save-dev 71 | # npm install grpc_tools_node_protoc_ts --save-dev 72 | PROTOC_GEN_TS_PATH="${PATH_ROOT}/node_modules/.bin/protoc-gen-ts" 73 | PROTOC_GEN_GRPC_PATH="${PATH_ROOT}/node_modules/.bin/grpc_tools_node_protoc_plugin" 74 | 75 | # Note: we specify --proto_path to show where we should start searching from. If we use import it will start from this path 76 | # this is why PATH_PROTO != PATH_PROTO_DAPR; PATH_PROTO_DAPR is where we save our proto files while the other is the namespace 77 | protoc \ 78 | --proto_path="${PATH_PROTO}" \ 79 | --dart_out="grpc:${PATH_PROTO}" \ 80 | "$PATH_PROTO/$PATH_FILE" 81 | } 82 | 83 | fail_trap() { 84 | result=$? 85 | if [ $result != 0 ]; then 86 | echo "Failed to generate gRPC interface and proto buf: $ret_val" 87 | fi 88 | cleanup 89 | exit $result 90 | } 91 | 92 | cleanup() { 93 | find $PATH_PROTO -type f -name '*.proto' -delete 94 | rm -rf protoc 95 | rm -f protoc.zip 96 | } 97 | 98 | generateGrpcSuccess() { 99 | echo -e "\ngRPC interface and proto buf generated successfully!" 100 | } 101 | 102 | # ----------------------------------------------------------------------------- 103 | # main 104 | # ----------------------------------------------------------------------------- 105 | #trap "fail_trap" EXIT 106 | 107 | echo "Checking Dependencies" 108 | prerequisiteCheckProtobuf 109 | prerequisiteCheckHttpRequestCLI 110 | 111 | echo "" 112 | echo "Removing old Proto Files" 113 | rm -rf "$PATH_ROOT/lib/src/proto" 114 | mkdir -p "$PATH_ROOT/lib/src/proto" 115 | 116 | echo "" 117 | echo "Downloading latest Dapr gRPC files" 118 | downloadFile "https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto/common/v1/common.proto" "$PATH_ROOT/lib/src/proto/dapr/proto/common/v1/common.proto" 119 | downloadFile "https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto/runtime/v1/appcallback.proto" "$PATH_ROOT/lib/src/proto/dapr/proto/runtime/v1/appcallback.proto" 120 | downloadFile "https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto/runtime/v1/dapr.proto" "$PATH_ROOT/lib/src/proto/dapr/proto/runtime/v1/dapr.proto" 121 | 122 | echo "" 123 | echo "Downloading latest Google Protobuf gRPC files" 124 | downloadFile "https://raw.githubusercontent.com/protocolbuffers/protobuf/master/src/google/protobuf/any.proto" "$PATH_ROOT/lib/src/proto/google/protobuf/any.proto" 125 | downloadFile "https://raw.githubusercontent.com/protocolbuffers/protobuf/master/src/google/protobuf/empty.proto" "$PATH_ROOT/lib/src/proto/google/protobuf/empty.proto" 126 | 127 | echo "" 128 | echo "Compiling gRPC files" 129 | generateGrpc "$PATH_ROOT/lib/src/proto" "dapr/proto/common/v1/common.proto" 130 | generateGrpc "$PATH_ROOT/lib/src/proto" "dapr/proto/runtime/v1/dapr.proto" 131 | generateGrpc "$PATH_ROOT/lib/src/proto" "dapr/proto/runtime/v1/appcallback.proto" 132 | generateGrpc "$PATH_ROOT/lib/src/proto" "google/protobuf/any.proto" 133 | generateGrpc "$PATH_ROOT/lib/src/proto" "google/protobuf/empty.proto" 134 | 135 | echo "" 136 | echo "DONE" 137 | 138 | # Format generated dart source 139 | dart format lib/src 140 | 141 | generateGrpcSuccess -------------------------------------------------------------------------------- /packages/dapr_proto/test/dapr_proto_test.dart: -------------------------------------------------------------------------------- 1 | // import 'package:dapr_proto/dapr_proto.dart'; 2 | // import 'package:test/test.dart'; 3 | 4 | // void main() { 5 | // group('A group of tests', () { 6 | // final awesome = Awesome(); 7 | 8 | // setUp(() { 9 | // // Additional setup goes here. 10 | // }); 11 | 12 | // test('First Test', () { 13 | // expect(awesome.isAwesome, isTrue); 14 | // }); 15 | // }); 16 | // } 17 | -------------------------------------------------------------------------------- /packages/dapr_server/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build outputs. 6 | build/ 7 | 8 | # Omit committing pubspec.lock for library packages; see 9 | # https://dart.dev/guides/libraries/private-files#pubspeclock. 10 | pubspec.lock 11 | 12 | # ignore test reports 13 | test/reports -------------------------------------------------------------------------------- /packages/dapr_server/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version. 4 | -------------------------------------------------------------------------------- /packages/dapr_server/README.md: -------------------------------------------------------------------------------- 1 | # Dapr_server 2 | 3 | Dapr dart sdk provides a **dapr_server** package to bootstrap a daperised dart micro services defined using function callbacks. 4 | These services can be deployed either using gRPC or HTTP protocol. 5 | 6 | ## Prerequisite 7 | - [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/) installed 8 | - Initialized [Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)) 9 | - [Dart installed](https://dart.dev/get-dart) or [Flutter installed](https://docs.flutter.dev/get-started/install) 10 | 11 | ## Install dapr_client dependency 12 | Install the `dapr_server` package as a dependency in your `pubspec.yaml` directly or using `pub add` command. 13 | 14 | ### In pubspec.yaml 15 | 16 | 17 | ```yaml 18 | dependencies: 19 | dapr_server: any 20 | ``` 21 | 22 | ### Dart 23 | 24 | ```bash 25 | dart pub add dapr_server 26 | ``` 27 | ### Flutter 28 | 29 | ```bash 30 | flutter pub add dapr_server 31 | ``` 32 | 33 | ## Import the server package 34 | ```dart 35 | import 'pacakge:dapr_server/dapr_server.dart' 36 | ``` 37 | 38 | ## Creating and Starting a DaprServer 39 | 40 | A `DaprSever` instance is required inorder to start a dapr server either using gRpc or http protocol. 41 | `DaprServer` object accepts three optional paramenters namely, 42 | 43 | 1. `communicationProtocol` - The protocol to be used to communicate with sidecar. 44 | * Accepts either `CommunicationProtocol.http`(_default_) or `CommunicationProtocol.grpc`. 45 | 46 | 2. `daprHost` - The hostname or the ip address of the dapr sidecar process. 47 | * Defaults to **127.0.0.1**. 48 | 49 | 3. `daprPort` - The port to access the dapr sidecar process. 50 | * If not provided, uses environment variables `DAPR_HTTP_PORT`, `DAPR_GRPC_PORT` respectively for http and grpc protocols. 51 | * If no environment variables set, defaults to **3500** for http and **50001** for grpc protocol 52 | 53 | 4. `serverHost` - The hostname or the ip address of the dapr server process. 54 | * Defaults to **127.0.0.1**. 55 | 56 | 3. `serverPort` - The port on which to run the dapr server. 57 | * If not provided, uses environment variables `APP_PORT`. 58 | * If no environment variable is set, defaults to **3000**. 59 | 60 | ### Http DaprServer 61 | 62 | ```dart 63 | /// Default server 64 | final daprServer = DaprServer(); 65 | 66 | /// Start the server 67 | daprServer.startServer(); 68 | 69 | /// Explicitly specifying the parameters 70 | final customServer = DaprServer( 71 | daprHost: "my.domain.com", 72 | daprPort: 3600, 73 | serverPort: 8080, 74 | serverHost: "my.server.org", 75 | communicationProtocol: CommunicationProtocol.http, 76 | ); 77 | ``` 78 | ### Grpc DaprServer 79 | 80 | ```dart 81 | /// Default server 82 | final daprServer = DaprServer( 83 | communicatonProtocol: CommunicationProtocol.grpc, 84 | ); 85 | ``` 86 | 87 | 103 | 104 | ## Stop the server 105 | DaprServer can be stopped by invoking the `stop` method. 106 | 107 | ```dart 108 | daprServer.stop() 109 | ``` 110 | 111 | ## Subscribe to topics 112 | Dapr allows subscribing to messages/events from a specifici topic. 113 | In order to subscribe to a topic dart sdk provides a `subscribe` which accepts a callback function that will be called with the event data enveloped in cloud event template. 114 | 115 | ```dart 116 | await daprServer.pubsub.subscribe( 117 | pubSubName: 'pubsub-redis', 118 | topic: 'test-topic-1', 119 | callback: (dynamic data){ 120 | print('received data : $data'); 121 | }, 122 | route: 'route1', 123 | ); 124 | ``` 125 | 126 | ## Service Invocation Handler 127 | Http services can be exposed as daperised service using the `dapr_server` package, which can then be invoked by any client using through the dapr sidecar seemlessly. 128 | 129 | The `dapr_server` provides a callback function based api to write http services. 130 | Following examples show how to define http services using differnt http methods. 131 | 132 | ### Get 133 | 134 | ```dart 135 | await daprServer.invoker.listen( 136 | callback: (content) async { 137 | /// simulate delay of 2 seconds 138 | Future.delayed(Duration(seconds: 2)); 139 | return 'Get Invoker invoked with ${content.body}'; 140 | }, 141 | methodName: 'test-invoker-get', 142 | callbackOptions: InvokerCallbackOptions(method: HttpMethod.get), 143 | ); 144 | ``` 145 | ### Post 146 | 147 | ```dart 148 | await daprServer.invoker.listen( 149 | callback: (content) async { 150 | return 'Post Invoker invoked with ${content.body}'; 151 | }, 152 | methodName: 'test-invoker-post', 153 | callbackOptions: InvokerCallbackOptions(method: HttpMethod.post), 154 | ); 155 | ``` 156 | ### Put 157 | 158 | ```dart 159 | await daprServer.invoker.listen( 160 | callback: (content) async { 161 | return 'Put Invoker invoked with ${content.body}'; 162 | }, 163 | methodName: 'test-invoker-put', 164 | callbackOptions: InvokerCallbackOptions(method: HttpMethod.put), 165 | ); 166 | ``` 167 | ### Delete 168 | ```dart 169 | await daprServer.invoker.listen( 170 | callback: (content) async { 171 | return 'Delete Invoker invoked with ${content.body}'; 172 | }, 173 | methodName: 'test-invoker-delete', 174 | callbackOptions: InvokerCallbackOptions(method: HttpMethod.delete), 175 | ); 176 | ``` 177 | 178 | ## Binding Invocation Handler 179 | Input bindings can be registered using the dart-sdk, which will be invoked by the dapr-sidecar whenever an output binding event is send to the binding. 180 | 181 | ```dart 182 | await daprServer.binding.receive( 183 | bindingName: bindingEventName, 184 | callback: mockTestBinding.testCallBack, 185 | ); 186 | ``` 187 | 188 | ## Related links 189 | -------------------------------------------------------------------------------- /packages/dapr_server/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | linter: 19 | rules: 20 | - prefer_relative_imports 21 | - public_member_api_docs 22 | 23 | # analyzer: 24 | # exclude: 25 | # - path/to/excluded/files/** 26 | 27 | # For more information about the core and recommended set of lints, see 28 | # https://dart.dev/go/core-lints 29 | 30 | # For additional information about configuring this file, see 31 | # https://dart.dev/guides/language/analysis-options 32 | -------------------------------------------------------------------------------- /packages/dapr_server/example/dapr_server_example.dart: -------------------------------------------------------------------------------- 1 | // import 'package:dapr_server/dapr_server.dart'; 2 | 3 | // void main() { 4 | // var awesome = Awesome(); 5 | // print('awesome: ${awesome.isAwesome}'); 6 | // } 7 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub. 2 | .dart_tool/ 3 | .packages 4 | 5 | # Conventional directory for build output. 6 | build/ 7 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | - Initial version. 4 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/README.md: -------------------------------------------------------------------------------- 1 | A simple command-line application. 2 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the static analysis results for your project (errors, 2 | # warnings, and lints). 3 | # 4 | # This enables the 'recommended' set of lints from `package:lints`. 5 | # This set helps identify many issues that may lead to problems when running 6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic 7 | # style and format. 8 | # 9 | # If you want a smaller set of lints you can change this to specify 10 | # 'package:lints/core.yaml'. These are just the most critical lints 11 | # (the recommended set includes the core lints). 12 | # The core lints are also what is used by pub.dev for scoring packages. 13 | 14 | include: package:lints/recommended.yaml 15 | 16 | # Uncomment the following section to specify additional rules. 17 | 18 | # linter: 19 | # rules: 20 | # - camel_case_types 21 | 22 | # analyzer: 23 | # exclude: 24 | # - path/to/excluded/files/** 25 | 26 | # For more information about the core and recommended set of lints, see 27 | # https://dart.dev/go/core-lints 28 | 29 | # For additional information about configuring this file, see 30 | # https://dart.dev/guides/language/analysis-options 31 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/bin/service_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dapr_client/dapr_client.dart'; 4 | import 'package:dapr_server/dapr_server.dart'; 5 | 6 | void main(List arguments) async { 7 | // Create dapr Server instance 8 | final daprServer = DaprServer( 9 | daprPort: 3500, 10 | serverPort: 2500, 11 | communicationProtocol: CommunicationProtocol.http, 12 | ); 13 | 14 | // Create a dapr client instance to invoke the service 15 | final daprClient = DaprClient( 16 | daprPort: 3500, 17 | communicationProtocol: CommunicationProtocol.http, 18 | ); 19 | 20 | // Register a service to be invoked using the daprServer instance 21 | await daprServer.invoker.listen( 22 | methodName: 'hello-world', 23 | callback: (inkCbCont) async { 24 | print('Sending Hellow world from the sevice cb'); 25 | return 'Hello daprerised world'; 26 | }, 27 | callbackOptions: InvokerCallbackOptions(method: HttpMethod.get), 28 | ); 29 | 30 | // Start the dapr server to register the service to be invoked. 31 | await daprServer.startServer(); 32 | await Future.delayed(Duration(milliseconds: 250)); 33 | 34 | // Use a daprClient to invoke the service 35 | final invokerResult = await daprClient.invoker.invoke( 36 | appId: 'myapp', 37 | methodName: 'hello-world', 38 | httpMethod: HttpMethod.get, 39 | data: "Hello from invoker", 40 | ); 41 | print("=================="); 42 | print("Invoker result $invokerResult"); 43 | print("=================="); 44 | await daprServer.stop(); 45 | exit(0); 46 | } 47 | // http protocol run 48 | // dapr run --app-id myapp --app-port 2500 --dapr-http-port 3500 --dapr-grpc-port 50000 dart run 49 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/melos_service_invoker.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_server/example/service_invoker/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: service_invoker 2 | description: A simple command-line application. 3 | version: 1.0.0 4 | # homepage: https://www.example.com 5 | publish_to: none 6 | environment: 7 | sdk: ">=2.14.4 <3.0.0" 8 | 9 | dependencies: 10 | dapr_server: 11 | path: "../../" 12 | dapr_client: 13 | path: "../../../dapr_client" 14 | 15 | dev_dependencies: 16 | lints: ^1.0.0 17 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/dapr_server.dart: -------------------------------------------------------------------------------- 1 | /// Support for doing something awesome. 2 | /// 3 | /// More dartdocs go here. 4 | library dapr_server; 5 | 6 | export 'src/implementations/dapr_server.dart'; 7 | export 'package:dapr_common/dapr_common.dart'; 8 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/abstractions/server.dart: -------------------------------------------------------------------------------- 1 | import 'server_binding.dart'; 2 | import 'server_invoker.dart'; 3 | import 'server_pub_sub.dart'; 4 | 5 | /// A server wrapping various user defined services such as topic subscritions, 6 | /// remote method invokation and input binding. 7 | /// 8 | /// All the server instances should implement this interface inorder to provide 9 | /// a unified development experience using different protocols. 10 | abstract class Server { 11 | // String get serverAddress; 12 | /// The current instance of the server running. 13 | T get server; 14 | 15 | /// The implementation instance which handles the method delegations from the 16 | /// [ServerBinding], [ServerInvoker] and [ServrePubSub] interfaces. 17 | I get implementation; 18 | 19 | /// Stop the server and release the resources. 20 | Future stop(); 21 | 22 | /// Start the server with the provided host and port bindings. 23 | Future start(String host, int port); 24 | } 25 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/abstractions/server_actor.dart: -------------------------------------------------------------------------------- 1 | /// An actor interface. 2 | abstract class ServerActor { 3 | /// Registor an actor 4 | Future registerActor(); 5 | /// Fetch a list of registered actors 6 | Future> get registeredActors; 7 | /// initialize 8 | Future init(); 9 | /// Deactivate a registered actor. 10 | Future deactivateActor( 11 | String actorType, 12 | String actorId, 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/abstractions/server_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | /// Class defining the methods to create Inputbindings. 4 | abstract class ServerBinding { 5 | /// The main server instance running the server. 6 | dynamic get server; 7 | 8 | /// A method to setup the input binding using a callback method of type 9 | /// [BindingCallback]. 10 | Future receive( 11 | {required String bindingName, required BindingCallback callback}); 12 | } 13 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/abstractions/server_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | /// Abstract definition for Service Invoker. 4 | abstract class ServerInvoker { 5 | /// The main server instance running the server. 6 | T get server; 7 | 8 | /// Registers a http enpoint on the [methodname] for the [HttpMethod] passed 9 | /// in via [callbackOptions.method]. On the invokation of this endpoint, the 10 | /// provided [callback] will be called with an instance of 11 | /// [InvokerCallbackContent] built using the data, queryParams, and other 12 | /// information passed in the request to this endpoint. 13 | /// 14 | /// Note:[methodName] is case insensitive. 15 | Future listen({ 16 | required String methodName, 17 | required InvokerCallback callback, 18 | required InvokerCallbackOptions callbackOptions, 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/abstractions/server_pub_sub.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | /// Provides the necessary api to subscribe to different topics of a pubsub 4 | /// component. 5 | abstract class ServrePubSub { 6 | /// The main server instance running the server. 7 | T get server; 8 | 9 | /// Registers the provided [callback] as the subscriber for the given [topic] 10 | /// in the publish/subscribe coponent registered under the [pubSubName]. The 11 | /// [route] is used as a REST end point in case of http server. 12 | Future subscribe({ 13 | /// The name of the publish/subscribe component. 14 | required String pubSubName, 15 | 16 | /// The name of the topic to be subscribed. 17 | required String topic, 18 | 19 | /// The call back function which will be called with the event data 20 | required PubSubCallback callback, 21 | 22 | /// The name fo the app route be built using the [callback]. 23 | String? route, 24 | 25 | /// Setting [rawEvents] to true means that the subscriber receives 26 | /// rawEvents instead of a CloudEvent. 27 | /// https://docs.dapr.io/developing-applications/building-blocks/pubsub/pubsub-raw/ 28 | bool rawEvents = false, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/exceptions/dapr_server_exceptions.dart: -------------------------------------------------------------------------------- 1 | /// A general exception that can be thrown from the dapr_server api. 2 | /// 3 | /// Maybe used for general errors related to server startup, initialization, 4 | /// and configuration exceptions. 5 | class DaprServerException implements Exception { 6 | /// A string message detailing the exception. 7 | final String message; 8 | 9 | /// A base exception for Dapr server api. 10 | DaprServerException({required this.message}); 11 | @override 12 | String toString() => 'A DaprServerException occured : \n $message'; 13 | } 14 | 15 | /// All exceptions relavant to the Invoker api should throw this error. 16 | class DaprServerInvokerException implements Exception { 17 | final String message; 18 | DaprServerInvokerException({required this.message}); 19 | } 20 | 21 | /// All exceptions relavant to the Binding api should throw this error. 22 | class DaprServerBindingException implements Exception { 23 | final String message; 24 | DaprServerBindingException({required this.message}); 25 | } 26 | 27 | /// All exceptions relavant to the PubSub api should throw this error. 28 | class DaprServerPubSubException implements Exception { 29 | final String message; 30 | DaprServerPubSubException({required this.message}); 31 | } 32 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/dapr_server.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | import 'package:shelf_plus/shelf_plus.dart' as shp; 5 | 6 | import '../abstractions/server_binding.dart'; 7 | import '../abstractions/server_invoker.dart'; 8 | import '../abstractions/server_pub_sub.dart'; 9 | import 'grpc/grpc_binding.dart'; 10 | import 'grpc/grpc_invoker.dart'; 11 | import 'grpc/grpc_pubsub.dart'; 12 | import 'grpc/grpc_server.dart'; 13 | import 'http/http_bindings.dart'; 14 | import 'http/http_invoker.dart'; 15 | import 'http/http_pub_sub.dart'; 16 | import 'http/http_server.dart'; 17 | 18 | /// This provides the necessary api's to create the Invoker, Binding, and 19 | /// Pubsub building blocks using both http and grpc protocols. 20 | /// 21 | /// This api takes care of adhering to the specifications of Dapr API for each 22 | /// building block providing a unified experience of creating different building 23 | /// blocks using Dart. 24 | /// 25 | /// When [communicationProtocol] is http, then a shelf server is started with 26 | /// different building blocks exposed as REST endpoints which will be accessed 27 | /// by the Dapr sidecar on various events from components configured while 28 | /// while running the [DaprServer]. 29 | /// 30 | /// When [communicationProtocol] is set as grpc, the building blocks are exposed 31 | /// as grpc services can be accessed by the Dapr side car using the grpc 32 | /// protocol. 33 | class DaprServer { 34 | /// Defaults to 127.0.0.1 35 | final String serverHost; 36 | 37 | /// Defaults to the APP_PORT environment variable set by Dapr. 38 | late final int _serverPort; 39 | 40 | /// Defaults to 127.0.0.1 41 | final String daprHost; 42 | 43 | /// Defaults to the DAPR_HTTP_PORT or DAPR_GRPC_PORT environment variable set 44 | /// by Dapr. 45 | late final int? _daprPort; 46 | 47 | /// Defaults to [CommunicationProtocol.http] 48 | final CommunicationProtocol communicationProtocol; 49 | 50 | /// The server instance depending on the choice of [communicationProtocol]. 51 | late final dynamic server; 52 | 53 | /// Provides api to create a service invoker building block 54 | late final ServerInvoker invoker; 55 | 56 | /// Provides api to subscribe to a topic via a pubsub component. 57 | late final ServrePubSub pubsub; 58 | 59 | /// Provides api to create an Input binding. 60 | late final ServerBinding binding; 61 | 62 | /// A list of [Shelfplus.Handler] which can be additionally deployed 63 | /// alongside the rest endpoints of different building blocks. 64 | /// 65 | /// Note: This handlers are only used when the [communicationProtocol] is 66 | /// [CommunicationProtocol.http]. 67 | final List _externalHttpRouteHandlers = []; 68 | 69 | /// Creates a [DaprServer] instance based on the [communicationProtocol]. 70 | /// 71 | /// Additionally bootstraps the properties [invoker], [pubsub], [binding] 72 | /// which provides helper methods to create the respective building blocks. 73 | DaprServer({ 74 | this.serverHost = DaprConf.defAppHost, 75 | int? serverPort, 76 | this.daprHost = DaprConf.defDaprHost, 77 | int? daprPort, 78 | this.communicationProtocol = CommunicationProtocol.http, 79 | List additionalRouteHandlers = const [], 80 | }) { 81 | // set default values from configurations if the environment variables is 82 | // not set or the port is not provided. 83 | _serverPort = serverPort ??= 84 | int.tryParse(Platform.environment['APP_PORT'] ?? '') ?? 85 | DaprConf.defHttpAppPort; 86 | // set default values from configurations if the environment variables is 87 | // not set or the port is not provided. 88 | _daprPort = daprPort ??= int.tryParse(Platform.environment[ 89 | communicationProtocol == CommunicationProtocol.http 90 | ? 'DAPR_HTTP_PORT' 91 | : 'DAPR_GRPC_PORT'] ?? 92 | ''); 93 | _daprPort ??= communicationProtocol == CommunicationProtocol.http 94 | ? DaprConf.defDaprHttpPort 95 | : DaprConf.defDaprGrpcPort; 96 | _externalHttpRouteHandlers.addAll(additionalRouteHandlers); 97 | switch (communicationProtocol) { 98 | case CommunicationProtocol.grpc: 99 | server = DaprGrpcServer(); 100 | invoker = GrpcServerInvoker(server: server); 101 | binding = GrpcServerBinding(server: server); 102 | pubsub = GrpcServerPubSub(server: server); 103 | break; 104 | case CommunicationProtocol.http: 105 | default: 106 | server = DaprHttpServer(); 107 | invoker = HttpServerInvoker(server: server); 108 | pubsub = HttpServerPubSub(server: server); 109 | binding = HttpServerBinding(server: server); 110 | } 111 | } 112 | 113 | /// Start the underlying server based on the [communicationProtocol]. 114 | Future startServer() async { 115 | if (communicationProtocol == CommunicationProtocol.http) { 116 | var _server = server as DaprHttpServer; 117 | var _invoker = invoker as HttpServerInvoker; 118 | var _pubsub = pubsub as HttpServerPubSub; 119 | var _binding = binding as HttpServerBinding; 120 | 121 | /// Start the http server. 122 | await _server.start( 123 | serverHost, 124 | _serverPort, 125 | handlers: [ 126 | _binding.bindingsHandler, 127 | _pubsub.pubSubHandler, 128 | _invoker.invokerHandler, 129 | ..._externalHttpRouteHandlers, 130 | ], 131 | ); 132 | } else { 133 | var _server = server as DaprGrpcServer; 134 | _server.start(serverHost, _serverPort); 135 | } 136 | } 137 | 138 | /// Stops the underlying server and releases the server resources. 139 | Future stop() async { 140 | await server.stop(); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/grpc/grpc_binding.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | import '../../abstractions/server_binding.dart'; 4 | import 'grpc_server.dart'; 5 | 6 | /// A grpc based implmentation of [ServerBinding] 7 | class GrpcServerBinding implements ServerBinding { 8 | @override 9 | final DaprGrpcServer server; 10 | 11 | /// A constructor to intialize the [GrpcServerPubSub] with the server passed 12 | /// down from [DaprServer]. 13 | GrpcServerBinding({required this.server}); 14 | @override 15 | Future receive( 16 | {required String bindingName, required BindingCallback callback}) async { 17 | server.implementation.bindingsCallbackMap 18 | .putIfAbsent(bindingName, () => callback); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/grpc/grpc_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | import 'grpc_server_impl.dart'; 3 | 4 | import '../../abstractions/server_invoker.dart'; 5 | import 'grpc_server.dart'; 6 | 7 | /// A grpc protocol based implementation of [serverInvoker]. 8 | /// 9 | /// Provides api to register callback for method invokation event. 10 | class GrpcServerInvoker implements ServerInvoker { 11 | @override 12 | final DaprGrpcServer server; 13 | 14 | /// A constructor to intialize the [GrpcServerPubSub] with the server passed 15 | /// down from [DaprServer]. 16 | GrpcServerInvoker({required this.server}); 17 | 18 | /// Simply maps the callback to the method name in a map maintained by the 19 | /// [GrpcServerImplementation] which is then used in 20 | /// [GrpcServerImplementation.onInvoke] method to perform the call back on 21 | /// the invoker event. 22 | @override 23 | Future listen({ 24 | required String methodName, 25 | required InvokerCallback callback, 26 | required InvokerCallbackOptions callbackOptions, 27 | }) async { 28 | server.implementation.invokerCallbackMap.putIfAbsent( 29 | '${methodName.toLowerCase()}-${callbackOptions.method.nameLower}', 30 | () => callback, 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/grpc/grpc_pubsub.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | 3 | import '../../abstractions/server_pub_sub.dart'; 4 | import 'grpc_server.dart'; 5 | 6 | /// A grpc based implmentation of [ServerPubSub] 7 | class GrpcServerPubSub implements ServrePubSub { 8 | @override 9 | DaprGrpcServer server; 10 | 11 | /// A constructor to intialize the [GrpcServerPubSub] with the server passed 12 | /// down from [DaprServer]. 13 | GrpcServerPubSub({required this.server}); 14 | 15 | @override 16 | Future subscribe({ 17 | required String pubSubName, 18 | required String topic, 19 | required PubSubCallback callback, 20 | String? route, 21 | bool rawEvents = false, 22 | }) async { 23 | server.implementation.pubSubCallbackMap.putIfAbsent( 24 | PubSubRoute( 25 | pubSubName: pubSubName, 26 | topic: topic, 27 | route: route ?? '', 28 | ), 29 | () => callback, 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/grpc/grpc_server.dart: -------------------------------------------------------------------------------- 1 | import 'package:grpc/grpc.dart' as grpc; 2 | 3 | import '../../abstractions/server.dart'; 4 | import 'grpc_server_impl.dart'; 5 | 6 | /// A grpc based implementation of [Server] to provide API to write daperized 7 | /// grpc services. 8 | class DaprGrpcServer implements Server { 9 | /// Server host address eg: 127.0.0.1, my-custom-domain 10 | late final String serverHost; 11 | 12 | /// The port that will be used to serve the http server. 13 | late final int serverPort; 14 | 15 | @override 16 | late final GrpcServerImplementation implementation; 17 | 18 | @override 19 | late final grpc.Server server; 20 | 21 | /// A list of external [grpc.Service] to be served alongside the Daperised 22 | /// services. 23 | List extServices; 24 | 25 | /// Setup the implemn 26 | DaprGrpcServer({this.extServices = const []}) { 27 | implementation = GrpcServerImplementation(); 28 | server = grpc.Server([ 29 | implementation, 30 | ...extServices, // Add externally provided gRpc services. 31 | ]); 32 | } 33 | @override 34 | Future start( 35 | String host, 36 | int port, 37 | ) { 38 | /// Start the grpc server. 39 | return server.serve( 40 | address: host, 41 | port: port, 42 | ); 43 | } 44 | 45 | @override 46 | Future stop() { 47 | /// Stop the grpc server 48 | return server.shutdown(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/grpc/grpc_server_impl.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | import 'package:dapr_proto/dapr_proto.dart'; 5 | import 'package:grpc/service_api.dart'; 6 | 7 | /// An implementation of grpc runtime services defined by Dapr. 8 | /// 9 | /// This implemention allows creating Daprised service using grpc protocol. 10 | class GrpcServerImplementation extends AppCallbackServiceBase { 11 | /// A map for holding invoker callbacks 12 | Map invokerCallbackMap = {}; 13 | 14 | /// A map for holding pubsub callbacks 15 | Map pubSubCallbackMap = {}; 16 | 17 | /// A map for holding bindings callbacks 18 | Map bindingsCallbackMap = {}; 19 | 20 | @override 21 | Future listInputBindings( 22 | ServiceCall call, 23 | Empty request, 24 | ) async { 25 | var bindingNames = bindingsCallbackMap.keys; 26 | bindingNames = bindingNames.isEmpty ? [] : bindingNames; 27 | return ListInputBindingsResponse( 28 | bindings: bindingNames, 29 | ); 30 | } 31 | 32 | @override 33 | Future listTopicSubscriptions( 34 | ServiceCall call, Empty request) async { 35 | var subscriptions = []; 36 | for (var pubSubRoute in pubSubCallbackMap.keys) { 37 | subscriptions.add( 38 | TopicSubscription( 39 | pubsubName: pubSubRoute.pubSubName, 40 | metadata: pubSubRoute.metadata, 41 | topic: pubSubRoute.topic, 42 | // TODO: Verify if routes needs to be set here. In go-sdk routes are 43 | // not set. Neither in js-sdk. But Python-sdk sets this routes. 44 | // 45 | // Currently not setting routes. 46 | // As per the specifitcation Dapr only needs to know the topics which 47 | // are being subscribed by the service. 48 | // The route information comes in the [TopicEventRequest] passed in 49 | // onTopicEvent which contains the route information which can then 50 | // be parsed and mapped to the correct callback. 51 | // 52 | routes: TopicRoutes(rules: [ 53 | TopicRule(path: pubSubRoute.route), 54 | ], default_2: pubSubRoute.route), 55 | ), 56 | ); 57 | } 58 | return ListTopicSubscriptionsResponse( 59 | subscriptions: subscriptions, 60 | ); 61 | } 62 | 63 | @override 64 | Future onBindingEvent( 65 | ServiceCall call, BindingEventRequest request) async { 66 | final bindingName = request.name; 67 | 68 | if (bindingsCallbackMap.containsKey(bindingName)) { 69 | final _callback = bindingsCallbackMap[bindingName]; 70 | final _bindingEvent = BindingEvent( 71 | data: utf8.decode(request.data), 72 | metadata: request.metadata, 73 | ); 74 | await _callback!(_bindingEvent); 75 | return BindingEventResponse(); 76 | } 77 | throw UnimplementedError('Input binding for $bindingName is not found'); 78 | } 79 | 80 | @override 81 | Future onInvoke( 82 | ServiceCall call, InvokeRequest request) async { 83 | final methodName = request.method.toLowerCase(); 84 | final httpMethod = request.httpExtension.verb.name.toLowerCase(); 85 | final cbKey = '$methodName-$httpMethod'; 86 | 87 | if (invokerCallbackMap.containsKey(cbKey)) { 88 | final _callBack = invokerCallbackMap[cbKey]; 89 | final _body = utf8.decode(request.data.value); 90 | final queryMap = queryParamStringToMap(request.httpExtension.querystring); 91 | final _result = await _callBack!( 92 | InvokerCallbackContent( 93 | body: _body, 94 | query: queryMap, 95 | metadata: InvokerCallbackMetadata( 96 | contentType: request.contentType, 97 | ), 98 | ), 99 | ); 100 | final respData = _result is String ? _result : jsonEncode(_result); 101 | final invokeResponse = InvokeResponse( 102 | data: Any( 103 | value: utf8.encode(respData), 104 | ), 105 | contentType: 'application/json', 106 | ); 107 | return invokeResponse; 108 | } 109 | 110 | throw UnimplementedError('Requested method $methodName is not implemented'); 111 | } 112 | 113 | @override 114 | Future onTopicEvent( 115 | ServiceCall call, 116 | TopicEventRequest request, 117 | ) async { 118 | final pubsubName = request.pubsubName; 119 | final topic = request.topic; 120 | final route = request.path; 121 | // final metaData = request.; 122 | final pubSubRoute = PubSubRoute( 123 | pubSubName: pubsubName, 124 | route: route, 125 | topic: topic, 126 | // metadata: metaData ?? {}, 127 | ); 128 | 129 | if (pubSubCallbackMap.containsKey(pubSubRoute)) { 130 | final _callback = pubSubCallbackMap[pubSubRoute]; 131 | // Decode bytes to string assuming it as utf8Encoded. 132 | var _tmpData = utf8.decode(request.data); 133 | late final dynamic _data; 134 | if (request.dataContentType.contains("text/plain")) { 135 | _data = _tmpData; 136 | } else if (request.dataContentType.startsWith("application/") && 137 | request.dataContentType.endsWith("json")) { 138 | _data = jsonDecode(_tmpData); 139 | } else { 140 | _data = _tmpData; 141 | } 142 | final _ce = CloudEvent( 143 | id: request.id, 144 | source: Uri.parse(request.source), 145 | data: _data, 146 | dataContentType: request.dataContentType, 147 | specVersion: request.specVersion, 148 | type: request.type, 149 | ); 150 | 151 | final _result = await _callback!(_ce); 152 | 153 | final _status = _result.when( 154 | success: () => TopicEventResponse_TopicEventResponseStatus.SUCCESS, 155 | drop: () => TopicEventResponse_TopicEventResponseStatus.DROP, 156 | retry: () => TopicEventResponse_TopicEventResponseStatus.RETRY, 157 | error: () => TopicEventResponse_TopicEventResponseStatus.RETRY, 158 | ); 159 | return TopicEventResponse(status: _status); 160 | } 161 | throw UnimplementedError( 162 | 'The topic $topic in the PubSub component $pubsubName is not subscribed by any callback with this route name $route'); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/http/http_bindings.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'http_server.dart'; 4 | import 'package:shelf_plus/shelf_plus.dart'; 5 | import 'package:dapr_common/dapr_common.dart'; 6 | 7 | import '../../abstractions/server_binding.dart'; 8 | 9 | /// A http based implementation of [ServerBinding]. 10 | class HttpServerBinding implements ServerBinding { 11 | @override 12 | final DaprHttpServer server; 13 | 14 | /// A constructor to intialize the [HttpServerBinding] with the server passed 15 | /// down from [DaprServer]. 16 | HttpServerBinding({required this.server}); 17 | 18 | /// All the http endpoints related to binding is registered in this handler. 19 | RouterPlus bindingsHandler = RouterPlus(); 20 | @override 21 | Future receive({ 22 | required String bindingName, 23 | required BindingCallback callback, 24 | }) async { 25 | print('Receive method called with binding name $bindingName'); 26 | // Register a options endpoint with this binding name which will be used by // Dapr. 27 | // 28 | // Ref: https://docs.dapr.io/developing-applications/building-blocks/bindings/bindings-overview/#input-bindings 29 | bindingsHandler.options('/$bindingName', (req) { 30 | print('Options request is called.'); 31 | return Response.ok(''); 32 | }); 33 | 34 | print('Options Handler setup'); 35 | // Register the binding enpoint and assign the handler performing the 36 | // callback. 37 | // Return status code is doumented in the following. 38 | // https://docs.dapr.io/reference/api/bindings_api/#binding-payload 39 | bindingsHandler.post('/$bindingName', (Request req) async { 40 | final body = await req.body.asString; 41 | print(body); 42 | try { 43 | final bindingEvent = BindingEvent( 44 | data: body, 45 | metadata: req.headers, 46 | ); 47 | await callback(bindingEvent); 48 | return Response.ok(null); 49 | } catch (e) { 50 | return Response.internalServerError( 51 | body: jsonEncode( 52 | { 53 | 'error': e.toString(), 54 | }, 55 | ), 56 | ); 57 | } 58 | }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/http/http_invoker.dart: -------------------------------------------------------------------------------- 1 | import 'package:dapr_common/dapr_common.dart'; 2 | import 'http_server.dart'; 3 | import 'package:shelf_plus/shelf_plus.dart'; 4 | 5 | import '../../abstractions/server_invoker.dart'; 6 | 7 | /// A http based implementation of [ServerInvoker] 8 | class HttpServerInvoker implements ServerInvoker { 9 | @override 10 | final DaprHttpServer server; 11 | 12 | /// A constructor to intialize the [HttpServerInvoker] with the server passed 13 | /// down from [DaprServer]. 14 | HttpServerInvoker({required this.server}); 15 | 16 | /// The router plus handler to which the new routes related to invoker will 17 | /// be added. 18 | final RouterPlus invokerHandler = RouterPlus(); 19 | 20 | @override 21 | Future listen({ 22 | required String methodName, 23 | required InvokerCallback callback, 24 | required InvokerCallbackOptions callbackOptions, 25 | }) async { 26 | invokerHandler.add( 27 | callbackOptions.method.name, 28 | '/$methodName', 29 | _genericHandler(callback), 30 | ); 31 | } 32 | 33 | /// A generic handler for all the http methods. 34 | /// 35 | /// The provided callback will be called with a [InvokerCallbackContent] 36 | /// instance built using the information from [request]. 37 | Function _genericHandler(InvokerCallback callback) { 38 | return (Request req) async { 39 | final body = await req.body.asString; 40 | late final dynamic cbResp; 41 | try { 42 | cbResp = await callback( 43 | InvokerCallbackContent( 44 | body: body, 45 | query: req.url.queryParameters, 46 | metadata: InvokerCallbackMetadata( 47 | contentType: req.headers['Content-type'], 48 | ), 49 | ), 50 | ); 51 | return Response.ok(cbResp); 52 | } on Exception catch (e) { 53 | return Response.internalServerError(body: e); 54 | } 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/http/http_pub_sub.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:dapr_common/dapr_common.dart'; 4 | import 'http_server.dart'; 5 | import 'package:shelf_plus/shelf_plus.dart'; 6 | 7 | import '../../abstractions/server_pub_sub.dart'; 8 | 9 | /// A http based implementation of [ServerPubSub] 10 | class HttpServerPubSub implements ServrePubSub { 11 | @override 12 | final DaprHttpServer server; 13 | 14 | /// The router plus handler to which the new routes related to pubsub will 15 | /// be added. 16 | final RouterPlus pubSubHandler = RouterPlus(); 17 | 18 | /// Holds a list of routes mapped to a one or more topics in one or more 19 | /// deployed pubsub components 20 | final List pubSubRoutes = []; 21 | 22 | /// A constructor to intialize the [HttpServerPubSub] with the server passed 23 | /// down from [DaprServer]. 24 | /// 25 | /// Also adds the list of 26 | /// subscriber as a handler as per the requirement of dapr under the endpoint 27 | /// '/dapr/subscribe/'. 28 | HttpServerPubSub({required this.server}) { 29 | pubSubHandler.get('/dapr/subscribe', (req) async { 30 | final result = jsonEncode(pubSubRoutes); 31 | return Response.ok(result); 32 | }); 33 | } 34 | 35 | @override 36 | Future subscribe({ 37 | required String pubSubName, 38 | required String topic, 39 | required PubSubCallback callback, 40 | String? route, 41 | bool rawEvents = false, 42 | }) async { 43 | final _route = route ?? 'route-$pubSubName-$topic'; 44 | // Add the pub sub route to the list. This list will used for the 45 | // `dapr/subscribe` route. 46 | pubSubRoutes.add( 47 | PubSubRoute( 48 | pubSubName: pubSubName, 49 | topic: topic, 50 | route: _route, 51 | metadata: { 52 | 'rawPayload': rawEvents.toString(), 53 | }, 54 | ), 55 | ); 56 | 57 | // Setup post route for the subscription. 58 | pubSubHandler.add( 59 | 'post', 60 | '/$_route', 61 | (Request request) async { 62 | try { 63 | final body = await request.body.asString; 64 | // print('for route $_route body is $body'); 65 | final result = await callback(body); 66 | // Send back response to dapr. 67 | // ref: https://github.com/dapr/go-sdk/blob/d9ad49d2a6/service/http/topic.go#L186 68 | // https://github.com/dapr/go-sdk/blob/d9ad49d2a6/service/http/topic.go#L186 69 | return result.when( 70 | success: () => Response.ok(jsonEncode({'status': 'SUCCESS'})), 71 | drop: () => Response.ok(jsonEncode({'status': 'DROP'})), 72 | retry: () => Response.ok(jsonEncode({'status': 'RETRY'})), 73 | error: () => Response.internalServerError(), 74 | ); 75 | } on Exception { 76 | return Response.internalServerError(); 77 | } 78 | }, 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/http/http_server.dart: -------------------------------------------------------------------------------- 1 | import 'package:shelf_plus/shelf_plus.dart' as shp; 2 | 3 | import '../../abstractions/server.dart'; 4 | import 'http_bindings.dart'; 5 | import 'http_invoker.dart'; 6 | import 'http_pub_sub.dart'; 7 | import 'http_server_impl.dart'; 8 | 9 | /// A http protocol based implementation of [Server]. 10 | /// 11 | /// Provides api to start a http server and stop using configuration such as 12 | /// [serverHost] and [serverPort]. 13 | /// 14 | /// This implmentation uses shelf_plus package to setup the various http 15 | /// handlers necessary to start a http server using shelf. This takes care of 16 | /// assembling together various handlers from all the building blocks such as 17 | /// [HttpServerPubSub], [HttpServerBinding], [HttpServerInvoker] which holds the 18 | /// handlers for their respective rest endpoints and start the server. 19 | /// 20 | /// In addition to component specific routes, this class also adds endpoints for 21 | /// Dapr's generic services such as `/healthz`. 22 | class DaprHttpServer implements Server { 23 | /// Server host address eg: 127.0.0.1, my-custom-domain 24 | late final String serverHost; 25 | 26 | /// The port that will be used to serve the http server. 27 | late final int serverPort; 28 | 29 | /// Holds the ShelfRunContext instance which allows to control the server. 30 | late final shp.ShelfRunContext _shelfRunContext; 31 | @override 32 | late final DaprHttpServer server; 33 | 34 | @override 35 | late final HttpServerImpl implementation; 36 | 37 | /// Healthz handler and other Dapr generic handlers. 38 | shp.RouterPlus daprGenericRoutes = shp.RouterPlus(); 39 | 40 | /// Initializes various configurations and sets up Dapr's generic endpoints 41 | /// such as `/healthz`. 42 | /// 43 | DaprHttpServer() { 44 | implementation = HttpServerImpl(); 45 | 46 | /// https://github.com/dapr/go-sdk/blob/d9ad49d2a6036d4498979a486245236337b3083b/service/http/topic.go#L62 47 | daprGenericRoutes.get('/healthz', () => shp.Response.ok(null)); 48 | 49 | // TODO: Add the configuration handler as well. 50 | } 51 | 52 | @override 53 | Future start(String host, int port, 54 | {List handlers = const []}) async { 55 | serverPort = port; 56 | serverHost = host; 57 | _shelfRunContext = await shp.shelfRun( 58 | () => shp.cascade([...handlers, daprGenericRoutes]), 59 | defaultBindAddress: serverHost, 60 | defaultBindPort: serverPort, 61 | defaultEnableHotReload: false, 62 | ); 63 | } 64 | 65 | @override 66 | Future stop() async { 67 | await _shelfRunContext.close(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/dapr_server/lib/src/implementations/http/http_server_impl.dart: -------------------------------------------------------------------------------- 1 | /// Present to only fullfill the interface definition. 2 | /// 3 | /// The GRPC implementation needs such a delegation to redirect the calls and 4 | /// hence tha api is designed this way. 5 | class HttpServerImpl {} 6 | -------------------------------------------------------------------------------- /packages/dapr_server/melos_dapr_server.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/dapr_server/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dapr_server 2 | description: A starting point for Dart libraries or applications. 3 | version: 0.0.1 4 | # homepage: https://www.example.com 5 | 6 | environment: 7 | sdk: '>=2.14.4 <3.0.0' 8 | 9 | 10 | # TODO: Remove before publishing and change the dapr_common to a versioned 11 | # dependency 12 | publish_to: none 13 | dependencies: 14 | grpc: ^3.0.2 15 | dapr_proto: ^0.0.3 16 | dapr_common: 17 | path: ../dapr_common 18 | shelf_plus: ^1.0.0 19 | 20 | dev_dependencies: 21 | http: ^0.13.4 22 | lints: ^1.0.0 23 | test: ^1.16.0 24 | mockito: ^5.0.16 25 | -------------------------------------------------------------------------------- /packages/dapr_server/test/components/bindings-mqtt.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.dapr.io/reference/components-reference/supported-bindings/rabbitmq/ 2 | apiVersion: dapr.io/v1alpha1 3 | kind: Component 4 | metadata: 5 | name: binding-rabbit 6 | namespace: default 7 | spec: 8 | type: bindings.rabbitmq 9 | version: v1 10 | metadata: 11 | - name: consumerID 12 | value: "{uuid}" 13 | - name: host 14 | value: "amqp://guest:guest@dapr_rabbitmq:5672" 15 | - name: queueName 16 | value: "test-queue" 17 | - name: qos 18 | value: 1 19 | - name: retain 20 | value: "false" 21 | - name: cleanSession 22 | value: "false" 23 | -------------------------------------------------------------------------------- /packages/dapr_server/test/components/pubsub-redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dapr.io/v1alpha1 2 | kind: Component 3 | metadata: 4 | name: pubsub-redis 5 | namespace: default 6 | spec: 7 | type: pubsub.redis 8 | version: v1 9 | metadata: 10 | - name: redisHost 11 | value: dapr_redis:6379 12 | - name: redisPassword 13 | value: "" 14 | - name: consumerID 15 | value: "myGroup" 16 | - name: enableTLS 17 | value: "false" --------------------------------------------------------------------------------