From ef588b8509441f1bc882c0d6e6438a3da9f77daf Mon Sep 17 00:00:00 2001 From: Will Tsai Date: Fri, 5 Nov 2021 14:23:41 -0700 Subject: [PATCH 01/73] create new v1.6 branch and config for v1.6 website --- .../{website-v1-5.yml => website-v1-6.yml} | 10 +++++----- daprdocs/config.toml | 15 +++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) rename .github/workflows/{website-v1-5.yml => website-v1-6.yml} (95%) diff --git a/.github/workflows/website-v1-5.yml b/.github/workflows/website-v1-6.yml similarity index 95% rename from .github/workflows/website-v1-5.yml rename to .github/workflows/website-v1-6.yml index 0e030ecd5..335fdb3d5 100644 --- a/.github/workflows/website-v1-5.yml +++ b/.github/workflows/website-v1-6.yml @@ -1,13 +1,13 @@ -name: Azure Static Web App v1.4 +name: Azure Static Web App v1.6 on: push: branches: - - v1.5 + - v1.6 pull_request: types: [opened, synchronize, reopened, closed] branches: - - v1.5 + - v1.6 jobs: build_and_deploy_job: @@ -27,7 +27,7 @@ jobs: HUGO_ENV: production HUGO_VERSION: "0.74.3" with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_5 }} + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_6 }} repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) skip_deploy_on_missing_secrets: true action: "upload" @@ -48,6 +48,6 @@ jobs: id: closepullrequest uses: Azure/static-web-apps-deploy@v0.0.1-preview with: - azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_5 }} + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_V1_6 }} skip_deploy_on_missing_secrets: true action: "close" diff --git a/daprdocs/config.toml b/daprdocs/config.toml index 976699036..3442e37f1 100644 --- a/daprdocs/config.toml +++ b/daprdocs/config.toml @@ -1,5 +1,5 @@ # Site Configuration -baseURL = "https://v1-5.docs.dapr.io/" +baseURL = "https://v1-6.docs.dapr.io/" title = "Dapr Docs" theme = "docsy" disableFastRender = true @@ -157,20 +157,23 @@ offlineSearch = false github_repo = "https://github.com/dapr/docs" github_project_repo = "https://github.com/dapr/dapr" github_subdir = "daprdocs" -github_branch = "v1.5" +github_branch = "v1.6" # Versioning -version_menu = "v1.5 (preview)" -version = "v1.5" +version_menu = "v1.6 (preview)" +version = "v1.6" archived_version = false url_latest_version = "https://docs.dapr.io" [[params.versions]] - version = "v1.5 (preview)" + version = "v1.6 (preview)" url = "#" [[params.versions]] - version = "v1.4 (latest)" + version = "v1.5 (latest)" url = "https://docs.dapr.io" +[[params.versions]] + version = "v1.4" + url = "https://v1-4.docs.dapr.io" [[params.versions]] version = "v1.3" url = "https://v1-3.docs.dapr.io" From 95379e0df2c12bdbb16b06f75dbacc211eeccad4 Mon Sep 17 00:00:00 2001 From: Will Tsai Date: Fri, 12 Nov 2021 11:14:07 -0800 Subject: [PATCH 02/73] resolve conflicts --- daprdocs/config.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/daprdocs/config.toml b/daprdocs/config.toml index f267d4092..3442e37f1 100644 --- a/daprdocs/config.toml +++ b/daprdocs/config.toml @@ -1,9 +1,5 @@ # Site Configuration -<<<<<<< HEAD baseURL = "https://v1-6.docs.dapr.io/" -======= -baseURL = "https://docs.dapr.io/" ->>>>>>> v1.5 title = "Dapr Docs" theme = "docsy" disableFastRender = true From 8b3937ae141a7aa7d61b09560b5b5ce6b10b0deb Mon Sep 17 00:00:00 2001 From: tanvigour <> Date: Thu, 18 Nov 2021 16:49:56 +0530 Subject: [PATCH 03/73] add rel attribute to remove association with previous page --- daprdocs/layouts/partials/navbar.html | 2 +- daprdocs/layouts/partials/page-meta-links.html | 4 ++-- daprdocs/layouts/partials/version-banner.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/daprdocs/layouts/partials/navbar.html b/daprdocs/layouts/partials/navbar.html index e1dc682d4..5a2bc8fd6 100644 --- a/daprdocs/layouts/partials/navbar.html +++ b/daprdocs/layouts/partials/navbar.html @@ -14,7 +14,7 @@ {{ end }} {{ $url := urls.Parse .URL }} {{ $baseurl := urls.Parse $.Site.Params.Baseurl }} - {{ .Name }} + {{ .Name }} {{ end }} {{ if .Site.Params.versions }} diff --git a/daprdocs/layouts/partials/page-meta-links.html b/daprdocs/layouts/partials/page-meta-links.html index bd55efdf3..6bf0d95a1 100644 --- a/daprdocs/layouts/partials/page-meta-links.html +++ b/daprdocs/layouts/partials/page-meta-links.html @@ -21,8 +21,8 @@ {{ $newPageQS := querify "value" $newPageStub.Content "filename" "change-me.md" | safeURL }} {{ $newPageURL := printf "%s/new/%s?%s" $gh_repo $gh_repo_path $newPageQS }} - {{ T "post_edit_this" }} - {{ T "post_create_issue" }} + {{ T "post_edit_this" }} + {{ T "post_create_issue" }} {{ end }} {{ end }} diff --git a/daprdocs/layouts/partials/version-banner.html b/daprdocs/layouts/partials/version-banner.html index 0436da130..09b705b07 100644 --- a/daprdocs/layouts/partials/version-banner.html +++ b/daprdocs/layouts/partials/version-banner.html @@ -8,7 +8,7 @@ {{ with $current_version }}

The documentation you are viewing is for Dapr {{ . | markdownify }} which is an older version of Dapr. {{ with $latest_version }}For up-to-date documentation, see the - latest version.

+ latest version.

{{ end }} {{ end }} From 581a7f5aeae289974e72da5a62dbb3adaea9bfa9 Mon Sep 17 00:00:00 2001 From: Scott Hussey Date: Tue, 28 Dec 2021 14:53:18 -0600 Subject: [PATCH 04/73] Document Kafka pub/sub OIDC authentication - Add documentation to configure Kafka pub/sub component for OIDC authentication - Update documentation on the Kafka pub/sub component TLS configuration to clarify a separation of TLS for transport and authentication. Signed-off-by: Scott Hussey --- .../supported-pubsub/setup-apache-kafka.md | 229 +++++++++++++++--- 1 file changed, 201 insertions(+), 28 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index e0e4167c9..616bd31d6 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -27,11 +27,11 @@ spec: value: "group1" - name: clientID # Optional. Used as client tracing ID by Kafka brokers. value: "my-dapr-app-id" - - name: authRequired # Required. - value: "true" - - name: saslUsername # Required if authRequired is `true`. + - name: authType # Required. + value: "password" + - name: saslUsername # Required if authType is `password`. value: "adminuser" - - name: saslPassword # Required if authRequired is `true`. + - name: saslPassword # Required if authType is `password`. secretKeyRef: name: kafka-secrets key: saslPasswordSecret @@ -50,22 +50,158 @@ spec: | brokers | Y | A comma-separated list of Kafka brokers. | `"localhost:9092,dapr-kafka.myapp.svc.cluster.local:9093"` | consumerGroup | N | A kafka consumer group to listen on. Each record published to a topic is delivered to one consumer within each consumer group subscribed to the topic. | `"group1"` | clientID | N | A user-provided string sent with every request to the Kafka brokers for logging, debugging, and auditing purposes. Defaults to `"sarama"`. | `"my-dapr-app"` -| authRequired | Y | Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"` -| saslUsername | N | The SASL username used for authentication. Only required if `authRequired` is set to `"true"`. | `"adminuser"` -| saslPassword | N | The SASL password used for authentication. Can be `secretKeyRef` to use a [secret reference]({{< ref component-secrets.md >}}). Only required if `authRequired` is set to `"true"`. | `""`, `"KeFg23!"` +| authRequired | N | *Deprecated* Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"` +| authType | Y | Configure or disable authentication. Supported values: `none`, `password`, `mtls`, or `oidc` | `"password"`, `"none"` +| saslUsername | N | The SASL username used for authentication. Only required if `authType` is set to `"password"`. | `"adminuser"` +| saslPassword | N | The SASL password used for authentication. Can be `secretKeyRef` to use a [secret reference]({{< ref component-secrets.md >}}). Only required if `authType is set to `"password"`. | `""`, `"KeFg23!"` | initialOffset | N | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"` | maxMessageBytes | N | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048` | consumeRetryInterval | N | The interval between retries when attempting to consume topics. Treats numbers without suffix as milliseconds. Defaults to 100ms. | `200ms` | version | N | Kafka cluster version. Defaults to 2.0.0.0 | `0.10.2.0` | caCert | N | Certificate authority certificate, required for using TLS. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"` -| clientCert | N | Client certificate, required for using TLS. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"` -| clientKey | N | Client key, required for using TLS. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN RSA PRIVATE KEY-----\n\n-----END RSA PRIVATE KEY-----"` +| clientCert | N | Client certificate, required for `authType` `mtls`. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN CERTIFICATE-----\n\n-----END CERTIFICATE-----"` +| clientKey | N | Client key, required for `authType` `mtls` Can be `secretKeyRef` to use a secret reference | `"-----BEGIN RSA PRIVATE KEY-----\n\n-----END RSA PRIVATE KEY-----"` | skipVerify | N | Skip TLS verification, this is not recommended for use in production. Defaults to `"false"` | `"true"`, `"false"` | +| disableTls | N | Disable TLS for transport security. This is not recommended for use in production. Defaults to `"false"` | `"true"`, `"false"` | +| oidcTokenEndpoint | N | Full URL to an OAuth2 identity provider access token endpoint. Required when `authType` is set to `oidc` | "https://identity.example.com/v1/token" | +| oidcClientID | N | The OAuth2 client ID that has been provisioned in the identity provider. Required when `authType is set to `oidc` | `dapr-kafka` | +| oidcClientSecret | N | The OAuth2 client secret that has been provisioned in the identity provider: Required when `authType` is set to `oidc` | `"KeFg23!"` | +| oidcScopes | N | Comma-delimited list of OAuth2/OIDC scopes to request with the access token. Recommended when `authType` is set to `oidc`. Defaults to `"openid"` | '"openid,kafka-prod"` | -### Communication using TLS -To configure communication using TLS, ensure the Kafka broker is configured to support certificates. -Pre-requisite includes `certficate authority certificate`, `ca issued client certificate`, `client private key`. -Below is an example of a Kafka pubsub component configured to use TLS: + +The `secretKeyRef` above is referencing a [kubernetes secrets store]({{< ref kubernetes-secret-store.md >}}) to access the tls information. Visit [here]({{< ref setup-secret-store.md >}}) to learn more about how to configure a secret store component. + +### Authentication + +Kafka supports a variety of authentication schemes and Dapr supports several: SASL password, mTLS, OIDC/OAuth2. With the added authentication methods, the `authRequired` field has been deprecated +and instead the `authType` field should be used. If `authRequired` is set to `true`, Dapr will attempt to configure `authType` correctly based on the value of `saslPassword`. There are four valid values for `authType`: `none`, `password`, `mtls`, and `oidc`. Note this is authentication only; authorization is still configured within Kafka. + +#### None + +Setting `authType` to `none` will disable any authentication. This is *NOT* recommended in production. + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: kafka-pubsub-noauth + namespace: default +spec: + type: pubsub.kafka + version: v1 + metadata: + - name: brokers # Required. Kafka broker connection setting + value: "dapr-kafka.myapp.svc.cluster.local:9092" + - name: consumerGroup # Optional. Used for input bindings. + value: "group1" + - name: clientID # Optional. Used as client tracing ID by Kafka brokers. + value: "my-dapr-app-id" + - name: authType # Required. + value: "none" + - name: maxMessageBytes # Optional. + value: 1024 + - name: consumeRetryInterval # Optional. + value: 200ms + - name: version # Optional. + value: 0.10.2.0 + - name: disableTls + value: "true" +``` + +#### SASL Password + +Setting `authType` to `password` will enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication using the **PLAIN** mechanism. This requires setting +the `saslUsername` and `saslPassword` fields. + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: kafka-pubsub-sasl + namespace: default +spec: + type: pubsub.kafka + version: v1 + metadata: + - name: brokers # Required. Kafka broker connection setting + value: "dapr-kafka.myapp.svc.cluster.local:9092" + - name: consumerGroup # Optional. Used for input bindings. + value: "group1" + - name: clientID # Optional. Used as client tracing ID by Kafka brokers. + value: "my-dapr-app-id" + - name: authType # Required. + value: "password" + - name: saslUsername # Required if authType is `password`. + value: "adminuser" + - name: saslPassword # Required if authType is `password`. + secretKeyRef: + name: kafka-secrets + key: saslPasswordSecret + - name: maxMessageBytes # Optional. + value: 1024 + - name: consumeRetryInterval # Optional. + value: 200ms + - name: version # Optional. + value: 0.10.2.0 + - name: caCert + secretKeyRef: + name: kafka-tls + key: caCert +``` + +#### Mutual TLS + +Setting `authType` to `mtls` will use a x509 client certificate (the `clientCert` field) and key (the `clientKey` field) to authenticate. Note that mTLS as an +authentication mechanism is distinct from using TLS to secure the transport layer via encryption. mTLS requires TLS transport (meaning `disableTls` must be `false`), but securing +the transport layer does not require using mTLS. See _Communication using TLS_ for configuring underlying TLS transport. + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: kafka-pubsub-mtls + namespace: default +spec: + type: pubsub.kafka + version: v1 + metadata: + - name: brokers # Required. Kafka broker connection setting + value: "dapr-kafka.myapp.svc.cluster.local:9092" + - name: consumerGroup # Optional. Used for input bindings. + value: "group1" + - name: clientID # Optional. Used as client tracing ID by Kafka brokers. + value: "my-dapr-app-id" + - name: authType # Required. + value: "mtls" + - name: caCert + secretKeyRef: + name: kafka-tls + key: caCert + - name: clientCert + secretKeyRef: + name: kafka-tls + key: clientCert + - name: clientKey + secretKeyRef: + name: kafka-tls + key: clientKey + - name: maxMessageBytes # Optional. + value: 1024 + - name: consumeRetryInterval # Optional. + value: 200ms + - name: version # Optional. + value: 0.10.2.0 +``` + +#### OAuth2 or OpenID Connect + +Setting `authType` to `oidc` will enable SASL authentication via the **OAUTHBEARER** mechanism. This supports specifying a bearer +token from an external OAuth2 or [OIDC](https://en.wikipedia.org/wiki/OpenID) identity provider. Currenly only the **client_credentials** grant is supported. Configure `oidcTokenEndpoint` to +the full URL for the identity provider access token endpoint. Set `oidcClientID` and `oidcClientSecret` to the client credentials provisioned in the identity provider. If `caCert` +is specified in the component configuration, the certificate will be appended to the system CA trust for verifying the identity provider certificate. Similarly, if `skipVerify` +is specified in the component configuration, it will also be applied when accessing the identity provider. By default, the only scope requested for the token is `openid` but it is highly recommended +that additional scopes be specified via `oidcScopes` in a comma-separated list and validated by the Kafka broken. If additional scopes are not used to narrow the validity of the access token, +a compromised Kafka broker could replay the token to access other services as the Dapr clientID. ```yaml apiVersion: dapr.io/v1alpha1 @@ -83,9 +219,57 @@ spec: value: "group1" - name: clientID # Optional. Used as client tracing ID by Kafka brokers. value: "my-dapr-app-id" - - name: authRequired # Required. - value: "true" - - name: saslUsername # Required if authRequired is `true`. + - name: authType # Required. + value: "oidc" + - name: oidcTokenEndpoint # Required if authType is `oidc`. + value: "https://identity.example.com/v1/token" + - name: oidcClientID # Required if authType is `oidc`. + value: "dapr-myapp" + - name: oidcClientSecret # Required if authType is `oidc`. + secretKeyRef: + name: kafka-secrets + key: oidcClientSecret + - name: oidcScopes # Recommended if authType is `oidc`. + value: "openid,kafka-dev" + - name: caCert # Also applied to verifying OIDC provider certificate + secretKeyRef: + name: kafka-tls + key: caCert + - name: maxMessageBytes # Optional. + value: 1024 + - name: consumeRetryInterval # Optional. + value: 200ms + - name: version # Optional. + value: 0.10.2.0 +``` + +### Communication using TLS + +By default TLS is enabled to secure the transport layer to Kafka. To disable TLS, set `disableTls` to `true`. When TLS is enabled, you can +control server certificate verification using `skipVerify` to disable verificaiton (*NOT* recommended in production environments) and `caCert` to +specify a trusted TLS certificate authority (CA). If no `caCert` is specified, the system CA trust will be used. To also configure mTLS authentication, +see the section under _Authentication_. +Below is an example of a Kafka pubsub component configured to use transport layer TLS: + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: kafka-pubsub + namespace: default +spec: + type: pubsub.kafka + version: v1 + metadata: + - name: brokers # Required. Kafka broker connection setting + value: "dapr-kafka.myapp.svc.cluster.local:9092" + - name: consumerGroup # Optional. Used for input bindings. + value: "group1" + - name: clientID # Optional. Used as client tracing ID by Kafka brokers. + value: "my-dapr-app-id" + - name: authType # Required. + value: "password" + - name: saslUsername # Required if authType is `password`. value: "adminuser" - name: consumeRetryInterval # Optional. value: 200ms @@ -101,21 +285,10 @@ spec: secretKeyRef: name: kafka-tls key: caCert - - name: clientCert # Client certificate. - secretKeyRef: - name: kafka-tls - key: clientCert - - name: clientKey # Client key. - secretKeyRef: - name: kafka-tls - key: clientKey auth: secretStore: ``` -The `secretKeyRef` above is referencing a [kubernetes secrets store]({{< ref kubernetes-secret-store.md >}}) to access the tls information. Visit [here]({{< ref setup-secret-store.md >}}) to learn more about how to configure a secret store component. - - ## Per-call metadata fields ### Partition Key @@ -154,4 +327,4 @@ To run Kafka on Kubernetes, you can use any Kafka operator, such as [Strimzi](ht ## Related links - [Basic schema for a Dapr component]({{< ref component-schema >}}) - Read [this guide]({{< ref "howto-publish-subscribe.md##step-1-setup-the-pubsub-component" >}}) for instructions on configuring pub/sub components -- [Pub/Sub building block]({{< ref pubsub >}}) \ No newline at end of file +- [Pub/Sub building block]({{< ref pubsub >}}) From 7deff4f04e9989888a7680b8b9ef033455e6012a Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Tue, 28 Dec 2021 15:20:48 -0800 Subject: [PATCH 05/73] Upmerge v1.5 to v1.6 20211227 (#2064) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added pub sub documentation * Changed port number in the command * Modified based on the review comments - 1 * Modified based on the review comments - 2 * Changed python commands * Changed python commands * Modified based on the review comments - 3 * Fix publish a topic examples Step 3 and 4 of the "How-To: Publish & subscribe" publishes to the wrong app id and pubsub. This commit fixes by changing the examples that write to the app-id "testpubsub" to "orderprocessing" and the pubsub "pubsub" to "order_pub_sub" * Wrap oauth links in ignore comment * Bumping tags to v1.5.0 * Update dapr versions for 1.5.1 hotfix * Correct the default component init timeout Signed-off-by: Amulya Varote * Fix incorrect warning log-level Signed-off-by: Amulya Varote * Added bindings documentation Signed-off-by: Amulya Varote * Changed python commands Signed-off-by: Amulya Varote * Changed image for bindings Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Modified based on the review comments - 2 Signed-off-by: Amulya Varote * Reverted a small change Signed-off-by: Amulya Varote * Added pub sub documentation Signed-off-by: Amulya Varote * Changed port number in the command Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Modified based on the review comments - 2 Signed-off-by: Amulya Varote * Changed python commands Signed-off-by: Amulya Varote * Changed python commands Signed-off-by: Amulya Varote * Modified based on the review comments - 3 Signed-off-by: Amulya Varote * Modified based on the review comments - 2 Signed-off-by: Amulya Varote * Wrap oauth links in ignore comment Signed-off-by: Amulya Varote * Bumping tags to v1.5.0 Signed-off-by: Amulya Varote * Modified based on the review comments -3 Signed-off-by: Amulya Varote * Modified a line based on the review comment Signed-off-by: Amulya Varote * Fix publish a topic examples Step 3 and 4 of the "How-To: Publish & subscribe" publishes to the wrong app id and pubsub. This commit fixes by changing the examples that write to the app-id "testpubsub" to "orderprocessing" and the pubsub "pubsub" to "order_pub_sub" Signed-off-by: Amulya Varote * Update dapr versions for 1.5.1 hotfix Signed-off-by: Amulya Varote * Modified a line based on the review comment Signed-off-by: Amulya Varote * Modified based on the review comments Signed-off-by: Amulya Varote * Added pub sub documentation Signed-off-by: Amulya Varote * Changed port number in the command Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Added secrets store documentation Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Modified based on the review comments - 2 Signed-off-by: Amulya Varote * Update daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md Signed-off-by: Amulya Varote * Update daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md Signed-off-by: Amulya Varote * Modified based on the review comments - 2 Signed-off-by: Amulya Varote * Changed python commands Signed-off-by: Amulya Varote * Changed python commands Signed-off-by: Amulya Varote * Modified based on the review comments - 3 Signed-off-by: Amulya Varote * Fix publish a topic examples Step 3 and 4 of the "How-To: Publish & subscribe" publishes to the wrong app id and pubsub. This commit fixes by changing the examples that write to the app-id "testpubsub" to "orderprocessing" and the pubsub "pubsub" to "order_pub_sub" Signed-off-by: Amulya Varote * Added full code snippets for service invocation Signed-off-by: Amulya Varote * Added full code snippets of secrets management Signed-off-by: Amulya Varote * Added full code snippets of state management Signed-off-by: Amulya Varote * Added full code snippets of pub sub Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Removed a line Signed-off-by: Amulya Varote * resolved merge conflicts Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Added full code snippets of secrets management Signed-off-by: Amulya Varote * Added full code snippets of pub sub Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Removed a line Signed-off-by: Amulya Varote * Added full code snippets of secrets management Signed-off-by: Amulya Varote * Added full code snippets of pub sub Signed-off-by: Amulya Varote * Modified based on the review comments - 1 Signed-off-by: Amulya Varote * Solved merge conflicts Signed-off-by: Amulya Varote * Modified go secrets code Signed-off-by: Amulya Varote * Update daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md Co-authored-by: Will * Added DCO sign-off guidance for contributing to Dapr Signed-off-by: Nick Greenfield * Address PR feedback Signed-off-by: Nick Greenfield * Add DCO check to PR template Signed-off-by: Nick Greenfield * simplify git command for DCO Signed-off-by: Will Tsai * Fix header * Display state value instead of StateResponse object (#2046) Signed-off-by: Jun Tian Co-authored-by: greenie-msft <56556602+greenie-msft@users.noreply.github.com> * add ForcePathStyle support for s3 binding (#2054) Signed-off-by: rainfd Co-authored-by: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Co-authored-by: Mark Fussell * Remove requests dep (#2055) * Add DCO check to PR template Signed-off-by: Nick Greenfield * Remove requests dep Signed-off-by: GitHub Co-authored-by: Nick Greenfield Co-authored-by: Yaron Schneider Co-authored-by: Mark Fussell * update endpoint in s3 binding doc (#2049) * update endpoint in s3 binding doc Signed-off-by: lizzzcai * fix jaeger link Signed-off-by: lizzzcai * update endpoint example to match region Signed-off-by: lizzzcai Co-authored-by: Mark Fussell * Update autoscale-keda.md (#2047) Co-authored-by: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Co-authored-by: Mark Fussell * Update service-mesh.md (#2044) Minor typo Co-authored-by: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Co-authored-by: Mark Fussell * Added missing HTTP verb to the documentation dapr/dapr#4030 (#2045) Signed-off-by: GitHub Co-authored-by: Mark Fussell * Update logs-troubleshooting.md (#2023) The label name `dapr-placement` has been changed to `dapr-placement-server`. Co-authored-by: Yaron Schneider Co-authored-by: Mark Fussell * update the DOTNET SDK Signed-off-by: Mark Fussell Co-authored-by: Amulya Varote Co-authored-by: Amulya Varote Co-authored-by: Amulya Varote Co-authored-by: David Millman Co-authored-by: emctl Co-authored-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> Co-authored-by: Will Co-authored-by: Will Tsai Co-authored-by: Aaron Crawfis Co-authored-by: Jun Tian Co-authored-by: RainFD Co-authored-by: Mark Fussell Co-authored-by: ChethanUK Co-authored-by: Yaron Schneider Co-authored-by: Lize Co-authored-by: Andrew Cartwright Co-authored-by: Shriroop Joshi Co-authored-by: Christoph Hofmann Co-authored-by: Will 保哥 Co-authored-by: Mark Fussell --- .github/pull_request_template.md | 2 +- daprdocs/content/en/concepts/service-mesh.md | 2 +- .../en/contributing/contributing-overview.md | 40 +- .../bindings/howto-bindings.md | 273 +++++- .../bindings/howto-triggers.md | 263 +++++- .../pubsub/howto-publish-subscribe.md | 801 +++++++++++------- .../building-blocks/secrets/howto-secrets.md | 69 +- .../howto-invoke-discover-services.md | 159 ++-- .../state-management/howto-get-save-state.md | 346 ++++---- .../integrations/autoscale-keda.md | 2 +- .../content/en/getting-started/quickstarts.md | 18 +- .../supported-tracing-backends/jaeger.md | 2 +- .../content/en/operations/security/oauth.md | 2 + .../support/support-release-policy.md | 29 +- .../troubleshooting/logs-troubleshooting.md | 42 +- .../reference/api/service_invocation_api.md | 2 +- .../supported-bindings/s3.md | 10 + .../shortcodes/dapr-latest-version.html | 2 +- .../building-block-input-binding-example.png | Bin 0 -> 88366 bytes .../building-block-output-binding-example.png | Bin 0 -> 95677 bytes .../images/building-block-pub-sub-example.png | Bin 0 -> 171404 bytes sdkdocs/dotnet | 2 +- 22 files changed, 1425 insertions(+), 641 deletions(-) create mode 100644 daprdocs/static/images/building-block-input-binding-example.png create mode 100644 daprdocs/static/images/building-block-output-binding-example.png create mode 100644 daprdocs/static/images/building-block-pub-sub-example.png diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index aa50e1dc1..a6b77f550 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +1,7 @@ Thank you for helping make the Dapr documentation better! **Please follow this checklist before submitting:** - +- [ ] Commits are signed with Developer Certificate of Origin (DCO - [learn more](https://docs.dapr.io/contributing/contributing-overview/#developer-certificate-of-origin-signing-your-work)) - [ ] [Read the contribution guide](https://docs.dapr.io/contributing/contributing-docs/) - [ ] Commands include options for Linux, MacOS, and Windows within codetabs - [ ] New file and folder names are globally unique diff --git a/daprdocs/content/en/concepts/service-mesh.md b/daprdocs/content/en/concepts/service-mesh.md index 1c81221f7..96613a319 100644 --- a/daprdocs/content/en/concepts/service-mesh.md +++ b/daprdocs/content/en/concepts/service-mesh.md @@ -7,7 +7,7 @@ description: > How Dapr compares to and works with service meshes --- -Dapr uses a sidecar architecture, running as a separate process alongside the application and includes features such as service invocation, network security, and distributed tracing. This often raises the question: how does Dapr compare to service mesh solutions such as [Linkerd](https://linkerd.io/), [Istio](https://istio.io/) and [Open Service Mesh](https://openservicemesh.io/) amoung others? +Dapr uses a sidecar architecture, running as a separate process alongside the application and includes features such as service invocation, network security, and distributed tracing. This often raises the question: how does Dapr compare to service mesh solutions such as [Linkerd](https://linkerd.io/), [Istio](https://istio.io/) and [Open Service Mesh](https://openservicemesh.io/) among others? ## How Dapr and service meshes compare While Dapr and service meshes do offer some overlapping capabilities, **Dapr is not a service mesh**, where a service mesh is defined as a *networking* service mesh. Unlike a service mesh which is focused on networking concerns, Dapr is focused on providing building blocks that make it easier for developers to build applications as microservices. Dapr is developer-centric, versus service meshes which are infrastructure-centric. diff --git a/daprdocs/content/en/contributing/contributing-overview.md b/daprdocs/content/en/contributing/contributing-overview.md index 6a8a404b3..69bb68c2f 100644 --- a/daprdocs/content/en/contributing/contributing-overview.md +++ b/daprdocs/content/en/contributing/contributing-overview.md @@ -43,6 +43,7 @@ Before you submit an issue, make sure you've checked the following: - Many changes to the Dapr runtime may require changes to the API. In that case, the best place to discuss the potential feature is the main [Dapr repo](https://github.com/dapr/dapr). - Other examples could include bindings, state stores or entirely new components. + ## Pull Requests All contributions come through pull requests. To submit a proposed change, follow this workflow: @@ -53,18 +54,53 @@ All contributions come through pull requests. To submit a proposed change, follo 1. Create your change - Code changes require tests 1. Update relevant documentation for the change -1. Commit and open a PR +1. Commit with [DCO sign-off]({{< ref "contributing-overview.md#developer-certificate-of-origin-signing-your-work" >}}) and open a PR 1. Wait for the CI process to finish and make sure all checks are green 1. A maintainer of the project will be assigned, and you can expect a review within a few days + #### Use work-in-progress PRs for early feedback A good way to communicate before investing too much time is to create a "Work-in-progress" PR and share it with your reviewers. The standard way of doing this is to add a "[WIP]" prefix in your PR's title and assign the **do-not-merge** label. This will let people looking at your PR know that it is not well baked yet. -### Use of Third-party code +## Use of Third-party code - Third-party code must include licenses. +## Developer Certificate of Origin: Signing your work +#### Every commit needs to be signed + +The Developer Certificate of Origin (DCO) is a lightweight way for contributors to certify that they wrote or otherwise have the right to submit the code they are contributing to the project. Here is the full text of the [DCO](https://developercertificate.org/), reformatted for readability: +``` +By making a contribution to this project, I certify that: + (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or + (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or + (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. + (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. +``` +Contributors sign-off that they adhere to these requirements by adding a `Signed-off-by` line to commit messages. + +``` +This is my commit message +Signed-off-by: Random J Developer +``` +Git even has a `-s` command line option to append this automatically to your commit message: +``` +$ git commit -s -m 'This is my commit message' +``` + +Each Pull Request is checked whether or not commits in a Pull Request do contain a valid Signed-off-by line. + +#### I didn't sign my commit, now what?! + +No worries - You can easily replay your changes, sign them and force push them! + +``` +git checkout +git commit --amend --no-edit --signoff +git push --force-with-lease +``` + ## Code of Conduct Please see the [Dapr community code of conduct](https://github.com/dapr/community/blob/master/CODE-OF-CONDUCT.md). diff --git a/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-bindings.md b/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-bindings.md index ea45ababf..ce9c1d87a 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-bindings.md +++ b/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-bindings.md @@ -9,11 +9,11 @@ weight: 300 Output bindings enable you to invoke external resources without taking dependencies on special SDK or libraries. For a complete sample showing output bindings, visit this [link](https://github.com/dapr/quickstarts/tree/master/bindings). -Watch this [video](https://www.youtube.com/watch?v=ysklxm81MTs&feature=youtu.be&t=1960) on how to use bi-directional output bindings. +## Example: -
- -
+The below code example loosely describes an application that processes orders. In the example, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to invoke external resources, in this case a Kafka, via an output binding. + +Diagram showing bindings of example service ## 1. Create a binding @@ -21,7 +21,7 @@ An output binding represents a resource that Dapr uses to invoke and send messag For the purpose of this guide, you'll use a Kafka binding. You can find a list of the different binding specs [here]({{< ref setup-bindings >}}). -Create a new binding component with the name of `myevent`. +Create a new binding component with the name of `checkout`. Inside the `metadata` section, configure Kafka related properties such as the topic to publish the message to and the broker. @@ -36,16 +36,24 @@ Create the following YAML file, named `binding.yaml`, and save this to a `compon apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: myevent - namespace: default + name: checkout spec: type: bindings.kafka version: v1 metadata: + # Kafka broker connection setting - name: brokers value: localhost:9092 + # consumer configuration: topic and consumer group + - name: topics + value: sample + - name: consumerGroup + value: group1 + # publisher configuration: topic - name: publishTopic - value: topic1 + value: sample + - name: authRequired + value: "false" ``` {{% /codetab %}} @@ -59,40 +67,273 @@ To deploy this into a Kubernetes cluster, fill in the `metadata` connection deta apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: myevent - namespace: default + name: checkout spec: type: bindings.kafka version: v1 metadata: + # Kafka broker connection setting - name: brokers value: localhost:9092 + # consumer configuration: topic and consumer group + - name: topics + value: sample + - name: consumerGroup + value: group1 + # publisher configuration: topic - name: publishTopic - value: topic1 + value: sample + - name: authRequired + value: "false" ``` {{% /codetab %}} {{< /tabs >}} -## 2. Send an event +## 2. Send an event (Output binding) + +Below are code examples that leverage Dapr SDKs to interact with an output binding. + +{{< tabs Dotnet Java Python Go Javascript>}} + +{{% codetab %}} + +```csharp +//dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; + +//code +namespace EventService +{ + class Program + { + static async Task Main(string[] args) + { + string BINDING_NAME = "checkout"; + string BINDING_OPERATION = "create"; + while(true) { + System.Threading.Thread.Sleep(5000); + Random random = new Random(); + int orderId = random.Next(1,1000); + using var client = new DaprClientBuilder().Build(); + //Using Dapr SDK to invoke output binding + await client.InvokeBindingAsync(BINDING_NAME, BINDING_OPERATION, orderId); + Console.WriteLine("Sending message: " + orderId); + } + } + } +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl dotnet run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```java +//dependencies +import io.dapr.client.DaprClient; +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.domain.HttpExtension; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +//code +@SpringBootApplication +public class OrderProcessingServiceApplication { + + private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); + + public static void main(String[] args) throws InterruptedException{ + String BINDING_NAME = "checkout"; + String BINDING_OPERATION = "create"; + while(true) { + TimeUnit.MILLISECONDS.sleep(5000); + Random random = new Random(); + int orderId = random.nextInt(1000-1) + 1; + DaprClient client = new DaprClientBuilder().build(); + //Using Dapr SDK to invoke output binding + client.invokeBinding(BINDING_NAME, BINDING_OPERATION, orderId).block(); + log.info("Sending message: " + orderId); + } + } +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```python +#dependencies +import random +from time import sleep +import requests +import logging +import json +from dapr.clients import DaprClient + +#code +logging.basicConfig(level = logging.INFO) +BINDING_NAME = 'checkout' +BINDING_OPERATION = 'create' +while True: + sleep(random.randrange(50, 5000) / 1000) + orderId = random.randint(1, 1000) + with DaprClient() as client: + #Using Dapr SDK to invoke output binding + resp = client.invoke_binding(BINDING_NAME, BINDING_OPERATION, json.dumps(orderId)) + logging.basicConfig(level = logging.INFO) + logging.info('Sending message: ' + str(orderId)) + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --app-protocol grpc python3 OrderProcessingService.py +``` + +{{% /codetab %}} + +{{% codetab %}} + +```go +//dependencies +import ( + "context" + "log" + "math/rand" + "time" + "strconv" + dapr "github.com/dapr/go-sdk/client" + +) + +//code +func main() { + BINDING_NAME := "checkout"; + BINDING_OPERATION := "create"; + for i := 0; i < 10; i++ { + time.Sleep(5000) + orderId := rand.Intn(1000-1) + 1 + client, err := dapr.NewClient() + if err != nil { + panic(err) + } + defer client.Close() + ctx := context.Background() + //Using Dapr SDK to invoke output binding + in := &dapr.InvokeBindingRequest{ Name: BINDING_NAME, Operation: BINDING_OPERATION , Data: []byte(strconv.Itoa(orderId))} + err = client.InvokeOutputBinding(ctx, in) + log.Println("Sending message: " + strconv.Itoa(orderId)) + } +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go +``` + +{{% /codetab %}} + +{{% codetab %}} + +```javascript +//dependencies + +import { DaprServer, DaprClient, CommunicationProtocolEnum } from 'dapr-client'; + +//code +const daprHost = "127.0.0.1"; + +var main = function() { + for(var i=0;i<10;i++) { + sleep(5000); + var orderId = Math.floor(Math.random() * (1000 - 1) + 1); + start(orderId).catch((e) => { + console.error(e); + process.exit(1); + }); + } +} + +async function start(orderId) { + const BINDING_NAME = "checkout"; + const BINDING_OPERATION = "create"; + const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); + //Using Dapr SDK to invoke output binding + const result = await client.binding.send(BINDING_NAME, BINDING_OPERATION, { orderId: orderId }); + console.log("Sending message: " + orderId); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +main(); + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start +``` + +{{% /codetab %}} + +{{< /tabs >}} All that's left now is to invoke the output bindings endpoint on a running Dapr instance. -You can do so using HTTP: +You can also invoke the output bindings endpoint using HTTP: ```bash -curl -X POST -H 'Content-Type: application/json' http://localhost:3500/v1.0/bindings/myevent -d '{ "data": { "message": "Hi!" }, "operation": "create" }' +curl -X POST -H 'Content-Type: application/json' http://localhost:3601/v1.0/bindings/checkout -d '{ "data": { "orderId": "100" }, "operation": "create" }' ``` -As seen above, you invoked the `/binding` endpoint with the name of the binding to invoke, in our case its `myevent`. +As seen above, you invoked the `/binding` endpoint with the name of the binding to invoke, in our case its `checkout`. The payload goes inside the mandatory `data` field, and can be any JSON serializable value. You'll also notice that there's an `operation` field that tells the binding what you need it to do. You can check [here]({{< ref supported-bindings >}}) which operations are supported for every output binding. +Watch this [video](https://www.youtube.com/watch?v=ysklxm81MTs&feature=youtu.be&t=1960) on how to use bi-directional output bindings. + +
+ +
+ ## References - [Binding API]({{< ref bindings_api.md >}}) - [Binding components]({{< ref bindings >}}) -- [Binding detailed specifications]({{< ref supported-bindings >}}) \ No newline at end of file +- [Binding detailed specifications]({{< ref supported-bindings >}}) diff --git a/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-triggers.md b/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-triggers.md index c0afc13a8..ad3da9c6a 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-triggers.md +++ b/daprdocs/content/en/developing-applications/building-blocks/bindings/howto-triggers.md @@ -1,7 +1,7 @@ --- type: docs title: "How-To: Trigger your application with input bindings" -linkTitle: "How-To: Triggers" +linkTitle: "How-To: Input bindings" description: "Use Dapr input bindings to trigger event driven applications" weight: 200 --- @@ -18,78 +18,270 @@ Dapr bindings allow you to: For more info on bindings, read [this overview]({{}}). -For a quickstart sample showing bindings, visit this [link](https://github.com/dapr/quickstarts/tree/master/bindings). +## Example: + +The below code example loosely describes an application that processes orders. In the example, there is an order processing service which has a Dapr sidecar. The checkout service uses Dapr to trigger the application via an input binding. + +Diagram showing bindings of example service ## 1. Create a binding -An input binding represents an event resource that Dapr uses to read events from and push to your application. +An input binding represents a resource that Dapr uses to read events from and push to your application. -For the purpose of this HowTo, we'll use a Kafka binding. You can find a list of the different binding specs [here]({{< ref supported-bindings >}}). +For the purpose of this guide, you'll use a Kafka binding. You can find a list of supported binding components [here]({{< ref setup-bindings >}}). -Create the following YAML file, named binding.yaml, and save this to a `components` sub-folder in your application directory. +Create a new binding component with the name of `checkout`. + +Inside the `metadata` section, configure Kafka related properties, such as the topic to publish the message to and the broker. + +{{< tabs "Self-Hosted (CLI)" Kubernetes >}} + +{{% codetab %}} + +Create the following YAML file, named `binding.yaml`, and save this to a `components` sub-folder in your application directory. (Use the `--components-path` flag with `dapr run` to point to your custom components dir) -*Note: When running in Kubernetes, apply this file to your cluster using `kubectl apply -f binding.yaml`* - ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: myevent - namespace: default + name: checkout spec: type: bindings.kafka version: v1 metadata: - - name: topics - value: topic1 + # Kafka broker connection setting - name: brokers value: localhost:9092 + # consumer configuration: topic and consumer group + - name: topics + value: sample - name: consumerGroup value: group1 + # publisher configuration: topic + - name: publishTopic + value: sample + - name: authRequired + value: "false" ``` -Here, you create a new binding component with the name of `myevent`. +{{% /codetab %}} -Inside the `metadata` section, configure the Kafka related properties such as the topics to listen on, the brokers and more. +{{% codetab %}} -## 2. Listen for incoming events +To deploy this into a Kubernetes cluster, fill in the `metadata` connection details of your [desired binding component]({{< ref setup-bindings >}}) in the yaml below (in this case kafka), save as `binding.yaml`, and run `kubectl apply -f binding.yaml`. -Now configure your application to receive incoming events. If using HTTP, you need to listen on a `POST` endpoint with the name of the binding as specified in `metadata.name` in the file. In this example, this is `myevent`. -*The following example shows how you would listen for the event in Node.js, but this is applicable to any programming language* +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: checkout +spec: + type: bindings.kafka + version: v1 + metadata: + # Kafka broker connection setting + - name: brokers + value: localhost:9092 + # consumer configuration: topic and consumer group + - name: topics + value: sample + - name: consumerGroup + value: group1 + # publisher configuration: topic + - name: publishTopic + value: sample + - name: authRequired + value: "false" +``` + +{{% /codetab %}} + +{{< /tabs >}} + +## 2. Listen for incoming events (input binding) + +Now configure your application to receive incoming events. If using HTTP, you need to listen on a `POST` endpoint with the name of the binding as specified in `metadata.name` in the file. + +Below are code examples that leverage Dapr SDKs to demonstrate an output binding. + +{{< tabs Dotnet Java Python Go Javascript>}} + +{{% codetab %}} + +```csharp +//dependencies +using System.Collections.Generic; +using System.Threading.Tasks; +using System; +using Microsoft.AspNetCore.Mvc; + +//code +namespace CheckoutService.controller +{ + [ApiController] + public class CheckoutServiceController : Controller + { + [HttpPost("/checkout")] + public ActionResult getCheckout([FromBody] int orderId) + { + Console.WriteLine("Received Message: " + orderId); + return "CID" + orderId; + } + } +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl dotnet run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```java +//dependencies +import org.springframework.web.bind.annotation.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; + +//code +@RestController +@RequestMapping("/") +public class CheckoutServiceController { + private static final Logger log = LoggerFactory.getLogger(CheckoutServiceController.class); + @PostMapping(path = "/checkout") + public Mono getCheckout(@RequestBody(required = false) byte[] body) { + return Mono.fromRunnable(() -> + log.info("Received Message: " + new String(body))); + } +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 mvn spring-boot:run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```python +#dependencies +import logging +from dapr.ext.grpc import App, BindingRequest + +#code +app = App() + +@app.binding('checkout') +def getCheckout(request: BindingRequest): + logging.basicConfig(level = logging.INFO) + logging.info('Received Message : ' + request.text()) + +app.run(6002) + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --app-protocol grpc -- python3 CheckoutService.py +``` + +{{% /codetab %}} + +{{% codetab %}} + +```go +//dependencies +import ( + "encoding/json" + "log" + "net/http" + "github.com/gorilla/mux" +) + +//code +func getCheckout(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + var orderId int + err := json.NewDecoder(r.Body).Decode(&orderId) + log.Println("Received Message: ", orderId) + if err != nil { + log.Printf("error parsing checkout input binding payload: %s", err) + w.WriteHeader(http.StatusOK) + return + } +} + +func main() { + r := mux.NewRouter() + r.HandleFunc("/checkout", getCheckout).Methods("POST", "OPTIONS") + http.ListenAndServe(":6002", r) +} + +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 go run CheckoutService.go +``` + +{{% /codetab %}} + +{{% codetab %}} ```javascript -const express = require('express') -const bodyParser = require('body-parser') -const app = express() -app.use(bodyParser.json()) +//dependencies +import { DaprServer, CommunicationProtocolEnum } from 'dapr-client'; -const port = 3000 +//code +const daprHost = "127.0.0.1"; +const serverHost = "127.0.0.1"; +const serverPort = "6002"; +const daprPort = "3602"; -app.post('/myevent', (req, res) => { - console.log(req.body) - res.status(200).send() -}) +start().catch((e) => { + console.error(e); + process.exit(1); +}); + +async function start() { + const server = new DaprServer(serverHost, serverPort, daprHost, daprPort, CommunicationProtocolEnum.HTTP); + await server.binding.receive('checkout', async (orderId) => console.log(`Received Message: ${JSON.stringify(orderId)}`)); + await server.startServer(); +} -app.listen(port, () => console.log(`Kafka consumer app listening on port ${port}!`)) ``` +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 dotnet npm start +``` + +{{% /codetab %}} + +{{< /tabs >}} + ### ACK-ing an event In order to tell Dapr that you successfully processed an event in your application, return a `200 OK` response from your HTTP handler. -```javascript -res.status(200).send() -``` - ### Rejecting an event -In order to tell Dapr that the event wasn't processed correctly in your application and schedule it for redelivery, return any response different from `200 OK`. For example, a `500 Error`. - -```javascript -res.status(500).send() -``` +In order to tell Dapr that the event was not processed correctly in your application and schedule it for redelivery, return any response other than `200 OK`. For example, a `500 Error`. ### Specifying a custom route @@ -108,7 +300,6 @@ spec: ### Event delivery Guarantees Event delivery guarantees are controlled by the binding implementation. Depending on the binding implementation, the event delivery can be exactly once or at least once. - ## References * [Bindings building block]({{< ref bindings >}}) diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/howto-publish-subscribe.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/howto-publish-subscribe.md index ca2c4289d..5ace3cdb7 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/howto-publish-subscribe.md +++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/howto-publish-subscribe.md @@ -20,33 +20,48 @@ When publishing a message, it's important to specify the content type of the dat Unless specified, Dapr will assume `text/plain`. When using Dapr's HTTP API, the content type can be set in a `Content-Type` header. gRPC clients and SDKs have a dedicated content type parameter. -## Step 1: Setup the Pub/Sub component -The following example creates applications to publish and subscribe to a topic called `deathStarStatus`. +## Example: - -

+The below code example loosely describes an application that processes orders. In the example, there are two services - an order processing service and a checkout service. Both services have Dapr sidecars. The order processing service uses Dapr to publish a message to RabbitMQ and the checkout service subscribes to the topic in the message queue. + +Diagram showing state management of example service + +## Step 1: Setup the Pub/Sub component +The following example creates applications to publish and subscribe to a topic called `orders`. The first step is to setup the Pub/Sub component: {{< tabs "Self-Hosted (CLI)" Kubernetes >}} {{% codetab %}} -Redis Streams is installed by default on a local machine when running `dapr init`. +The pubsub.yaml is created by default on your local machine when running `dapr init`. Verify by opening your components file under `%UserProfile%\.dapr\components\pubsub.yaml` on Windows or `~/.dapr/components/pubsub.yaml` on Linux/MacOS. + +In this example, RabbitMQ is used for publish and subscribe. Replace `pubsub.yaml` file contents with the below contents. -Verify by opening your components file under `%UserProfile%\.dapr\components\pubsub.yaml` on Windows or `~/.dapr/components/pubsub.yaml` on Linux/MacOS: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: pubsub + name: order_pub_sub spec: - type: pubsub.redis + type: pubsub.rabbitmq version: v1 metadata: - - name: redisHost - value: localhost:6379 - - name: redisPassword - value: "" + - name: host + value: "amqp://localhost:5672" + - name: durable + value: "false" + - name: deletedWhenUnused + value: "false" + - name: autoAck + value: "false" + - name: reconnectWait + value: "0" + - name: concurrency + value: parallel +scopes: + - orderprocessing + - checkout ``` You can override this file with another Redis instance or another [pubsub component]({{< ref setup-pubsub >}}) by creating a `components` directory containing the file and using the flag `--components-path` with the `dapr run` CLI command. @@ -59,16 +74,27 @@ To deploy this into a Kubernetes cluster, fill in the `metadata` connection deta apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: pubsub + name: order_pub_sub namespace: default spec: - type: pubsub.redis + type: pubsub.rabbitmq version: v1 metadata: - - name: redisHost - value: localhost:6379 - - name: redisPassword - value: "" + - name: host + value: "amqp://localhost:5672" + - name: durable + value: "false" + - name: deletedWhenUnused + value: "false" + - name: autoAck + value: "false" + - name: reconnectWait + value: "0" + - name: concurrency + value: parallel +scopes: + - orderprocessing + - checkout ``` {{% /codetab %}} @@ -95,41 +121,72 @@ You can subscribe to a topic using the following Custom Resources Definition (CR apiVersion: dapr.io/v1alpha1 kind: Subscription metadata: - name: myevent-subscription + name: order_pub_sub spec: - topic: deathStarStatus - route: /dsstatus - pubsubname: pubsub + topic: orders + route: /checkout + pubsubname: order_pub_sub scopes: -- app1 -- app2 +- orderprocessing +- checkout ``` -The example above shows an event subscription to topic `deathStarStatus`, for the pubsub component `pubsub`. -- The `route` field tells Dapr to send all topic messages to the `/dsstatus` endpoint in the app. -- The `scopes` field enables this subscription for apps with IDs `app1` and `app2`. +The example above shows an event subscription to topic `orders`, for the pubsub component `order_pub_sub`. +- The `route` field tells Dapr to send all topic messages to the `/checkout` endpoint in the app. +- The `scopes` field enables this subscription for apps with IDs `orderprocessing` and `checkout`. Set the component with: -{{< tabs "Self-Hosted (CLI)" Kubernetes>}} -{{% codetab %}} Place the CRD in your `./components` directory. When Dapr starts up, it loads subscriptions along with components. Note: By default, Dapr loads components from `$HOME/.dapr/components` on MacOS/Linux and `%USERPROFILE%\.dapr\components` on Windows. You can also override the default directory by pointing the Dapr CLI to a components path: +{{< tabs Dotnet Java Python Go Javascript Kubernetes>}} + +{{% codetab %}} + ```bash -dapr run --app-id myapp --components-path ./myComponents -- python3 app1.py +dapr run --app-id myapp --components-path ./myComponents -- dotnet run ``` -*Note: If you place the subscription in a custom components path, make sure the Pub/Sub component is present also.* +{{% /codetab %}} + +{{% codetab %}} + +```bash +dapr run --app-id myapp --components-path ./myComponents -- mvn spring-boot:run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```bash +dapr run --app-id myapp --components-path ./myComponents -- python3 app.py +``` + +{{% /codetab %}} + +{{% codetab %}} + +```bash +dapr run --app-id myapp --components-path ./myComponents -- go run app.go +``` + +{{% /codetab %}} + +{{% codetab %}} + +```bash +dapr run --app-id myapp --components-path ./myComponents -- npm start +``` {{% /codetab %}} {{% codetab %}} In Kubernetes, save the CRD to a file and apply it to the cluster: - ```bash kubectl apply -f subscription.yaml ``` @@ -137,251 +194,233 @@ kubectl apply -f subscription.yaml {{< /tabs >}} -#### Example +Below are code examples that leverage Dapr SDKs to subscribe to a topic. -{{< tabs Python Node PHP>}} - -{{% codetab %}} -Create a file named `app1.py` and paste in the following: -```python -import flask -from flask import request, jsonify -from flask_cors import CORS -import json -import sys - -app = flask.Flask(__name__) -CORS(app) - -@app.route('/dsstatus', methods=['POST']) -def ds_subscriber(): - print(request.json, flush=True) - return json.dumps({'success':True}), 200, {'ContentType':'application/json'} - -app.run() -``` -After creating `app1.py` ensure flask and flask_cors are installed: - -```bash -pip install flask -pip install flask_cors -``` - -Then run: - -```bash -dapr --app-id app1 --app-port 5000 run python app1.py -``` -{{% /codetab %}} - -{{% codetab %}} -After setting up the subscription above, download this javascript (Node > 4.16) into a `app2.js` file: - -```javascript -const express = require('express') -const bodyParser = require('body-parser') -const app = express() -app.use(bodyParser.json({ type: 'application/*+json' })); - -const port = 3000 - -app.post('/dsstatus', (req, res) => { - console.log(req.body); - res.sendStatus(200); -}); - -app.listen(port, () => console.log(`consumer app listening on port ${port}!`)) -``` -Run this app with: - -```bash -dapr --app-id app2 --app-port 3000 run node app2.js -``` -{{% /codetab %}} +{{< tabs Dotnet Java Python Go Javascript>}} {{% codetab %}} -Create a file named `app1.php` and paste in the following: +```csharp +//dependencies +using System.Collections.Generic; +using System.Threading.Tasks; +using System; +using Microsoft.AspNetCore.Mvc; +using Dapr; +using Dapr.Client; -```php -post('/dsstatus', function( - #[\Dapr\Attributes\FromBody] - \Dapr\PubSub\CloudEvent $cloudEvent, - \Psr\Log\LoggerInterface $logger - ) { - $logger->alert('Received event: {event}', ['event' => $cloudEvent]); - return ['status' => 'SUCCESS']; - } -); -$app->start(); -``` - -After creating `app1.php`, and with the [SDK installed](https://docs.dapr.io/developing-applications/sdks/php/), -go ahead and start the app: - -```bash -dapr --app-id app1 --app-port 3000 run -- php -S 0.0.0.0:3000 app1.php -``` - -{{% /codetab %}} - -{{< /tabs >}} - -### Programmatic subscriptions - -To subscribe to topics, start a web server in the programming language of your choice and listen on the following `GET` endpoint: `/dapr/subscribe`. -The Dapr instance calls into your app at startup and expect a JSON response for the topic subscriptions with: -- `pubsubname`: Which pub/sub component Dapr should use. -- `topic`: Which topic to subscribe to. -- `route`: Which endpoint for Dapr to call on when a message comes to that topic. - -#### Example - -{{< tabs Python Node PHP>}} - -{{% codetab %}} -```python -import flask -from flask import request, jsonify -from flask_cors import CORS -import json -import sys - -app = flask.Flask(__name__) -CORS(app) - -@app.route('/dapr/subscribe', methods=['GET']) -def subscribe(): - subscriptions = [{'pubsubname': 'pubsub', - 'topic': 'deathStarStatus', - 'route': 'dsstatus'}] - return jsonify(subscriptions) - -@app.route('/dsstatus', methods=['POST']) -def ds_subscriber(): - print(request.json, flush=True) - return json.dumps({'success':True}), 200, {'ContentType':'application/json'} -app.run() -``` -After creating `app1.py` ensure flask and flask_cors are installed: - -```bash -pip install flask -pip install flask_cors -``` - -Then run: - -```bash -dapr --app-id app1 --app-port 5000 run python app1.py -``` -{{% /codetab %}} - -{{% codetab %}} -```javascript -const express = require('express') -const bodyParser = require('body-parser') -const app = express() -app.use(bodyParser.json({ type: 'application/*+json' })); - -const port = 3000 - -app.get('/dapr/subscribe', (req, res) => { - res.json([ +//code +namespace CheckoutService.controller +{ + [ApiController] + public class CheckoutServiceController : Controller + { + //Subscribe to a topic + [Topic("order_pub_sub", "orders")] + [HttpPost("checkout")] + public void getCheckout([FromBody] int orderId) { - pubsubname: "pubsub", - topic: "deathStarStatus", - route: "dsstatus" + Console.WriteLine("Subscriber received : " + orderId); } - ]); -}) - -app.post('/dsstatus', (req, res) => { - console.log(req.body); - res.sendStatus(200); -}); - -app.listen(port, () => console.log(`consumer app listening on port ${port}!`)) + } +} ``` -Run this app with: + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: ```bash -dapr --app-id app2 --app-port 3000 run node app2.js +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl dotnet run ``` + {{% /codetab %}} {{% codetab %}} -Update `app1.php` with the following: +```java +//dependencies +import io.dapr.Topic; +import io.dapr.client.domain.CloudEvent; +import org.springframework.web.bind.annotation.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; -```php - $builder->addDefinitions(['dapr.subscriptions' => [ - new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'deathStarStatus', route: '/dsstatus'), -]])); -$app->post('/dsstatus', function( - #[\Dapr\Attributes\FromBody] - \Dapr\PubSub\CloudEvent $cloudEvent, - \Psr\Log\LoggerInterface $logger - ) { - $logger->alert('Received event: {event}', ['event' => $cloudEvent]); - return ['status' => 'SUCCESS']; + private static final Logger log = LoggerFactory.getLogger(CheckoutServiceController.class); + //Subscribe to a topic + @Topic(name = "orders", pubsubName = "order_pub_sub") + @PostMapping(path = "/checkout") + public Mono getCheckout(@RequestBody(required = false) CloudEvent cloudEvent) { + return Mono.fromRunnable(() -> { + try { + log.info("Subscriber received: " + cloudEvent.getData()); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); } -); -$app->start(); +} ``` -Run this app with: +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: ```bash -dapr --app-id app1 --app-port 3000 run -- php -S 0.0.0.0:3000 app1.php +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 mvn spring-boot:run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```python +#dependencies +from cloudevents.sdk.event import v1 +from dapr.ext.grpc import App +import logging +import json + +#code +app = App() +logging.basicConfig(level = logging.INFO) +#Subscribe to a topic +@app.subscribe(pubsub_name='order_pub_sub', topic='orders') +def mytopic(event: v1.Event) -> None: + data = json.loads(event.Data()) + logging.info('Subscriber received: ' + str(data)) + +app.run(6002) +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --app-protocol grpc -- python3 CheckoutService.py +``` + +{{% /codetab %}} + +{{% codetab %}} + +```go +//dependencies +import ( + "log" + "net/http" + "context" + + "github.com/dapr/go-sdk/service/common" + daprd "github.com/dapr/go-sdk/service/http" +) + +//code +var sub = &common.Subscription{ + PubsubName: "order_pub_sub", + Topic: "orders", + Route: "/checkout", +} + +func main() { + s := daprd.NewService(":6002") + //Subscribe to a topic + if err := s.AddTopicEventHandler(sub, eventHandler); err != nil { + log.Fatalf("error adding topic subscription: %v", err) + } + if err := s.Start(); err != nil && err != http.ErrServerClosed { + log.Fatalf("error listenning: %v", err) + } +} + +func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err error) { + log.Printf("Subscriber received: %s", e.Data) + return false, nil +} +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 go run CheckoutService.go +``` + +{{% /codetab %}} + +{{% codetab %}} + +```javascript +//dependencies +import { DaprServer, CommunicationProtocolEnum } from 'dapr-client'; + +//code +const daprHost = "127.0.0.1"; +const serverHost = "127.0.0.1"; +const serverPort = "6002"; + +start().catch((e) => { + console.error(e); + process.exit(1); +}); + +async function start(orderId) { + const server = new DaprServer( + serverHost, + serverPort, + daprHost, + process.env.DAPR_HTTP_PORT, + CommunicationProtocolEnum.HTTP + ); + //Subscribe to a topic + await server.pubsub.subscribe("order_pub_sub", "orders", async (orderId) => { + console.log(`Subscriber received: ${JSON.stringify(orderId)}`) + }); + await server.startServer(); +} +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 npm start ``` {{% /codetab %}} {{< /tabs >}} -The `/dsstatus` endpoint matches the `route` defined in the subscriptions and this is where Dapr will send all topic messages to. +The `/checkout` endpoint matches the `route` defined in the subscriptions and this is where Dapr will send all topic messages to. ## Step 3: Publish a topic -To publish a topic you need to run an instance of a Dapr sidecar to use the pubsub Redis component. You can use the default Redis component installed into your local environment. - -Start an instance of Dapr with an app-id called `testpubsub`: +Start an instance of Dapr with an app-id called `orderprocessing`: ```bash -dapr run --app-id testpubsub --dapr-http-port 3500 +dapr run --app-id orderprocessing --dapr-http-port 3601 ``` {{< tabs "Dapr CLI" "HTTP API (Bash)" "HTTP API (PowerShell)">}} {{% codetab %}} -Then publish a message to the `deathStarStatus` topic: +Then publish a message to the `orders` topic: ```bash -dapr publish --publish-app-id testpubsub --pubsub pubsub --topic deathStarStatus --data '{"status": "completed"}' +dapr publish --publish-app-id orderprocessing --pubsub order_pub_sub --topic orders --data '{"orderId": "100"}' ``` {{% /codetab %}} {{% codetab %}} -Then publish a message to the `deathStarStatus` topic: +Then publish a message to the `orders` topic: ```bash -curl -X POST http://localhost:3500/v1.0/publish/pubsub/deathStarStatus -H "Content-Type: application/json" -d '{"status": "completed"}' +curl -X POST http://localhost:3601/v1.0/publish/order_pub_sub/orders -H "Content-Type: application/json" -d '{"orderId": "100"}' ``` {{% /codetab %}} {{% codetab %}} -Then publish a message to the `deathStarStatus` topic: +Then publish a message to the `orders` topic: ```powershell -Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"status": "completed"}' -Uri 'http://localhost:3500/v1.0/publish/pubsub/deathStarStatus' +Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"orderId": "100"}' -Uri 'http://localhost:3601/v1.0/publish/order_pub_sub/orders' ``` {{% /codetab %}} @@ -389,96 +428,240 @@ Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"status": Dapr automatically wraps the user payload in a Cloud Events v1.0 compliant envelope, using `Content-Type` header value for `datacontenttype` attribute. -## Step 4: ACK-ing a message +Below are code examples that leverage Dapr SDKs to publish a topic. -In order to tell Dapr that a message was processed successfully, return a `200 OK` response. If Dapr receives any other return status code than `200`, or if your app crashes, Dapr will attempt to redeliver the message following At-Least-Once semantics. - -#### Example - -{{< tabs Python Node>}} - -{{% codetab %}} -```python -@app.route('/dsstatus', methods=['POST']) -def ds_subscriber(): - print(request.json, flush=True) - return json.dumps({'success':True}), 200, {'ContentType':'application/json'} -``` -{{% /codetab %}} - -{{% codetab %}} -```javascript -app.post('/dsstatus', (req, res) => { - res.sendStatus(200); -}); -``` -{{% /codetab %}} - -{{< /tabs >}} - -{{% alert title="Note on message redelivery" color="primary" %}} -Some pubsub components (e.g. Redis) will redeliver a message if a response is not sent back within a specified time window. Make sure to configure metadata such as `processingTimeout` to customize this behavior. For more information refer to the respective [component references]({{< ref supported-pubsub >}}). -{{% /alert %}} - -## (Optional) Step 5: Publishing a topic with code - -{{< tabs Node PHP>}} - -{{% codetab %}} -If you prefer publishing a topic using code, here is an example. - -```javascript -const express = require('express'); -const path = require('path'); -const request = require('request'); -const bodyParser = require('body-parser'); - -const app = express(); -app.use(bodyParser.json()); - -const daprPort = process.env.DAPR_HTTP_PORT || 3500; -const daprUrl = `http://localhost:${daprPort}/v1.0`; -const port = 8080; -const pubsubName = 'pubsub'; - -app.post('/publish', (req, res) => { - console.log("Publishing: ", req.body); - const publishUrl = `${daprUrl}/publish/${pubsubName}/deathStarStatus`; - request( { uri: publishUrl, method: 'POST', json: req.body } ); - res.sendStatus(200); -}); - -app.listen(process.env.PORT || port, () => console.log(`Listening on port ${port}!`)); -``` -{{% /codetab %}} +{{< tabs Dotnet Java Python Go Javascript>}} {{% codetab %}} -If you prefer publishing a topic using code, here is an example. +```csharp +//dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; -```php -run(function(\DI\FactoryInterface $factory, \Psr\Log\LoggerInterface $logger) { - $publisher = $factory->make(\Dapr\PubSub\Publish::class, ['pubsub' => 'pubsub']); - $publisher->topic('deathStarStatus')->publish('operational'); - $logger->alert('published!'); -}); +//code +namespace EventService +{ + class Program + { + static async Task Main(string[] args) + { + string PUBSUB_NAME = "order_pub_sub"; + string TOPIC_NAME = "orders"; + while(true) { + System.Threading.Thread.Sleep(5000); + Random random = new Random(); + int orderId = random.Next(1,1000); + CancellationTokenSource source = new CancellationTokenSource(); + CancellationToken cancellationToken = source.Token; + using var client = new DaprClientBuilder().Build(); + //Using Dapr SDK to publish a topic + await client.PublishEventAsync(PUBSUB_NAME, TOPIC_NAME, orderId, cancellationToken); + Console.WriteLine("Published data: " + orderId); + } + } + } +} ``` -You can save this to `app2.php` and while `app1` is running in another terminal, execute: +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: ```bash -dapr --app-id app2 run -- php app2.php +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl dotnet run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```java +//dependencies +import io.dapr.client.DaprClient; +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.domain.Metadata; +import static java.util.Collections.singletonMap; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +//code +@SpringBootApplication +public class OrderProcessingServiceApplication { + + private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); + + public static void main(String[] args) throws InterruptedException{ + String MESSAGE_TTL_IN_SECONDS = "1000"; + String TOPIC_NAME = "orders"; + String PUBSUB_NAME = "order_pub_sub"; + + while(true) { + TimeUnit.MILLISECONDS.sleep(5000); + Random random = new Random(); + int orderId = random.nextInt(1000-1) + 1; + DaprClient client = new DaprClientBuilder().build(); + //Using Dapr SDK to publish a topic + client.publishEvent( + PUBSUB_NAME, + TOPIC_NAME, + orderId, + singletonMap(Metadata.TTL_IN_SECONDS, MESSAGE_TTL_IN_SECONDS)).block(); + log.info("Published data:" + orderId); + } + } +} +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run +``` + +{{% /codetab %}} + +{{% codetab %}} + +```python +#dependencies +import random +from time import sleep +import requests +import logging +import json +from dapr.clients import DaprClient + +#code +logging.basicConfig(level = logging.INFO) +while True: + sleep(random.randrange(50, 5000) / 1000) + orderId = random.randint(1, 1000) + PUBSUB_NAME = 'order_pub_sub' + TOPIC_NAME = 'orders' + with DaprClient() as client: + #Using Dapr SDK to publish a topic + result = client.publish_event( + pubsub_name=PUBSUB_NAME, + topic_name=TOPIC_NAME, + data=json.dumps(orderId), + data_content_type='application/json', + ) + logging.info('Published data: ' + str(orderId)) +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --app-protocol grpc python3 OrderProcessingService.py +``` + +{{% /codetab %}} + +{{% codetab %}} + +```go +//dependencies +import ( + "context" + "log" + "math/rand" + "time" + "strconv" + dapr "github.com/dapr/go-sdk/client" +) + +//code +var ( + PUBSUB_NAME = "order_pub_sub" + TOPIC_NAME = "orders" +) + +func main() { + for i := 0; i < 10; i++ { + time.Sleep(5000) + orderId := rand.Intn(1000-1) + 1 + client, err := dapr.NewClient() + if err != nil { + panic(err) + } + defer client.Close() + ctx := context.Background() + //Using Dapr SDK to publish a topic + if err := client.PublishEvent(ctx, PUBSUB_NAME, TOPIC_NAME, []byte(strconv.Itoa(orderId))); + err != nil { + panic(err) + } + + log.Println("Published data: " + strconv.Itoa(orderId)) + } +} +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go +``` + +{{% /codetab %}} + +{{% codetab %}} + +```javascript +//dependencies +import { DaprServer, DaprClient, CommunicationProtocolEnum } from 'dapr-client'; + +const daprHost = "127.0.0.1"; + +var main = function() { + for(var i=0;i<10;i++) { + sleep(5000); + var orderId = Math.floor(Math.random() * (1000 - 1) + 1); + start(orderId).catch((e) => { + console.error(e); + process.exit(1); + }); + } +} + +async function start(orderId) { + const PUBSUB_NAME = "order_pub_sub" + const TOPIC_NAME = "orders" + const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); + console.log("Published data:" + orderId) + //Using Dapr SDK to publish a topic + await client.pubsub.publish(PUBSUB_NAME, TOPIC_NAME, orderId); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +main(); +``` + +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start ``` {{% /codetab %}} {{< /tabs >}} +## Step 4: ACK-ing a message + +In order to tell Dapr that a message was processed successfully, return a `200 OK` response. If Dapr receives any other return status code than `200`, or if your app crashes, Dapr will attempt to redeliver the message following at-least-once semantics. + ## Sending a custom CloudEvent Dapr automatically takes the data sent on the publish request and wraps it in a CloudEvent 1.0 envelope. @@ -491,23 +674,23 @@ Read about content types [here](#content-types), and about the [Cloud Events mes {{< tabs "Dapr CLI" "HTTP API (Bash)" "HTTP API (PowerShell)">}} {{% codetab %}} -Publish a custom CloudEvent to the `deathStarStatus` topic: +Publish a custom CloudEvent to the `orders` topic: ```bash -dapr publish --publish-app-id testpubsub --pubsub pubsub --topic deathStarStatus --data '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"status": "completed"}}' +dapr publish --publish-app-id orderprocessing --pubsub order_pub_sub --topic orders --data '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"orderId": "100"}}' ``` {{% /codetab %}} {{% codetab %}} -Publish a custom CloudEvent to the `deathStarStatus` topic: +Publish a custom CloudEvent to the `orders` topic: ```bash -curl -X POST http://localhost:3500/v1.0/publish/pubsub/deathStarStatus -H "Content-Type: application/cloudevents+json" -d '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"status": "completed"}}' +curl -X POST http://localhost:3601/v1.0/publish/order_pub_sub/orders -H "Content-Type: application/cloudevents+json" -d '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"orderId": "100"}}' ``` {{% /codetab %}} {{% codetab %}} -Publish a custom CloudEvent to the `deathStarStatus` topic: +Publish a custom CloudEvent to the `orders` topic: ```powershell -Invoke-RestMethod -Method Post -ContentType 'application/cloudevents+json' -Body '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"status": "completed"}}' -Uri 'http://localhost:3500/v1.0/publish/pubsub/deathStarStatus' +Invoke-RestMethod -Method Post -ContentType 'application/cloudevents+json' -Body '{"specversion" : "1.0", "type" : "com.dapr.cloudevent.sent", "source" : "testcloudeventspubsub", "subject" : "Cloud Events Test", "id" : "someCloudEventId", "time" : "2021-08-02T09:00:00Z", "datacontenttype" : "application/cloudevents+json", "data" : {"orderId": "100"}}' -Uri 'http://localhost:3601/v1.0/publish/order_pub_sub/orders' ``` {{% /codetab %}} @@ -521,4 +704,4 @@ Invoke-RestMethod -Method Post -ContentType 'application/cloudevents+json' -Body - Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}}) - Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}}) - List of [pub/sub components]({{< ref setup-pubsub >}}) -- Read the [API reference]({{< ref pubsub_api.md >}}) \ No newline at end of file +- Read the [API reference]({{< ref pubsub_api.md >}}) diff --git a/daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md b/daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md index 73565e055..4ac50cf55 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md +++ b/daprdocs/content/en/developing-applications/building-blocks/secrets/howto-secrets.md @@ -55,7 +55,6 @@ To configure a different kind of secret store see the guidance on [how to config Run the Dapr sidecar with the application. - {{< tabs Dotnet Java Python Go Javascript>}} {{% codetab %}} @@ -110,9 +109,16 @@ Once you have a secret store, call Dapr to get the secrets from your application {{% codetab %}} ```csharp - //dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; +using System.Text.Json; //code namespace EventService @@ -126,54 +132,59 @@ namespace EventService //Using Dapr SDK to get a secret var secret = await client.GetSecretAsync(SECRET_STORE_NAME, "secret"); Console.WriteLine($"Result: {string.Join(", ", secret)}"); - Console.WriteLine($"Result for bulk: {string.Join(", ", secret.Keys)}"); } } } - ``` {{% /codetab %}} {{% codetab %}} ```java - //dependencies +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Map; + //code @SpringBootApplication public class OrderProcessingServiceApplication { - private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); - private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper(); + private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); + private static final ObjectMapper JSON_SERIALIZER = new ObjectMapper(); - private static final String SECRET_STORE_NAME = "localsecretstore"; + private static final String SECRET_STORE_NAME = "localsecretstore"; - public static void main(String[] args) throws InterruptedException, JsonProcessingException { - DaprClient client = new DaprClientBuilder().build(); + public static void main(String[] args) throws InterruptedException, JsonProcessingException { + DaprClient client = new DaprClientBuilder().build(); //Using Dapr SDK to get a secret - Map secret = client.getSecret(SECRET_STORE_NAME, "secret").block(); - log.info("Result: " + JSON_SERIALIZER.writeValueAsString(secret)); - } + Map secret = client.getSecret(SECRET_STORE_NAME, "secret").block(); + log.info("Result: " + JSON_SERIALIZER.writeValueAsString(secret)); + } } - ``` {{% /codetab %}} {{% codetab %}} ```python - #dependencies +import random +from time import sleep +import requests +import logging from dapr.clients import DaprClient from dapr.clients.grpc._state import StateItem from dapr.clients.grpc._request import TransactionalStateOperation, TransactionOperationType #code logging.basicConfig(level = logging.INFO) - DAPR_STORE_NAME = "localsecretstore" key = 'secret' @@ -182,21 +193,21 @@ with DaprClient() as client: secret = client.get_secret(store_name=DAPR_STORE_NAME, key=key) logging.info('Result: ') logging.info(secret.secret) + #Using Dapr SDK to get bulk secrets secret = client.get_bulk_secret(store_name=DAPR_STORE_NAME) logging.info('Result for bulk secret: ') logging.info(sorted(secret.secrets.items())) - ``` {{% /codetab %}} {{% codetab %}} ```go - //dependencies import ( "context" "log" + dapr "github.com/dapr/go-sdk/client" ) @@ -209,35 +220,26 @@ func main() { } defer client.Close() ctx := context.Background() - + //Using Dapr SDK to get a secret secret, err := client.GetSecret(ctx, SECRET_STORE_NAME, "secret", nil) - if err != nil { - return nil, errors.Wrap(err, "Got error for accessing key") - } - if secret != nil { log.Println("Result : ") log.Println(secret) } - - secretRandom, err := client.GetBulkSecret(ctx, SECRET_STORE_NAME, nil) - if err != nil { - return nil, errors.Wrap(err, "Got error for accessing key") - } + //Using Dapr SDK to get bulk secrets + secretBulk, err := client.GetBulkSecret(ctx, SECRET_STORE_NAME, nil) if secret != nil { log.Println("Result for bulk: ") - log.Println(secretRandom) + log.Println(secretBulk) } } - ``` {{% /codetab %}} {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; @@ -247,14 +249,15 @@ const daprHost = "127.0.0.1"; async function main() { const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); const SECRET_STORE_NAME = "localsecretstore"; + //Using Dapr SDK to get a secret var secret = await client.secret.get(SECRET_STORE_NAME, "secret"); console.log("Result: " + secret); + //Using Dapr SDK to get bulk secrets secret = await client.secret.getBulk(SECRET_STORE_NAME); console.log("Result for bulk: " + secret); } main(); - ``` {{% /codetab %}} @@ -267,4 +270,4 @@ main(); - [Configure a secret store]({{}}) - [Supported secrets]({{}}) - [Using secrets in components]({{}}) -- [Secret stores quickstart](https://github.com/dapr/quickstarts/tree/master/secretstore) \ No newline at end of file +- [Secret stores quickstart](https://github.com/dapr/quickstarts/tree/master/secretstore) diff --git a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-discover-services.md b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-discover-services.md index 4f0cb2127..77dd0e386 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-discover-services.md +++ b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-discover-services.md @@ -183,9 +183,15 @@ Below are code examples that leverage Dapr SDKs for service invocation. {{% codetab %}} ```csharp - //dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; //code namespace EventService @@ -194,113 +200,164 @@ namespace EventService { static async Task Main(string[] args) { - int orderId = 100; - CancellationTokenSource source = new CancellationTokenSource(); - CancellationToken cancellationToken = source.Token; - //Using Dapr SDK to invoke a method - using var client = new DaprClientBuilder().Build(); - var result = client.CreateInvokeMethodRequest(HttpMethod.Get, "checkout", "checkout/" + orderId, cancellationToken); - await client.InvokeMethodAsync(result); + while(true) { + System.Threading.Thread.Sleep(5000); + Random random = new Random(); + int orderId = random.Next(1,1000); + CancellationTokenSource source = new CancellationTokenSource(); + CancellationToken cancellationToken = source.Token; + using var client = new DaprClientBuilder().Build(); + //Using Dapr SDK to invoke a method + var result = client.CreateInvokeMethodRequest(HttpMethod.Get, "checkout", "checkout/" + orderId, cancellationToken); + await client.InvokeMethodAsync(result); + Console.WriteLine("Order requested: " + orderId); + Console.WriteLine("Result: " + result); + } } } } - ``` {{% /codetab %}} {{% codetab %}} ```java - //dependencies import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; import io.dapr.client.domain.HttpExtension; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Random; +import java.util.concurrent.TimeUnit; //code @SpringBootApplication public class OrderProcessingServiceApplication { - public static void main(String[] args) throws InterruptedException { - int orderId = 100; - //Using Dapr SDK to invoke a method - DaprClient client = new DaprClientBuilder().build(); - var result = client.invokeMethod( - "checkout", - "checkout/" + orderId, - null, - HttpExtension.GET, - String.class - ); + + private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); + + public static void main(String[] args) throws InterruptedException{ + while(true) { + TimeUnit.MILLISECONDS.sleep(5000); + Random random = new Random(); + int orderId = random.nextInt(1000-1) + 1; + DaprClient daprClient = new DaprClientBuilder().build(); + //Using Dapr SDK to invoke a method + var result = daprClient.invokeMethod( + "checkout", + "checkout/" + orderId, + null, + HttpExtension.GET, + String.class + ); + log.info("Order requested: " + orderId); + log.info("Result: " + result); + } } } - ``` {{% /codetab %}} {{% codetab %}} ```python - #dependencies +import random +from time import sleep +import logging from dapr.clients import DaprClient #code -orderId = 100 -#Using Dapr SDK to invoke a method -with DaprClient() as client: - result = client.invoke_method( - "checkout", - f"checkout/{orderId}", - data=b'', - http_verb="GET" - ) - +logging.basicConfig(level = logging.INFO) +while True: + sleep(random.randrange(50, 5000) / 1000) + orderId = random.randint(1, 1000) + with DaprClient() as daprClient: + #Using Dapr SDK to invoke a method + result = daprClient.invoke_method( + "checkout", + f"checkout/{orderId}", + data=b'', + http_verb="GET" + ) + logging.basicConfig(level = logging.INFO) + logging.info('Order requested: ' + str(orderId)) + logging.info('Result: ' + str(result)) ``` {{% /codetab %}} {{% codetab %}} ```go - //dependencies import ( + "context" + "log" + "math/rand" + "time" "strconv" dapr "github.com/dapr/go-sdk/client" ) //code -func main() { - orderId := 100 - //Using Dapr SDK to invoke a method - client, err := dapr.NewClient() - if err != nil { - panic(err) - } - defer client.Close() - ctx := context.Background() - result, err := client.InvokeMethod(ctx, "checkout", "checkout/" + strconv.Itoa(orderId), "get") +type Order struct { + orderName string + orderNum string } +func main() { + for i := 0; i < 10; i++ { + time.Sleep(5000) + orderId := rand.Intn(1000-1) + 1 + client, err := dapr.NewClient() + if err != nil { + panic(err) + } + defer client.Close() + ctx := context.Background() + //Using Dapr SDK to invoke a method + result, err := client.InvokeMethod(ctx, "checkout", "checkout/" + strconv.Itoa(orderId), "get") + log.Println("Order requested: " + strconv.Itoa(orderId)) + log.Println("Result: ") + log.Println(result) + } +} ``` {{% /codetab %}} {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; //code -const daprHost = "127.0.0.1"; +const daprHost = "127.0.0.1"; var main = function() { - var orderId = 100; - //Using Dapr SDK to invoke a method - const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); - const result = await client.invoker.invoke('checkout' , "checkout/" + orderId , HttpMethod.GET); + for(var i=0;i<10;i++) { + sleep(5000); + var orderId = Math.floor(Math.random() * (1000 - 1) + 1); + start(orderId).catch((e) => { + console.error(e); + process.exit(1); + }); + } +} + +async function start(orderId) { + const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); + //Using Dapr SDK to invoke a method + const result = await client.invoker.invoke('checkoutservice' , "checkout/" + orderId , HttpMethod.GET); + console.log("Order requested: " + orderId); + console.log("Result: " + result); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); } main(); - ``` {{% /codetab %}} diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md index 1684b7ddb..e40eb7995 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md @@ -81,7 +81,15 @@ Below are code examples that leverage Dapr SDKs for saving and retrieving a sing ```csharp //dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; +using System.Text.Json; //code namespace EventService @@ -91,17 +99,20 @@ namespace EventService static async Task Main(string[] args) { string DAPR_STORE_NAME = "statestore"; - - int orderId = 100; - //Using Dapr SDK to save and get state - using var client = new DaprClientBuilder().Build(); - await client.SaveStateAsync(DAPR_STORE_NAME, "order_1", orderId.ToString()); - await client.SaveStateAsync(DAPR_STORE_NAME, "order_2", orderId.ToString()); - var result = await client.GetStateAsync(DAPR_STORE_NAME, orderId.ToString()); + while(true) { + System.Threading.Thread.Sleep(5000); + using var client = new DaprClientBuilder().Build(); + Random random = new Random(); + int orderId = random.Next(1,1000); + //Using Dapr SDK to save and get state + await client.SaveStateAsync(DAPR_STORE_NAME, "order_1", orderId.ToString()); + await client.SaveStateAsync(DAPR_STORE_NAME, "order_2", orderId.ToString()); + var result = await client.GetStateAsync(DAPR_STORE_NAME, orderId.ToString()); + Console.WriteLine("Result after get: " + result); + } } } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -116,12 +127,17 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```java - //dependencies import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; import io.dapr.client.domain.State; +import io.dapr.client.domain.TransactionalStateOperation; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; +import java.util.Random; +import java.util.concurrent.TimeUnit; //code @SpringBootApplication @@ -129,18 +145,23 @@ public class OrderProcessingServiceApplication { private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); - public static void main(String[] args) throws InterruptedException { - String STATE_STORE_NAME = "statestore"; + private static final String STATE_STORE_NAME = "statestore"; - int orderId = 100; - //Using Dapr SDK to save and get state - DaprClient client = new DaprClientBuilder().build(); - client.saveState(STATE_STORE_NAME, "order_1", Integer.toString(orderId)).block(); - client.saveState(STATE_STORE_NAME, "order_2", Integer.toString(orderId)).block(); - Mono> result = client.getState(STATE_STORE_NAME, "order_1", String.class); + public static void main(String[] args) throws InterruptedException{ + while(true) { + TimeUnit.MILLISECONDS.sleep(5000); + Random random = new Random(); + int orderId = random.nextInt(1000-1) + 1; + DaprClient client = new DaprClientBuilder().build(); + //Using Dapr SDK to save and get state + client.saveState(STATE_STORE_NAME, "order_1", Integer.toString(orderId)).block(); + client.saveState(STATE_STORE_NAME, "order_2", Integer.toString(orderId)).block(); + Mono> result = client.getState(STATE_STORE_NAME, "order_1", String.class); + log.info("Result after get" + result); + } } -} +} ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -155,22 +176,26 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```python - #dependencies +import random +from time import sleep +import requests +import logging from dapr.clients import DaprClient +from dapr.clients.grpc._state import StateItem +from dapr.clients.grpc._request import TransactionalStateOperation, TransactionOperationType #code logging.basicConfig(level = logging.INFO) - DAPR_STORE_NAME = "statestore" - -orderId = 100 -#Using Dapr SDK to save and get state -with DaprClient() as client: - client.save_state(DAPR_STORE_NAME, "order_1", str(orderId)) - result = client.get_state(DAPR_STORE_NAME, "order_1") - logging.info('Result after get: ' + str(result)) - +while True: + sleep(random.randrange(50, 5000) / 1000) + orderId = random.randint(1, 1000) + with DaprClient() as client: + #Using Dapr SDK to save and get state + client.save_state(DAPR_STORE_NAME, "order_1", str(orderId)) + result = client.get_state(DAPR_STORE_NAME, "order_1") + logging.info('Result after get: ' + result.data.decode('utf-8')) ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -185,7 +210,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```go - //dependencies import ( "context" @@ -194,34 +218,32 @@ import ( "time" "strconv" dapr "github.com/dapr/go-sdk/client" - ) //code func main() { - - STATE_STORE_NAME := "statestore" - - orderId := 100 - - //Using Dapr SDK to save and get state - client, err := dapr.NewClient() - if err != nil { - panic(err) - } - defer client.Close() - ctx := context.Background() - - if err := client.SaveState(ctx, STATE_STORE_NAME, "order_1", []byte(strconv.Itoa(orderId))); err != nil { - panic(err) - } - - result, err := client.GetState(ctx, STATE_STORE_NAME, "order_1") - if err != nil { - panic(err) - } + for i := 0; i < 10; i++ { + time.Sleep(5000) + orderId := rand.Intn(1000-1) + 1 + client, err := dapr.NewClient() + STATE_STORE_NAME := "statestore" + if err != nil { + panic(err) + } + defer client.Close() + ctx := context.Background() + //Using Dapr SDK to save and get state + if err := client.SaveState(ctx, STATE_STORE_NAME, "order_1", []byte(strconv.Itoa(orderId))); err != nil { + panic(err) + } + result, err := client.GetState(ctx, STATE_STORE_NAME, "order_2") + if err != nil { + panic(err) + } + log.Println("Result after get: ") + log.Println(result) + } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -236,19 +258,26 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; //code const daprHost = "127.0.0.1"; - var main = function() { - const STATE_STORE_NAME = "statestore"; + for(var i=0;i<10;i++) { + sleep(5000); + var orderId = Math.floor(Math.random() * (1000 - 1) + 1); + start(orderId).catch((e) => { + console.error(e); + process.exit(1); + }); + } +} - var orderId = 100; - //Using Dapr SDK to save and get state +async function start(orderId) { const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); + const STATE_STORE_NAME = "statestore"; + //Using Dapr SDK to save and get state await client.state.save(STATE_STORE_NAME, [ { key: "order_1", @@ -260,10 +289,14 @@ var main = function() { } ]); var result = await client.state.get(STATE_STORE_NAME, "order_1"); + console.log("Result after get: " + result); +} + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); } main(); - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -329,7 +362,6 @@ Below are code examples that leverage Dapr SDKs for deleting the state. {{% codetab %}} ```csharp - //dependencies using Dapr.Client; @@ -347,7 +379,6 @@ namespace EventService } } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -362,10 +393,10 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```java - //dependencies import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; +import org.springframework.boot.autoconfigure.SpringBootApplication; //code @SpringBootApplication @@ -379,7 +410,6 @@ public class OrderProcessingServiceApplication { client.deleteState(STATE_STORE_NAME, "order_1", storedEtag, null).block(); } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -394,19 +424,16 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```python - #dependencies from dapr.clients.grpc._request import TransactionalStateOperation, TransactionOperationType #code logging.basicConfig(level = logging.INFO) - DAPR_STORE_NAME = "statestore" #Using Dapr SDK to delete the state with DaprClient() as client: client.delete_state(store_name=DAPR_STORE_NAME, key="order_1") - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -421,7 +448,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```go - //dependencies import ( "context" @@ -431,9 +457,7 @@ import ( //code func main() { - STATE_STORE_NAME := "statestore" - //Using Dapr SDK to delete the state client, err := dapr.NewClient() if err != nil { @@ -446,7 +470,6 @@ func main() { panic(err) } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -461,23 +484,19 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; //code const daprHost = "127.0.0.1"; - var main = function() { const STATE_STORE_NAME = "statestore"; - //Using Dapr SDK to save and get state const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); await client.state.delete(STATE_STORE_NAME, "order_1"); } main(); - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -515,11 +534,11 @@ Below are code examples that leverage Dapr SDKs for saving and retrieving multip {{% codetab %}} ```java - //dependencies import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; import io.dapr.client.domain.State; +import java.util.Arrays; //code @SpringBootApplication @@ -529,15 +548,12 @@ public class OrderProcessingServiceApplication { public static void main(String[] args) throws InterruptedException{ String STATE_STORE_NAME = "statestore"; - - int orderId = 100; //Using Dapr SDK to retrieve multiple states DaprClient client = new DaprClientBuilder().build(); Mono>> resultBulk = client.getBulkState(STATE_STORE_NAME, Arrays.asList("order_1", "order_2"), String.class); } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -548,27 +564,22 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% /codetab %}} - {{% codetab %}} ```python - #dependencies from dapr.clients import DaprClient from dapr.clients.grpc._state import StateItem #code logging.basicConfig(level = logging.INFO) - DAPR_STORE_NAME = "statestore" - orderId = 100 #Using Dapr SDK to save and retrieve multiple states with DaprClient() as client: client.save_bulk_state(store_name=DAPR_STORE_NAME, states=[StateItem(key="order_2", value=str(orderId))]) result = client.get_bulk_state(store_name=DAPR_STORE_NAME, keys=["order_1", "order_2"], states_metadata={"metakey": "metavalue"}).items logging.info('Result after get bulk: ' + str(result)) - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -579,21 +590,16 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% /codetab %}} - - {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; //code const daprHost = "127.0.0.1"; - var main = function() { const STATE_STORE_NAME = "statestore"; - var orderId = 100; //Using Dapr SDK to save and retrieve multiple states const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); @@ -611,7 +617,6 @@ var main = function() { } main(); - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -662,9 +667,16 @@ Below are code examples that leverage Dapr SDKs for performing state transaction {{% codetab %}} ```csharp - //dependencies +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Dapr.Client; +using Microsoft.AspNetCore.Mvc; +using System.Threading; +using System.Text.Json; //code namespace EventService @@ -674,22 +686,26 @@ namespace EventService static async Task Main(string[] args) { string DAPR_STORE_NAME = "statestore"; - - int orderId = 100; - //Using Dapr SDK to perform the state transactions - using var client = new DaprClientBuilder().Build(); - var requests = new List() - { - new StateTransactionRequest("order_3", JsonSerializer.SerializeToUtf8Bytes(orderId.ToString()), StateOperationType.Upsert), - new StateTransactionRequest("order_2", null, StateOperationType.Delete) - }; - CancellationTokenSource source = new CancellationTokenSource(); - CancellationToken cancellationToken = source.Token; - await client.ExecuteStateTransactionAsync(DAPR_STORE_NAME, requests, cancellationToken: cancellationToken); + while(true) { + System.Threading.Thread.Sleep(5000); + Random random = new Random(); + int orderId = random.Next(1,1000); + using var client = new DaprClientBuilder().Build(); + var requests = new List() + { + new StateTransactionRequest("order_3", JsonSerializer.SerializeToUtf8Bytes(orderId.ToString()), StateOperationType.Upsert), + new StateTransactionRequest("order_2", null, StateOperationType.Delete) + }; + CancellationTokenSource source = new CancellationTokenSource(); + CancellationToken cancellationToken = source.Token; + //Using Dapr SDK to perform the state transactions + await client.ExecuteStateTransactionAsync(DAPR_STORE_NAME, requests, cancellationToken: cancellationToken); + Console.WriteLine("Order requested: " + orderId); + Console.WriteLine("Result: " + result); + } } } } - ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -704,13 +720,19 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```java - //dependencies import io.dapr.client.DaprClient; import io.dapr.client.DaprClientBuilder; import io.dapr.client.domain.State; import io.dapr.client.domain.TransactionalStateOperation; - +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; //code @SpringBootApplication @@ -718,21 +740,26 @@ public class OrderProcessingServiceApplication { private static final Logger log = LoggerFactory.getLogger(OrderProcessingServiceApplication.class); + private static final String STATE_STORE_NAME = "statestore"; + public static void main(String[] args) throws InterruptedException{ - String STATE_STORE_NAME = "statestore"; - - int orderId = 100; - //Using Dapr SDK to perform the state transactions - DaprClient client = new DaprClientBuilder().build(); - List> operationList = new ArrayList<>(); - operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.UPSERT, - new State<>("order_3", Integer.toString(orderId), ""))); - operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.DELETE, - new State<>("order_2"))); - client.executeStateTransaction(STATE_STORE_NAME, operationList).block(); + while(true) { + TimeUnit.MILLISECONDS.sleep(5000); + Random random = new Random(); + int orderId = random.nextInt(1000-1) + 1; + DaprClient client = new DaprClientBuilder().build(); + List> operationList = new ArrayList<>(); + operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.UPSERT, + new State<>("order_3", Integer.toString(orderId), ""))); + operationList.add(new TransactionalStateOperation<>(TransactionalStateOperation.OperationType.DELETE, + new State<>("order_2"))); + //Using Dapr SDK to perform the state transactions + client.executeStateTransaction(STATE_STORE_NAME, operationList).block(); + log.info("Order requested: " + orderId); + } } -} +} ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -743,37 +770,42 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% /codetab %}} - {{% codetab %}} - ```python - #dependencies +import random +from time import sleep +import requests +import logging from dapr.clients import DaprClient from dapr.clients.grpc._state import StateItem from dapr.clients.grpc._request import TransactionalStateOperation, TransactionOperationType #code -logging.basicConfig(level = logging.INFO) - +logging.basicConfig(level = logging.INFO) DAPR_STORE_NAME = "statestore" +while True: + sleep(random.randrange(50, 5000) / 1000) + orderId = random.randint(1, 1000) + with DaprClient() as client: + #Using Dapr SDK to perform the state transactions + client.execute_state_transaction(store_name=DAPR_STORE_NAME, operations=[ + TransactionalStateOperation( + operation_type=TransactionOperationType.upsert, + key="order_3", + data=str(orderId)), + TransactionalStateOperation(key="order_3", data=str(orderId)), + TransactionalStateOperation( + operation_type=TransactionOperationType.delete, + key="order_2", + data=str(orderId)), + TransactionalStateOperation(key="order_2", data=str(orderId)) + ]) -orderId = 100 -#Using Dapr SDK to perform the state transactions -with DaprClient() as client: - client.execute_state_transaction(store_name=DAPR_STORE_NAME, operations=[ - TransactionalStateOperation( - operation_type=TransactionOperationType.upsert, - key="order_3", - data=str(orderId)), - TransactionalStateOperation(key="order_3", data=str(orderId)), - TransactionalStateOperation( - operation_type=TransactionOperationType.delete, - key="order_2", - data=str(orderId)), - TransactionalStateOperation(key="order_2", data=str(orderId)) - ]) - + client.delete_state(store_name=DAPR_STORE_NAME, key="order_1") + logging.basicConfig(level = logging.INFO) + logging.info('Order requested: ' + str(orderId)) + logging.info('Result: ' + str(result)) ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: @@ -788,38 +820,48 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g {{% codetab %}} ```javascript - //dependencies import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client'; //code const daprHost = "127.0.0.1"; - var main = function() { - const STATE_STORE_NAME = "statestore"; + for(var i=0;i<10;i++) { + sleep(5000); + var orderId = Math.floor(Math.random() * (1000 - 1) + 1); + start(orderId).catch((e) => { + console.error(e); + process.exit(1); + }); + } +} - var orderId = 100; - //Using Dapr SDK to save and retrieve multiple states +async function start(orderId) { const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT, CommunicationProtocolEnum.HTTP); + const STATE_STORE_NAME = "statestore"; + //Using Dapr SDK to save and retrieve multiple states await client.state.transaction(STATE_STORE_NAME, [ { - operation: "upsert", - request: { - key: "order_3", - value: orderId.toString() - } + operation: "upsert", + request: { + key: "order_3", + value: orderId.toString() + } }, { - operation: "delete", - request: { - key: "order_2" - } + operation: "delete", + request: { + key: "order_2" + } } ]); } -main(); +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} +main(); ``` Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: diff --git a/daprdocs/content/en/developing-applications/integrations/autoscale-keda.md b/daprdocs/content/en/developing-applications/integrations/autoscale-keda.md index e6fd74149..7e685010f 100644 --- a/daprdocs/content/en/developing-applications/integrations/autoscale-keda.md +++ b/daprdocs/content/en/developing-applications/integrations/autoscale-keda.md @@ -6,7 +6,7 @@ description: "How to configure your Dapr application to autoscale using KEDA" weight: 2000 --- -Dapr, with its modular building-block approach, along with the 10+ different [pub/sub components]({{< ref pubsub >}}), make it easy to write message processing applications. Since Dapr can run in many environments (e.g. VM, bare-metal, Cloud, or Edge) the autoscaling of Dapr applications is managed by the hosting later. +Dapr, with its modular building-block approach, along with the 10+ different [pub/sub components]({{< ref pubsub >}}), make it easy to write message processing applications. Since Dapr can run in many environments (e.g. VM, bare-metal, Cloud, or Edge) the autoscaling of Dapr applications is managed by the hosting layer. For Kubernetes, Dapr integrates with [KEDA](https://github.com/kedacore/keda), an event driven autoscaler for Kubernetes. Many of Dapr's pub/sub components overlap with the scalers provided by [KEDA](https://github.com/kedacore/keda) so it's easy to configure your Dapr deployment on Kubernetes to autoscale based on the back pressure using KEDA. diff --git a/daprdocs/content/en/getting-started/quickstarts.md b/daprdocs/content/en/getting-started/quickstarts.md index bfb892117..de6a3313c 100644 --- a/daprdocs/content/en/getting-started/quickstarts.md +++ b/daprdocs/content/en/getting-started/quickstarts.md @@ -6,7 +6,7 @@ weight: 60 description: "Tutorials with code samples that are aimed to get you started quickly with Dapr" --- -The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.0.0) are a collection of tutorials with code samples that are aimed to get you started quickly with Dapr, each highlighting a different Dapr capability. +The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.5.0) are a collection of tutorials with code samples that are aimed to get you started quickly with Dapr, each highlighting a different Dapr capability. - A good place to start is the hello-world quickstart, it demonstrates how to run Dapr in standalone mode locally on your machine and demonstrates state management and service invocation in a simple application. - Next, if you are familiar with Kubernetes and want to see how to run the same application in a Kubernetes environment, look for the hello-kubernetes quickstart. Other quickstarts such as pub-sub, bindings and the distributed-calculator quickstart explore different Dapr capabilities include instructions for running both locally and on Kubernetes and can be completed in any order. A full list of the quickstarts can be found below. @@ -17,12 +17,12 @@ The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.0.0) are a co | Quickstart | Description | |--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Hello World](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. | -| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.4.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. | -| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.4.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. | -| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.4.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. | -| [Bindings](https://github.com/dapr/quickstarts/tree/v1.4.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. | -| [Middleware](https://github.com/dapr/quickstarts/tree/v1.4.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. | -| [Observability](https://github.com/dapr/quickstarts/tree/v1.4.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. | -| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.4.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. | +| [Hello World](https://github.com/dapr/quickstarts/tree/v1.5.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. | +| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.5.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. | +| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.5.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. | +| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.5.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. | +| [Bindings](https://github.com/dapr/quickstarts/tree/v1.5.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. | +| [Middleware](https://github.com/dapr/quickstarts/tree/v1.5.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. | +| [Observability](https://github.com/dapr/quickstarts/tree/v1.5.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. | +| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.5.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. | diff --git a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md index 44a453649..e4e6b4903 100644 --- a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md +++ b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md @@ -83,7 +83,7 @@ spec: #### Production -Jaeger uses Elasticsearch as the backend storage, and you can create a secret in k8s cluster to access Elasticsearch server with access control. See [Configuring and Deploying Jaeger](https://docs.openshift.com/container-platform/4.7/jaeger/jaeger_install/rhbjaeger-deploying.html) +Jaeger uses Elasticsearch as the backend storage, and you can create a secret in k8s cluster to access Elasticsearch server with access control. See [Configuring and Deploying Jaeger](https://docs.openshift.com/container-platform/4.9/distr_tracing/distr_tracing_install/distr-tracing-deploying.html) ```shell kubectl create secret generic jaeger-secret --from-literal=ES_PASSWORD='xxx' --from-literal=ES_USERNAME='xxx' -n ${NAMESPACE} diff --git a/daprdocs/content/en/operations/security/oauth.md b/daprdocs/content/en/operations/security/oauth.md index 5fedd524d..ef663cbff 100644 --- a/daprdocs/content/en/operations/security/oauth.md +++ b/daprdocs/content/en/operations/security/oauth.md @@ -34,12 +34,14 @@ To figure the Dapr OAuth middleware, you'll need to collect the following inform Authorization/Token URLs of some of the popular authorization servers: + | Server | Authorization URL | Token URL | |---------|-------------------|-----------| |Azure AAD||| |GitHub||| |Google|| | |Twitter||| + ## Define the middleware component definition diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 318036117..6bd27c761 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -45,7 +45,9 @@ The table below shows the versions of Dapr releases that have been tested togeth | Sep 22nd 2021 | 1.4.1
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | Sep 24th 2021 | 1.4.2
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | | Oct 7th 2021 | 1.4.3
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | -| Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported (current) | +| Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | +| Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported (current) | +| Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported (current) | ## Upgrade paths After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1 @@ -59,23 +61,22 @@ General guidance on upgrading can be found for [self hosted mode]({{}}) +* [How to setup logging in Dapr]({{< ref "logging.md" >}}) diff --git a/daprdocs/content/en/reference/api/service_invocation_api.md b/daprdocs/content/en/reference/api/service_invocation_api.md index 94888067b..15de82351 100644 --- a/daprdocs/content/en/reference/api/service_invocation_api.md +++ b/daprdocs/content/en/reference/api/service_invocation_api.md @@ -16,7 +16,7 @@ This endpoint lets you invoke a method in another Dapr enabled app. ### HTTP Request ``` -POST/GET/PUT/DELETE http://localhost:/v1.0/invoke//method/ +PATCH/POST/GET/PUT/DELETE http://localhost:/v1.0/invoke//method/ ``` ### HTTP Response codes diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/s3.md b/daprdocs/content/en/reference/components-reference/supported-bindings/s3.md index b48aa37d2..68754b50a 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/s3.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/s3.md @@ -27,6 +27,8 @@ spec: value: mybucket - name: region value: us-west-2 + - name: endpoint + value: s3-us-west-2.amazonaws.com - name: accessKey value: ***************** - name: secretKey @@ -37,6 +39,8 @@ spec: value: - name: encodeBase64 value: + - name: forcePathStyle + value: ``` {{% alert title="Warning" color="warning" %}} @@ -49,9 +53,11 @@ The above example uses secrets as plain strings. It is recommended to use a secr |--------------------|:--------:|------------|-----|---------| | bucket | Y | Output | The name of the S3 bucket to write to | `"bucket"` | | region | Y | Output | The specific AWS region | `"us-east-1"` | +| endpoint | N | Output | The specific AWS endpoint | `"s3-us-east-1.amazonaws.com"` | | accessKey | Y | Output | The AWS Access Key to access this resource | `"key"` | | secretKey | Y | Output | The AWS Secret Access Key to access this resource | `"secretAccessKey"` | | sessionToken | N | Output | The AWS session token to use | `"sessionToken"` | +| forcePathStyle | N | Output | Currently Amazon S3 SDK supports virtual hosted-style and path-style access. `true` is path-style format like `https:////`. `false` is hosted-style format like `https://./`. Defaults to `false` | `true`, `false` | | decodeBase64 | N | Output | Configuration to decode base64 file content before saving to bucket storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` | | encodeBase64 | N | Output | Configuration to encode base64 file content before return the content. (In case of opening a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` | @@ -136,6 +142,8 @@ spec: value: mybucket - name: region value: us-west-2 + - name: endpoint + value: s3-us-west-2.amazonaws.com - name: accessKey value: ***************** - name: secretKey @@ -144,6 +152,8 @@ spec: value: mysession - name: decodeBase64 value: + - name: forcePathStyle + value: ``` Then you can upload it as you would normally: diff --git a/daprdocs/layouts/shortcodes/dapr-latest-version.html b/daprdocs/layouts/shortcodes/dapr-latest-version.html index 60da16a51..77638b68f 100644 --- a/daprdocs/layouts/shortcodes/dapr-latest-version.html +++ b/daprdocs/layouts/shortcodes/dapr-latest-version.html @@ -1 +1 @@ -{{- if .Get "short" }}1.5{{ else if .Get "long" }}1.5.0{{ else if .Get "cli" }}1.5.0{{ else }}1.5.0{{ end -}} +{{- if .Get "short" }}1.5{{ else if .Get "long" }}1.5.1{{ else if .Get "cli" }}1.5.1{{ else }}1.5.1{{ end -}} diff --git a/daprdocs/static/images/building-block-input-binding-example.png b/daprdocs/static/images/building-block-input-binding-example.png new file mode 100644 index 0000000000000000000000000000000000000000..408c373786918a32c28bfd2005d5894b630b8162 GIT binary patch literal 88366 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

tM@)75JskdWj~tbSGCM0^uyW_V(3A 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 PfPbc^El-u7bdUQ#)hN`t literal 0 HcmV?d00001 diff --git a/daprdocs/static/images/building-block-output-binding-example.png b/daprdocs/static/images/building-block-output-binding-example.png new file mode 100644 index 0000000000000000000000000000000000000000..ac114b4bd1251e6b8be90b70ad4babd275b28ba1 GIT binary patch literal 95677 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

@HpLe&nH( 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 E0aH9l9smFU literal 0 HcmV?d00001 diff --git a/daprdocs/static/images/building-block-pub-sub-example.png b/daprdocs/static/images/building-block-pub-sub-example.png new file mode 100644 index 0000000000000000000000000000000000000000..4ffe87ce4b8715c8991df5849ec82705240bad7e GIT binary patch literal 171404 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%0AaP|%Z$c=;O`#^78K85G_=*Hh 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⩔UlA9F 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 z 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�bj!Os1%tK1LYJrr^&eoo)Y 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 Date: Tue, 28 Dec 2021 16:50:48 -0800 Subject: [PATCH 06/73] statestore query api: simplify query JSON (#2061) Signed-off-by: Dmitry Shmulevich --- .../state-management/howto-state-query-api.md | 142 +++++++++--------- .../query-api-examples/query1.json | 20 ++- .../query-api-examples/query2.json | 6 +- .../query-api-examples/query3-token.json | 50 +++--- .../query-api-examples/query3.json | 48 +++--- .../content/en/reference/api/state_api.md | 48 +++--- 6 files changed, 155 insertions(+), 159 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md index 011d8a7d8..b0e4a040c 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md @@ -25,7 +25,7 @@ You can find additional information in the [related links]({{< ref "#related-lin ## Querying the state You submit query requests via HTTP POST/PUT or gRPC. -The body of the request is the JSON map with 3 entries: `filter`, `sort`, and `pagination`. +The body of the request is the JSON map with 3 entries: `filter`, `sort`, and `page`. The `filter` is an optional section. It specifies the query conditions in the form of a tree of key/value operations, where the key is the operator and the value is the operands. @@ -42,7 +42,7 @@ If `filter` section is omitted, the query returns all entries. The `sort` is an optional section and is an ordered array of `key:order` pairs, where `key` is a key in the state store, and the `order` is an optional string indicating sorting order: `"ASC"` for ascending and `"DESC"` for descending. If omitted, ascending order is the default. -The `pagination` is an optional section containing `limit` and `token` parameters. `limit` sets the page size. `token` is an iteration token returned by the component, and is used in subsequent queries. +The `page` is an optional section containing `limit` and `token` parameters. `limit` sets the page size. `token` is an iteration token returned by the component, and is used in subsequent queries. For some background understanding, this query request is translated into the native query language and executed by the state store component. @@ -87,17 +87,15 @@ First, let's find all employees in the state of California and sort them by thei This is the [query](../query-api-examples/query1.json): ```json { - "query": { - "filter": { - "EQ": { "value.state": "CA" } - }, - "sort": [ - { - "key": "value.person.id", - "order": "DESC" - } - ] - } + "filter": { + "EQ": { "value.state": "CA" } + }, + "sort": [ + { + "key": "value.person.id", + "order": "DESC" + } + ] } ``` @@ -186,10 +184,8 @@ Let's now find all employees from the "Dev Ops" and "Hardware" organizations. This is the [query](../query-api-examples/query2.json): ```json { - "query": { - "filter": { - "IN": { "value.person.org": [ "Dev Ops", "Hardware" ] } - } + "filter": { + "IN": { "value.person.org": [ "Dev Ops", "Hardware" ] } } } ``` @@ -228,36 +224,34 @@ This is the [query](../query-api-examples/query3.json): ```json { - "query": { - "filter": { - "OR": [ - { - "EQ": { "value.person.org": "Dev Ops" } - }, - { - "AND": [ - { - "EQ": { "value.person.org": "Finance" } - }, - { - "IN": { "value.state": [ "CA", "WA" ] } - } - ] - } - ] - }, - "sort": [ + "filter": { + "OR": [ { - "key": "value.state", - "order": "DESC" + "EQ": { "value.person.org": "Dev Ops" } }, { - "key": "value.person.id" + "AND": [ + { + "EQ": { "value.person.org": "Finance" } + }, + { + "IN": { "value.state": [ "CA", "WA" ] } + } + ] } - ], - "pagination": { - "limit": 3 + ] + }, + "sort": [ + { + "key": "value.state", + "order": "DESC" + }, + { + "key": "value.person.id" } + ], + "page": { + "limit": 3 } } ``` @@ -336,40 +330,52 @@ The pagination token is used "as is" in the [subsequent query](../query-api-exam ```json { - "query": { - "filter": { - "OR": [ - { - "EQ": { "value.person.org": "Dev Ops" } - }, - { - "AND": [ - { - "EQ": { "value.person.org": "Finance" } - }, - { - "IN": { "value.state": [ "CA", "WA" ] } - } - ] - } - ] - }, - "sort": [ + "filter": { + "OR": [ { - "key": "value.state", - "order": "DESC" + "EQ": { "value.person.org": "Dev Ops" } }, { - "key": "value.person.id" + "AND": [ + { + "EQ": { "value.person.org": "Finance" } + }, + { + "IN": { "value.state": [ "CA", "WA" ] } + } + ] } - ], - "pagination": { - "limit": 3, - "token": "3" + ] + }, + "sort": [ + { + "key": "value.state", + "order": "DESC" + }, + { + "key": "value.person.id" } + ], + "page": { + "limit": 3, + "token": "3" } } ``` + +{{< tabs "HTTP API (Bash)" "HTTP API (PowerShell)" >}} +{{% codetab %}} +```bash +curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query3-token.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq . +``` +{{% /codetab %}} +{{% codetab %}} +```powershell +Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query3-token.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query' +``` +{{% /codetab %}} +{{< /tabs >}} + And the result of this query is: ```json { diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query1.json b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query1.json index 816246e90..ada5369e8 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query1.json +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query1.json @@ -1,13 +1,11 @@ { - "query": { - "filter": { - "EQ": { "value.state": "CA" } - }, - "sort": [ - { - "key": "value.person.id", - "order": "DESC" - } - ] - } + "filter": { + "EQ": { "value.state": "CA" } + }, + "sort": [ + { + "key": "value.person.id", + "order": "DESC" + } + ] } diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query2.json b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query2.json index 47f3be7b4..e66e566c2 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query2.json +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query2.json @@ -1,7 +1,5 @@ { - "query": { - "filter": { - "IN": { "value.person.org": [ "Dev Ops", "Hardware" ] } - } + "filter": { + "IN": { "value.person.org": [ "Dev Ops", "Hardware" ] } } } diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3-token.json b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3-token.json index 3506d6445..87a2e5582 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3-token.json +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3-token.json @@ -1,34 +1,32 @@ { - "query": { - "filter": { - "OR": [ - { - "EQ": { "value.person.org": "Dev Ops" } - }, - { - "AND": [ - { - "EQ": { "value.person.org": "Finance" } - }, - { - "IN": { "value.state": [ "CA", "WA" ] } - } - ] - } - ] - }, - "sort": [ + "filter": { + "OR": [ { - "key": "value.state", - "order": "DESC" + "EQ": { "value.person.org": "Dev Ops" } }, { - "key": "value.person.id" + "AND": [ + { + "EQ": { "value.person.org": "Finance" } + }, + { + "IN": { "value.state": [ "CA", "WA" ] } + } + ] } - ], - "pagination": { - "limit": 3, - "token": "3" + ] + }, + "sort": [ + { + "key": "value.state", + "order": "DESC" + }, + { + "key": "value.person.id" } + ], + "page": { + "limit": 3, + "token": "3" } } diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3.json b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3.json index 3621acd5d..5a8b7ff1c 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3.json +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/query-api-examples/query3.json @@ -1,33 +1,31 @@ { - "query": { - "filter": { - "OR": [ - { - "EQ": { "value.person.org": "Dev Ops" } - }, - { - "AND": [ - { - "EQ": { "value.person.org": "Finance" } - }, - { - "IN": { "value.state": [ "CA", "WA" ] } - } - ] - } - ] - }, - "sort": [ + "filter": { + "OR": [ { - "key": "value.state", - "order": "DESC" + "EQ": { "value.person.org": "Dev Ops" } }, { - "key": "value.person.id" + "AND": [ + { + "EQ": { "value.person.org": "Finance" } + }, + { + "IN": { "value.state": [ "CA", "WA" ] } + } + ] } - ], - "pagination": { - "limit": 3 + ] + }, + "sort": [ + { + "key": "value.state", + "order": "DESC" + }, + { + "key": "value.person.id" } + ], + "page": { + "limit": 3 } } diff --git a/daprdocs/content/en/reference/api/state_api.md b/daprdocs/content/en/reference/api/state_api.md index e0df6724b..7068a92c3 100644 --- a/daprdocs/content/en/reference/api/state_api.md +++ b/daprdocs/content/en/reference/api/state_api.md @@ -333,36 +333,34 @@ An array of JSON-encoded values curl http://localhost:3500/v1.0-alpha1/state/myStore/query \ -H "Content-Type: application/json" \ -d '{ - "query": { - "filter": { - "OR": [ - { - "EQ": { "value.person.org": "Dev Ops" } - }, - { - "AND": [ - { - "EQ": { "value.person.org": "Finance" } - }, - { - "IN": { "value.state": [ "CA", "WA" ] } - } - ] - } - ] - }, - "sort": [ + "filter": { + "OR": [ { - "key": "value.state", - "order": "DESC" + "EQ": { "value.person.org": "Dev Ops" } }, { - "key": "value.person.id" + "AND": [ + { + "EQ": { "value.person.org": "Finance" } + }, + { + "IN": { "value.state": [ "CA", "WA" ] } + } + ] } - ], - "pagination": { - "limit": 3 + ] + }, + "sort": [ + { + "key": "value.state", + "order": "DESC" + }, + { + "key": "value.person.id" } + ], + "page": { + "limit": 3 } }' ``` From 3d4e97d4fdbe9501e01840711576cd6f699084a6 Mon Sep 17 00:00:00 2001 From: Dmitry Shmulevich Date: Tue, 28 Dec 2021 16:06:29 -0800 Subject: [PATCH 07/73] updated RabbitMQ Pub/Sub status Signed-off-by: Dmitry Shmulevich --- .../supported-pubsub/_index.md | 2 +- .../supported-pubsub/setup-rabbitmq.md | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md index dea6d87a3..6b452ba13 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md @@ -29,7 +29,7 @@ Table captions: | [In Memory]({{< ref setup-inmemory.md >}}) | Alpha | v1 | 1.4 | | [JetStream]({{< ref setup-jetstream.md >}}) | Alpha | v1 | 1.4 | | [Pulsar]({{< ref setup-pulsar.md >}}) | Alpha | v1 | 1.0 | -| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Alpha | v1 | 1.0 | +| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Stable | v1 | 1.6 | | [Redis Streams]({{< ref setup-redis-pubsub.md >}}) | Stable | v1 | 1.0 | ### Amazon Web Services (AWS) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md index ad0c1c040..17b2bcadb 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md @@ -21,34 +21,36 @@ spec: metadata: - name: host value: "amqp://localhost:5672" + - name: consumerID + value: myapp - name: durable - value: "false" + value: false - name: deletedWhenUnused - value: "false" + value: false - name: autoAck - value: "false" + value: false - name: deliveryMode - value: "0" + value: 0 - name: requeueInFailure - value: "false" + value: false - name: prefetchCount - value: "0" + value: 0 - name: reconnectWait - value: "0" + value: 0 - name: concurrencyMode value: parallel - name: backOffPolicy - value: "exponential" + value: exponential - name: backOffInitialInterval - value: "100" + value: 100 - name: backOffMaxRetries - value: "16" + value: 16 - name: enableDeadLetter # Optional enable dead Letter or not - value: "true" + value: true - name: maxLen # Optional max message count in a queue - value: "3000" + value: 3000 - name: maxLenBytes # Optional maximum length in bytes of a queue. - value: "10485760" + value: 10485760 ``` {{% alert title="Warning" color="warning" %}} The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}). @@ -59,6 +61,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| | host | Y | Connection-string for the rabbitmq host | `amqp://user:pass@localhost:5672` +| consumerID | N | Consumer ID a.k.a consumer tag organizes one or more consumers into a group. Consumers with the same consumer ID work as one visrtual consumer, i.e. a message is processed only once by one of the consumers in the group. If the consumer ID is not set, dapr runtime will set it to the dapr application ID | | durable | N | Whether or not to use [durable](https://www.rabbitmq.com/queues.html#durability) queues. Defaults to `"false"` | `"true"`, `"false"` | deletedWhenUnused | N | Whether or not the queue should be configured to [auto-delete](https://www.rabbitmq.com/queues.html) Defaults to `"true"` | `"true"`, `"false"` | autoAck | N | Whether or not the queue consumer should [auto-ack](https://www.rabbitmq.com/confirms.html) messages. Defaults to `"false"` | `"true"`, `"false"` From bdde1917155e8f692df9d0848e90d31c467c88e4 Mon Sep 17 00:00:00 2001 From: Dmitry Shmulevich Date: Wed, 29 Dec 2021 15:35:26 -0800 Subject: [PATCH 08/73] fixed typo Signed-off-by: Dmitry Shmulevich --- .../components-reference/supported-pubsub/setup-rabbitmq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md index 17b2bcadb..993e3351f 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-rabbitmq.md @@ -61,7 +61,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| | host | Y | Connection-string for the rabbitmq host | `amqp://user:pass@localhost:5672` -| consumerID | N | Consumer ID a.k.a consumer tag organizes one or more consumers into a group. Consumers with the same consumer ID work as one visrtual consumer, i.e. a message is processed only once by one of the consumers in the group. If the consumer ID is not set, dapr runtime will set it to the dapr application ID | +| consumerID | N | Consumer ID a.k.a consumer tag organizes one or more consumers into a group. Consumers with the same consumer ID work as one virtual consumer, i.e. a message is processed only once by one of the consumers in the group. If the consumer ID is not set, the dapr runtime will set it to the dapr application ID. | | durable | N | Whether or not to use [durable](https://www.rabbitmq.com/queues.html#durability) queues. Defaults to `"false"` | `"true"`, `"false"` | deletedWhenUnused | N | Whether or not the queue should be configured to [auto-delete](https://www.rabbitmq.com/queues.html) Defaults to `"true"` | `"true"`, `"false"` | autoAck | N | Whether or not the queue consumer should [auto-ack](https://www.rabbitmq.com/confirms.html) messages. Defaults to `"false"` | `"true"`, `"false"` From 2dd4b4362715a636d92b651a29630f76dfff2d49 Mon Sep 17 00:00:00 2001 From: zhangchao Date: Thu, 9 Dec 2021 19:54:05 +0800 Subject: [PATCH 09/73] content: Make the grace period configurable Signed-off-by: Taction --- .../content/en/reference/arguments-annotations-overview.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/arguments-annotations-overview.md b/daprdocs/content/en/reference/arguments-annotations-overview.md index e1c1cb2c3..e52285337 100644 --- a/daprdocs/content/en/reference/arguments-annotations-overview.md +++ b/daprdocs/content/en/reference/arguments-annotations-overview.md @@ -21,7 +21,7 @@ This table is meant to help users understand the equivalent options for running | `--control-plane-address` | not supported | | not supported | Address for a Dapr control plane | | `--dapr-grpc-port` | `--dapr-grpc-port` | | not supported | gRPC port for the Dapr API to listen on (default "50001") | | `--dapr-http-port` | `--dapr-http-port` | | not supported | The HTTP port for the Dapr API | -|` --dapr-http-max-request-size` | --dapr-http-max-request-size | | `dapr.io/http-max-request-size` | Increasing max size of request body http and grpc servers parameter in MB to handle uploading of big files. Default is `4` MB | +| `--dapr-http-max-request-size` | --dapr-http-max-request-size | | `dapr.io/http-max-request-size` | Increasing max size of request body http and grpc servers parameter in MB to handle uploading of big files. Default is `4` MB | | not supported | `--image` | | `dapr.io/sidecar-image` | Dapr sidecar image. Default is `daprio/daprd:latest` | | `--internal-grpc-port` | not supported | | not supported | gRPC port for the Dapr Internal API to listen on | | `--enable-metrics` | not supported | | configuration spec | Enable prometheus metric (default true) | @@ -38,6 +38,7 @@ This table is meant to help users understand the equivalent options for running | `--app-protocol` | `--app-protocol` | `-P` | `dapr.io/app-protocol` | Tells Dapr which protocol your application is using. Valid options are `http` and `grpc`. Default is `http` | | `--sentry-address` | `--sentry-address` | | not supported | Address for the Sentry CA service | | `--version` | `--version` | `-v` | not supported | Prints the runtime version | +| `--dapr-graceful-shutdown-seconds` | not supported | | `dapr.io/graceful-shutdown-seconds` | Graceful shutdown duration in seconds for dapr, the maximum duration before force shutdown when waitting all in-progress requests to complete. Defaults to `5`, and maximum to `30` which is equivalent to Kubernetes termination grace period. Any vaule larger than the minimum duration will be setting to the minimum duration. | | not supported | not supported | | `dapr.io/enabled` | Setting this paramater to true injects the Dapr sidecar into the pod | | not supported | not supported | | `dapr.io/api-token-secret` | Tells Dapr which Kubernetes secret to use for token based API authentication. By default this is not set | | `--dapr-listen-addresses` | not supported | | `dapr.io/sidecar-listen-addresses` | Comma separated list of IP addresses that sidecar will listen to. Defaults to all in standalone mode. Defaults to `[::1],127.0.0.1` in Kubernetes. To listen to all IPv4 addresses, use `0.0.0.0`. To listen to all IPv6 addresses, use `[::]`. From 1417e9ab5746751e05b44131e14f2b740c0f02cf Mon Sep 17 00:00:00 2001 From: zhangchao Date: Fri, 10 Dec 2021 09:12:34 +0800 Subject: [PATCH 10/73] fix review Signed-off-by: Taction --- daprdocs/content/en/reference/arguments-annotations-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/arguments-annotations-overview.md b/daprdocs/content/en/reference/arguments-annotations-overview.md index e52285337..9546b1fd5 100644 --- a/daprdocs/content/en/reference/arguments-annotations-overview.md +++ b/daprdocs/content/en/reference/arguments-annotations-overview.md @@ -38,7 +38,7 @@ This table is meant to help users understand the equivalent options for running | `--app-protocol` | `--app-protocol` | `-P` | `dapr.io/app-protocol` | Tells Dapr which protocol your application is using. Valid options are `http` and `grpc`. Default is `http` | | `--sentry-address` | `--sentry-address` | | not supported | Address for the Sentry CA service | | `--version` | `--version` | `-v` | not supported | Prints the runtime version | -| `--dapr-graceful-shutdown-seconds` | not supported | | `dapr.io/graceful-shutdown-seconds` | Graceful shutdown duration in seconds for dapr, the maximum duration before force shutdown when waitting all in-progress requests to complete. Defaults to `5`, and maximum to `30` which is equivalent to Kubernetes termination grace period. Any vaule larger than the minimum duration will be setting to the minimum duration. | +| `--dapr-graceful-shutdown-seconds` | not supported | | `dapr.io/graceful-shutdown-seconds` | Graceful shutdown duration in seconds for Dapr, the maximum duration before forced shutdown when waiting for all in-progress requests to complete. Defaults to `5`, and maximum value is `30` which is equivalent to Kubernetes termination grace period. Any value larger than the maximum duration will be set to the maximum duration. | | not supported | not supported | | `dapr.io/enabled` | Setting this paramater to true injects the Dapr sidecar into the pod | | not supported | not supported | | `dapr.io/api-token-secret` | Tells Dapr which Kubernetes secret to use for token based API authentication. By default this is not set | | `--dapr-listen-addresses` | not supported | | `dapr.io/sidecar-listen-addresses` | Comma separated list of IP addresses that sidecar will listen to. Defaults to all in standalone mode. Defaults to `[::1],127.0.0.1` in Kubernetes. To listen to all IPv4 addresses, use `0.0.0.0`. To listen to all IPv6 addresses, use `[::]`. From 54e42331889ad710045cb2c9da81c6b1f80cdbce Mon Sep 17 00:00:00 2001 From: zhangchao Date: Sat, 11 Dec 2021 13:42:18 +0800 Subject: [PATCH 11/73] update doc remove the maximum limit Signed-off-by: Taction --- daprdocs/content/en/reference/arguments-annotations-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/arguments-annotations-overview.md b/daprdocs/content/en/reference/arguments-annotations-overview.md index 9546b1fd5..bef7a9214 100644 --- a/daprdocs/content/en/reference/arguments-annotations-overview.md +++ b/daprdocs/content/en/reference/arguments-annotations-overview.md @@ -38,7 +38,7 @@ This table is meant to help users understand the equivalent options for running | `--app-protocol` | `--app-protocol` | `-P` | `dapr.io/app-protocol` | Tells Dapr which protocol your application is using. Valid options are `http` and `grpc`. Default is `http` | | `--sentry-address` | `--sentry-address` | | not supported | Address for the Sentry CA service | | `--version` | `--version` | `-v` | not supported | Prints the runtime version | -| `--dapr-graceful-shutdown-seconds` | not supported | | `dapr.io/graceful-shutdown-seconds` | Graceful shutdown duration in seconds for Dapr, the maximum duration before forced shutdown when waiting for all in-progress requests to complete. Defaults to `5`, and maximum value is `30` which is equivalent to Kubernetes termination grace period. Any value larger than the maximum duration will be set to the maximum duration. | +| `--dapr-graceful-shutdown-seconds` | not supported | | `dapr.io/graceful-shutdown-seconds` | Graceful shutdown duration in seconds for Dapr, the maximum duration before forced shutdown when waiting for all in-progress requests to complete. Defaults to `5`. If you are running in Kubernetes mode, this value should not be larger than the Kubernetes termination grace period, who's default value is `30`.| | not supported | not supported | | `dapr.io/enabled` | Setting this paramater to true injects the Dapr sidecar into the pod | | not supported | not supported | | `dapr.io/api-token-secret` | Tells Dapr which Kubernetes secret to use for token based API authentication. By default this is not set | | `--dapr-listen-addresses` | not supported | | `dapr.io/sidecar-listen-addresses` | Comma separated list of IP addresses that sidecar will listen to. Defaults to all in standalone mode. Defaults to `[::1],127.0.0.1` in Kubernetes. To listen to all IPv4 addresses, use `0.0.0.0`. To listen to all IPv6 addresses, use `[::]`. From d16b035c0e2ae746447a4c9032e6ed4477537c03 Mon Sep 17 00:00:00 2001 From: lucasjellema Date: Tue, 4 Jan 2022 12:05:12 +0100 Subject: [PATCH 12/73] Introducing documentation for OCI Object Storage state store component Signed-off-by: lucasjellema --- .../supported-state-stores/_index.md | 6 + .../setup-oci-objectstorage.md | 116 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md index b52fcdd01..b7c8644d3 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md @@ -60,3 +60,9 @@ The following stores are supported, at various levels, by the Dapr state managem | [Azure CosmosDB]({{< ref setup-azure-cosmosdb.md >}}) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Stable | v1 | 1.0 | | [Azure SQL Server]({{< ref setup-sqlserver.md >}}) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | Stable | v1 | 1.5 | | [Azure Table Storage]({{< ref setup-azure-tablestorage.md >}}) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | Alpha | v1 | 1.0 | + +### Oracle Cloud Infrastructure (OCI) + +| Name |CRUD|Transactional|ETag| [TTL]({{< ref state-store-ttl.md >}}) | [Actors]({{< ref howto-actors.md >}}) | [Query]({{< ref howto-state-query-api.md >}}) | Status | Component version | Since | +|------------------------------------------------------------------|----|-------------|----|----|----|----|-------|----|-----| +| [OCI Object Storage]({{< ref setup-oci-objectstorage.md >}}) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | Alpha | v1 | 1.6 | diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md new file mode 100644 index 000000000..b202a45bf --- /dev/null +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -0,0 +1,116 @@ +--- +type: docs +title: "OCI Object Storage " +linkTitle: "OCI Object Storage " +description: Detailed information on the OCI Object Storage state store component +aliases: + - "/operations/components/setup-state-store/supported-state-stores/setup-oci-objectstorage/" +--- + +## Component format + +To setup OCI Object Storage state store create a component of type `state.oci.objectstorage`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration. + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: + namespace: +spec: + type: state.oci.objectstorage + version: v1 + metadata: + - name: tenancyOCID + value: + - name: userOCID + value: + - name: fingerPrint + value: + - name: privateKey + value: | + -----BEGIN RSA PRIVATE KEY----- + REPLACE-WIH-PRIVATE-KEY-AS-IN-PEM-FILE + -----END RSA PRIVATE KEY----- + - name: region + value: + - name: bucketName + value: + - name: compartmentOCID + value: + +``` + +{{% alert title="Warning" color="warning" %}} +The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described [here]({{< ref component-secrets.md >}}). +{{% /alert %}} + +## Spec metadata fields + +| Field | Required | Details | Example | +|--------------------|:--------:|---------|---------| +| tenancyOCID | Y | The OCI tenancy identifier. | `"ocid1.tenancy.oc1..aaaaaaaag7c7sljhsdjhsdyuwe723"`. +| userOCID | Y | The OCID for an OCI account (this account requires permissions to access OCI Object Storage).| `"ocid1.user.oc1..aaaaaaaaby4oyyyuqwy7623yuwe76"` +| fingerPrint | Y | Fingerprint of the public key. | `"02:91:6c:49:e2:94:21:15:a7:6b:0e:a7:34:e1:3d:1b"` +| privateKey | Y | Private key of the RSA key pair | `"MIIEoyuweHAFGFG2727as+7BTwQRAIW4V"` +| region | Y | OCI Region | `"us-ashburn-1"` +| bucketName | Y | Name of the bucket written to and read from (and if necessary created) | `"application-state-store-bucket"` +| compartmentOCID | Y | The OCID for the compartment that contains the bucket | `"ocid1.compartment.oc1..aaaaaaaacsssekayyuq7asjh78"` + +## Setup OCI Object Storage +The OCI Object Storage state store needs to interact through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. + +If you wish to create the bucket for Dapr to use, you can do so beforehand. However, Object Storage state provider will create one - in the specified compartment - for you automatically if it doesn't exist. + +In order to setup OCI Object Storage as a state store, you will need the following properties: +- **tenancyOCID**: The identifier for the OCI cloud tenancy in which the state is to be stored. +- **userOCID**: The identifier for the account used by the state store component to connect to OCI; this must be an account with appropriate permissions on the OCI Object Storage service in the specified compartment and bucket +- **fingerPrint**: The fingerprint for the public key in the RSA key pair generated for the account indicated by **userOCID** +- **privateKey**: The private key in the RSA key pair generated for the account indicated by **userOCID** +- **region**: The OCI region - for example **us-ashburn-1**, **eu-amsterdam-1**, **ap-mumbai-1** +- **bucketName**: The name of the bucket on OCI Object Storage in which state will be created. This bucket can exist already when the state store is initialized or it will be created during initialization of the state store. Note that the name of buckets is unique within a namespace +- **compartmentOCID**: The identifier of the compartment within the tenancy in which the bucket exists or will be created. + + +## What Happens at Runtime? + +Every state entry is represented by an object in OCI Object Storage. The OCI Object Storage state store uses the `key` property provided in the requests to the Dapr API to determine the name of the object. The `value` is stored as the (literal) content of the object. Each object is assigned a unique ETag value - whenever it is created or updated (aka overwritten). + +For example, the following operation + +```shell +curl -X POST http://localhost:3500/v1.0/state \ + -H "Content-Type: application/json" + -d '[ + { + "key": "nihilus", + "value": "darth" + } + ]' +``` + +will create the following object: + +| Bucket | Object Name | Object Content | +| ------------ | ------- | ----- | +| as specified with **bucketName** in components.yaml | nihilus | darth | + +You will be able to inspect all state stored through the OCI Object Storage state store by inspecting the contents of the bucket through the console, the APIs, CLI or SDKs. By going directly to the bucket, you can prepare state that will be available as state to your application at runtime. + +## Concurrency + +OCI Object Storage state concurrency is achieved by using `ETag`s. Each object in OCI Object Storage is assigned a unique ETag when it is created or updated (aka replaced). When the Set and Delete requests for this state store specify the FirstWrite concurrency policy, then the request need to provide the actual ETag value for the state to be written or removed for the request to be successful. + +## Consistency + +OCI Object Storage state does not support Transactions. + +## Query + +OCI Object Storage state does not support the Query API. + + +## Related links +- [Basic schema for a Dapr component]({{< ref component-schema >}}) +- Read [this guide]({{< ref "howto-get-save-state.md#step-2-save-and-retrieve-a-single-state" >}}) for instructions on configuring state store components +- [State management building block]({{< ref state-management >}}) From 13809291c3a96d1a6fe36d4317906912326e4eab Mon Sep 17 00:00:00 2001 From: Dmitry Shmulevich Date: Tue, 4 Jan 2022 11:21:58 -0800 Subject: [PATCH 13/73] update docs.newrelic.com link for Alerts and Applied Intelligence Signed-off-by: Dmitry Shmulevich --- .../content/en/operations/monitoring/logging/newrelic.md | 2 +- .../content/en/operations/monitoring/metrics/newrelic.md | 2 +- .../tracing/supported-tracing-backends/newrelic.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/daprdocs/content/en/operations/monitoring/logging/newrelic.md b/daprdocs/content/en/operations/monitoring/logging/newrelic.md index b7885bc7c..356231fd1 100644 --- a/daprdocs/content/en/operations/monitoring/logging/newrelic.md +++ b/daprdocs/content/en/operations/monitoring/logging/newrelic.md @@ -75,4 +75,4 @@ By default, tailing is set to /var/log/containers/*.log. To change this setting, * [Telemetry Data Platform](https://newrelic.com/platform/telemetry-data-platform) * [New Relic Logging](https://github.com/newrelic/helm-charts/tree/master/charts/newrelic-logging) * [Types of New Relic API keys](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/) -* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence) +* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/learn-alerts/alerts-ai-transition-guide-2022/) diff --git a/daprdocs/content/en/operations/monitoring/metrics/newrelic.md b/daprdocs/content/en/operations/monitoring/metrics/newrelic.md index 219c92306..9db539ac2 100644 --- a/daprdocs/content/en/operations/monitoring/metrics/newrelic.md +++ b/daprdocs/content/en/operations/monitoring/metrics/newrelic.md @@ -40,4 +40,4 @@ This document explains how to install it in your cluster, either using a Helm ch * [Telemetry Data Platform](https://newrelic.com/platform/telemetry-data-platform) * [New Relic Prometheus OpenMetrics Integration](https://github.com/newrelic/helm-charts/tree/master/charts/nri-prometheus) * [Types of New Relic API keys](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/) -* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence) +* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/learn-alerts/alerts-ai-transition-guide-2022/) diff --git a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/newrelic.md b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/newrelic.md index 9b98303d1..4c888db3b 100644 --- a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/newrelic.md +++ b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/newrelic.md @@ -53,7 +53,7 @@ Similarly to the OpenTelemetry instrumentation, you can also leverage a New Reli In case Dapr and your applications run in the context of a Kubernetes environment, you can enable additional metrics and logs. -The easiest way to install the New Relic Kubernetes integration is to use the [automated installer](https://one.newrelic.com/launcher/nr1-core.settings?pane=eyJuZXJkbGV0SWQiOiJrOHMtY2x1c3Rlci1leHBsb3Jlci1uZXJkbGV0Lms4cy1zZXR1cCJ9) to generate a manifest. It bundles not just the integration DaemonSets, but also other New Relic Kubernetes configurations, like [Kubernetes events](https://docs.newrelic.com/docs/integrations/kubernetes-integration/kubernetes-events/install-kubernetes-events-integration), [Prometheus OpenMetrics](https://docs.newrelic.com/docs/integrations/prometheus-integrations/get-started/send-prometheus-metric-data-new-relic/), and [New Relic log monitoring](https://docs.newrelic.com/docs/logs). +The easiest way to install the New Relic Kubernetes integration is to use the [automated installer](https://one.newrelic.com/launcher/nr1-core.settings?pane=eyJuZXJkbGV0SWQiOiJrOHMtY2x1c3Rlci1leHBsb3Jlci1uZXJkbGV0Lms4cy1zZXR1cCJ9) to generate a manifest. It bundles not just the integration DaemonSets, but also other New Relic Kubernetes configurations, like [Kubernetes events](https://docs.newrelic.com/docs/integrations/kubernetes-integration/kubernetes-events/install-kubernetes-events-integration), [Prometheus OpenMetrics](https://docs.newrelic.com/docs/integrations/prometheus-integrations/get-started/send-prometheus-metric-data-new-relic/), and [New Relic log monitoring](https://docs.newrelic.com/docs/logs/ui-data/use-logs-ui/). ### New Relic Kubernetes Cluster Explorer @@ -101,7 +101,7 @@ And the exact same dashboard templates from Dapr can be imported to visualize Da ## New Relic Alerts -All the data that is collected from Dapr, Kubernetes or any services that run on top of can be used to set-up alerts and notifications into the preferred channel of your choice. See [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence). +All the data that is collected from Dapr, Kubernetes or any services that run on top of can be used to set-up alerts and notifications into the preferred channel of your choice. See [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/learn-alerts/alerts-ai-transition-guide-2022/). ## Related Links/References @@ -111,4 +111,4 @@ All the data that is collected from Dapr, Kubernetes or any services that run on * [New Relic Trace API](https://docs.newrelic.com/docs/distributed-tracing/trace-api/introduction-trace-api/) * [Types of New Relic API keys](https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/) * [New Relic OpenTelemetry User Experience](https://blog.newrelic.com/product-news/opentelemetry-user-experience/) -* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence) +* [Alerts and Applied Intelligence](https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/learn-alerts/alerts-ai-transition-guide-2022/) From 6079c0e34bf45e917a9e7b7c4370c861ad2d0f11 Mon Sep 17 00:00:00 2001 From: Phil Kedy Date: Wed, 5 Jan 2022 10:18:08 -0500 Subject: [PATCH 14/73] Docs tweak for #1408 / #1409: Kafka PubSub using metadata as headers Signed-off-by: Phil Kedy --- .../supported-pubsub/setup-apache-kafka.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index e0e4167c9..c44505880 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -136,6 +136,20 @@ curl -X POST http://localhost:3500/v1.0/publish/myKafka/myTopic?metadata.partiti }' ``` +### Message headers + +All other metadata key/value pairs (that are not `partitionKey`) are set as headers in the Kafka message. For example, here is an example setting a `correlationId` for the message. + +```shell +curl -X POST http://localhost:3500/v1.0/publish/myKafka/myTopic?metadata.correlationId=myCorrelationID \ + -H "Content-Type: application/json" \ + -d '{ + "data": { + "message": "Hi" + } + }' +``` + ## Create a Kafka instance {{< tabs "Self-Hosted" "Kubernetes">}} From 2e4ef526a3cbf569098a35d2a2afb42a44cb11da Mon Sep 17 00:00:00 2001 From: Dmitry Shmulevich Date: Wed, 5 Jan 2022 08:58:44 -0800 Subject: [PATCH 15/73] update rabbitmq pub/sub version to 'beta' (#2076) Signed-off-by: Dmitry Shmulevich --- .../reference/components-reference/supported-pubsub/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md index 6b452ba13..d939f0269 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md @@ -29,7 +29,7 @@ Table captions: | [In Memory]({{< ref setup-inmemory.md >}}) | Alpha | v1 | 1.4 | | [JetStream]({{< ref setup-jetstream.md >}}) | Alpha | v1 | 1.4 | | [Pulsar]({{< ref setup-pulsar.md >}}) | Alpha | v1 | 1.0 | -| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Stable | v1 | 1.6 | +| [RabbitMQ]({{< ref setup-rabbitmq.md >}}) | Beta | v1 | 1.6 | | [Redis Streams]({{< ref setup-redis-pubsub.md >}}) | Stable | v1 | 1.0 | ### Amazon Web Services (AWS) From 4979af3abc9340ab18f0c683c99eb0cdb2e16eb0 Mon Sep 17 00:00:00 2001 From: Scott Hussey Date: Wed, 5 Jan 2022 20:09:06 -0600 Subject: [PATCH 16/73] Update some phrasing and links - Correctly link to subsection Signed-off-by: Scott Hussey --- .../supported-pubsub/setup-apache-kafka.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index 616bd31d6..a7968be25 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -73,8 +73,9 @@ The `secretKeyRef` above is referencing a [kubernetes secrets store]({{< ref ku ### Authentication -Kafka supports a variety of authentication schemes and Dapr supports several: SASL password, mTLS, OIDC/OAuth2. With the added authentication methods, the `authRequired` field has been deprecated -and instead the `authType` field should be used. If `authRequired` is set to `true`, Dapr will attempt to configure `authType` correctly based on the value of `saslPassword`. There are four valid values for `authType`: `none`, `password`, `mtls`, and `oidc`. Note this is authentication only; authorization is still configured within Kafka. +Kafka supports a variety of authentication schemes and Dapr supports several: SASL password, mTLS, OIDC/OAuth2. With the added authentication methods, the `authRequired` field has +been deprecated from the v1.6 release and instead the `authType` field should be used. If `authRequired` is set to `true`, Dapr will attempt to configure `authType` correctly +based on the value of `saslPassword`. There are four valid values for `authType`: `none`, `password`, `mtls`, and `oidc`. Note this is authentication only; authorization is still configured within Kafka. #### None @@ -110,7 +111,7 @@ spec: #### SASL Password -Setting `authType` to `password` will enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication using the **PLAIN** mechanism. This requires setting +Setting `authType` to `password` enables [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication using the **PLAIN** mechanism. This requires setting the `saslUsername` and `saslPassword` fields. ```yaml @@ -151,9 +152,9 @@ spec: #### Mutual TLS -Setting `authType` to `mtls` will use a x509 client certificate (the `clientCert` field) and key (the `clientKey` field) to authenticate. Note that mTLS as an +Setting `authType` to `mtls` uses a x509 client certificate (the `clientCert` field) and key (the `clientKey` field) to authenticate. Note that mTLS as an authentication mechanism is distinct from using TLS to secure the transport layer via encryption. mTLS requires TLS transport (meaning `disableTls` must be `false`), but securing -the transport layer does not require using mTLS. See _Communication using TLS_ for configuring underlying TLS transport. +the transport layer does not require using mTLS. See [Communication using TLS](#communication-using-tls) for configuring underlying TLS transport. ```yaml apiVersion: dapr.io/v1alpha1 @@ -195,12 +196,12 @@ spec: #### OAuth2 or OpenID Connect -Setting `authType` to `oidc` will enable SASL authentication via the **OAUTHBEARER** mechanism. This supports specifying a bearer +Setting `authType` to `oidc` enables SASL authentication via the **OAUTHBEARER** mechanism. This supports specifying a bearer token from an external OAuth2 or [OIDC](https://en.wikipedia.org/wiki/OpenID) identity provider. Currenly only the **client_credentials** grant is supported. Configure `oidcTokenEndpoint` to the full URL for the identity provider access token endpoint. Set `oidcClientID` and `oidcClientSecret` to the client credentials provisioned in the identity provider. If `caCert` -is specified in the component configuration, the certificate will be appended to the system CA trust for verifying the identity provider certificate. Similarly, if `skipVerify` -is specified in the component configuration, it will also be applied when accessing the identity provider. By default, the only scope requested for the token is `openid` but it is highly recommended -that additional scopes be specified via `oidcScopes` in a comma-separated list and validated by the Kafka broken. If additional scopes are not used to narrow the validity of the access token, +is specified in the component configuration, the certificate is appended to the system CA trust for verifying the identity provider certificate. Similarly, if `skipVerify` +is specified in the component configuration, verification will also be skipped when accessing the identity provider. By default, the only scope requested for the token is `openid`; it is **highly** recommended +that additional scopes be specified via `oidcScopes` in a comma-separated list and validated by the Kafka broker. If additional scopes are not used to narrow the validity of the access token, a compromised Kafka broker could replay the token to access other services as the Dapr clientID. ```yaml From 5826b150f48800b7b403cb3fc5e176c77891f463 Mon Sep 17 00:00:00 2001 From: lucasjellema Date: Thu, 6 Jan 2022 10:45:41 +0100 Subject: [PATCH 17/73] adding OCI ObjectStorage TTL and composite key support Signed-off-by: lucasjellema --- .../supported-state-stores/_index.md | 2 +- .../setup-oci-objectstorage.md | 63 +++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md index b7c8644d3..70c209e93 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/_index.md @@ -65,4 +65,4 @@ The following stores are supported, at various levels, by the Dapr state managem | Name |CRUD|Transactional|ETag| [TTL]({{< ref state-store-ttl.md >}}) | [Actors]({{< ref howto-actors.md >}}) | [Query]({{< ref howto-state-query-api.md >}}) | Status | Component version | Since | |------------------------------------------------------------------|----|-------------|----|----|----|----|-------|----|-----| -| [OCI Object Storage]({{< ref setup-oci-objectstorage.md >}}) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | Alpha | v1 | 1.6 | +| [OCI Object Storage]({{< ref setup-oci-objectstorage.md >}}) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | Alpha | v1 | 1.6 | diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md index b202a45bf..cd8345b71 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -74,7 +74,7 @@ In order to setup OCI Object Storage as a state store, you will need the followi ## What Happens at Runtime? -Every state entry is represented by an object in OCI Object Storage. The OCI Object Storage state store uses the `key` property provided in the requests to the Dapr API to determine the name of the object. The `value` is stored as the (literal) content of the object. Each object is assigned a unique ETag value - whenever it is created or updated (aka overwritten). +Every state entry is represented by an object in OCI Object Storage. The OCI Object Storage state store uses the `key` property provided in the requests to the Dapr API to determine the name of the object. The `value` is stored as the (literal) content of the object. Each object is assigned a unique ETag value - whenever it is created or updated (aka overwritten); this is native behavior of OCI Object Storage. The state store assigns a meta data tag to every object it writes; the tag is __category__ and its value is __dapr-state-store__. This allows the objects created as state for Daprized applications to be identified. For example, the following operation @@ -91,12 +91,67 @@ curl -X POST http://localhost:3500/v1.0/state \ will create the following object: -| Bucket | Object Name | Object Content | -| ------------ | ------- | ----- | -| as specified with **bucketName** in components.yaml | nihilus | darth | +| Bucket | Directory | Object Name | Object Content | Meta Tags | +| ------------ | ------- | ----- | ----- | ---- | +| as specified with **bucketName** in components.yaml | - (root) | nihilus | darth | category: dapr-state-store + + +Dapr uses a fixed key scheme with *composite keys* to partition state across applications. For general states, the key format is: +`App-ID||state key` +The OCI Object Storage state store maps the first key segment (for App-ID) to a directory within a bucket, using the [Prefixes and Hierarchy used for simulating a directory structure as described in the OCI Object Storage documentation](https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/managingobjects.htm#nameprefix). + +The following operation therefore (notice the composite key) + +```shell +curl -X POST http://localhost:3500/v1.0/state \ + -H "Content-Type: application/json" + -d '[ + { + "key": "myApplication||nihilus", + "value": "darth" + } + ]' +``` + +will create the following object: + +| Bucket | Directory | Object Name | Object Content | Meta Tags | +| ------------ | ------- | ----- | ----- | ---- | +| as specified with **bucketName** in components.yaml | myApplication | nihilus | darth | category: dapr-state-store + You will be able to inspect all state stored through the OCI Object Storage state store by inspecting the contents of the bucket through the console, the APIs, CLI or SDKs. By going directly to the bucket, you can prepare state that will be available as state to your application at runtime. +## Time To Live and State Expiration +The OCI Object Storage state store supports Dapr's Time To Live logic that ensure that state cannot be retrieved after it has expired. See [this How To on Setting State Time To Live]({{< ref "state-store-ttl.md" >}}) for details. + +OCI Object Storage does not have native support for a Time To Live setting. The implementation in this component uses a meta data tag put on each object for which a TTL has been specified. The tag is called **expiry-time-from-ttl** and it contains a string in ISO date time format with the UTC based expiry time. When state is retrieved through a call to Get, this component checks if it has the **expiry-time-from-ttl** set and if so it checks whether it is in the past. In that case, no state is returned. + +The following operation therefore (notice the composite key) + +```shell +curl -X POST http://localhost:3500/v1.0/state \ + -H "Content-Type: application/json" + -d '[ + { + "key": "temporary", + "value": "ephemeral", + "metadata": {"ttlInSeconds": "120"}} + } + ]' +``` + +will create the following object: + +| Bucket | Directory | Object Name | Object Content | Meta Tags | +| ------------ | ------- | ----- | ----- | ---- | +| as specified with **bucketName** in components.yaml | - | nihilus | darth | category: dapr-state-store , expiry-time-from-ttl: 2022-01-06T08:34:32 + +The exact value of the expiry-time-from-ttl depends of course on the time at which the state was created and will be 120 seconds later than that moment. + + +Note that expired state is not removed from the state store by this component. An application operator may decide to run a periodic job that does a form of garbage collection in order to explicitly remove all state that has an **expiry-time-from-ttl** label with a timestamp in the past. + ## Concurrency OCI Object Storage state concurrency is achieved by using `ETag`s. Each object in OCI Object Storage is assigned a unique ETag when it is created or updated (aka replaced). When the Set and Delete requests for this state store specify the FirstWrite concurrency policy, then the request need to provide the actual ETag value for the state to be written or removed for the request to be successful. From 63c4c158108ca1a60a7ad687a0f5101532c6f8e7 Mon Sep 17 00:00:00 2001 From: lucasjellema Date: Sun, 9 Jan 2022 09:11:37 +0100 Subject: [PATCH 18/73] Adding InstancePrincipalAuthentication to docs on OCI ObjectStorage state store Signed-off-by: lucasjellema --- .../setup-oci-objectstorage.md | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md index cd8345b71..4527e4469 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -21,19 +21,21 @@ spec: type: state.oci.objectstorage version: v1 metadata: + - name: instancePrincipalAuthentication + value: <"true" or "false"> # Optional. default: "false" - name: tenancyOCID - value: + value: # Not used when instancePrincipalAuthentication == "true" - name: userOCID - value: + value: # Not used when instancePrincipalAuthentication == "true" - name: fingerPrint - value: - - name: privateKey + value: # Not used when instancePrincipalAuthentication == "true" + - name: privateKey # Not used when instancePrincipalAuthentication == "true" value: | -----BEGIN RSA PRIVATE KEY----- REPLACE-WIH-PRIVATE-KEY-AS-IN-PEM-FILE - -----END RSA PRIVATE KEY----- + -----END RSA PRIVATE KEY----- - name: region - value: + value: # Not used when instancePrincipalAuthentication == "true" - name: bucketName value: - name: compartmentOCID @@ -49,25 +51,31 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| tenancyOCID | Y | The OCI tenancy identifier. | `"ocid1.tenancy.oc1..aaaaaaaag7c7sljhsdjhsdyuwe723"`. -| userOCID | Y | The OCID for an OCI account (this account requires permissions to access OCI Object Storage).| `"ocid1.user.oc1..aaaaaaaaby4oyyyuqwy7623yuwe76"` -| fingerPrint | Y | Fingerprint of the public key. | `"02:91:6c:49:e2:94:21:15:a7:6b:0e:a7:34:e1:3d:1b"` -| privateKey | Y | Private key of the RSA key pair | `"MIIEoyuweHAFGFG2727as+7BTwQRAIW4V"` -| region | Y | OCI Region | `"us-ashburn-1"` +| instancePrincipalAuthentication | N | Boolean to indicate whether instance principal based authentication is used. Default: `"false"` | `"true"` or `"false"` . +| tenancyOCID | Y | The OCI tenancy identifier. Not required nor used when instancePrincipalAuthentication is true. | `"ocid1.tenancy.oc1..aaaaaaaag7c7sljhsdjhsdyuwe723"`. +| userOCID | Y | The OCID for an OCI account (this account requires permissions to access OCI Object Storage). Not required nor used when instancePrincipalAuthentication is true.| `"ocid1.user.oc1..aaaaaaaaby4oyyyuqwy7623yuwe76"` +| fingerPrint | Y | Fingerprint of the public key. Not required nor used when instancePrincipalAuthentication is true. | `"02:91:6c:49:e2:94:21:15:a7:6b:0e:a7:34:e1:3d:1b"` +| privateKey | Y | Private key of the RSA key pair. Not required nor used when instancePrincipalAuthentication is true. | `"MIIEoyuweHAFGFG2727as+7BTwQRAIW4V"` +| region | Y | OCI Region. Not required nor used when instancePrincipalAuthentication is true. | `"us-ashburn-1"` | bucketName | Y | Name of the bucket written to and read from (and if necessary created) | `"application-state-store-bucket"` -| compartmentOCID | Y | The OCID for the compartment that contains the bucket | `"ocid1.compartment.oc1..aaaaaaaacsssekayyuq7asjh78"` +| compartmentOCID | Y | The OCID for the compartment that contains the bucket | `"ocid1.compartment.oc1..aaaaaaaacsssekayyuq7asjh78"` ## Setup OCI Object Storage -The OCI Object Storage state store needs to interact through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. +The OCI Object Storage state store needs to interact with Oracle Cloud Infrastructure. The state store supports two different approaches to authentication. One is based on an identity (a user or service account) and the other is instance principal authentication leveraging the permissions granted to the cmopute instance running the application workload. + +Dapr-applications running on Oracle Cloud Infrastructure - in a compute instance, a container on Kubernetes or as a function - can leverage instance principal authentication. See the [OCI documentation on calling OCI Services from instances](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm) for more background. In short: The instance needs to be member of a Dynamic Group and this Dynamic Group needs to get permissions for interacting with the Object Storage service through IAM policies. In case of such instance principal authentication, specify property instancePrincipalAuthentication as `"true"`. You do not need to configure the properties tenancyOCID, userOCID, region, fingerPrint and privateKey - these will be ignored if you define values for them. + +Identity based authentication interact with OCI through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. If you wish to create the bucket for Dapr to use, you can do so beforehand. However, Object Storage state provider will create one - in the specified compartment - for you automatically if it doesn't exist. In order to setup OCI Object Storage as a state store, you will need the following properties: -- **tenancyOCID**: The identifier for the OCI cloud tenancy in which the state is to be stored. -- **userOCID**: The identifier for the account used by the state store component to connect to OCI; this must be an account with appropriate permissions on the OCI Object Storage service in the specified compartment and bucket -- **fingerPrint**: The fingerprint for the public key in the RSA key pair generated for the account indicated by **userOCID** -- **privateKey**: The private key in the RSA key pair generated for the account indicated by **userOCID** -- **region**: The OCI region - for example **us-ashburn-1**, **eu-amsterdam-1**, **ap-mumbai-1** +- **instancePrincipalAuthentication**: The flag that indicates if instance principal based authentication should be used. +- **tenancyOCID**: The identifier for the OCI cloud tenancy in which the state is to be stored. Not used when **instancePrincipalAuthentication** is true. +- **userOCID**: The identifier for the account used by the state store component to connect to OCI; this must be an account with appropriate permissions on the OCI Object Storage service in the specified compartment and bucket. Not used when **instancePrincipalAuthentication** is true. +- **fingerPrint**: The fingerprint for the public key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true. +- **privateKey**: The private key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true. +- **region**: The OCI region - for example **us-ashburn-1**, **eu-amsterdam-1**, **ap-mumbai-1**. Not used when **instancePrincipalAuthentication** is true. - **bucketName**: The name of the bucket on OCI Object Storage in which state will be created. This bucket can exist already when the state store is initialized or it will be created during initialization of the state store. Note that the name of buckets is unique within a namespace - **compartmentOCID**: The identifier of the compartment within the tenancy in which the bucket exists or will be created. From 61c072e4ffd7c3d9692e9ff08f4c73ac12e26ae5 Mon Sep 17 00:00:00 2001 From: lucasjellema Date: Sun, 9 Jan 2022 21:29:30 +0100 Subject: [PATCH 19/73] Describe Resource Principal Authentication, remove Functions from description of Instance Principal Authentication, Fix type Signed-off-by: lucasjellema --- .../supported-state-stores/setup-oci-objectstorage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md index 4527e4469..60ba891c7 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -61,9 +61,9 @@ The above example uses secrets as plain strings. It is recommended to use a secr | compartmentOCID | Y | The OCID for the compartment that contains the bucket | `"ocid1.compartment.oc1..aaaaaaaacsssekayyuq7asjh78"` ## Setup OCI Object Storage -The OCI Object Storage state store needs to interact with Oracle Cloud Infrastructure. The state store supports two different approaches to authentication. One is based on an identity (a user or service account) and the other is instance principal authentication leveraging the permissions granted to the cmopute instance running the application workload. +The OCI Object Storage state store needs to interact with Oracle Cloud Infrastructure. The state store supports two different approaches to authentication. One is based on an identity (a user or service account) and the other is instance principal authentication leveraging the permissions granted to the compute instance running the application workload. Note: Resource Principal Authentication - used for resources that are not instances such as serverless functions - is not currently supported. -Dapr-applications running on Oracle Cloud Infrastructure - in a compute instance, a container on Kubernetes or as a function - can leverage instance principal authentication. See the [OCI documentation on calling OCI Services from instances](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm) for more background. In short: The instance needs to be member of a Dynamic Group and this Dynamic Group needs to get permissions for interacting with the Object Storage service through IAM policies. In case of such instance principal authentication, specify property instancePrincipalAuthentication as `"true"`. You do not need to configure the properties tenancyOCID, userOCID, region, fingerPrint and privateKey - these will be ignored if you define values for them. +Dapr-applications running on Oracle Cloud Infrastructure - in a compute instance or as a container on Kubernetes - can leverage instance principal authentication. See the [OCI documentation on calling OCI Services from instances](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm) for more background. In short: The instance needs to be member of a Dynamic Group and this Dynamic Group needs to get permissions for interacting with the Object Storage service through IAM policies. In case of such instance principal authentication, specify property instancePrincipalAuthentication as `"true"`. You do not need to configure the properties tenancyOCID, userOCID, region, fingerPrint and privateKey - these will be ignored if you define values for them. Identity based authentication interact with OCI through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. From 6cd8144d7465aaec15072ae21fcd8258b4326370 Mon Sep 17 00:00:00 2001 From: lucasjellema Date: Mon, 10 Jan 2022 14:52:10 +0100 Subject: [PATCH 20/73] Adding Configuration File based authentication to OCI ObjectStorage state store docs Signed-off-by: lucasjellema --- .../setup-oci-objectstorage.md | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md index 60ba891c7..4dfbf38ff 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -23,19 +23,25 @@ spec: metadata: - name: instancePrincipalAuthentication value: <"true" or "false"> # Optional. default: "false" + - name: configFileAuthentication + value: <"true" or "false"> # Optional. default: "false" . Not used when instancePrincipalAuthentication == "true" + - name: configFilePath + value: # Optional. default: the operating system specific default location for the OCI config file; on Linux: "~/.oci/config" . Only used when configFileAuthentication == "true" + - name: configFileProfile + value: # Optional. default: "DEFAULT" . Only used when configFileAuthentication == "true" - name: tenancyOCID - value: # Not used when instancePrincipalAuthentication == "true" + value: # Not used when configFileAuthentication == "true" or instancePrincipalAuthentication == "true" - name: userOCID - value: # Not used when instancePrincipalAuthentication == "true" + value: # Not used when configFileAuthentication == "true" or instancePrincipalAuthentication == "true" - name: fingerPrint - value: # Not used when instancePrincipalAuthentication == "true" - - name: privateKey # Not used when instancePrincipalAuthentication == "true" + value: # Not used when configFileAuthentication == "true" or instancePrincipalAuthentication == "true" + - name: privateKey # Not used when configFileAuthentication == "true" or instancePrincipalAuthentication == "true" value: | -----BEGIN RSA PRIVATE KEY----- REPLACE-WIH-PRIVATE-KEY-AS-IN-PEM-FILE -----END RSA PRIVATE KEY----- - name: region - value: # Not used when instancePrincipalAuthentication == "true" + value: # Not used when configFileAuthentication == "true" or instancePrincipalAuthentication == "true" - name: bucketName value: - name: compartmentOCID @@ -52,6 +58,9 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| | instancePrincipalAuthentication | N | Boolean to indicate whether instance principal based authentication is used. Default: `"false"` | `"true"` or `"false"` . +| configFileAuthentication | N | Boolean to indicate whether identity credential details are provided through a configuration file. Default: `"false"` Not required nor used when instancePrincipalAuthentication is true. | `"true"` or `"false"` . +| configFilePath | N | Full path name to the OCI configuration file. Default: the default location on your operating system for the OCI confile file, for example `"~/.oci/config"` on Linux. Not used when instancePrincipalAuthentication is true. | `"/home/apps/configuration-files/myOCIConfig.txt"`. +| configFileProfile | N | Name of profile in configuration file to use. Default: `"DEFAULT"` Not used when instancePrincipalAuthentication is true. | `"DEFAULT"` or `"PRODUCTION"` . | tenancyOCID | Y | The OCI tenancy identifier. Not required nor used when instancePrincipalAuthentication is true. | `"ocid1.tenancy.oc1..aaaaaaaag7c7sljhsdjhsdyuwe723"`. | userOCID | Y | The OCID for an OCI account (this account requires permissions to access OCI Object Storage). Not required nor used when instancePrincipalAuthentication is true.| `"ocid1.user.oc1..aaaaaaaaby4oyyyuqwy7623yuwe76"` | fingerPrint | Y | Fingerprint of the public key. Not required nor used when instancePrincipalAuthentication is true. | `"02:91:6c:49:e2:94:21:15:a7:6b:0e:a7:34:e1:3d:1b"` @@ -65,17 +74,22 @@ The OCI Object Storage state store needs to interact with Oracle Cloud Infrastru Dapr-applications running on Oracle Cloud Infrastructure - in a compute instance or as a container on Kubernetes - can leverage instance principal authentication. See the [OCI documentation on calling OCI Services from instances](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm) for more background. In short: The instance needs to be member of a Dynamic Group and this Dynamic Group needs to get permissions for interacting with the Object Storage service through IAM policies. In case of such instance principal authentication, specify property instancePrincipalAuthentication as `"true"`. You do not need to configure the properties tenancyOCID, userOCID, region, fingerPrint and privateKey - these will be ignored if you define values for them. -Identity based authentication interact with OCI through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. +Identity based authentication interacts with OCI through an OCI account that has permissions to create, read and delete objects through OCI Object Storage in the indicated bucket and that is allowed to create a bucket in the specified compartment if the bucket is not created beforehand. The OCI documentation [describes how to create an OCI Account](https://docs.oracle.com/en-us/iaas/Content/GSG/Tasks/addingusers.htm#Adding_Users). The interaction by the state store is performed using the public key's fingerprint and a private key from an RSA Key Pair generated for the OCI account. The [instructions for generating the key pair and getting hold of the required information](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm) are available in the OCI documentation. + +Details for the identity and identity's credentials to be used for interaction with OCI can be provided directly in the Dapr component properties file - using the properties tenancyOCID, userOCID, fingerPrint, privateKey and region - or can be provided from a configuration file as is common for many OCI related tools (such as CLI and Terraform) and SDKs. In the latter case, a default configuration file can be assumed (such as ~/.oci/config on Linux) or the exact file name and path can be provided through property configFilePath. A configuration file can contain multiple profiles; the desired profile can be specified through property configFileProfile. If no value is provided, DEFAULT is used as the name for the profile to be used. Note: if the indicated profile is not found, then the DEFAULT profile (if it exists) is used instead. The OCI SDK documentation gives [details about the definition of the configuration file](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm). If you wish to create the bucket for Dapr to use, you can do so beforehand. However, Object Storage state provider will create one - in the specified compartment - for you automatically if it doesn't exist. In order to setup OCI Object Storage as a state store, you will need the following properties: - **instancePrincipalAuthentication**: The flag that indicates if instance principal based authentication should be used. -- **tenancyOCID**: The identifier for the OCI cloud tenancy in which the state is to be stored. Not used when **instancePrincipalAuthentication** is true. -- **userOCID**: The identifier for the account used by the state store component to connect to OCI; this must be an account with appropriate permissions on the OCI Object Storage service in the specified compartment and bucket. Not used when **instancePrincipalAuthentication** is true. -- **fingerPrint**: The fingerprint for the public key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true. -- **privateKey**: The private key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true. -- **region**: The OCI region - for example **us-ashburn-1**, **eu-amsterdam-1**, **ap-mumbai-1**. Not used when **instancePrincipalAuthentication** is true. +- **configFileAuthentication**: The flag that indicates if the OCI identity credential details are provided through a configuration file. Not used when **instancePrincipalAuthentication** is true. +- **configFilePath**: Full path name to the OCI configuration file. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is not true. +- **configFileProfile**: Name of profile in configuration file to use. Default: `"DEFAULT"` Not required nor used when instancePrincipalAuthentication is true or **configFileAuthentication** is not true. When the specified profile is not found in the configuration file, the DEFAULT profile is used when it exists +- **tenancyOCID**: The identifier for the OCI cloud tenancy in which the state is to be stored. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is true. +- **userOCID**: The identifier for the account used by the state store component to connect to OCI; this must be an account with appropriate permissions on the OCI Object Storage service in the specified compartment and bucket. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is true. +- **fingerPrint**: The fingerprint for the public key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is true. +- **privateKey**: The private key in the RSA key pair generated for the account indicated by **userOCID**. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is true. +- **region**: The OCI region - for example **us-ashburn-1**, **eu-amsterdam-1**, **ap-mumbai-1**. Not used when **instancePrincipalAuthentication** is true - **bucketName**: The name of the bucket on OCI Object Storage in which state will be created. This bucket can exist already when the state store is initialized or it will be created during initialization of the state store. Note that the name of buckets is unique within a namespace - **compartmentOCID**: The identifier of the compartment within the tenancy in which the bucket exists or will be created. From 6abad58a89682606b2753915bd825642af97834f Mon Sep 17 00:00:00 2001 From: Amit Mor Date: Wed, 12 Jan 2022 03:13:08 +0200 Subject: [PATCH 21/73] update pub/sub aws snssqs component to 'beta' (#2089) Signed-off-by: Amit Mor --- .../reference/components-reference/supported-pubsub/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md index d939f0269..fb78b1374 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md @@ -35,8 +35,8 @@ Table captions: ### Amazon Web Services (AWS) | Name | Status | Component version | Since | -|---------------------------------------------------|--------| ---- |---------------| -| [AWS SNS/SQS]({{< ref setup-aws-snssqs.md >}}) | Alpha | v1 | 1.0 | +|---------------------------------------------------|--------| ---- | --------------| +| [AWS SNS/SQS]({{< ref setup-aws-snssqs.md >}}) | Beta | v1 | 1.6 | ### Google Cloud Platform (GCP) From 37f359bb442f2907fbf5c3a07b7bca1fffa09647 Mon Sep 17 00:00:00 2001 From: Lucas Jellema Date: Wed, 12 Jan 2022 05:52:04 +0100 Subject: [PATCH 22/73] Apply suggestions from code review Signed-off-by: lucasjellema Co-authored-by: Mark Fussell Signed-off-by: lucasjellema --- .../supported-state-stores/setup-oci-objectstorage.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md index 4dfbf38ff..67fb4a4d3 100644 --- a/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md +++ b/daprdocs/content/en/reference/components-reference/supported-state-stores/setup-oci-objectstorage.md @@ -80,7 +80,7 @@ Details for the identity and identity's credentials to be used for interaction w If you wish to create the bucket for Dapr to use, you can do so beforehand. However, Object Storage state provider will create one - in the specified compartment - for you automatically if it doesn't exist. -In order to setup OCI Object Storage as a state store, you will need the following properties: +In order to setup OCI Object Storage as a state store, you need the following properties: - **instancePrincipalAuthentication**: The flag that indicates if instance principal based authentication should be used. - **configFileAuthentication**: The flag that indicates if the OCI identity credential details are provided through a configuration file. Not used when **instancePrincipalAuthentication** is true. - **configFilePath**: Full path name to the OCI configuration file. Not used when **instancePrincipalAuthentication** is true or **configFileAuthentication** is not true. @@ -111,7 +111,7 @@ curl -X POST http://localhost:3500/v1.0/state \ ]' ``` -will create the following object: +creates the following object: | Bucket | Directory | Object Name | Object Content | Meta Tags | | ------------ | ------- | ----- | ----- | ---- | @@ -163,7 +163,7 @@ curl -X POST http://localhost:3500/v1.0/state \ ]' ``` -will create the following object: +creates the following object: | Bucket | Directory | Object Name | Object Content | Meta Tags | | ------------ | ------- | ----- | ----- | ---- | @@ -176,7 +176,7 @@ Note that expired state is not removed from the state store by this component. A ## Concurrency -OCI Object Storage state concurrency is achieved by using `ETag`s. Each object in OCI Object Storage is assigned a unique ETag when it is created or updated (aka replaced). When the Set and Delete requests for this state store specify the FirstWrite concurrency policy, then the request need to provide the actual ETag value for the state to be written or removed for the request to be successful. +OCI Object Storage state concurrency is achieved by using `ETag`s. Each object in OCI Object Storage is assigned a unique ETag when it is created or updated (aka replaced). When the `Set` and `Delete` requests for this state store specify the FirstWrite concurrency policy, then the request need to provide the actual ETag value for the state to be written or removed for the request to be successful. ## Consistency From 78d918ca37e55ed57aa775015de6c86a13b29138 Mon Sep 17 00:00:00 2001 From: 1046102779 Date: Thu, 13 Jan 2022 09:38:27 +0800 Subject: [PATCH 23/73] feature/pulsar: provide token && http request Signed-off-by: 1046102779 --- .../components-reference/supported-pubsub/setup-pulsar.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md index 2c4a25a23..284f57042 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md @@ -24,14 +24,17 @@ spec: value: "localhost:6650" - name: enableTLS value: "false" + - name: token + value: "eyJrZXlJZCI6InB1bHNhci1wajU0cXd3ZHB6NGIiLCJhbGciOiJIUzI1NiJ9.eyJzd" ``` ## Spec metadata fields | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| host | Y | Address of the Pulsar broker. Default is `"localhost:6650"` | `"localhost:6650"`| +| host | Y | Address of the Pulsar broker. Default is `"localhost:6650"` | `"localhost:6650"` OR `"http://pulsar-pj54qwwdpz4b-pulsar.ap-sg.public.pulsar.com:8080"`| | enableTLS | N | Enable TLS. Default: `"false"` | `"true"`, `"false"`| +| token | N | Enable Authentication. | [How to create pulsar token](https://pulsar.apache.org/docs/en/security-jwt/#generate-tokens)| ### Delay queue From f1974b3704e5f04ce9e0cdee1cb7699805bca8c8 Mon Sep 17 00:00:00 2001 From: Amit Mor Date: Fri, 14 Jan 2022 19:20:04 +0200 Subject: [PATCH 24/73] pubsub aws snssqs update (#2069) * pub/sub aws snssqs docs update to v1.6 Signed-off-by: Amit Mor * review requested changes Signed-off-by: Amit Mor * disableDeleteOnRetry + assetsManagement Signed-off-by: Amit Mor * endpoint and localstack docker Signed-off-by: Amit Mor * json annotations Signed-off-by: Amit Mor --- .../supported-pubsub/setup-aws-snssqs.md | 150 +++++++++++++++--- 1 file changed, 128 insertions(+), 22 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md index 4d1c1b802..627055f5a 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-aws-snssqs.md @@ -26,16 +26,35 @@ spec: value: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" - name: region value: "us-east-1" - - name: sessionToken - value: "TOKEN" - - name: messageVisibilityTimeout - value: 10 - - name: messageRetryLimit - value: 10 - - name: messageWaitTimeSeconds - value: 1 - - name: messageMaxNumber - value: 10 + # - name: endpoint # Optional. + # value: "http://localhost:4566" + # - name: sessionToken # Optional (mandatory if using AssignedRole, i.e. temporary accessKey and secretKey) + # value: "TOKEN" + # - name: messageVisibilityTimeout # Optional + # value: 10 + # - name: messageRetryLimit # Optional + # value: 10 + # - name: messageReceiveLimit # Optional + # value: 10 + # - name: sqsDeadLettersQueueName # Optional + # - value: "myapp-dlq" + # - name: messageWaitTimeSeconds # Optional + # value: 1 + # - name: messageMaxNumber # Optional + # value: 10 + # - name: fifo # Optional + # value: "true" + # - name: fifoMessageGroupID # Optional + # value: "app1-mgi" + # - name: disableEntityManagement # Optional + # value: "false" + # - name: disableDeleteOnRetryLimit # Optional + # value: "false" + # - name: assetsManagementTimeoutSeconds # Optional + # value: 5 + + + ``` {{% alert title="Warning" color="warning" %}} @@ -46,22 +65,42 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| accessKey | Y | ID of the AWS account with appropriate permissions to SNS and SQS. Can be `secretKeyRef` to use a secret reference | `"AKIAIOSFODNN7EXAMPLE"` -| secretKey | Y | Secret for the AWS user. Can be `secretKeyRef` to use a secret reference |`"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` -| region | Y | The AWS region to the instance. See this page for valid regions: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html. Ensure that SNS and SQS are available in that region.| `"us-east-1"` -| endpoint | N |AWS endpoint for the component to use. Only used for local development. The `endpoint` is unncessary when running against production AWS | `"http://localhost:4566"` -| sessionToken | N |AWS session token to use. A session token is only required if you are using temporary security credentials | `"TOKEN"` -| messageVisibilityTimeout | N |Amount of time in seconds that a message is hidden from receive requests after it is sent to a subscriber. Default: `10` | `10` -| messageRetryLimit | N |Number of times to resend a message after processing of that message fails before removing that message from the queue. Default: `10` | `10` -| messageWaitTimeSeconds | N |amount of time to await receipt of a message before making another request. Default: `1` | `1` -| messageMaxNumber | N |maximum number of messages to receive from the queue at a time. Default: `10`, Maximum: `10` | `10` +| accessKey | Y | ID of the AWS account/role with appropriate permissions to SNS and SQS (see below) | `"AKIAIOSFODNN7EXAMPLE"` +| secretKey | Y | Secret for the AWS user/role. If using an `AssumeRole` access, you will also need to provide a `sessionToken` |`"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"` +| region | Y | The AWS region where the SNS/SQS assets are located or be created in. See [this page](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/?p=ugi&l=na) for valid regions. Ensure that SNS and SQS are available in that region | `"us-east-1"` +| endpoint | N | AWS endpoint for the component to use. Only used for local development with, for example, [localstack](https://github.com/localstack/localstack). The `endpoint` is unncessary when running against production AWS | `"http://localhost:4566"` +| sessionToken | N | AWS session token to use. A session token is only required if you are using temporary security credentials | `"TOKEN"` +| messageReceiveLimit | N | Number of times a message is received, after processing of that message fails, that once reached, results in removing of that message from the queue. If `sqsDeadLettersQueueName` is specified, `messageReceiveLimit` is the number of times a message is received, after processing of that message fails, that once reached, results in moving of the message to the SQS dead-letters queue. Default: `10` | `10` +| sqsDeadLettersQueueName | N | Name of the dead letters queue for this application | `"myapp-dlq"` +| messageVisibilityTimeout | N | Amount of time in seconds that a message is hidden from receive requests after it is sent to a subscriber. Default: `10` | `10` +| messageRetryLimit | N | Number of times to resend a message after processing of that message fails before removing that message from the queue. Default: `10` | `10` +| messageWaitTimeSeconds | N | The duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than `messageWaitTimeSeconds`. If no messages are available and the wait time expires, the call returns successfully with an empty list of messages. Default: `1` | `1` +| messageMaxNumber | N | Maximum number of messages to receive from the queue at a time. Default: `10`, Maximum: `10` | `10` +| fifo | N | Use SQS FIFO queue to provide message ordering and deduplication. Default: `"false"`. See further details about [SQS FIFO](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html) | `"true"`, `"false"` +| fifoMessageGroupID | N | If `fifo` is enabled, instructs Dapr to use a custom [Message Group ID](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html) for the pubsub deployment. This is not mandatory as Dapr creates a custom Message Group ID for each producer, thus ensuring ordering of messages per a Dapr producer. Default: `""` | `"app1-mgi"` +| disableEntityManagement | N | When set to true, SNS topics, SQS queues and the SQS subscriptions to SNS do not get created automatically. Default: `"false"` | `"true"`, `"false"` +| disableDeleteOnRetryLimit | N | When set to true, after retrying and failing of `messageRetryLimit` times processing a message, reset the message visibility timeout so that other consumers can try processing, instead of deleting the message from SQS (the default behvior). Default: `"false"` | `"true"`, `"false"` +| assetsManagementTimeoutSeconds | N | Amount of time in seconds, for an AWS asset management operation, before it times out and cancelled. Asset management operations are any operations performed on STS, SNS and SQS, except message publish and consume operations that implement the default Dapr component retry behavior. The value can be set to any non-negative float/integer. Default: `5` | `0.5`, `10` + + +* Dapr created SNS topic and SQS queue names conform with [AWS specifications](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-queues.html). By default, Dapr creates an SQS queue name based on the consumer `app-id`, therefore Dapr might perform name standardization to meet with AWS specifications. +* Using SQS FIFO (`fifo` metadata field set to `"true"`), per AWS specifications, provides message ordering and deduplication, but incurs a lower SQS processing throughput, among other caveats +* Be aware that specifying `fifoMessageGroupID` limits the number of concurrent consumers of the FIFO queue used to only one but guarantees global ordering of messages published by the app's Dapr sidecars. See [this](https://aws.amazon.com/blogs/compute/solving-complex-ordering-challenges-with-amazon-sqs-fifo-queues/) post to better understand the topic of Message Group IDs and FIFO queues. + + ## Create an SNS/SQS instance {{< tabs "Self-Hosted" "Kubernetes" "AWS" >}} {{% codetab %}} -For local development the [localstack project](https://github.com/localstack/localstack) is used to integrate AWS SNS/SQS. Follow the instructions [here](https://github.com/localstack/localstack#installing) to install the localstack CLI. +For local development the [localstack project](https://github.com/localstack/localstack) is used to integrate AWS SNS/SQS. Follow the instructions [here](https://github.com/localstack/localstack#running) to run localstack. + +To run localstack locally from the command line using Docker, apply the following cmd: +```shell +docker run --rm -it -p 4566:4566 -p 4571:4571 -e SERVICES="sts,sns,sqs" -e AWS_DEFAULT_REGION="us-east-1" localstack/localstack +``` + In order to use localstack with your pubsub binding, you need to provide the `endpoint` configuration in the component metadata. The `endpoint` is unncessary when running against production AWS. @@ -77,9 +116,13 @@ spec: type: pubsub.snssqs version: v1 metadata: + - name: accessKey + value: "anyString" + - name: secretKey + value: "anyString" - name: endpoint value: http://localhost:4566 - # Use us-east-1 for localstack + # Use us-east-1 or any other region if provided to localstack as defined by "AWS_DEFAULT_REGION" envvar - name: region value: us-east-1 ``` @@ -133,8 +176,71 @@ spec: {{% /codetab %}} {{% codetab %}} -In order to run in AWS, you should create an IAM user with permissions to the SNS and SQS services. +In order to run in AWS, you should create or assign an IAM user with permissions to the SNS and SQS services having a Policy such as: +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "YOUR_POLICY_NAME", + "Effect": "Allow", + "Action": [ + "sqs:CreateQueue", + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:GetQueueAttributes", + "sqs:SetQueueAttributes", + "sns:CreateTopic", + "sns:ListSubscriptionsByTopic", + "sns:Publish", + "sns:Subscribe", + "sns:ListSubscriptionsByTopic", + "sns:GetTopicAttributes" + + ], + "Resource": [ + "arn:aws:sns:AWS_REGION:AWS_ACCOUNT_ID:*", + "arn:aws:sqs:AWS_REGION:AWS_ACCOUNT_ID:*" + ] + } + ] +} +``` Use the `AWS account ID` and `AWS account secret` and plug them into the `accessKey` and `secretKey` in the component metadata using Kubernetes secrets and `secretKeyRef`. + + +Alternatively, if you want to provision the SNS and SQS assets using your own tool of choice (e.g. Terraform), while preventing Dapr from doing so dynamically, you need to enable `disableEntityManagement` and assign your Dapr-using application with an IAM Role having a Policy such as: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "YOUR_POLICY_NAME", + "Effect": "Allow", + "Action": [ + "sqs:DeleteMessage", + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:GetQueueAttributes", + "sns:Publish", + "sns:ListSubscriptionsByTopic", + "sns:GetTopicAttributes" + + ], + "Resource": [ + "arn:aws:sns:AWS_REGION:AWS_ACCOUNT_ID:APP_TOPIC_NAME", + "arn:aws:sqs:AWS_REGION:AWS_ACCOUNT_ID:APP_ID" + ] + } + ] +} +``` + +If you are running your applications on an EKS cluster with dynamic assets creation (the default Dapr behavior) {{% /codetab %}} {{< /tabs >}} From 30e018604c48fa64d13e09044348c81e74d2bb2e Mon Sep 17 00:00:00 2001 From: Mark Fussell Date: Fri, 14 Jan 2022 13:00:07 -0800 Subject: [PATCH 25/73] Added link to Apache Pulsar docs --- .../components-reference/supported-pubsub/setup-pulsar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md index 284f57042..8514f72de 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md @@ -8,7 +8,7 @@ aliases: --- ## Component format -To setup Pulsar pubsub create a component of type `pubsub.pulsar`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. +To setup Apache Pulsar pubsub create a component of type `pubsub.pulsar`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. For more information on Apache Pulsar [read the docs]({{< ref "https://pulsar.apache.org/docs/en/concepts-overview/" >}}) ```yaml apiVersion: dapr.io/v1alpha1 From 818c0a622bad65c0a630f46b80f7c6961ef3eaf7 Mon Sep 17 00:00:00 2001 From: Dmitry Shmulevich Date: Fri, 14 Jan 2022 15:31:00 -0800 Subject: [PATCH 26/73] update state query API doc with usage limitations (#2101) Signed-off-by: Dmitry Shmulevich Co-authored-by: Mark Fussell Co-authored-by: Mark Fussell --- .../state-management/howto-state-query-api.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md index b0e4a040c..4a5bd7cca 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-state-query-api.md @@ -17,8 +17,13 @@ The state query API provides a way of querying the key/value data stored in stat Even though the state store is a key/value store, the `value` might be a JSON document with its own hierarchy, keys, and values. The query API allows you to use those keys and values to retrive corresponding documents. -This query API does not support querying of actor state stored in a state store. For that you need to use the query API for the specific database. -See [querying actor state]({{< ref "state-management-overview.md#querying-actor-state" >}}). +### Limitations +The state query API has the following limitations: + + - The API does not support querying of actor state stored in a state store. For that you need to use the query API for the specific database. See [querying actor state]({{< ref "state-management-overview.md#querying-actor-state" >}}). + - The API does not work with Dapr [encrypted state stores]({{}}) capability. Since the encryption is done by the Dapr runtime and stored as encrypted data, then this effectively prevents server side querying. + + You can find additional information in the [related links]({{< ref "#related-links" >}}) section. From 17369eed68ffe9c8ebd2f40e07d607eec36a7553 Mon Sep 17 00:00:00 2001 From: rabollin Date: Tue, 18 Jan 2022 18:38:24 +0530 Subject: [PATCH 27/73] Update open-telemetry-collector-appinsights.yaml Signed-off-by: rabollin --- .../open-telemetry-collector-appinsights.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/static/docs/open-telemetry-collector/open-telemetry-collector-appinsights.yaml b/daprdocs/static/docs/open-telemetry-collector/open-telemetry-collector-appinsights.yaml index aa760183b..2b606b203 100644 --- a/daprdocs/static/docs/open-telemetry-collector/open-telemetry-collector-appinsights.yaml +++ b/daprdocs/static/docs/open-telemetry-collector/open-telemetry-collector-appinsights.yaml @@ -71,7 +71,7 @@ spec: spec: containers: - name: otel-collector - image: otel/opentelemetry-collector-contrib-dev:latest + image: otel/opentelemetry-collector-contrib:0.40.0 command: - "/otelcontribcol" - "--config=/conf/otel-collector-config.yaml" From 65bdea43f51869b814e0c851fe19ba043441085c Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Tue, 18 Jan 2022 16:00:24 -0800 Subject: [PATCH 28/73] Remove app-protocol from gRPC proxying (#2116) Signed-off-by: Nick Greenfield --- .../service-invocation/howto-invoke-services-grpc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-services-grpc.md b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-services-grpc.md index 8639791a7..d4f810aa5 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-services-grpc.md +++ b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-services-grpc.md @@ -90,7 +90,7 @@ spec: Run the sidecar and the Go server: ```bash -dapr run --app-id server --app-protocol grpc --app-port 50051 --config config.yaml -- go run main.go +dapr run --app-id server --app-port 50051 --config config.yaml -- go run main.go ``` Using the Dapr CLI, we're assigning a unique id to the app, `server`, using the `--app-id` flag. From 0cc4b38d8868991df20b8a5c7c070c120a2ad0c0 Mon Sep 17 00:00:00 2001 From: Zheng Dayu Date: Thu, 20 Jan 2022 06:28:25 +0800 Subject: [PATCH 29/73] add alibabacloud oos parameter store docs (#2111) Signed-off-by: Zheng Dayu Co-authored-by: Yaron Schneider --- .../supported-secret-stores/_index.md | 6 ++ .../alicloud-oos-parameter-store.md | 56 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 daprdocs/content/en/reference/components-reference/supported-secret-stores/alicloud-oos-parameter-store.md diff --git a/daprdocs/content/en/reference/components-reference/supported-secret-stores/_index.md b/daprdocs/content/en/reference/components-reference/supported-secret-stores/_index.md index 16dc4879f..a6509a8e4 100644 --- a/daprdocs/content/en/reference/components-reference/supported-secret-stores/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-secret-stores/_index.md @@ -46,3 +46,9 @@ Table captions: | Name | Status | Component version | Since | |---------------------------------------------------------------------------------------|--------| ---- |--------------| | [Azure Key Vault]({{< ref azure-keyvault.md >}}) | Stable | v1 | 1.0 | + +### Alibaba Cloud + +| Name | Status | Component version | Since | +|---------------------------------------------------------------------------------------|--------| ---- |--------------| +| [AlibabaCloud OOS Parameter Store]({{< ref alicloud-oos-parameter-store.md >}}) | Alpha | v1 | 1.6 | diff --git a/daprdocs/content/en/reference/components-reference/supported-secret-stores/alicloud-oos-parameter-store.md b/daprdocs/content/en/reference/components-reference/supported-secret-stores/alicloud-oos-parameter-store.md new file mode 100644 index 000000000..7ceaefa84 --- /dev/null +++ b/daprdocs/content/en/reference/components-reference/supported-secret-stores/alicloud-oos-parameter-store.md @@ -0,0 +1,56 @@ +--- +type: docs +title: "AlibabaCloud OOS Parameter Store" +linkTitle: "AlibabaCloud OOS Parameter Store" +description: Detailed information on the AlibabaCloud OOS Parameter Store - secret store component +aliases: + - "/operations/components/setup-secret-store/supported-secret-stores/alibabacloud-oos-parameter-store/" +--- + +## Component format + +To setup AlibabaCloud OOS Parameter Store secret store create a component of type `secretstores.alicloud.parameterstore`. See [this guide]({{< ref "setup-secret-store.md#apply-the-configuration" >}}) on how to create and apply a secretstore configuration. See this guide on [referencing secrets]({{< ref component-secrets.md >}}) to retrieve and use the secret with Dapr components. + +```yaml +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: alibabacloudparameterstore + namespace: default +spec: + type: secretstores.alicloud.parameterstore + version: v1 + metadata: + - name: regionId + value: "[alicloud_region_id]" + - name: accessKeyId + value: "[alicloud_access_key_id]" + - name: accessKeySecret + value: "[alicloud_access_key_secret]" + - name: securityToken + value: "[alicloud_security_token]" +``` + +{{% alert title="Warning" color="warning" %}} +The above example uses secrets as plain strings. It is recommended to use a local secret store such as [Kubernetes secret store]({{< ref kubernetes-secret-store.md >}}) or a [local file]({{< ref file-secret-store.md >}}) to bootstrap secure key storage. +{{% /alert %}} + +## Spec metadata fields + +| Field | Required | Details | Example | +|--------------------|:--------:|-------------------------------------------------------------------------|---------------------| +| regionId | Y | The specific region the AlibabaCloud OOS Parameter Store instance is deployed in | `"cn-hangzhou"` | +| accessKeyId | Y | The AlibabaCloud Access Key ID to access this resource | `"accessKeyId"` | +| accessKeySecret | Y | The AlibabaCloud Access Key Secret to access this resource | `"accessKeySecret"` | +| securityToken | N | The AlibabaCloud Security Token to use | `"securityToken"` | + +## Create an AlibabaCloud OOS Parameter Store instance + +Setup AlibabaCloud OOS Parameter Store using the AlibabaCloud documentation: https://www.alibabacloud.com/help/en/doc-detail/186828.html. + +## Related links + +- [Secrets building block]({{< ref secrets >}}) +- [How-To: Retrieve a secret]({{< ref "howto-secrets.md" >}}) +- [How-To: Reference secrets in Dapr components]({{< ref component-secrets.md >}}) +- [Secrets API reference]({{< ref secrets_api.md >}}) From 604485977b22c9f66ac008f5b358fe03859fed5f Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Wed, 19 Jan 2022 16:26:44 -0800 Subject: [PATCH 30/73] Upmerge v1.5 to v1.6 20220119 (#2119) * moving middleware to samples Signed-off-by: Paul Yuknewicz * Updated middleware doc to point to updated sample location Signed-off-by: Paul Yuknewicz * Fixing one more link after moving middleware code from quickstarts to samples repo Signed-off-by: Paul Yuknewicz Co-authored-by: Paul Yuknewicz --- daprdocs/content/en/developing-applications/middleware.md | 2 +- daprdocs/content/en/getting-started/quickstarts.md | 1 - .../supported-middleware/middleware-oauth2.md | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/developing-applications/middleware.md b/daprdocs/content/en/developing-applications/middleware.md index a48ceac16..282cffd2d 100644 --- a/daprdocs/content/en/developing-applications/middleware.md +++ b/daprdocs/content/en/developing-applications/middleware.md @@ -74,4 +74,4 @@ After the components-contrib change has been accepted, submit another pull reque * [Component schema]({{< ref component-schema.md >}}) * [Configuration overview]({{< ref configuration-overview.md >}}) -* [Middleware quickstart](https://github.com/dapr/quickstarts/tree/master/middleware) +* [Middleware sample](https://github.com/dapr/samples/tree/master/middleware-oauth-google) diff --git a/daprdocs/content/en/getting-started/quickstarts.md b/daprdocs/content/en/getting-started/quickstarts.md index de6a3313c..ecf04966a 100644 --- a/daprdocs/content/en/getting-started/quickstarts.md +++ b/daprdocs/content/en/getting-started/quickstarts.md @@ -22,7 +22,6 @@ The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.5.0) are a co | [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.5.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. | | [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.5.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. | | [Bindings](https://github.com/dapr/quickstarts/tree/v1.5.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. | -| [Middleware](https://github.com/dapr/quickstarts/tree/v1.5.0/middleware) | Demonstrates use of Dapr middleware to enable OAuth 2.0 authorization. | | [Observability](https://github.com/dapr/quickstarts/tree/v1.5.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. | | [Secret Store](https://github.com/dapr/quickstarts/tree/v1.5.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. | diff --git a/daprdocs/content/en/reference/components-reference/supported-middleware/middleware-oauth2.md b/daprdocs/content/en/reference/components-reference/supported-middleware/middleware-oauth2.md index 7097835a1..90e0a3fa1 100644 --- a/daprdocs/content/en/reference/components-reference/supported-middleware/middleware-oauth2.md +++ b/daprdocs/content/en/reference/components-reference/supported-middleware/middleware-oauth2.md @@ -74,7 +74,7 @@ spec: ## Related links - [Configure API authorization with OAuth]({{< ref oauth >}}) -- [Middleware OAuth quickstart](https://github.com/dapr/quickstarts/tree/master/middleware) +- [Middleware OAuth sample (interactive)](https://github.com/dapr/samples/tree/master/middleware-oauth-google) - [Middleware]({{< ref middleware.md >}}) - [Configuration concept]({{< ref configuration-concept.md >}}) - [Configuration overview]({{< ref configuration-overview.md >}}) From 50911c11264af4742b78604ca9de7a797cdf7067 Mon Sep 17 00:00:00 2001 From: Mukundan Sundararajan Date: Thu, 20 Jan 2022 16:47:20 +0530 Subject: [PATCH 31/73] Update docs for Event Hubs pubsub Signed-off-by: Mukundan Sundararajan --- .gitignore | 1 + .../supported-pubsub/_index.md | 2 +- .../supported-pubsub/setup-azure-eventhubs.md | 37 ++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 35a57cc3a..2cf039ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ node_modules/ daprdocs/public daprdocs/resources/_gen .venv/ +.hugo_build.lock \ No newline at end of file diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md index fb78b1374..d7ad5a8c6 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md @@ -48,5 +48,5 @@ Table captions: | Name | Status | Component version | Since | |-----------------------------------------------------------|--------| ----------------| -- | -| [Azure Event Hubs]({{< ref setup-azure-eventhubs.md >}}) | Alpha | v1 | 1.0 | +| [Azure Event Hubs]({{< ref setup-azure-eventhubs.md >}}) | Beta | v1 | 1.6 | | [Azure Service Bus]({{< ref setup-azure-servicebus.md >}})| Stable | v1 | 1.0 | diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md index 1af3cd062..e47b03e2f 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md @@ -9,6 +9,7 @@ aliases: ## Component format To setup Azure Event Hubs pubsub create a component of type `pubsub.azure.eventhubs`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. +Apart from the configuration metadata fields shown below, Azure Event Hubs also support [Azure Authentication]({{< ref "authenticating-azure.md" >}}) mechanisms. ```yaml apiVersion: dapr.io/v1alpha1 @@ -20,8 +21,23 @@ spec: type: pubsub.azure.eventhubs version: v1 metadata: - - name: connectionString + - name: connectionString # Either connectionString or eventHubNamespace. Should not be used when + # Azure Authentication mechanism is used. value: "Endpoint=sb://{EventHubNamespace}.servicebus.windows.net/;SharedAccessKeyName={PolicyName};SharedAccessKey={Key};EntityPath={EventHub}" + - name: eventHubNamespace # Either connectionString or eventHubNamespace. Should be used when + # Azure Authentication mechanism is used. + value: "namespace" + - name: enableEntityManagement + value: "false" + ## The following four properties are needed only if enableEntityManagement is set to true + - name: resourceGroupName + value: "test-rg" + - name: subscriptionID + value: "value of Azure subscription ID" + - name: partitionCount + value: "1" + - name: messageRetentionInDays + ## Subscriber attributes - name: storageAccountName value: "myeventhubstorage" - name: storageAccountKey @@ -38,10 +54,16 @@ The above example uses secrets as plain strings. It is recommended to use a secr | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| connectionString | Y | Connection-string for the Event Hubs | `"Endpoint=sb://{EventHubNamespace}.servicebus.windows.net/;SharedAccessKeyName={PolicyName};SharedAccessKey={Key};EntityPath={EventHub}"` +| connectionString | Y | Connection-string for the Event Hub or the Event Hub namespace. Mutally exclusive with `eventHubNamespace` field. Not to be used when [Azure Authentication]({{< ref "authenticating-azure.md" >}}) is used | `"Endpoint=sb://{EventHubNamespace}.servicebus.windows.net/;SharedAccessKeyName={PolicyName};SharedAccessKey={Key};EntityPath={EventHub}"` or `"Endpoint=sb://{EventHubNamespace}.servicebus.windows.net/;SharedAccessKeyName={PolicyName};SharedAccessKey={Key}"` +| eventHubNamespace | Y | The Event Hub Namespace name. Mutally exclusive with `connectionString` field. To be used when [Azure Authentication]({{< ref "authenticating-azure.md" >}}) is used | `"namespace"` | storageAccountName | Y | Storage account name to use for the EventProcessorHost |`"myeventhubstorage"` | storageAccountKey | Y | Storage account key to use for the EventProcessorHost. Can be `secretKeyRef` to use a secret reference | `"112233445566778899"` | storageContainerName | Y | Storage container name for the storage account name. | `"myeventhubstoragecontainer"` +| enableEntityManagement | N | Boolean value to allow management of EventHub namespace. Default: `false` | `"true", "false"` +| resourceGroupName | N | Name of the resource group the event hub namespace is a part of. Needed when entity management is enabled | `"test-rg"` +| subscriptionID | N | Azure subscription ID value. Needed when entity management is enabled | `"azure subscription id"` +| partitionCount | N | Number of partitions for the new event hub. Only used when entity management is enabled. Default: `"1"` | `"2"` +| messageRetentionInDays | N | Number of days to retain messages for in the newly created event hub. Used only when entity management is enabled. Default: `"1"` | `"90"` ## Create an Azure Event Hub @@ -58,6 +80,16 @@ For example, a Dapr app running on Kubernetes with `dapr.io/app-id: "myapp"` wil Note: Dapr passes the name of the Consumer group to the EventHub and so this is not supplied in the metadata. +## Entity Management + +When entity management is enabled in configuration, as long as the application has the right role and permissions to manipulate the Event Hub namespace, creation of Event Hubs and consumer groups can be done on the fly. + +The Evet Hub name is the `topic` field in the incoming request to publish or subscribe to, while the consumer group name is the name of the `dapr app` which subscribes to a given Event Hub. For example, a Dapr app running on Kubernetes with name `dapr.io/app-id: "myapp"` requires an Event Hubs consumer group named `myapp`. + +Entity management is only possible when using [Azure Authentication]({{< ref "authenticating-azure.md" >}}) mechanisms and not via `connectionString`. + +Note: Dapr passes the name of the Consumer group to the EventHub and this is not supplied in the metadata. + ## Subscribing to Azure IoT Hub Events Azure IoT Hub provides an [endpoint that is compatible with Event Hubs](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-read-builtin#read-from-the-built-in-endpoint), so the Azure Event Hubs pubsub component can also be used to subscribe to Azure IoT Hub events. @@ -98,3 +130,4 @@ For example, the headers of a delivered HTTP subscription message would contain: - [Basic schema for a Dapr component]({{< ref component-schema >}}) - Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components - [Pub/Sub building block]({{< ref pubsub >}}) +- [Authentication to Azure]({{< ref "authenticating-azure.md" >}}) From 15bb344f5ab77aa909439b6b04a187558128fc9e Mon Sep 17 00:00:00 2001 From: Mukundan Sundararajan Date: Thu, 20 Jan 2022 23:56:32 +0530 Subject: [PATCH 32/73] fix typo Signed-off-by: Mukundan Sundararajan --- .../supported-pubsub/setup-azure-eventhubs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md index e47b03e2f..16de600b6 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-azure-eventhubs.md @@ -9,7 +9,7 @@ aliases: ## Component format To setup Azure Event Hubs pubsub create a component of type `pubsub.azure.eventhubs`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. -Apart from the configuration metadata fields shown below, Azure Event Hubs also support [Azure Authentication]({{< ref "authenticating-azure.md" >}}) mechanisms. +Apart from the configuration metadata fields shown below, Azure Event Hubs also supports [Azure Authentication]({{< ref "authenticating-azure.md" >}}) mechanisms. ```yaml apiVersion: dapr.io/v1alpha1 From 429bce6f30e4a7384d41ddcecf2d448441f1c35c Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Fri, 21 Jan 2022 00:14:31 +0530 Subject: [PATCH 33/73] Update MQTT pubsub to beta (#2113) Signed-off-by: shivam Co-authored-by: Mark Fussell --- .../reference/components-reference/supported-pubsub/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md index fb78b1374..4d5c1ccd0 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/_index.md @@ -24,7 +24,7 @@ Table captions: |-------------------------------------------------------|--------| -----| ------------- | | [Apache Kafka]({{< ref setup-apache-kafka.md >}}) | Stable | v1 | 1.5 | | [Hazelcast]({{< ref setup-hazelcast.md >}}) | Alpha | v1 | 1.0 | -| [MQTT]({{< ref setup-mqtt.md >}}) | Alpha | v1 | 1.0 | +| [MQTT]({{< ref setup-mqtt.md >}}) | Beta | v1 | 1.6 | | [NATS Streaming]({{< ref setup-nats-streaming.md >}}) | Beta | v1 | 1.0 | | [In Memory]({{< ref setup-inmemory.md >}}) | Alpha | v1 | 1.4 | | [JetStream]({{< ref setup-jetstream.md >}}) | Alpha | v1 | 1.4 | From 888f47f145ee7f7c8d70409d9d73f7e943b02c28 Mon Sep 17 00:00:00 2001 From: Abel Perez Martinez Date: Thu, 20 Jan 2022 18:59:05 +0000 Subject: [PATCH 34/73] Added notes for EKS users to watch out for hostnework issue (#2112) Signed-off-by: Abel Perez Martinez Co-authored-by: Mark Fussell --- .../troubleshooting/common_issues.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/daprdocs/content/en/operations/troubleshooting/common_issues.md b/daprdocs/content/en/operations/troubleshooting/common_issues.md index f63e0d54d..c374dd00f 100644 --- a/daprdocs/content/en/operations/troubleshooting/common_issues.md +++ b/daprdocs/content/en/operations/troubleshooting/common_issues.md @@ -64,6 +64,32 @@ In order to further diagnose any issue, check the logs of the Dapr sidecar injec *Note: If you installed Dapr to a different namespace, replace dapr-system above with the desired namespace* +If you are deploying Dapr on Amazon EKS and using an overlay network such as Calico, you will need to set `hostNetwork` parameter to true, this is a limitation of EKS with such CNIs. + +You can set this parameter using Helm `values.yaml` file: + +``` +helm upgrade --install dapr dapr/dapr \ + --namespace dapr-system \ + --create-namespace \ + --values values.yaml +``` + +`values.yaml` +```yaml +dapr_sidecar_injector: + hostNetwork: true +``` + +or using command line: + +``` +helm upgrade --install dapr dapr/dapr \ + --namespace dapr-system \ + --create-namespace \ + --set dapr_sidecar_injector.hostNetwork=true +``` + ## My pod is in CrashLoopBackoff or another failed state due to the daprd sidecar If the Dapr sidecar (`daprd`) is taking too long to initialize, this might be surfaced as a failing health check by Kubernetes. From 33981f34f8752d87c3856873efdc98d583eb7177 Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Thu, 20 Jan 2022 12:35:59 -0800 Subject: [PATCH 35/73] List the specific software dependencies tested for a given Dapr releaseList (#2105) * List the specific software dependencies tested for a given Dapr releaseList Signed-off-by: Nick Greenfield * Add OTEL link Signed-off-by: Nick Greenfield * Change OTEL link Signed-off-by: Nick Greenfield Co-authored-by: Mark Fussell --- .../en/operations/support/support-release-policy.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 6bd27c761..7bed1e92d 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -95,9 +95,14 @@ After announcing a future breaking change, the change will happen in 2 releases ## Upgrade on Hosting platforms Dapr can support multiple hosting platforms for production. With the 1.0 release the two supported platforms are Kubernetes and physical machines. For Kubernetes upgrades see [Production guidelines on Kubernetes]({{< ref kubernetes-production.md >}}) -### Supported Kubernetes versions +### Supported versions of dependencies +Below is a list of software that the latest version of Dapr (v{{% dapr-latest-version long="true" %}}) has been tested against. -Dapr follows [Kubernetes Version Skew Policy](https://kubernetes.io/releases/version-skew-policy). +| Dependency | Supported Version | +|-----------------------|----------------------------------------------------------------------------------------------------------------------------------| +| Kubernetes | Dapr support for Kubernetes is aligned with [Kubernetes Version Skew Policy](https://kubernetes.io/releases/version-skew-policy/) | +| [Open Telemetry collector (OTEL)](https://github.com/open-telemetry/opentelemetry-collector/releases)| v0.4.0| +| [Prometheus](https://prometheus.io/download/) | v2.28 | ## Related links * Read the [Versioning policy]({{< ref support-versioning.md >}}) From 6d7f5c86c68c9382c83f48f197caa176ed02bd63 Mon Sep 17 00:00:00 2001 From: Taction Date: Fri, 21 Jan 2022 05:15:57 +0800 Subject: [PATCH 36/73] Feature/pulsar: Add tenant namespace and backoff doc (#1930) * Add tenant namespace and backoff Signed-off-by: Taction * fix review Signed-off-by: Taction Co-authored-by: Mark Fussell --- .../supported-pubsub/setup-pulsar.md | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md index 2c4a25a23..834df5457 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md @@ -24,14 +24,35 @@ spec: value: "localhost:6650" - name: enableTLS value: "false" -``` + - name: tenant + value: "public" + - name: namespace + value: "default" + - name: persistent + value: "true" + - name: backOffPolicy + value: "constant" + - name: backOffMaxRetries + value: "-1" +``` ## Spec metadata fields | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| host | Y | Address of the Pulsar broker. Default is `"localhost:6650"` | `"localhost:6650"`| -| enableTLS | N | Enable TLS. Default: `"false"` | `"true"`, `"false"`| +| host | Y | Address of the Pulsar broker. Default is `"localhost:6650"` | `"localhost:6650"` +| enableTLS | N | Enable TLS. Default: `"false"` | `"true"`, `"false"` +| tenant | N | The topic tenant within the instance. Tenants are essential to multi-tenancy in Pulsar, and spread across clusters. Default: `"public"` | `"public"` +| namespace | N | The administrative unit of the topic, which acts as a grouping mechanism for related topics. Default: `"default"` | `"default"` +| persistent | N | Pulsar supports two kind of topics: [persistent](https://pulsar.apache.org/docs/en/concepts-architecture-overview#persistent-storage) and [non-persistent](https://pulsar.apache.org/docs/en/concepts-messaging/#non-persistent-topics). With persistent topics, all messages are durably persisted on disks (if the broker is not standalone, messages are durably persisted on multiple disks), whereas data for non-persistent topics is not persisted to storage disks. Note: the default retry behavior is to retry until it succeeds, so when you use a non-persistent theme, you can reduce or prohibit retries by defining `backOffMaxRetries` to `0`. Default: `"true"` | `"true"`, `"false"` +| backOffPolicy | N | Retry policy, `"constant"` is a backoff policy that always returns the same backoff delay. `"exponential"` is a backoff policy that increases the backoff period for each retry attempt using a randomization function that grows exponentially. Defaults to `"constant"`. | `constant`、`exponential` | +| backOffDuration | N | The fixed interval only takes effect when the `backOffPolicy` is `"constant"`. There are two valid formats, one is the fraction with a unit suffix format, and the other is the pure digital format that is processed as milliseconds. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Defaults to `"5s"`. | `"5s"`、`"5000"` | +| backOffInitialInterval | N | The backoff initial interval on retry. Only takes effect when the `backOffPolicy` is `"exponential"`. There are two valid formats, one is the fraction with a unit suffix format, and the other is the pure digital format that is processed as milliseconds. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Defaults to `"500"` | `"50"` | +| backOffMaxInterval | N | The backoff initial interval on retry. Only takes effect when the `backOffPolicy` is `"exponential"`. There are two valid formats, one is the fraction with a unit suffix format, and the other is the pure digital format that is processed as milliseconds. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Defaults to `"60s"` | `"60000"` | +| backOffMaxRetries | N | The maximum number of retries to process the message before returning an error. Defaults to `"0"` which means the component will not retry processing the message. `"-1"` will retry indefinitely until the message is processed or the application is shutdown. Any positive number is treated as the maximum retry count. | `"3"` | +| backOffRandomizationFactor | N | Randomization factor, between 1 and 0, including 0 but not 1. Randomized interval = RetryInterval * (1 ± backOffRandomizationFactor). Defaults to `"0.5"`. | `"0.5"` | +| backOffMultiplier | N | Backoff multiplier for the policy. Increments the interval by multiplying it with the multiplier. Defaults to `"1.5"` | `"1.5"` | +| backOffMaxElapsedTime | N | After MaxElapsedTime the ExponentialBackOff returns Stop. There are two valid formats, one is the fraction with a unit suffix format, and the other is the pure digital format that is processed as milliseconds. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Defaults to `"15m"` | `"15m"` | ### Delay queue From 162a07e1268478846d6c42ab60f521fcf9d24a29 Mon Sep 17 00:00:00 2001 From: Phil Kedy Date: Fri, 21 Jan 2022 10:35:28 -0500 Subject: [PATCH 37/73] Comments per PR Signed-off-by: Phil Kedy --- .../supported-pubsub/setup-apache-kafka.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md index c44505880..051f6a473 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md @@ -138,10 +138,10 @@ curl -X POST http://localhost:3500/v1.0/publish/myKafka/myTopic?metadata.partiti ### Message headers -All other metadata key/value pairs (that are not `partitionKey`) are set as headers in the Kafka message. For example, here is an example setting a `correlationId` for the message. +All other metadata key/value pairs (that are not `partitionKey`) are set as headers in the Kafka message. Here is an example setting a `correlationId` for the message. ```shell -curl -X POST http://localhost:3500/v1.0/publish/myKafka/myTopic?metadata.correlationId=myCorrelationID \ +curl -X POST http://localhost:3500/v1.0/publish/myKafka/myTopic?metadata.correlationId=myCorrelationID&metadata.partitionKey=key1 \ -H "Content-Type: application/json" \ -d '{ "data": { From 7365fcdc2487880517d6bd67af7733abcc7a4f27 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Fri, 21 Jan 2022 11:29:01 -0800 Subject: [PATCH 38/73] Release v1.6 (Day of release changes to v1.6) Signed-off-by: Nick Greenfield --- .github/workflows/website-root.yml | 4 ++-- README.md | 4 ++-- daprdocs/config.toml | 13 +++++++---- .../support/support-release-policy.md | 23 ++++++++++++------- .../shortcodes/dapr-latest-version.html | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index 818cf8c2d..ed487f50a 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -3,11 +3,11 @@ name: Azure Static Web App Root on: push: branches: - - v1.5 + - v1.6 pull_request: types: [opened, synchronize, reopened, closed] branches: - - v1.5 + - v1.6 jobs: build_and_deploy_job: diff --git a/README.md b/README.md index 06c19fff9..70a711021 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ The following branches are currently maintained: | Branch | Website | Description | | ------------------------------------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------ | -| [v1.5](https://github.com/dapr/docs) (primary) | https://docs.dapr.io | Latest Dapr release documentation. Typo fixes, clarifications, and most documentation goes here. | -| [v1.6](https://github.com/dapr/docs/tree/v1.6) (pre-release) | https://v1-6.docs.dapr.io/ | Pre-release documentation. Doc updates that are only applicable to v1.6+ go here. | +| [v1.6](https://github.com/dapr/docs) (primary) | https://docs.dapr.io | Latest Dapr release documentation. Typo fixes, clarifications, and most documentation goes here. | +| [v1.7](https://github.com/dapr/docs/tree/v1.7) (pre-release) | https://v1-7.docs.dapr.io/ | Pre-release documentation. Doc updates that are only applicable to v1.7+ go here. | For more information visit the [Dapr branch structure](https://docs.dapr.io/contributing/contributing-docs/#branch-guidance) document. diff --git a/daprdocs/config.toml b/daprdocs/config.toml index 0b32c9021..2e0af0ea6 100644 --- a/daprdocs/config.toml +++ b/daprdocs/config.toml @@ -1,5 +1,5 @@ # Site Configuration -baseURL = "https://v1-6.docs.dapr.io/" +baseURL = "https://docs.dapr.io/" title = "Dapr Docs" theme = "docsy" disableFastRender = true @@ -163,17 +163,20 @@ github_subdir = "daprdocs" github_branch = "v1.6" # Versioning -version_menu = "v1.6 (preview)" +version_menu = "v1.6 (latest)" version = "v1.6" archived_version = false url_latest_version = "https://docs.dapr.io" [[params.versions]] - version = "v1.6 (preview)" + version = "v1.7 (preview)" + url = "https://v1-7.docs.dapr.io" +[[params.versions]] + version = "v1.6 (latest)" url = "#" [[params.versions]] - version = "v1.5 (latest)" - url = "https://docs.dapr.io" + version = "v1.5" + url = "https://v1-5.docs.dapr.io" [[params.versions]] version = "v1.4" url = "https://v1-4.docs.dapr.io" diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 7bed1e92d..d9a75c3fb 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -41,13 +41,14 @@ The table below shows the versions of Dapr releases that have been tested togeth | Jun 16th 2021 | 1.2.2
| 1.2.0 | Java 1.1.0
Go 1.1.0
PHP 1.1.0
Python 1.1.0
.NET 1.2.0 | 0.6.0 | Unsupported | | Jul 26th 2021 | 1.3
| 1.3.0 | Java 1.2.0
Go 1.2.0
PHP 1.1.0
Python 1.2.0
.NET 1.3.0 | 0.7.0 | Unsupported | | Sep 14th 2021 | 1.3.1
| 1.3.0 | Java 1.2.0
Go 1.2.0
PHP 1.1.0
Python 1.2.0
.NET 1.3.0 | 0.7.0 | Unsupported | -| Sep 15th 2021 | 1.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | -| Sep 22nd 2021 | 1.4.1
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported -| Sep 24th 2021 | 1.4.2
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | -| Oct 7th 2021 | 1.4.3
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | -| Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Supported | -| Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported (current) | -| Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported (current) | +| Sep 15th 2021 | 1.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | +| Sep 22nd 2021 | 1.4.1
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported +| Sep 24th 2021 | 1.4.2
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | +| Oct 7th 2021 | 1.4.3
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | +| Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | +| Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | +| Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | +| Jan 24th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 1.1. | 0.9.0 | Supported (current) | ## Upgrade paths After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1 @@ -63,20 +64,26 @@ General guidance on upgrading can be found for [self hosted mode]({{ Date: Fri, 21 Jan 2022 11:32:10 -0800 Subject: [PATCH 39/73] Update Quickstart references Signed-off-by: Nick Greenfield --- daprdocs/content/en/getting-started/quickstarts.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/daprdocs/content/en/getting-started/quickstarts.md b/daprdocs/content/en/getting-started/quickstarts.md index ecf04966a..ab257b1be 100644 --- a/daprdocs/content/en/getting-started/quickstarts.md +++ b/daprdocs/content/en/getting-started/quickstarts.md @@ -17,11 +17,11 @@ The [Dapr Quickstarts](https://github.com/dapr/quickstarts/tree/v1.5.0) are a co | Quickstart | Description | |--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Hello World](https://github.com/dapr/quickstarts/tree/v1.5.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. | -| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.5.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. | -| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.5.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. | -| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.5.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. | -| [Bindings](https://github.com/dapr/quickstarts/tree/v1.5.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. | -| [Observability](https://github.com/dapr/quickstarts/tree/v1.5.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. | -| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.5.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. | +| [Hello World](https://github.com/dapr/quickstarts/tree/v1.6.0/hello-world) | Demonstrates how to run Dapr locally. Highlights service invocation and state management. | +| [Hello Kubernetes](https://github.com/dapr/quickstarts/tree/v1.6.0/hello-kubernetes) | Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and state management. | +| [Distributed Calculator](https://github.com/dapr/quickstarts/tree/v1.6.0/distributed-calculator) | Demonstrates a distributed calculator application that uses Dapr services to power a React web app. Highlights polyglot (multi-language) programming, service invocation and state management. | +| [Pub/Sub](https://github.com/dapr/quickstarts/tree/v1.6.0/pub-sub) | Demonstrates how to use Dapr to enable pub-sub applications. Uses Redis as a pub-sub component. | +| [Bindings](https://github.com/dapr/quickstarts/tree/v1.6.0/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. | +| [Observability](https://github.com/dapr/quickstarts/tree/v1.6.0/observability) | Demonstrates Dapr tracing capabilities. Uses Zipkin as a tracing component. | +| [Secret Store](https://github.com/dapr/quickstarts/tree/v1.6.0/secretstore) | Demonstrates the use of Dapr Secrets API to access secret stores. | From d82884b83d7b06f496271ac52027342ccc3dc73d Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Fri, 21 Jan 2022 12:06:02 -0800 Subject: [PATCH 40/73] Update Azure binding components from Alpha to Beta Signed-off-by: Nick Greenfield --- .../components-reference/supported-bindings/_index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/_index.md b/daprdocs/content/en/reference/components-reference/supported-bindings/_index.md index 2c0e2625e..ea3cd2adb 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/_index.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/_index.md @@ -74,12 +74,12 @@ Table captions: | Name | Input
Binding | Output
Binding | Status | Component version | Since | |------|:----------------:|:-----------------:|--------| --------- | ---------- | -| [Azure Blob Storage]({{< ref blobstorage.md >}}) | | ✅ | Alpha | v1 | 1.0 | -| [Azure CosmosDB]({{< ref cosmosdb.md >}}) | | ✅ | Alpha | v1 | 1.0 | +| [Azure Blob Storage]({{< ref blobstorage.md >}}) | | ✅ | Beta | v1 | 1.0 | +| [Azure CosmosDB]({{< ref cosmosdb.md >}}) | | ✅ | Beta | v1 | 1.0 | | [Azure CosmosDBGremlinAPI]({{< ref cosmosdbgremlinapi.md >}}) | | ✅ | Alpha | v1 | 1.5 | | [Azure Event Grid]({{< ref eventgrid.md >}}) | ✅ | ✅ | Alpha | v1 | 1.0 | -| [Azure Event Hubs]({{< ref eventhubs.md >}}) | ✅ | ✅ | Alpha | v1 | 1.0 | -| [Azure Service Bus Queues]({{< ref servicebusqueues.md >}}) | ✅ | ✅ | Alpha | v1 | 1.0 | +| [Azure Event Hubs]({{< ref eventhubs.md >}}) | ✅ | ✅ | Beta | v1 | 1.0 | +| [Azure Service Bus Queues]({{< ref servicebusqueues.md >}}) | ✅ | ✅ | Beta | v1 | 1.0 | | [Azure SignalR]({{< ref signalr.md >}}) | | ✅ | Alpha | v1 | 1.0 | | [Azure Storage Queues]({{< ref storagequeues.md >}}) | ✅ | ✅ | Stable| v1 | 1.0 | From 360659b258f28e60c9160f0b91e4c617324d1e93 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Fri, 21 Jan 2022 13:11:01 -0800 Subject: [PATCH 41/73] Update Python SDK repo submodule to include state query api and config api docs Signed-off-by: Nick Greenfield --- sdkdocs/python | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdkdocs/python b/sdkdocs/python index 058cfcf4d..6d7d94007 160000 --- a/sdkdocs/python +++ b/sdkdocs/python @@ -1 +1 @@ -Subproject commit 058cfcf4d603823c5916bb5ae533bb9f5bb862fd +Subproject commit 6d7d9400736d2c58901c7b49f666a159f987e789 From 34707c18dc6fd7ec85da5d23eb100086956fdd42 Mon Sep 17 00:00:00 2001 From: Hal Spang Date: Fri, 21 Jan 2022 13:30:06 -0800 Subject: [PATCH 42/73] Updated .NET SDK Docs to include Configuration API Signed-off-by: Hal Spang --- sdkdocs/dotnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdkdocs/dotnet b/sdkdocs/dotnet index 2ffbb113e..20ef37382 160000 --- a/sdkdocs/dotnet +++ b/sdkdocs/dotnet @@ -1 +1 @@ -Subproject commit 2ffbb113e7b5186a96ee38426a2c08526e83b0e0 +Subproject commit 20ef37382cf3e3e4ef74475c72772733abb21922 From 2aaae124f2b877d183c72631c0c3227d9672d131 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Briend Date: Mon, 24 Jan 2022 18:18:10 +0100 Subject: [PATCH 43/73] PubSub overview: correct typo (#2110) Signed-off-by: Jean-Philippe Briend Co-authored-by: Mark Fussell --- .../building-blocks/pubsub/pubsub-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-overview.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-overview.md index 2099b8984..c011fdfd0 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-overview.md @@ -93,7 +93,7 @@ Similarly, if two different applications (different app-IDs) subscribe to the sa ### Topic scoping -By default, all topics backing the Dapr pub/sub component (e.g. Kafka, Redis Stream, RabbitMQ) are available to every application configured with that component. To limit which application can publish or subscribe to topics, Dapr provides topic scoping. This enables to you say which topics an application is allowed to publish and which topics an application is allowed to subscribe to. For more information read [publish/subscribe topic scoping]({{< ref pubsub-scopes.md >}}). +By default, all topics backing the Dapr pub/sub component (e.g. Kafka, Redis Stream, RabbitMQ) are available to every application configured with that component. To limit which application can publish or subscribe to topics, Dapr provides topic scoping. This enables you to say which topics an application is allowed to publish and which topics an application is allowed to subscribe to. For more information read [publish/subscribe topic scoping]({{< ref pubsub-scopes.md >}}). ### Message Time-to-Live (TTL) Dapr can set a timeout message on a per message basis, meaning that if the message is not read from the pub/sub component, then the message is discarded. This is to prevent the build up of messages that are not read. A message that has been in the queue for longer than the configured TTL is said to be dead. For more information read [publish/subscribe message time-to-live]({{< ref pubsub-message-ttl.md >}}). From 70258dca6673ab1fbf02f6b03703c0250c712487 Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Mon, 24 Jan 2022 11:21:38 -0800 Subject: [PATCH 44/73] Update setup-pulsar.md --- .../components-reference/supported-pubsub/setup-pulsar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md index 8514f72de..a6eff060f 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md @@ -8,7 +8,7 @@ aliases: --- ## Component format -To setup Apache Pulsar pubsub create a component of type `pubsub.pulsar`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. For more information on Apache Pulsar [read the docs]({{< ref "https://pulsar.apache.org/docs/en/concepts-overview/" >}}) +To setup Apache Pulsar pubsub create a component of type `pubsub.pulsar`. See [this guide]({{< ref "howto-publish-subscribe.md#step-1-setup-the-pubsub-component" >}}) on how to create and apply a pubsub configuration. For more information on Apache Pulsar [read the docs](https://pulsar.apache.org/docs/en/concepts-overview/) ```yaml apiVersion: dapr.io/v1alpha1 From 9f36a810e0f76e263e01a9a5e69c5d10dff617a0 Mon Sep 17 00:00:00 2001 From: Hal Spang Date: Mon, 24 Jan 2022 11:42:33 -0800 Subject: [PATCH 45/73] Update .NET SDK docs reference Signed-off-by: Hal Spang --- sdkdocs/dotnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdkdocs/dotnet b/sdkdocs/dotnet index 20ef37382..b47c63ac1 160000 --- a/sdkdocs/dotnet +++ b/sdkdocs/dotnet @@ -1 +1 @@ -Subproject commit 20ef37382cf3e3e4ef74475c72772733abb21922 +Subproject commit b47c63ac140845b178a1b29b1e988e30e4c7b579 From 09dd0a03d950ccb0944c7e79748791fe1bc7a131 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 24 Jan 2022 12:15:47 -0800 Subject: [PATCH 46/73] Add pulsar pubsub disable batching option Signed-off-by: Nick Greenfield --- .../components-reference/supported-pubsub/setup-pulsar.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md index 834df5457..c0906ef98 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-pulsar.md @@ -34,7 +34,8 @@ spec: value: "constant" - name: backOffMaxRetries value: "-1" - + - name: disableBatching + value: "false" ``` ## Spec metadata fields @@ -53,7 +54,7 @@ spec: | backOffRandomizationFactor | N | Randomization factor, between 1 and 0, including 0 but not 1. Randomized interval = RetryInterval * (1 ± backOffRandomizationFactor). Defaults to `"0.5"`. | `"0.5"` | | backOffMultiplier | N | Backoff multiplier for the policy. Increments the interval by multiplying it with the multiplier. Defaults to `"1.5"` | `"1.5"` | | backOffMaxElapsedTime | N | After MaxElapsedTime the ExponentialBackOff returns Stop. There are two valid formats, one is the fraction with a unit suffix format, and the other is the pure digital format that is processed as milliseconds. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Defaults to `"15m"` | `"15m"` | - +| disableBatching | N | disable batching. Default: `"false"` | `"true"`, `"false"`| ### Delay queue From 486a5b66c6b6a05ce4013c28e15b70b1311b1e7d Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 24 Jan 2022 12:19:41 -0800 Subject: [PATCH 47/73] Add docs to stop watching configuration updates Signed-off-by: Nick Greenfield --- .../howto-manage-configuration.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index 8aa8d651c..dc05254aa 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -108,5 +108,23 @@ message SubscribeConfigurationRequest { Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language - see the [gRPC examples here](https://grpc.io/docs/languages/) for usage. +### Stop watching configuration items + +After you have subscribed to watch configuration items, the gRPC-server stream starts. This stream thread does not close itself, and you have to do by explicitly call the `UnSubscribeConfigurationRequest` API. This method accepts the following request object: + +```proto +// UnSubscribeConfigurationRequest is the message to stop watching the key-value configuration. +message UnSubscribeConfigurationRequest { + // The name of configuration store. + string store_name = 1; + // Optional. The keys of the configuration item to stop watching. + // Store_name and keys should match previous SubscribeConfigurationRequest's keys and store_name. + // Once invoked, the subscription that is watching update for the key-value event is stopped + repeated string keys = 2; +} +``` + +Using this unsubscribe method, you can stop watching configuration update events. Dapr locates the subscription stream based on the `store_name` and any optional keys supplied and closes it. + ## Next steps * Read [configuration API overview]({{< ref configuration-api-overview.md >}}) \ No newline at end of file From c5865307be211968b574db1eec3157ee55fa2e42 Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Mon, 24 Jan 2022 12:22:01 -0800 Subject: [PATCH 48/73] Update daprdocs/content/en/operations/support/support-release-policy.md Co-authored-by: Will --- daprdocs/content/en/operations/support/support-release-policy.md | 1 + 1 file changed, 1 insertion(+) diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index d9a75c3fb..3ac72a6ff 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -84,6 +84,7 @@ General guidance on upgrading can be found for [self hosted mode]({{ Date: Mon, 24 Jan 2022 12:22:10 -0800 Subject: [PATCH 49/73] Update daprdocs/content/en/operations/support/support-release-policy.md Co-authored-by: Will --- .../content/en/operations/support/support-release-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 3ac72a6ff..6dbfcab97 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -48,7 +48,7 @@ The table below shows the versions of Dapr releases that have been tested togeth | Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | | Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | | Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | -| Jan 24th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 1.1. | 0.9.0 | Supported (current) | +| Jan 24th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 1.1.0 | 0.9.0 | Supported (current) | ## Upgrade paths After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1 From 6e8ee9c98fc909ef7d3c98d4308a7b08263a960d Mon Sep 17 00:00:00 2001 From: Amulya Varote Date: Wed, 19 Jan 2022 17:09:24 -0800 Subject: [PATCH 50/73] Added config API documentation Signed-off-by: Amulya Varote --- .../howto-manage-configuration.md | 49 ++++++++++++------ .../building-block-configuration-example.png | Bin 0 -> 116060 bytes 2 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 daprdocs/static/images/building-block-configuration-example.png diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index 8aa8d651c..0798bfe0f 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -11,6 +11,12 @@ This HowTo uses the Redis configuration store component as an example on how to *This API is currently in `Alpha` state and only available on gRPC. An HTTP1.1 supported version with this URL syntax `/v1.0/configuration` will be available before the API is certified into `Stable` state.* +## Example: + +The below code examples loosely describe an application that processes orders. In the examples, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to get the configuration from redis configuration store. + +Diagram showing get configuration of example service + ## Step 1: Create a configuration item in store First, create a configuration item in a supported configuration store. This can be a simple key-value item, with any key of your choice. For this example, we'll use the Redis configuration store component. @@ -31,7 +37,7 @@ redis-cli -p 6379 Save a configuration item: ``` -set myconfig "wookie" +SET orderId "100||1" ``` ### Configure a Dapr configuration store @@ -42,7 +48,7 @@ Save the following component file, for example to the [default components folder apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: redisconfigstore + name: configurationstore spec: type: configuration.redis metadata: @@ -54,9 +60,16 @@ spec: ### Get configuration items using gRPC API -Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). The following examples show Java, C#, Python and Javascript clients. +Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). -{{< tabs Java Dotnet Python Javascript >}} +{{< tabs Dotnet Java Python Javascript >}} + +{{% codetab %}} +```csharp + +var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); +``` +{{% /codetab %}} {{% codetab %}} ```java @@ -66,23 +79,25 @@ stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfi ``` {{% /codetab %}} -{{% codetab %}} -```csharp - -var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); -``` -{{% /codetab %}} - {{% codetab %}} ```python -response = stub.GetConfigurationAlpha1(request={ StoreName: 'redisconfigstore', Keys = ['myconfig'] }) +#dependencies +from dapr.clients import DaprClient +#code +with DaprClient() as d: + storeName = 'configurationstore' + key = 'orderId' + d.wait(20) + configuration = d.get_configuration(store_name=storeName, keys=[key], config_metadata={}) + print(f"Got key={configuration.items[0].key} value={configuration.items[0].value} version={configuration.items[0].version}") ``` -{{% /codetab %}} -{{% codetab %}} -```javascript -client.GetConfigurationAlpha1({ StoreName: 'redisconfigstore', Keys = ['myconfig'] }) +Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: + +```bash +dapr run --app-id orderprocessing python3 OrderProcessingService.py ``` + {{% /codetab %}} {{< /tabs >}} @@ -109,4 +124,4 @@ message SubscribeConfigurationRequest { Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language - see the [gRPC examples here](https://grpc.io/docs/languages/) for usage. ## Next steps -* Read [configuration API overview]({{< ref configuration-api-overview.md >}}) \ No newline at end of file +* Read [configuration API overview]({{< ref configuration-api-overview.md >}}) diff --git a/daprdocs/static/images/building-block-configuration-example.png b/daprdocs/static/images/building-block-configuration-example.png new file mode 100644 index 0000000000000000000000000000000000000000..5255c3bff94e5663d16576d76742abee64d4035f GIT binary patch literal 116060 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 Jp^GW3U){w|(&PW&88QqJBPyyM4fK1WTWPt?B>v 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%0D|PbD;3LL^=oU3>5^^y7vk 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 BM{WQB literal 0 HcmV?d00001 From ea37e2d355a3206f918567f9d9d0e33dd19e28ca Mon Sep 17 00:00:00 2001 From: Amulya Varote Date: Wed, 19 Jan 2022 23:02:01 -0800 Subject: [PATCH 51/73] Modified based on the review comments Signed-off-by: Amulya Varote --- .../configuration/howto-manage-configuration.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index 0798bfe0f..ed40d0bbb 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -13,7 +13,7 @@ This HowTo uses the Redis configuration store component as an example on how to ## Example: -The below code examples loosely describe an application that processes orders. In the examples, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to get the configuration from redis configuration store. +The below code examples loosely describe an application that processes orders. In the examples, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to retrieve the configuration from a Redis configuration store. Diagram showing get configuration of example service @@ -87,12 +87,13 @@ from dapr.clients import DaprClient with DaprClient() as d: storeName = 'configurationstore' key = 'orderId' + #Startup time for dapr d.wait(20) configuration = d.get_configuration(store_name=storeName, keys=[key], config_metadata={}) print(f"Got key={configuration.items[0].key} value={configuration.items[0].value} version={configuration.items[0].version}") ``` -Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application: +Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar: ```bash dapr run --app-id orderprocessing python3 OrderProcessingService.py From c3a7d0863db41f611a1293fa4a6d7792ae75cd53 Mon Sep 17 00:00:00 2001 From: Amulya Varote Date: Mon, 24 Jan 2022 14:18:02 -0800 Subject: [PATCH 52/73] Added consistent examples Signed-off-by: Amulya Varote --- .../howto-manage-configuration.md | 75 ++++++++++++++++--- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index ed40d0bbb..fe42916e4 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -37,7 +37,7 @@ redis-cli -p 6379 Save a configuration item: ``` -SET orderId "100||1" +MSET orderId1 "101||1" orderId2 "102||1" ``` ### Configure a Dapr configuration store @@ -48,7 +48,7 @@ Save the following component file, for example to the [default components folder apiVersion: dapr.io/v1alpha1 kind: Component metadata: - name: configurationstore + name: configstore spec: type: configuration.redis metadata: @@ -62,20 +62,75 @@ spec: Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). -{{< tabs Dotnet Java Python Javascript >}} +{{< tabs Dotnet Java Python>}} {{% codetab %}} ```csharp +//dependencies +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Dapr.Client; -var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); +//code +namespace ConfigurationApi +{ + public class Program + { + private static readonly string CONFIG_STORE_NAME = "configstore"; + + [Obsolete] + public static async Task Main(string[] args) + { + using var client = new DaprClientBuilder().Build(); + var configuration = await client.GetConfiguration(CONFIG_STORE_NAME, new List() { "orderId1", "orderId2" }); + Console.WriteLine($"Got key=\n{configuration[0].Key} -> {configuration[0].Value}\n{configuration[1].Key} -> {configuration[1].Value}"); + } + } +} +``` + +Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar: + +```bash +dapr run --app-id orderprocessing --components-path ./components -- dotnet run ``` {{% /codetab %}} {{% codetab %}} ```java +//dependencies +import io.dapr.client.DaprClientBuilder; +import io.dapr.client.DaprPreviewClient; +import io.dapr.client.domain.ConfigurationItem; +import io.dapr.client.domain.GetConfigurationRequest; +import io.dapr.client.domain.SubscribeConfigurationRequest; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -Dapr.ServiceBlockingStub stub = Dapr.newBlockingStub(channel); -stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); +//code +private static final String CONFIG_STORE_NAME = "configstore"; + +public static void main(String[] args) throws Exception { + try (DaprPreviewClient client = (new DaprClientBuilder()).buildPreviewClient()) { + List keys = new ArrayList<>(); + keys.add("orderId1"); + keys.add("orderId2"); + GetConfigurationRequest req = new GetConfigurationRequest(CONFIG_STORE_NAME, keys); + try { + Mono> items = client.getConfiguration(req); + items.block().forEach(ConfigurationClient::print); + } catch (Exception ex) { + System.out.println(ex.getMessage()); + } + } +} +``` + +Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar: + +```bash +dapr run --app-id orderprocessing --components-path ./components mvn spring-boot:run ``` {{% /codetab %}} @@ -85,18 +140,18 @@ stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfi from dapr.clients import DaprClient #code with DaprClient() as d: - storeName = 'configurationstore' - key = 'orderId' + CONFIG_STORE_NAME = 'configstore' + keys = ['orderId1', 'orderId2'] #Startup time for dapr d.wait(20) - configuration = d.get_configuration(store_name=storeName, keys=[key], config_metadata={}) + configuration = d.get_configuration(store_name=CONFIG_STORE_NAME, keys=[keys], config_metadata={}) print(f"Got key={configuration.items[0].key} value={configuration.items[0].value} version={configuration.items[0].version}") ``` Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar: ```bash -dapr run --app-id orderprocessing python3 OrderProcessingService.py +dapr run --app-id orderprocessing --components-path ./components python3 OrderProcessingService.py ``` {{% /codetab %}} From 882b40ee878cb89dda13b35cf156199e77c6b779 Mon Sep 17 00:00:00 2001 From: Amulya Varote Date: Mon, 24 Jan 2022 15:08:02 -0800 Subject: [PATCH 53/73] Chnaged title of sdk examples Signed-off-by: Amulya Varote --- .../configuration/howto-manage-configuration.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index fe42916e4..78d3cbc8c 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -58,9 +58,7 @@ spec: value: ``` -### Get configuration items using gRPC API - -Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). +### Get configuration items using Dapr SDKs {{< tabs Dotnet Java Python>}} From 051c58ef6609b50be3a40b55b880baf43a191945 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 24 Jan 2022 15:35:17 -0800 Subject: [PATCH 54/73] Update Java and .NET SDK submodules Signed-off-by: Nick Greenfield --- sdkdocs/dotnet | 2 +- sdkdocs/java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdkdocs/dotnet b/sdkdocs/dotnet index 20ef37382..b47c63ac1 160000 --- a/sdkdocs/dotnet +++ b/sdkdocs/dotnet @@ -1 +1 @@ -Subproject commit 20ef37382cf3e3e4ef74475c72772733abb21922 +Subproject commit b47c63ac140845b178a1b29b1e988e30e4c7b579 diff --git a/sdkdocs/java b/sdkdocs/java index d3df194ba..db33b48fd 160000 --- a/sdkdocs/java +++ b/sdkdocs/java @@ -1 +1 @@ -Subproject commit d3df194bad3826069b7c9cda5178196e92dacad1 +Subproject commit db33b48fd4af80f638d4fa8713b557e43cabec49 From d00b389a8b5f8c56d8e4fad98a0d663bd36f3805 Mon Sep 17 00:00:00 2001 From: Paul Yuknewicz Date: Mon, 24 Jan 2022 20:59:15 -0800 Subject: [PATCH 55/73] Fixing the main link to SDK docs Signed-off-by: Paul Yuknewicz --- daprdocs/content/en/developing-applications/sdks/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/sdks/_index.md b/daprdocs/content/en/developing-applications/sdks/_index.md index 4e84fddf2..f5302e3e4 100644 --- a/daprdocs/content/en/developing-applications/sdks/_index.md +++ b/daprdocs/content/en/developing-applications/sdks/_index.md @@ -36,7 +36,7 @@ The Dapr SDKs are the easiest way for you to get Dapr into your application. Cho | [Java]({{< ref java >}}) | Stable | ✔ | Spring Boot | ✔ | | [Go]({{< ref go >}}) | Stable | ✔ | ✔ | ✔ | | [PHP]({{< ref php >}}) | Stable | ✔ | ✔ | ✔ | -| [Javascript](https://github.com/dapr/js-sdk) | Stable| ✔ | | ✔ | +| [Javascript]({{< ref js >}}) | Stable| ✔ | | ✔ | | [C++](https://github.com/dapr/cpp-sdk) | In development | ✔ | | | [Rust](https://github.com/dapr/rust-sdk) | In development | ✔ | | | From 24981ac333acdc07ba50e1c2f24308a3e52314b7 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Tue, 25 Jan 2022 09:21:03 -0800 Subject: [PATCH 56/73] Fix JS SDK version Signed-off-by: Nick Greenfield --- .../content/en/operations/support/support-release-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 6dbfcab97..2e84e66d8 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -48,7 +48,7 @@ The table below shows the versions of Dapr releases that have been tested togeth | Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | | Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | | Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | -| Jan 24th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 1.1.0 | 0.9.0 | Supported (current) | +| Jan 25th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 2.0.0 | 0.9.0 | Supported (current) | ## Upgrade paths After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1 From d8eac9d5fb1a96b896f3af2d0a7f71b75569dea7 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Tue, 25 Jan 2022 15:34:39 -0800 Subject: [PATCH 57/73] Fix Go SDK version to 1.3.1 Signed-off-by: Nick Greenfield --- .../content/en/operations/support/support-release-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/support/support-release-policy.md b/daprdocs/content/en/operations/support/support-release-policy.md index 2e84e66d8..c0adce7e7 100644 --- a/daprdocs/content/en/operations/support/support-release-policy.md +++ b/daprdocs/content/en/operations/support/support-release-policy.md @@ -48,7 +48,7 @@ The table below shows the versions of Dapr releases that have been tested togeth | Dev 6th 2021 | 1.4.4
| 1.4.0 | Java 1.3.0
Go 1.2.0
PHP 1.1.0
Python 1.3.0
.NET 1.4.0 | 0.8.0 | Unsupported | | Nov 11th 2021 | 1.5.0
| 1.5.0 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | | Dec 6th 2021 | 1.5.1
| 1.5.1 | Java 1.3.0
Go 1.3.0
PHP 1.1.0
Python 1.4.0
.NET 1.5.0
JS 1.0.2 | 0.9.0 | Supported | -| Jan 25th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.4.0
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 2.0.0 | 0.9.0 | Supported (current) | +| Jan 25th 2022 | 1.6.0
| 1.6.0 | Java 1.4.0
Go 1.3.1
PHP 1.1.0
Python 1.5.0
.NET 1.6.0
JS 2.0.0 | 0.9.0 | Supported (current) | ## Upgrade paths After the 1.0 release of the runtime there may be situations where it is necessary to explicitly upgrade through an additional release to reach the desired target. For example an upgrade from v1.0 to v1.2 may need go pass through v1.1 From ad1589e39dc41f3db2b2d322aca0431daaf15b8f Mon Sep 17 00:00:00 2001 From: Bernd Verst <4535280+berndverst@users.noreply.github.com> Date: Wed, 26 Jan 2022 11:50:13 -0800 Subject: [PATCH 58/73] Update guidance: Rolling mTLS certificates in K8s Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> --- .../content/en/operations/security/mtls.md | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/daprdocs/content/en/operations/security/mtls.md b/daprdocs/content/en/operations/security/mtls.md index 5425d4db2..989ac7bcf 100644 --- a/daprdocs/content/en/operations/security/mtls.md +++ b/daprdocs/content/en/operations/security/mtls.md @@ -91,6 +91,10 @@ kubectl logs --selector=app=dapr-sentry --namespace Using Helm, you can provide the PEM encoded root cert, issuer cert and private key that will be populated into the Kubernetes secret used by the Sentry service. +{{% alert title="Avoiding downtime" color="warning" %}} +To avoid downtime when rotating expiring certificates always sign your certificates with the same private root key. +{{% /alert %}} + _Note: This example uses the OpenSSL command line tool, this is a widely distributed package, easily installed on Linux via the package manager. On Windows OpenSSL can be installed [using chocolatey](https://community.chocolatey.org/packages/openssl). On MacOS it can be installed using brew `brew install openssl`_ Create config files for generating the certificates, this is necessary for generating v3 certificates with the SAN (Subject Alt Name) extension fields. First save the following to a file named `root.conf`: @@ -125,6 +129,7 @@ basicConstraints = critical, CA:true, pathlen:0 Run the following to generate the root cert and key ```bash +# skip the following line to reuse an existing root key, required for rotating expiring certificates openssl ecparam -genkey -name prime256v1 | openssl ec -out root.key openssl req -new -nodes -sha256 -key root.key -out root.csr -config root.conf -extensions v3_req openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM -out root.pem -extfile root.conf -extensions v3_req @@ -133,6 +138,7 @@ openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM Next run the following to generate the issuer cert and key: ```bash +# skip the following line to reuse an existing issuer key, required for rotating expiring certificates openssl ecparam -genkey -name prime256v1 | openssl ec -out issuer.key openssl req -new -sha256 -key issuer.key -out issuer.csr -config issuer.conf -extensions v3_req openssl x509 -req -in issuer.csr -CA root.pem -CAkey root.key -CAcreateserial -outform PEM -out issuer.pem -days 365 -sha256 -extfile issuer.conf -extensions v3_req @@ -156,24 +162,50 @@ helm install \ If the Root or Issuer certs are about to expire, you can update them and restart the required system services. +{{% alert title="Avoiding downtime when rotating certificates" color="warning" %}} +To avoid downtime when rotating expiring certificates your new certificates must be signed with the same private root key as the previous certificates. +{{% /alert %}} + First, issue new certificates using the step above in [Bringing your own certificates](#bringing-your-own-certificates). -Now that you have the new certificates, you can update the Kubernetes secret that holds them. -Edit the Kubernetes secret: +Now that you have the new certificates, use Helm to upgrade the certificates: +```bash +helm upgrade \ + --set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \ + --set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \ + --set-file dapr_sentry.tls.root.certPEM=root.pem \ + --namespace dapr-system \ + dapr \ + dapr/dapr ``` + +Alternatively, you can update the Kubernetes secret that holds them: + +```bash kubectl edit secret dapr-trust-bundle -n ``` Replace the `ca.crt`, `issuer.crt` and `issuer.key` keys in the Kubernetes secret with their corresponding values from the new certificates. *__Note: The values must be base64 encoded__* -If you signed the new cert root with a different private key, restart all Dapr-enabled pods. +If you signed the new cert root with the same private key the Dapr Sentry service will pick up the new certificates automatically. You can restart your application deployments using `kubectl rollout restart` with zero downtime. It is not necessary to restart all deployments at once, as long as deployments are restarted before original certificate expiration. + +If you signed the new cert root with a different private key, you must restart the Dapr sentry service. + +```bash +kubectl rollout restart deploy/dapr-sentry -n +``` + +Next, you must restart all Dapr-enabled pods. The recommended way to do this is to perform a rollout restart of your deployment: ``` kubectl rollout restart deploy/myapp ``` + +You will experience potential downtime due to mismatching certificates until all deployments have successfully been restarted (and hence loaded the new Dapr certificates). + ### Kubernetes video demo Watch this video to show how to update mTLS certificates on Kubernetes From 6c19f182b7243f25129c1fec834955560902390a Mon Sep 17 00:00:00 2001 From: Giovanni van der Schelde Date: Wed, 26 Jan 2022 23:29:45 +0100 Subject: [PATCH 59/73] Fix typo in reference API for Actors Signed-off-by: Giovanni van der Schelde --- daprdocs/content/en/reference/api/actors_api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/api/actors_api.md b/daprdocs/content/en/reference/api/actors_api.md index 133d6291a..864cb661e 100644 --- a/daprdocs/content/en/reference/api/actors_api.md +++ b/daprdocs/content/en/reference/api/actors_api.md @@ -549,7 +549,7 @@ curl -X POST http://localhost:3000/actors/stormtrooper/50/method/performAction \ ### Invoke reminder -Invokes a reminder for an actor with the specified reminderName. If the actor is not already running, the app side should [activate](#activating-an-actor) it. +Invokes a reminder for an actor with the specified reminderName. If the actor is not already running, the app side should [activate](#activating-an-actor) it. #### HTTP Request @@ -587,7 +587,7 @@ curl -X POST http://localhost:3000/actors/stormtrooper/50/method/remind/checkReb ### Invoke timer -Invokes a timer for an actor rwith the specified timerName. If the actor is not already running, the app side should [activate](#activating-an-actor) it. +Invokes a timer for an actor with the specified timerName. If the actor is not already running, the app side should [activate](#activating-an-actor) it. #### HTTP Request From 6824152a61f17d75570a42f42166efa9b637348e Mon Sep 17 00:00:00 2001 From: Amulya Varote Date: Fri, 28 Jan 2022 15:52:35 -0800 Subject: [PATCH 60/73] Bug fix Signed-off-by: Amulya Varote --- .../building-blocks/state-management/howto-get-save-state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md index e40eb7995..1eeb059ea 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/howto-get-save-state.md @@ -107,7 +107,7 @@ namespace EventService //Using Dapr SDK to save and get state await client.SaveStateAsync(DAPR_STORE_NAME, "order_1", orderId.ToString()); await client.SaveStateAsync(DAPR_STORE_NAME, "order_2", orderId.ToString()); - var result = await client.GetStateAsync(DAPR_STORE_NAME, orderId.ToString()); + var result = await client.GetStateAsync(DAPR_STORE_NAME, "order_1"); Console.WriteLine("Result after get: " + result); } } From d5cfef545c92daab1f917b9cc42487ac113489b1 Mon Sep 17 00:00:00 2001 From: Ryuji Iwata Date: Tue, 1 Feb 2022 02:18:30 +0900 Subject: [PATCH 61/73] Fix typo (#2169) Fix typo one word. Signed-off-by: Ryuji Iwata --- daprdocs/content/en/concepts/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/concepts/overview.md b/daprdocs/content/en/concepts/overview.md index deb611d5b..f7a009d85 100644 --- a/daprdocs/content/en/concepts/overview.md +++ b/daprdocs/content/en/concepts/overview.md @@ -21,7 +21,7 @@ Today we are experiencing a wave of cloud adoption. Developers are comfortable w This is where Dapr comes in. Dapr codifies the *best practices* for building microservice applications into open, independent APIs called building blocks, that enable you to build portable applications with the language and framework of your choice. Each building block is completely independent and you can use one, some, or all of them in your application. -Using Dapr you can incrementally migrate your existing applications to a microserivces architecture, thereby adopting cloud native patterns such scale out/in, resilency and independent deployments. +Using Dapr you can incrementally migrate your existing applications to a microserivces architecture, thereby adopting cloud native patterns such scale out/in, resiliency and independent deployments. In addition, Dapr is platform agnostic, meaning you can run your applications locally, on any Kubernetes cluster, on virtual or physical machines and in other hosting environments that Dapr integrates with. This enables you to build microservice applications that can run on the cloud and edge. From ccb993b0b3b3d74113cd66f8aaaaa85946f431d0 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 31 Jan 2022 13:49:29 -0800 Subject: [PATCH 62/73] Revert gRPC examples back for config how-to Signed-off-by: Nick Greenfield --- .../howto-manage-configuration.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index 8c072c37f..e21d0c092 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -156,6 +156,41 @@ dapr run --app-id orderprocessing --components-path ./components python3 OrderPr {{< /tabs >}} +### Get configuration items using gRPC API + +Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). The following examples show Java, C#, Python and Javascript clients. + +{{< tabs Java Dotnet Python Javascript >}} + +{{% codetab %}} +```java + +Dapr.ServiceBlockingStub stub = Dapr.newBlockingStub(channel); +stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); +``` +{{% /codetab %}} + +{{% codetab %}} +```csharp + +var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} }); +``` +{{% /codetab %}} + +{{% codetab %}} +```python +response = stub.GetConfigurationAlpha1(request={ StoreName: 'redisconfigstore', Keys = ['myconfig'] }) +``` +{{% /codetab %}} + +{{% codetab %}} +```javascript +client.GetConfigurationAlpha1({ StoreName: 'redisconfigstore', Keys = ['myconfig'] }) +``` +{{% /codetab %}} + +{{< /tabs >}} + ### Watch configuration items Create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) using your [preferred language](https://grpc.io/docs/languages/). Then use the proto method `SubscribeConfigurationAlpha1` on your client stub to start subscribing to events. The method accepts the following request object: From ed5ee475051491a0a786f9ce57cf4387086f65a3 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 31 Jan 2022 14:46:02 -0800 Subject: [PATCH 63/73] Move watch conf and stop watch config sub headings Signed-off-by: Nick Greenfield --- .../configuration/howto-manage-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md index e21d0c092..03a39298c 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md +++ b/daprdocs/content/en/developing-applications/building-blocks/configuration/howto-manage-configuration.md @@ -191,7 +191,7 @@ client.GetConfigurationAlpha1({ StoreName: 'redisconfigstore', Keys = ['myconfig {{< /tabs >}} -### Watch configuration items +##### Watch configuration items Create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) using your [preferred language](https://grpc.io/docs/languages/). Then use the proto method `SubscribeConfigurationAlpha1` on your client stub to start subscribing to events. The method accepts the following request object: @@ -212,7 +212,7 @@ message SubscribeConfigurationRequest { Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language - see the [gRPC examples here](https://grpc.io/docs/languages/) for usage. -### Stop watching configuration items +##### Stop watching configuration items After you have subscribed to watch configuration items, the gRPC-server stream starts. This stream thread does not close itself, and you have to do by explicitly call the `UnSubscribeConfigurationRequest` API. This method accepts the following request object: From d7c7cd068ccf1271338290592c0b4eeb3e1f580d Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Fri, 4 Feb 2022 14:39:37 -0800 Subject: [PATCH 64/73] Add integration doc for AKS Dapr extension and clean up hosting k8s pages (#2173) * Add integration doc for AKS Dapr extension Signed-off-by: Nick Greenfield * Address PR feedback Signed-off-by: Nick Greenfield --- .../azure-kubernetes-service-extension.md | 89 +++++++++++++++++++ .../hosting/kubernetes/cluster/_index.md | 2 +- .../hosting/kubernetes/kubernetes-deploy.md | 3 +- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 daprdocs/content/en/developing-applications/integrations/Azure/azure-kubernetes-service-extension.md diff --git a/daprdocs/content/en/developing-applications/integrations/Azure/azure-kubernetes-service-extension.md b/daprdocs/content/en/developing-applications/integrations/Azure/azure-kubernetes-service-extension.md new file mode 100644 index 000000000..eaecef865 --- /dev/null +++ b/daprdocs/content/en/developing-applications/integrations/Azure/azure-kubernetes-service-extension.md @@ -0,0 +1,89 @@ +--- +type: docs +title: "Dapr extension for Azure Kubernetes Service (AKS)" +linkTitle: "Dapr extension for Azure Kubernetes Service (AKS)" +description: "Provision Dapr on your Azure Kubernetes Service (AKS) cluster with the Dapr extension" +weight: 4000 +--- + +# Prerequisites +- [Azure subscription](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) +- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) and the ***aks-preview*** extension. +- [Azure Kubernetes Service (AKS) cluster](https://docs.microsoft.com/azure/aks/tutorial-kubernetes-deploy-cluster?tabs=azure-cli) + +## Install Dapr using the AKS Dapr extension +The recommended approach for installing Dapr on AKS is to use the AKS Dapr extension. The extension offers support for all native Dapr configuration capabilities through command-line arguments via the Azure CLI and offers the option of opting into automatic minor version upgrades of the Dapr runtime. + +{{% alert title="Note" color="warning" %}} +If you install Dapr through the AKS extension, our recommendation is to continue using the extension for future management of Dapr instead of the Dapr CLI. Combining the two tools can cause conflicts and result in undesired behavior. +{{% /alert %}} + +### How the extension works +The Dapr extension works by provisioning the Dapr control plane on your AKS cluster through the Azure CLI. The dapr control plane consists of: + +- **dapr-operator**: Manages component updates and Kubernetes services endpoints for Dapr (state stores, pub/subs, etc.) +- **dapr-sidecar-injector**: Injects Dapr into annotated deployment pods and adds the environment variables `DAPR_HTTP_PORT` and `DAPR_GRPC_PORT`. This enables user-defined applications to communicate with Dapr without the need to hard-code Dapr port values. +- **dapr-placement**: Used for actors only. Creates mapping tables that map actor instances to pods +- **dapr-sentry**: Manages mTLS between services and acts as a certificate authority. For more information read the security overview. + +### Extension Prerequisites +In order to use the AKS Dapr extension, you must first enable the `AKS-ExtensionManager` and `AKS-Dapr` feature flags on your Azure subscription. + +The below command will register the `AKS-ExtensionManager` and `AKS-Dapr` feature flags on your Azure subscription: + +```bash +az feature register --namespace "Microsoft.ContainerService" --name "AKS-ExtensionManager" +az feature register --namespace "Microsoft.ContainerService" --name "AKS-Dapr" +``` + +After a few minutes, check the status to show `Registered`. Confirm the registration status by using the az feature list command: + +```bash +az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-ExtensionManager')].{Name:name,State:properties.state}" +az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-Dapr')].{Name:name,State:properties.state}" +``` + +Next, refresh the registration of the `Microsoft.KubernetesConfiguration` and `Microsoft.ContainerService` resource providers by using the az provider register command: + +```bash +az provider register --namespace Microsoft.KubernetesConfiguration +az provider register --namespace Microsoft.ContainerService +``` + +#### Enable the Azure CLI extension for cluster extensions +You will also need the `k8s-extension` Azure CLI extension. Install this by running the following commands: + +```bash +az extension add --name k8s-extension +``` + +If the `k8s-extension` extension is already present, you can update it to the latest version using the below command: + +```bash +az extension update --name k8s-extension +``` + +#### Create the extension and install Dapr on your AKS cluster +After your subscription is registered to use Kubernetes extensions, install Dapr on your cluster by creating the Dapr extension. For example: + +```bash +az k8s-extension create --cluster-type managedClusters \ +--cluster-name myAKSCluster \ +--resource-group myResourceGroup \ +--name myDaprExtension \ +--extension-type Microsoft.Dapr +``` + +Additionally, Dapr can automatically update its minor version. To enable this, set the `--auto-upgrade-minor-version` parameter to true: + +```bash +--auto-upgrade-minor-version true +``` + +Once the k8-extension finishes provisioning, you can confirm that the Dapr control plane is installed on your AKS cluster by running: + +```bash +kubectl get pods -n dapr-system +``` + +For further information such as configuration options and targeting specific versions of Dapr, please see the official [AKS Dapr Extension Docs](https://docs.microsoft.com/azure/aks/dapr). \ No newline at end of file diff --git a/daprdocs/content/en/operations/hosting/kubernetes/cluster/_index.md b/daprdocs/content/en/operations/hosting/kubernetes/cluster/_index.md index ce3cad39c..1aa788f29 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/cluster/_index.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/cluster/_index.md @@ -2,7 +2,7 @@ type: docs title: "Kubernetes cluster setup" linkTitle: "How-to: Setup clusters" -weight: 80000 +weight: 15000 description: > How to create a Kubernetes cluster --- \ No newline at end of file diff --git a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md index 81b62d716..749672a92 100644 --- a/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md +++ b/daprdocs/content/en/operations/hosting/kubernetes/kubernetes-deploy.md @@ -22,9 +22,10 @@ For more information on what is deployed to your Kubernetes cluster read the [Ku You can install Dapr on any Kubernetes cluster. Here are some helpful links: +- [Setup KiNd Cluster]({{< ref setup-kind.md >}}) - [Setup Minikube Cluster]({{< ref setup-minikube.md >}}) - [Setup Azure Kubernetes Service Cluster]({{< ref setup-aks.md >}}) -- [Setup Google Cloud Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/quickstart) +- [Setup Google Cloud Kubernetes Engine](https://docs.dapr.io/operations/hosting/kubernetes/cluster/setup-gke/) - [Setup Amazon Elastic Kubernetes Service](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) {{% alert title="Hybrid clusters" color="primary" %}} From a8b76851ba7d115ff9b429e458897800d84971f0 Mon Sep 17 00:00:00 2001 From: greenie-msft <56556602+greenie-msft@users.noreply.github.com> Date: Fri, 4 Feb 2022 15:14:32 -0800 Subject: [PATCH 65/73] Update jaeger.md --- .../monitoring/tracing/supported-tracing-backends/jaeger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md index e4e6b4903..b61d93dac 100644 --- a/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md +++ b/daprdocs/content/en/operations/monitoring/tracing/supported-tracing-backends/jaeger.md @@ -83,7 +83,7 @@ spec: #### Production -Jaeger uses Elasticsearch as the backend storage, and you can create a secret in k8s cluster to access Elasticsearch server with access control. See [Configuring and Deploying Jaeger](https://docs.openshift.com/container-platform/4.9/distr_tracing/distr_tracing_install/distr-tracing-deploying.html) +Jaeger uses Elasticsearch as the backend storage, and you can create a secret in k8s cluster to access Elasticsearch server with access control. ```shell kubectl create secret generic jaeger-secret --from-literal=ES_PASSWORD='xxx' --from-literal=ES_USERNAME='xxx' -n ${NAMESPACE} From 00e8aa1e72f5642bb4d6189222271b736b23a5d3 Mon Sep 17 00:00:00 2001 From: Derrick Burns Date: Sun, 6 Feb 2022 22:32:18 -0800 Subject: [PATCH 66/73] Update pubsub_api.md (#2178) Fixed typo. --- daprdocs/content/en/reference/api/pubsub_api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/api/pubsub_api.md b/daprdocs/content/en/reference/api/pubsub_api.md index eed507d1a..c88448050 100644 --- a/daprdocs/content/en/reference/api/pubsub_api.md +++ b/daprdocs/content/en/reference/api/pubsub_api.md @@ -51,7 +51,7 @@ The `Content-Type` header tells Dapr which content type your data adheres to whe The value of the `Content-Type` header populates the `datacontenttype` field in the CloudEvent. Unless specified, Dapr assumes `text/plain`. If your content type is JSON, use a `Content-Type` header with the value of `application/json`. -If you want to send your own custom CloundEvent, use the `application/cloudevents+json` value for the `Content-Type` header. +If you want to send your own custom CloudEvent, use the `application/cloudevents+json` value for the `Content-Type` header. #### Metadata From 4ea3833f7e933c651b4fc441355534dfc0e27504 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Thu, 10 Feb 2022 09:00:01 -0800 Subject: [PATCH 67/73] Update JS sdk submodule which will bring in doc changes to use http and not grpc Signed-off-by: Nick Greenfield --- sdkdocs/js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdkdocs/js b/sdkdocs/js index 1e23f32ea..18a72819a 160000 --- a/sdkdocs/js +++ b/sdkdocs/js @@ -1 +1 @@ -Subproject commit 1e23f32eafdebe571db6e19717cf5317f09a5402 +Subproject commit 18a72819a6b620e889ae4b5beecba100ee65ee34 From 21b01fd9da163f46b05c15c9fec115c2a99fe881 Mon Sep 17 00:00:00 2001 From: David Gladstone Date: Sat, 12 Feb 2022 13:20:10 +1300 Subject: [PATCH 68/73] Update w3c-tracing-overview.md (#2188) Fix spelling error. Signed-off-by: David Gladstone Co-authored-by: Mark Fussell --- .../observability/w3c-tracing/w3c-tracing-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/observability/w3c-tracing/w3c-tracing-overview.md b/daprdocs/content/en/developing-applications/building-blocks/observability/w3c-tracing/w3c-tracing-overview.md index db89c0cd5..48a44254b 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/observability/w3c-tracing/w3c-tracing-overview.md +++ b/daprdocs/content/en/developing-applications/building-blocks/observability/w3c-tracing/w3c-tracing-overview.md @@ -84,7 +84,7 @@ This is much more unusual. There may be occasions where you specifically chose t Theses are the specific trace context headers that are generated and propagated by Dapr for HTTP and gRPC. ### Trace context HTTP headers format -When propogating a trace context header from an HTTP response to an HTTP request, these are the headers that you need to copy. +When propagating a trace context header from an HTTP response to an HTTP request, these are the headers that you need to copy. #### Traceparent Header The traceparent header represents the incoming request in a tracing system in a common format, understood by all vendors. From dcb7c70d5523163cee98b53ac15953780f3ec691 Mon Sep 17 00:00:00 2001 From: Viktor Farcic Date: Thu, 17 Feb 2022 02:25:23 +0100 Subject: [PATCH 69/73] Video (#2198) Signed-off-by: Viktor Farcic --- daprdocs/content/en/contributing/presentations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/daprdocs/content/en/contributing/presentations.md b/daprdocs/content/en/contributing/presentations.md index b346d6ba9..cc2b618de 100644 --- a/daprdocs/content/en/contributing/presentations.md +++ b/daprdocs/content/en/contributing/presentations.md @@ -20,6 +20,7 @@ We welcome community members giving presentations on Dapr and spreading the word | Presentation | Recording | Deck | |--------------|-----------|------| +| Running Event-Driven Pub/Sub Microservices In Kubernetes With Dapr | [Link](https://youtu.be/-4sHUvfk2Eg) | N/A | Ignite 2019: Mark Russinovich Presents the Future of Cloud Native Applications | [Link](https://www.youtube.com/watch?v=LAUDVk8PaCY) | [Link](/presentations/2019IgniteCloudNativeApps.pdf) | Azure Community Live: Build microservice applications using DAPR with Mark Fussell | [Link](https://www.youtube.com/watch?v=CgqI7nen-Ng) | N/A | Ready 2020: Mark Russinovich Presents Cloud Native Applications | [Link](https://youtu.be/eJCu6a-x9uo?t=1614) | [Link](/presentations/2020ReadyCloudNativeApps.pdf) From 1a0d4d31362e911ec9cafa370e7f787095d8137f Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Sat, 19 Feb 2022 01:10:00 +0530 Subject: [PATCH 70/73] Updating request payload format for cosmosdbgremlinapi (#2161) Signed-off-by: Pravin Pushkar Co-authored-by: Mark Fussell --- .../supported-bindings/cosmosdbgremlinapi.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/cosmosdbgremlinapi.md b/daprdocs/content/en/reference/components-reference/supported-bindings/cosmosdbgremlinapi.md index 599525949..cb92886bd 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/cosmosdbgremlinapi.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/cosmosdbgremlinapi.md @@ -38,7 +38,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr |--------------------|:--------:|--------|---------|---------| | url | Y | Output | The CosmosDBGremlinAPI url | `"wss://******.gremlin.cosmos.azure.com:443/"` | | masterKey | Y | Output | The CosmosDBGremlinAPI account master key | `"masterKey"` | -| database | Y | Output | The username of the CosmosDBGremlinAPI database | `"username"` | +| username | Y | Output | The username of the CosmosDBGremlinAPI database | `"/dbs//colls/"` | For more information see [Quickstart: Azure Cosmos Graph DB using Gremlin ](https://docs.microsoft.com/azure/cosmos-db/graph/create-graph-console). @@ -48,6 +48,17 @@ This component supports **output binding** with the following operations: - `query` +## Request payload sample + +```json +{ + "data": { + "gremlin": "g.V().count()" + }, + "operation": "query" +} +``` + ## Related links - [Basic schema for a Dapr component]({{< ref component-schema >}}) From 428d8c2e002bdca5243325ad5a93c7678099080c Mon Sep 17 00:00:00 2001 From: Armin Schlegel Date: Fri, 18 Feb 2022 21:08:33 +0100 Subject: [PATCH 71/73] Update setup-jetstream.md (#2200) * Update setup-jetstream.md Added missing information how to create the JetStream. Creating a JetStream is essential. Otherwise the pub/sub for jetstream won't work properly. Signed-off-by: Armin Schlegel * Update setup-jetstream.md Signed-off-by: Armin Schlegel Co-authored-by: Mark Fussell --- .../supported-pubsub/setup-jetstream.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-jetstream.md b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-jetstream.md index 791a2f02b..225a20ef5 100644 --- a/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-jetstream.md +++ b/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-jetstream.md @@ -82,6 +82,14 @@ with NATS, find the service with: `kubectl get svc my-nats`. {{< /tabs >}} +## Create JetStream + +It is essential to create a NATS JetStream for a specific subject. For example, for a NATS server running locally use: + +```bash +nats -s localhost:4222 stream add myStream --subjects mySubject +``` + ## Related links - [Basic schema for a Dapr component]({{< ref component-schema >}}) - Read [this guide]({{< ref "howto-publish-subscribe.md#step-2-publish-a-topic" >}}) for instructions on configuring pub/sub components From e8e9b2c10156f29a3f23291e9054301417f3199a Mon Sep 17 00:00:00 2001 From: Bernd Verst <4535280+berndverst@users.noreply.github.com> Date: Tue, 22 Feb 2022 17:56:33 -0800 Subject: [PATCH 72/73] Update mTLS certificate rotation guidance (#2208) * Update mTLS rotation guidance Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> * Update daprdocs/content/en/operations/security/mtls.md Co-authored-by: Mark Fussell Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> * Update daprdocs/content/en/operations/security/mtls.md Co-authored-by: Mark Fussell Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> * Update daprdocs/content/en/operations/security/mtls.md Co-authored-by: Mark Fussell Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> * Update daprdocs/content/en/operations/security/mtls.md Co-authored-by: Yaron Schneider Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> * Refine downtime warning Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> Co-authored-by: Mark Fussell Co-authored-by: Yaron Schneider --- .../content/en/operations/security/mtls.md | 72 +++++++++++++++++-- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/daprdocs/content/en/operations/security/mtls.md b/daprdocs/content/en/operations/security/mtls.md index 989ac7bcf..459f3f331 100644 --- a/daprdocs/content/en/operations/security/mtls.md +++ b/daprdocs/content/en/operations/security/mtls.md @@ -62,6 +62,7 @@ kubectl rollout restart statefulsets/dapr-placement-server -n *Note: the control plane Sidecar Injector service does not need to be redeployed* ### Disabling mTLS with Helm +*The control plane will continue to use mTLS* ```bash kubectl create ns dapr-system @@ -74,6 +75,7 @@ helm install \ ``` ### Disabling mTLS with the CLI +*The control plane will continue to use mTLS* ``` dapr init --kubernetes --enable-mtls=false @@ -86,7 +88,6 @@ In order to view the Sentry service logs, run the following command: ``` kubectl logs --selector=app=dapr-sentry --namespace ``` - ### Bringing your own certificates Using Helm, you can provide the PEM encoded root cert, issuer cert and private key that will be populated into the Kubernetes secret used by the Sentry service. @@ -163,9 +164,52 @@ helm install \ If the Root or Issuer certs are about to expire, you can update them and restart the required system services. {{% alert title="Avoiding downtime when rotating certificates" color="warning" %}} -To avoid downtime when rotating expiring certificates your new certificates must be signed with the same private root key as the previous certificates. +To avoid downtime when rotating expiring certificates your new certificates must be signed with the same private root key as the previous certificates. This is not currently possible using self-signed certificates generated by Dapr. {{% /alert %}} +#### Dapr-generated self-signed certificates + +1. Clear the existing Dapr Trust Bundle secret by saving the following YAML to a file (e.g. `clear-trust-bundle.yaml`) and applying this secret. +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: dapr-trust-bundle + labels: + app: dapr-sentry +data: +``` + +```bash +kubectl apply -f `clear-trust-bundle.yaml` -n +``` + +2. Restart the Dapr Sentry service. This will generate a new certificate bundle and update the `dapr-trust-bundle` Kubernetes secret. + +```bash +kubectl rollout restart -n deployment/dapr-sentry +``` + +3. Once the Sentry service has been restarted, restart the rest of the Dapr control plane to pick up the new Dapr Trust Bundle. + +```bash +kubectl rollout restart deploy/dapr-sentry -n +kubectl rollout restart deploy/dapr-operator -n +kubectl rollout restart statefulsets/dapr-placement-server -n +``` + +4. Restart your Dapr applications to pick up the latest trust bundle. + +{{% alert title="Potential application downtime with mTLS enabled." color="warning" %}} +Restarts of deployments using service to service invocation using mTLS will fail until the callee service has also been restarted (thereby loading the new Dapr Trust Bundle). Additionally, the placement service will not be able to assign new actors (while existing actors remain unaffected) until applications have been restarted to load the new Dapr Trust Bundle. +{{% /alert %}} + +```bash +kubectl rollout restart deployment/mydaprservice1 kubectl deployment/myotherdaprservice2 +``` + +#### Custom certificates (bring your own) + First, issue new certificates using the step above in [Bringing your own certificates](#bringing-your-own-certificates). Now that you have the new certificates, use Helm to upgrade the certificates: @@ -189,14 +233,22 @@ kubectl edit secret dapr-trust-bundle -n Replace the `ca.crt`, `issuer.crt` and `issuer.key` keys in the Kubernetes secret with their corresponding values from the new certificates. *__Note: The values must be base64 encoded__* -If you signed the new cert root with the same private key the Dapr Sentry service will pick up the new certificates automatically. You can restart your application deployments using `kubectl rollout restart` with zero downtime. It is not necessary to restart all deployments at once, as long as deployments are restarted before original certificate expiration. +If you signed the new cert root with the **same private key** the Dapr Sentry service will pick up the new certificates automatically. You can restart your application deployments using `kubectl rollout restart` with zero downtime. It is not necessary to restart all deployments at once, as long as deployments are restarted before original certificate expiration. -If you signed the new cert root with a different private key, you must restart the Dapr sentry service. +If you signed the new cert root with a **different private key**, you must restart the Dapr Sentry service, followed by the remainder of the Dapr control plane service. ```bash kubectl rollout restart deploy/dapr-sentry -n ``` +Once Sentry has been completely restarted run: + +```bash +kubectl rollout restart deploy/dapr-sentry -n +kubectl rollout restart deploy/dapr-operator -n +kubectl rollout restart statefulsets/dapr-placement-server -n +``` + Next, you must restart all Dapr-enabled pods. The recommended way to do this is to perform a rollout restart of your deployment: @@ -342,9 +394,15 @@ Place `ca.crt`, `issuer.crt` and `issuer.key` in a desired path (`$HOME/.dapr/ce If the Root or Issuer certs are about to expire, you can update them and restart the required system services. -First, issue new certificates using the step above in [Bringing your own certificates](#bringing-your-own-certificates). +To have Dapr generate new certificates, delete the existing certificates at `$HOME/.dapr/certs` and restart the sentry service to generate new certificates. + +```bash +./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=./config.yaml +``` + +To replace with your own certificates, first generate new certificates using the step above in [Bringing your own certificates](#bringing-your-own-certificates). Copy `ca.crt`, `issuer.crt` and `issuer.key` to the filesystem path of every configured system service, and restart the process or container. -By default, system services will look for the credentials in `/var/run/dapr/credentials`. +By default, system services will look for the credentials in `/var/run/dapr/credentials`. The examples above use `$HOME/.dapr/certs` as a custom location. -*Note:If you signed the cert root with a different private key, restart the Dapr instances.* +*Note: If you signed the cert root with a different private key, restart the Dapr instances.* From d72b38b0ea23baafc130c3af4c83156d76ddd560 Mon Sep 17 00:00:00 2001 From: Bernd Verst <4535280+berndverst@users.noreply.github.com> Date: Tue, 22 Feb 2022 19:07:11 -0800 Subject: [PATCH 73/73] Remove unnecessary sentry restarts (#2209) Signed-off-by: Bernd Verst <4535280+berndverst@users.noreply.github.com> --- daprdocs/content/en/operations/security/mtls.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/daprdocs/content/en/operations/security/mtls.md b/daprdocs/content/en/operations/security/mtls.md index 459f3f331..130708bb5 100644 --- a/daprdocs/content/en/operations/security/mtls.md +++ b/daprdocs/content/en/operations/security/mtls.md @@ -193,7 +193,6 @@ kubectl rollout restart -n deployment/dapr-sentry 3. Once the Sentry service has been restarted, restart the rest of the Dapr control plane to pick up the new Dapr Trust Bundle. ```bash -kubectl rollout restart deploy/dapr-sentry -n kubectl rollout restart deploy/dapr-operator -n kubectl rollout restart statefulsets/dapr-placement-server -n ``` @@ -244,7 +243,6 @@ kubectl rollout restart deploy/dapr-sentry -n Once Sentry has been completely restarted run: ```bash -kubectl rollout restart deploy/dapr-sentry -n kubectl rollout restart deploy/dapr-operator -n kubectl rollout restart statefulsets/dapr-placement-server -n ```