From 7c4bbcf75c016033935c2bff54c5670d510954c8 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 14 Jun 2023 11:20:45 -0400 Subject: [PATCH 01/31] initial edits Signed-off-by: Hannah Hunter --- .../components => reference/resource-specs}/component-schema.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename daprdocs/content/en/{operations/components => reference/resource-specs}/component-schema.md (100%) diff --git a/daprdocs/content/en/operations/components/component-schema.md b/daprdocs/content/en/reference/resource-specs/component-schema.md similarity index 100% rename from daprdocs/content/en/operations/components/component-schema.md rename to daprdocs/content/en/reference/resource-specs/component-schema.md From 76b869cb81e979e65c0a6690571e92b3e4cdb44b Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 14 Jun 2023 16:14:17 -0400 Subject: [PATCH 02/31] add resiliency schema doc - still in progress Signed-off-by: Hannah Hunter --- .../en/reference/resource-specs/component-schema.md | 2 +- .../en/reference/resource-specs/httpendpoints-reference.md | 2 +- .../en/reference/resource-specs/resiliency-schema.md | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 daprdocs/content/en/reference/resource-specs/resiliency-schema.md diff --git a/daprdocs/content/en/reference/resource-specs/component-schema.md b/daprdocs/content/en/reference/resource-specs/component-schema.md index bf60364cd..89cde4f4d 100644 --- a/daprdocs/content/en/reference/resource-specs/component-schema.md +++ b/daprdocs/content/en/reference/resource-specs/component-schema.md @@ -2,7 +2,7 @@ type: docs title: "Component schema" linkTitle: "Component schema" -weight: 100 +weight: 1000 description: "The basic schema for a Dapr component" --- diff --git a/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md b/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md index 66d4f5606..c4293debb 100644 --- a/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md +++ b/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md @@ -3,7 +3,7 @@ type: docs title: "HTTPEndpoint spec" linkTitle: "HTTPEndpoint spec" description: "The HTTPEndpoint resource spec" -weight: 300 +weight: 3000 aliases: - "/operations/httpEndpoints/" --- diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md new file mode 100644 index 000000000..4dfefcc4d --- /dev/null +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -0,0 +1,7 @@ +--- +type: docs +title: "Resiliency schema" +linkTitle: "Resiliency schema" +weight: 2000 +description: "The basic schema for a Dapr component" +--- \ No newline at end of file From e23ae809da09cf2ba9e3d9932fef5aff070d7087 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 15 Jun 2023 14:34:03 -0400 Subject: [PATCH 03/31] add saslmechanism Signed-off-by: Hannah Hunter --- .../reference/components-reference/supported-bindings/kafka.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md b/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md index 3ec497552..cc40d1b95 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md @@ -39,6 +39,8 @@ spec: secretKeyRef: name: kafka-secrets key: saslPasswordSecret + - name: saslMechanism + value: "SHA-512" - name: initialOffset # Optional. Used for input bindings. value: "newest" - name: maxMessageBytes # Optional. @@ -61,6 +63,7 @@ spec: | authType | Y | Input/Output | Configure or disable authentication. Supported values: `none`, `password`, `mtls`, or `oidc` | `"password"`, `"none"` | | saslUsername | N | Input/Output | The SASL username used for authentication. Only required if `authRequired` is set to `"true"`. | `"adminuser"` | | saslPassword | N | Input/Output | 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!"` | +| saslMechanism | N | Input/Output | The SASL authentication mechanism you'd like to use. Only required if `authtype` is set to `"password"`. If not provided, will default to `PLAINTEXT`, which could cause a break for some services, like Amazon Managed Service for Kafka. | `""`, `"SHA-512"` | | initialOffset | N | Input | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"` | | maxMessageBytes | N | Input/Output | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048` | | oidcTokenEndpoint | N | Input/Output | Full URL to an OAuth2 identity provider access token endpoint. Required when `authType` is set to `oidc` | "https://identity.example.com/v1/token" | From e388bd56e7538ad9734f73c00e27ab4274e1000b Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 15 Jun 2023 15:44:20 -0400 Subject: [PATCH 04/31] duplicate changes from deleted repo Signed-off-by: Hannah Hunter --- .../supported-bindings/redis.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md b/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md index 8fe7638e0..d399d2650 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md @@ -96,6 +96,8 @@ An HTTP 204 (No Content) and empty body is returned if successful. You can get a record in Redis using the `get` operation. This gets a key that was previously set. +This takes an optional parameter `delete`, which is by default `false`. When it is set to `true`, this operation will use the `GETDEL` operation of Redis. For example, it will return the `value` which was previously set and delete it. + #### Request ```json @@ -120,6 +122,20 @@ You can get a record in Redis using the `get` operation. This gets a key that wa } ``` +#### Request with delete flag + +```json +{ + "operation": "get", + "metadata": { + "key": "key1", + "delete": "true" + }, + "data": { + } +} +``` + ### delete You can delete a record in Redis using the `delete` operation. Returns success whether the key exists or not. From df28a2745ab4eeb3985adffc1e2c6f41a144c189 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 15 Jun 2023 15:52:45 -0400 Subject: [PATCH 05/31] add suggested warning Signed-off-by: Hannah Hunter --- .../components-reference/supported-pubsub/setup-pulsar.md | 5 +++++ 1 file changed, 5 insertions(+) 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 5adca74a8..5e6bc861e 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 @@ -62,6 +62,11 @@ spec: } ``` +{{% alert title="Warning" color="warning" %}} +This component supports storing the `token` parameter and any other sensitive parameter and data as Kubernetes Secrets. +{{% /alert %}} + + ## Spec metadata fields | Field | Required | Details | Example | From 21c77557fa04bafbd9960efe4eb3dbfd7d8ff7e1 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Thu, 15 Jun 2023 16:24:46 -0400 Subject: [PATCH 06/31] add env variable Signed-off-by: Hannah Hunter --- daprdocs/content/en/reference/environment/_index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/environment/_index.md b/daprdocs/content/en/reference/environment/_index.md index 201f80f36..064b0b16a 100644 --- a/daprdocs/content/en/reference/environment/_index.md +++ b/daprdocs/content/en/reference/environment/_index.md @@ -24,4 +24,5 @@ The following table lists the environment variables used by the Dapr runtime, CL | DAPR_HELM_REPO_PASSWORD | A password for a private Helm chart |The password required to access the private Dapr helm chart. If it can be accessed publicly, this env variable does not need to be set| | OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry Tracing | Sets the Open Telemetry (OTEL) server address, turns on tracing. (Example: `http://localhost:4318`) | | OTEL_EXPORTER_OTLP_INSECURE | OpenTelemetry Tracing | Sets the connection to the endpoint as unencrypted. (`true`, `false`) | -| OTEL_EXPORTER_OTLP_PROTOCOL | OpenTelemetry Tracing | The OTLP protocol to use Transport protocol. (`grpc`, `http/protobuf`, `http/json`) | \ No newline at end of file +| OTEL_EXPORTER_OTLP_PROTOCOL | OpenTelemetry Tracing | The OTLP protocol to use Transport protocol. (`grpc`, `http/protobuf`, `http/json`) | +| DAPR_COMPONENTS_SOCKET_FOLDER | Pluggable component | The location for the `.sock` file for the shared directory location socket | From 92e83e57defb92b5f8fd0d029afa134b45e2414f Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:13:17 -0400 Subject: [PATCH 07/31] Update daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- .../reference/components-reference/supported-bindings/kafka.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md b/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md index cc40d1b95..912471cbb 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/kafka.md @@ -63,7 +63,7 @@ spec: | authType | Y | Input/Output | Configure or disable authentication. Supported values: `none`, `password`, `mtls`, or `oidc` | `"password"`, `"none"` | | saslUsername | N | Input/Output | The SASL username used for authentication. Only required if `authRequired` is set to `"true"`. | `"adminuser"` | | saslPassword | N | Input/Output | 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!"` | -| saslMechanism | N | Input/Output | The SASL authentication mechanism you'd like to use. Only required if `authtype` is set to `"password"`. If not provided, will default to `PLAINTEXT`, which could cause a break for some services, like Amazon Managed Service for Kafka. | `""`, `"SHA-512"` | +| saslMechanism | N | Input/Output | The SASL authentication mechanism you'd like to use. Only required if `authtype` is set to `"password"`. If not provided, defaults to `PLAINTEXT`, which could cause a break for some services, like Amazon Managed Service for Kafka. | `"SHA-512", "SHA-256", "PLAINTEXT"` | | initialOffset | N | Input | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"` | | maxMessageBytes | N | Input/Output | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048` | | oidcTokenEndpoint | N | Input/Output | Full URL to an OAuth2 identity provider access token endpoint. Required when `authType` is set to `oidc` | "https://identity.example.com/v1/token" | From cf3afe5e84a7a00ba1ac7e9908ca5053cd837d50 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Fri, 16 Jun 2023 10:22:44 -0400 Subject: [PATCH 08/31] Update daprdocs/content/en/reference/components-reference/supported-bindings/redis.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --- .../reference/components-reference/supported-bindings/redis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md b/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md index d399d2650..7d5fdc8ae 100644 --- a/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md +++ b/daprdocs/content/en/reference/components-reference/supported-bindings/redis.md @@ -96,7 +96,7 @@ An HTTP 204 (No Content) and empty body is returned if successful. You can get a record in Redis using the `get` operation. This gets a key that was previously set. -This takes an optional parameter `delete`, which is by default `false`. When it is set to `true`, this operation will use the `GETDEL` operation of Redis. For example, it will return the `value` which was previously set and delete it. +This takes an optional parameter `delete`, which is by default `false`. When it is set to `true`, this operation uses the `GETDEL` operation of Redis. For example, it returns the `value` which was previously set and then deletes it. #### Request From 26624224b9f29ec2860b2bda23c1f7a77c678955 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 16 Jun 2023 10:34:28 -0400 Subject: [PATCH 09/31] update notes Signed-off-by: Hannah Hunter --- .../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 5e6bc861e..45726e253 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 @@ -63,7 +63,7 @@ spec: ``` {{% alert title="Warning" color="warning" %}} -This component supports storing the `token` parameter and any other sensitive parameter and data as Kubernetes Secrets. +The above example uses secrets as plain strings. It is recommended to use a [secret store for the secrets]({{< ref component-secrets.md >}}). This component supports storing the `token` parameter and any other sensitive parameter and data as Kubernetes Secrets. {{% /alert %}} From 377d8a5ae080cf61b6fee2042a1fbf7d66dd9025 Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Fri, 16 Jun 2023 16:23:27 -0700 Subject: [PATCH 10/31] Update code snippets to show button on hover (#3561) Signed-off-by: Aaron Crawfis --- daprdocs/assets/scss/_code.scss | 56 +++++++------------ daprdocs/static/js/copy-code-button.js | 74 +++++++++++--------------- 2 files changed, 48 insertions(+), 82 deletions(-) diff --git a/daprdocs/assets/scss/_code.scss b/daprdocs/assets/scss/_code.scss index dd05e51bf..49ad9c8b3 100644 --- a/daprdocs/assets/scss/_code.scss +++ b/daprdocs/assets/scss/_code.scss @@ -1,38 +1,12 @@ // Code formatting. -.copy-code-button { - color: #272822; - background-color: #FFF; - border-color: #0D2192; - border: 2px solid; - border-radius: 3px 3px 0px 0px; - - /* right-align */ - display: block; - margin-left: auto; - margin-right: 0; - - margin-bottom: -2px; - padding: 3px 8px; - font-size: 0.8em; +.highlight .copy-icon { + position: absolute; + right: 20px; + top: 18px; + opacity: 0.7; } -.copy-code-button:hover { - cursor: pointer; - background-color: #F2F2F2; -} - -.copy-code-button:focus { - /* Avoid an ugly focus outline on click in Chrome, - but darken the button for accessibility. - See https://stackoverflow.com/a/25298082/1481479 */ - background-color: #E6E6E6; - outline: 0; -} - -.copy-code-button:active { - background-color: #D9D9D9; -} .highlight pre { /* Avoid pushing up the copy buttons. */ @@ -40,25 +14,31 @@ } .td-content { - // Highlighted code. + + // Highlighted code. .highlight { @extend .card; - + margin: 0rem 0; padding: 0rem; margin-bottom: 2rem; max-width: 100%; - + + border: none; + pre { margin: 0; padding: 1rem; + border-radius: 10px; } } // Inline code - p code, li > code, table code { + p code, + li>code, + table code { color: inherit; padding: 0.2em 0.4em; margin: 0; @@ -78,11 +58,11 @@ word-wrap: normal; background-color: $gray-100; padding: $spacer; - + max-width: 100%; - > code { - background-color: inherit !important; + >code { + background-color: inherit !important; padding: 0; margin: 0; font-size: 100%; diff --git a/daprdocs/static/js/copy-code-button.js b/daprdocs/static/js/copy-code-button.js index 579d25148..ca5d0e26e 100644 --- a/daprdocs/static/js/copy-code-button.js +++ b/daprdocs/static/js/copy-code-button.js @@ -1,49 +1,35 @@ -function addCopyButtons(clipboard) { - document.querySelectorAll('pre > code').forEach(function(codeBlock) { - var button = document.createElement('button'); - button.className = 'copy-code-button'; - button.type = 'button'; - button.innerText = 'Copy'; +const highlightClass = document.querySelectorAll('.highlight'); - button.addEventListener('click', function() { - clipboard.writeText(codeBlock.textContent).then( - function() { - button.blur(); +highlightClass.forEach(element => { + const copyIcon = document.createElement('i'); + copyIcon.classList.add('fas', 'fa-copy', 'copy-icon'); + copyIcon.style.color = 'white'; + copyIcon.style.display = 'none'; + element.appendChild(copyIcon); - button.innerText = 'Copied!'; - setTimeout(function() { - button.innerText = 'Copy'; - }, 2000); - }, - function(error) { - button.innerText = 'Error'; - console.error(error); - } - ); - }); + element.addEventListener('mouseenter', () => { + copyIcon.style.display = 'inline'; + }); - var pre = codeBlock.parentNode; - if (pre.parentNode.classList.contains('highlight')) { - var highlight = pre.parentNode; - highlight.parentNode.insertBefore(button, highlight); - } else { - pre.parentNode.insertBefore(button, pre); - } - }); -} + element.addEventListener('mouseleave', () => { + copyIcon.style.display = 'none'; + copyIcon.classList.replace('fa-check', 'fa-copy'); + }); -if (navigator && navigator.clipboard) { - addCopyButtons(navigator.clipboard); -} else { - var script = document.createElement('script'); - script.src = - 'https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/2.7.0/clipboard-polyfill.promise.js'; - script.integrity = 'sha256-waClS2re9NUbXRsryKoof+F9qc1gjjIhc2eT7ZbIv94='; - script.crossOrigin = 'anonymous'; + copyIcon.addEventListener('click', async () => { + const selection = window.getSelection(); + const range = document.createRange(); + range.selectNodeContents(element); + selection.removeAllRanges(); + selection.addRange(range); - script.onload = function() { - addCopyButtons(clipboard); - }; - - document.body.appendChild(script); -} + try { + await navigator.clipboard.writeText(selection.toString()); + console.log('Text copied to clipboard'); + copyIcon.classList.replace('fa-copy', 'fa-check'); + selection.removeAllRanges(); + } catch (error) { + console.error('Failed to copy: ', error); + } + }); +}); From ee25a6a753b38305ae7ba85c44ada8f15fdcbcee Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:06:01 -0400 Subject: [PATCH 11/31] [Azure Monitor] Reformat/refresh doc and update from retired terminology (#3549) * general doc/formatting refresh and update from retired terminology Signed-off-by: Hannah Hunter * Update daprdocs/content/en/operations/monitoring/metrics/azure-monitor.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --------- Signed-off-by: Hannah Hunter Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Co-authored-by: Mark Fussell --- .../monitoring/metrics/azure-monitor.md | 178 +++++++++--------- 1 file changed, 90 insertions(+), 88 deletions(-) diff --git a/daprdocs/content/en/operations/monitoring/metrics/azure-monitor.md b/daprdocs/content/en/operations/monitoring/metrics/azure-monitor.md index d63b820ea..3011ef399 100644 --- a/daprdocs/content/en/operations/monitoring/metrics/azure-monitor.md +++ b/daprdocs/content/en/operations/monitoring/metrics/azure-monitor.md @@ -15,118 +15,120 @@ description: "Enable Dapr metrics and logs with Azure Monitor for Azure Kubernet ## Enable Prometheus metric scrape using config map -1. Make sure that omsagents are running +1. Make sure that Azure Monitor Agents (AMA) are running. -```bash -$ kubectl get pods -n kube-system -NAME READY STATUS RESTARTS AGE -... -omsagent-75qjs 1/1 Running 1 44h -omsagent-c7c4t 1/1 Running 0 44h -omsagent-rs-74f488997c-dshpx 1/1 Running 1 44h -omsagent-smtk7 1/1 Running 1 44h -... -``` + ```bash + $ kubectl get pods -n kube-system + NAME READY STATUS RESTARTS AGE + ... + ama-logs-48kpv 2/2 Running 0 2d13h + ama-logs-mx24c 2/2 Running 0 2d13h + ama-logs-rs-f9bbb9898-vbt6k 1/1 Running 0 30h + ama-logs-sm2mz 2/2 Running 0 2d13h + ama-logs-z7p4c 2/2 Running 0 2d13h + ... + ``` -2. Apply config map to enable Prometheus metrics endpoint scrape. +1. Apply config map to enable Prometheus metrics endpoint scrape. -You can use [azm-config-map.yaml](/docs/azm-config-map.yaml) to enable prometheus metrics endpoint scrape. + You can use [azm-config-map.yaml](/docs/azm-config-map.yaml) to enable Prometheus metrics endpoint scrape. -If you installed Dapr to the different namespace, you need to change the `monitor_kubernetes_pod_namespaces` array values. For example: + If you installed Dapr to a different namespace, you need to change the `monitor_kubernetes_pod_namespaces` array values. For example: -```yaml -... - prometheus-data-collection-settings: |- - [prometheus_data_collection_settings.cluster] - interval = "1m" - monitor_kubernetes_pods = true - monitor_kubernetes_pods_namespaces = ["dapr-system", "default"] - [prometheus_data_collection_settings.node] - interval = "1m" -... -``` + ```yaml + ... + prometheus-data-collection-settings: |- + [prometheus_data_collection_settings.cluster] + interval = "1m" + monitor_kubernetes_pods = true + monitor_kubernetes_pods_namespaces = ["dapr-system", "default"] + [prometheus_data_collection_settings.node] + interval = "1m" + ... + ``` -Apply config map: + Apply config map: -```bash -kubectl apply -f ./azm-config.map.yaml -``` + ```bash + kubectl apply -f ./azm-config.map.yaml + ``` ## Install Dapr with JSON formatted logs -1. Install Dapr with enabling JSON-formatted logs +1. Install Dapr with enabling JSON-formatted logs. -```bash -helm install dapr dapr/dapr --namespace dapr-system --set global.logAsJson=true -``` + ```bash + helm install dapr dapr/dapr --namespace dapr-system --set global.logAsJson=true + ``` -2. Enable JSON formatted log in Dapr sidecar and add Prometheus annotations. +1. Enable JSON formatted log in Dapr sidecar and add Prometheus annotations. -> Note: OMS Agent scrapes the metrics only if replicaset has Prometheus annotations. + > Note: The Azure Monitor Agents (AMA) only sends the metrics if the Prometheus annotations are set. -Add `dapr.io/log-as-json: "true"` annotation to your deployment yaml. + Add `dapr.io/log-as-json: "true"` annotation to your deployment yaml. -Example: -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: pythonapp - namespace: default - labels: - app: python -spec: - replicas: 1 - selector: - matchLabels: - app: python - template: - metadata: - labels: - app: python - annotations: - dapr.io/enabled: "true" - dapr.io/app-id: "pythonapp" - dapr.io/log-as-json: "true" - prometheus.io/scrape: "true" - prometheus.io/port: "9090" - prometheus.io/path: "/" + Example: -... -``` + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: pythonapp + namespace: default + labels: + app: python + spec: + replicas: 1 + selector: + matchLabels: + app: python + template: + metadata: + labels: + app: python + annotations: + dapr.io/enabled: "true" + dapr.io/app-id: "pythonapp" + dapr.io/log-as-json: "true" + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + prometheus.io/path: "/" + + ... + ``` ## Search metrics and logs with Azure Monitor -1. Go to Azure Monitor +1. Go to Azure Monitor in the Azure portal. -2. Search Dapr logs +1. Search Dapr **Logs**. -Here is an example query, to parse JSON formatted logs and query logs from dapr system processes. + Here is an example query, to parse JSON formatted logs and query logs from Dapr system processes. -``` -ContainerLog -| extend parsed=parse_json(LogEntry) -| project Time=todatetime(parsed['time']), app_id=parsed['app_id'], scope=parsed['scope'],level=parsed['level'], msg=parsed['msg'], type=parsed['type'], ver=parsed['ver'], instance=parsed['instance'] -| where level != "" -| sort by Time -``` + ``` + ContainerLog + | extend parsed=parse_json(LogEntry) + | project Time=todatetime(parsed['time']), app_id=parsed['app_id'], scope=parsed['scope'],level=parsed['level'], msg=parsed['msg'], type=parsed['type'], ver=parsed['ver'], instance=parsed['instance'] + | where level != "" + | sort by Time + ``` -3. Search metrics +1. Search **Metrics**. -This query, queries process_resident_memory_bytes Prometheus metrics for Dapr system processes and renders timecharts + This query, queries `process_resident_memory_bytes` Prometheus metrics for Dapr system processes and renders timecharts. -``` -InsightsMetrics -| where Namespace == "prometheus" and Name == "process_resident_memory_bytes" -| extend tags=parse_json(Tags) -| project TimeGenerated, Name, Val, app=tostring(tags['app']) -| summarize memInBytes=percentile(Val, 99) by bin(TimeGenerated, 1m), app -| where app startswith "dapr-" -| render timechart -``` + ``` + InsightsMetrics + | where Namespace == "prometheus" and Name == "process_resident_memory_bytes" + | extend tags=parse_json(Tags) + | project TimeGenerated, Name, Val, app=tostring(tags['app']) + | summarize memInBytes=percentile(Val, 99) by bin(TimeGenerated, 1m), app + | where app startswith "dapr-" + | render timechart + ``` -# References +## References -* [Configure scraping of Prometheus metrics with Azure Monitor for containers](https://docs.microsoft.com/azure/azure-monitor/insights/container-insights-prometheus-integration) -* [Configure agent data collection for Azure Monitor for containers](https://docs.microsoft.com/azure/azure-monitor/insights/container-insights-agent-config) -* [Azure Monitor Query](https://docs.microsoft.com/azure/azure-monitor/log-query/query-language) +- [Configure scraping of Prometheus metrics with Azure Monitor for containers](https://docs.microsoft.com/azure/azure-monitor/insights/container-insights-prometheus-integration) +- [Configure agent data collection for Azure Monitor for containers](https://docs.microsoft.com/azure/azure-monitor/insights/container-insights-agent-config) +- [Azure Monitor Query](https://docs.microsoft.com/azure/azure-monitor/log-query/query-language) From b9759702d581df0a18b7a6d5cba6eaf9589ac705 Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Fri, 16 Jun 2023 21:10:04 -0700 Subject: [PATCH 12/31] Manually build website and upload artifacts (#3559) * update dapr publish command Signed-off-by: Hannah Hunter Signed-off-by: Aaron Crawfis * Split workflow into two steps Signed-off-by: Aaron Crawfis * Update upload path Signed-off-by: Aaron Crawfis * Add concurrency check Signed-off-by: Aaron Crawfis * Consolidate jobs Signed-off-by: Aaron Crawfis --------- Signed-off-by: Hannah Hunter Signed-off-by: Aaron Crawfis Co-authored-by: Hannah Hunter Co-authored-by: Mark Fussell --- .github/workflows/website-root.yml | 67 ++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index 0265713f7..98d2aec11 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -1,6 +1,7 @@ name: Azure Static Web App Root on: + workflow_dispatch: push: branches: - v1.11 @@ -9,35 +10,65 @@ on: branches: - v1.11 +concurrency: + # Cancel the previously triggered build for only PR build. + group: website-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + jobs: build_and_deploy_job: - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + name: Build Hugo Website + if: github.event.action != 'closed' runs-on: ubuntu-latest - name: Build and Deploy Job + env: + SWA_BASE: 'proud-bay-0e9e0e81e' + HUGO_ENV: production steps: - - uses: actions/checkout@v3 + - name: Checkout docs repo + uses: actions/checkout@v3 with: - submodules: recursive - fetch-depth: 0 + submodules: true + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: '14' + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2.5.0 + with: + hugo-version: 0.102.3 + extended: true - name: Setup Docsy - run: cd daprdocs && git submodule update --init --recursive && sudo npm install -D --save autoprefixer && sudo npm install -D --save postcss-cli - - name: Build And Deploy - id: builddeploy + run: | + cd daprdocs + git submodule update --init --recursive + sudo npm install -D --save autoprefixer + sudo npm install -D --save postcss-cli + - name: Build Hugo Website + run: | + cd daprdocs + git config --global --add safe.directory /github/workspace + if [ $GITHUB_EVENT_NAME == 'pull_request' ]; then + STAGING_URL="https://${SWA_BASE}-${{github.event.number}}.westus2.azurestaticapps.net/" + fi + hugo ${STAGING_URL+-b "$STAGING_URL"} + - name: Deploy docs site uses: Azure/static-web-apps-deploy@v1 - env: - HUGO_ENV: production - HUGO_VERSION: "0.100.2" with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_PROUD_BAY_0E9E0E81E }} - skip_deploy_on_missing_secrets: true - repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + repo_token: ${{ secrets.GITHUB_TOKEN }} action: "upload" - app_location: "/daprdocs" - app_build_command: "git config --global --add safe.directory /github/workspace && hugo" - output_location: "public" - skip_api_build: true + app_location: "daprdocs/public/" + api_location: "daprdocs/public/" + output_location: "" + skip_app_build: true + - name: Upload Hugo artifacts + uses: actions/upload-artifact@v3 + with: + name: hugo_build + path: ./daprdocs/public/ + if-no-files-found: error - close_pull_request_job: + close_staging_site: if: github.event_name == 'pull_request' && github.event.action == 'closed' runs-on: ubuntu-latest name: Close Pull Request Job From 0d0d29ac92cfba8bb1dcc5e526e6f39fc88354a3 Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Fri, 16 Jun 2023 21:18:24 -0700 Subject: [PATCH 13/31] Upgrade Algolia search to v3 (#3560) * update dapr publish command Signed-off-by: Hannah Hunter Signed-off-by: Aaron Crawfis * Split workflow into two steps Signed-off-by: Aaron Crawfis * Update upload path Signed-off-by: Aaron Crawfis * Add concurrency check Signed-off-by: Aaron Crawfis * Add Algolia workflow script and step Signed-off-by: Aaron Crawfis * Update Algolia box to v3 Signed-off-by: Aaron Crawfis * Fix secret name Signed-off-by: Aaron Crawfis * Override default search bar in Docsy v3 Signed-off-by: Aaron Crawfis * Remove temporary comment Signed-off-by: Aaron Crawfis * Consolidate build and deploy Signed-off-by: Aaron Crawfis --------- Signed-off-by: Hannah Hunter Signed-off-by: Aaron Crawfis Co-authored-by: Hannah Hunter Co-authored-by: Mark Fussell --- .github/scripts/algolia.py | 118 ++++++++++++++++++ .github/workflows/website-root.yml | 26 ++++ daprdocs/layouts/partials/hooks/body-end.html | 20 ++- daprdocs/layouts/partials/hooks/head-end.html | 2 +- daprdocs/layouts/partials/search-input.html | 30 +++++ 5 files changed, 182 insertions(+), 14 deletions(-) create mode 100644 .github/scripts/algolia.py create mode 100644 daprdocs/layouts/partials/search-input.html diff --git a/.github/scripts/algolia.py b/.github/scripts/algolia.py new file mode 100644 index 000000000..5071ea580 --- /dev/null +++ b/.github/scripts/algolia.py @@ -0,0 +1,118 @@ +import os +from re import S +import sys +import json +from bs4 import BeautifulSoup +from algoliasearch.search_client import SearchClient + +url = "docs.dapr.io" +if len(sys.argv) > 1: + starting_directory = os.path.join(os.getcwd(), str(sys.argv[1])) +else: + starting_directory = os.getcwd() + +ALGOLIA_APP_ID = os.getenv('ALGOLIA_APP_ID') +ALGOLIA_API_KEY = os.getenv('ALGOLIA_API_WRITE_KEY') +ALGOLIA_INDEX_NAME = os.getenv('ALGOLIA_INDEX_NAME') + +client = SearchClient.create(ALGOLIA_APP_ID, ALGOLIA_API_KEY) +index = client.init_index(ALGOLIA_INDEX_NAME) + +excluded_files = [ + "404.html", +] + +exluded_directories = [ + "zh-hans", +] + +rankings = { + "Getting started": 0, + "Concepts": 100, + "Developing applications": 200, + "Operations": 300, + "Reference": 400, + "Contributing": 500, + "Home": 600 +} + +def scan_directory(directory: str, pages: list): + if os.path.basename(directory) in exluded_directories: + print(f'Skipping directory: {directory}') + return + for file in os.listdir(directory): + path = os.path.join(directory, file) + if os.path.isfile(path): + if file.endswith(".html") and file not in excluded_files: + if '' not in open(path, encoding="utf8").read(): + print(f'Indexing: {path}') + pages.append(path) + else: + print(f'Skipping hidden page: {path}') + else: + scan_directory(path, pages) + +def parse_file(path: str): + data = {} + data["hierarchy"] = {} + data["rank"] = 999 + data["subrank"] = 99 + data["type"] = "lvl2" + data["lvl0"] = "" + data["lvl1"] = "" + data["lvl2"] = "" + data["lvl3"] = "" + text = "" + subrank = 0 + with open(path, "r", errors='ignore') as file: + content = file.read() + soup = BeautifulSoup(content, "html.parser") + for meta in soup.find_all("meta"): + if meta.get("name") == "description": + data["lvl2"] = meta.get("content") + data["hierarchy"]["lvl1"] = meta.get("content") + elif meta.get("property") == "og:title": + data["lvl0"] = meta.get("content") + data["hierarchy"]["lvl0"] = meta.get("content") + data["hierarchy"]["lvl2"] = meta.get("content") + elif meta.get("property") == "og:url": + data["url"] = meta.get("content") + data["path"] = meta.get("content").split(url)[1] + data["objectID"] = meta.get("content").split(url)[1] + breadcrumbs = soup.find_all("li", class_="breadcrumb-item") + try: + subrank = len(breadcrumbs) + data["subrank"] = subrank + except: + subrank = 99 + data["subrank"] = 99 + for bc in breadcrumbs: + section = bc.text.strip() + data["lvl1"] = section + data["hierarchy"]["lvl0"] = section + try: + data["rank"] = rankings[section] + subrank + except: + print(f"Rank not found for section {section}") + data["rank"] = 998 + break + for p in soup.find_all("p"): + if p.text != "": + text = text + p.text + data["text"] = text + return data + +def index_payload(payload): + res = index.replace_all_objects(payload) + res.wait() + + +if __name__ == "__main__": + pages = [] + payload = [] + scan_directory(starting_directory, pages) + for page in pages: + data = parse_file(page) + if "objectID" in data: + payload.append(data) + index_payload(payload) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index 98d2aec11..ed8c3b491 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -79,3 +79,29 @@ jobs: with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_PROUD_BAY_0E9E0E81E }} action: "close" + + algolia_index: + name: Index site for Algolia + if: github.event_name == 'push' + needs: ['build_and_deploy_job'] + runs-on: ubuntu-latest + env: + ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }} + ALGOLIA_API_WRITE_KEY: ${{ secrets.ALGOLIA_API_WRITE_KEY }} + ALGOLIA_INDEX_NAME: daprdocs + steps: + - name: Checkout docs repo + uses: actions/checkout@v2 + with: + submodules: false + - name: Download Hugo artifacts + uses: actions/download-artifact@v3 + with: + name: hugo_build + path: site/ + - name: Install Python packages + run: | + pip install --upgrade bs4 + pip install --upgrade 'algoliasearch>=2.0,<3.0' + - name: Index site + run: python ./.github/scripts/algolia.py ./site diff --git a/daprdocs/layouts/partials/hooks/body-end.html b/daprdocs/layouts/partials/hooks/body-end.html index 695cf8638..79cbc117c 100644 --- a/daprdocs/layouts/partials/hooks/body-end.html +++ b/daprdocs/layouts/partials/hooks/body-end.html @@ -1,19 +1,13 @@ + + {{ with .Site.Params.algolia_docsearch }} - - + {{ end }} - - \ No newline at end of file diff --git a/daprdocs/layouts/partials/hooks/head-end.html b/daprdocs/layouts/partials/hooks/head-end.html index 804fe38e9..03e91efa2 100644 --- a/daprdocs/layouts/partials/hooks/head-end.html +++ b/daprdocs/layouts/partials/hooks/head-end.html @@ -1,3 +1,3 @@ {{ with .Site.Params.algolia_docsearch }} - + {{ end }} \ No newline at end of file diff --git a/daprdocs/layouts/partials/search-input.html b/daprdocs/layouts/partials/search-input.html new file mode 100644 index 000000000..22e900247 --- /dev/null +++ b/daprdocs/layouts/partials/search-input.html @@ -0,0 +1,30 @@ +{{ if .Site.Params.gcs_engine_id -}} + +{{ else if .Site.Params.algolia_docsearch -}} +
+{{ else if .Site.Params.offlineSearch -}} +{{ $offlineSearchIndex := resources.Get "json/offline-search-index.json" | resources.ExecuteAsTemplate "offline-search-index.json" . -}} +{{ if hugo.IsProduction -}} +{{/* Use `md5` as finger print hash function to shorten file name to avoid `file name too long` error. */ -}} +{{ $offlineSearchIndex = $offlineSearchIndex | fingerprint "md5" -}} +{{ end -}} +{{ $offlineSearchLink := $offlineSearchIndex.RelPermalink -}} + + +{{ end -}} From 3770cf0712436ce9025ce2cc7f75c8acbaff57c1 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 10:42:58 -0400 Subject: [PATCH 14/31] block out the other schemas Signed-off-by: Hannah Hunter --- .../resource-specs/component-schema.md | 6 +- .../resource-specs/httpendpoints-reference.md | 6 +- .../resource-specs/resiliency-schema.md | 146 +++++++++++++++++- 3 files changed, 147 insertions(+), 11 deletions(-) diff --git a/daprdocs/content/en/reference/resource-specs/component-schema.md b/daprdocs/content/en/reference/resource-specs/component-schema.md index 89cde4f4d..c36bded52 100644 --- a/daprdocs/content/en/reference/resource-specs/component-schema.md +++ b/daprdocs/content/en/reference/resource-specs/component-schema.md @@ -1,9 +1,9 @@ --- type: docs -title: "Component schema" -linkTitle: "Component schema" +title: "Component spec" +linkTitle: "Component" weight: 1000 -description: "The basic schema for a Dapr component" +description: "The basic spec for a Dapr component" --- Dapr defines and registers components using a [CustomResourceDefinition](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/). All components are defined as a CRD and can be applied to any hosting environment where Dapr is running, not just Kubernetes. diff --git a/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md b/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md index c4293debb..d2f5429e7 100644 --- a/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md +++ b/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md @@ -1,9 +1,9 @@ --- type: docs title: "HTTPEndpoint spec" -linkTitle: "HTTPEndpoint spec" -description: "The HTTPEndpoint resource spec" -weight: 3000 +linkTitle: "HTTPEndpoint" +description: "The basic spec for a Dapr HTTPEndpoint resource" +weight: 4000 aliases: - "/operations/httpEndpoints/" --- diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index 4dfefcc4d..c3ba272c9 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -1,7 +1,143 @@ --- type: docs -title: "Resiliency schema" -linkTitle: "Resiliency schema" -weight: 2000 -description: "The basic schema for a Dapr component" ---- \ No newline at end of file +title: "Resiliency spec" +linkTitle: "Resiliency spec" +weight: 3000 +description: "The basic spec for a Dapr resiliency resource" +--- + + +```yml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: resiliencies.dapr.io + labels: + app.kubernetes.io/part-of: "dapr" +spec: + group: dapr.io + names: + kind: Resiliency + listKind: ResiliencyList + plural: resiliencies + singular: resiliency + categories: + - dapr + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + scopes: + items: + type: string + type: array + spec: + properties: + policies: + properties: + circuitBreakers: + additionalProperties: + properties: + interval: + type: string + maxRequests: + type: integer + timeout: + type: string + trip: + type: string + type: object + type: object + retries: + additionalProperties: + properties: + duration: + type: string + maxInterval: + type: string + maxRetries: + type: integer + policy: + type: string + type: object + type: object + timeouts: + additionalProperties: + type: string + type: object + type: object + targets: + properties: + actors: + additionalProperties: + properties: + circuitBreaker: + type: string + circuitBreakerCacheSize: + type: integer + circuitBreakerScope: + type: string + retry: + type: string + timeout: + type: string + type: object + type: object + apps: + additionalProperties: + properties: + circuitBreaker: + type: string + circuitBreakerCacheSize: + type: integer + retry: + type: string + timeout: + type: string + type: object + type: object + components: + additionalProperties: + properties: + inbound: + properties: + circuitBreaker: + type: string + retry: + type: string + timeout: + type: string + type: object + outbound: + properties: + circuitBreaker: + type: string + retry: + type: string + timeout: + type: string + type: object + type: object + type: object + type: object + required: + - policies + - targets + type: object + type: object + served: true + storage: true +``` \ No newline at end of file From 72c84d40b3a70a3ec4672f054e07458b37acdff9 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 10:48:14 -0400 Subject: [PATCH 15/31] add new doc Signed-off-by: Hannah Hunter --- .../resource-specs/subscription-schema.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 daprdocs/content/en/reference/resource-specs/subscription-schema.md diff --git a/daprdocs/content/en/reference/resource-specs/subscription-schema.md b/daprdocs/content/en/reference/resource-specs/subscription-schema.md new file mode 100644 index 000000000..6d79c7c77 --- /dev/null +++ b/daprdocs/content/en/reference/resource-specs/subscription-schema.md @@ -0,0 +1,184 @@ +--- +type: docs +title: "Subscription spec" +linkTitle: "Subscription spec" +weight: 2000 +description: "The basic spec for a Dapr subscription" +--- + + + +```yml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: subscriptions.dapr.io + labels: + app.kubernetes.io/part-of: "dapr" +spec: + group: dapr.io + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: replaceme # Patched by post-install webhook + name: dapr-webhook + path: /convert + #caBundle: Patched by post-install webhook + conversionReviewVersions: + - v1 + - v2alpha1 + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Subscription describes an pub/sub event subscription. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + scopes: + items: + type: string + type: array + spec: + description: SubscriptionSpec is the spec for an event subscription. + properties: + pubsubname: + type: string + route: + type: string + topic: + type: string + deadLetterTopic: + type: string + bulkSubscribe: + description: Represents bulk subscribe properies + properties: + enabled: + type: boolean + maxMessagesCount: + type: integer + maxAwaitDurationMs: + type: integer + required: + - enabled + type: object + metadata: + additionalProperties: + type: string + type: object + required: + - pubsubname + - route + - topic + type: object + type: object + served: true + storage: false + - name: v2alpha1 + schema: + openAPIV3Schema: + description: Subscription describes an pub/sub event subscription. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + scopes: + items: + type: string + type: array + spec: + description: SubscriptionSpec is the spec for an event subscription. + properties: + metadata: + additionalProperties: + type: string + description: The optional metadata to provide the subscription. + type: object + pubsubname: + description: The PubSub component name. + type: string + routes: + description: The Routes configuration for this topic. + properties: + default: + type: string + rules: + description: The list of rules for this topic. + items: + description: Rule is used to specify the condition for sending + a message to a specific path. + properties: + match: + description: The optional CEL expression used to match the + event. If the match is not specified, then the route is + considered the default. The rules are tested in the order + specified, so they should be define from most-to-least + specific. The default route should appear last in the + list. + type: string + path: + description: The path for events that match this rule. + type: string + required: + - match + - path + type: object + type: array + type: object + topic: + description: The topic name to subscribe to. + type: string + deadLetterTopic: + description: The optional dead letter queue for this topic to send events to. + type: string + bulkSubscribe: + description: Represents bulk subscribe properies + properties: + enabled: + type: boolean + maxMessagesCount: + type: integer + maxAwaitDurationMs: + type: integer + required: + - enabled + type: object + required: + - pubsubname + - routes + - topic + type: object + type: object + served: true + storage: true + names: + kind: Subscription + listKind: SubscriptionList + plural: subscriptions + singular: subscription + categories: + - all + - dapr + scope: Namespaced +``` \ No newline at end of file From 927c6e12d55bcb3ebbcb4191191e089a90cd7ed9 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 11:03:44 -0400 Subject: [PATCH 16/31] add suggestions from tiago and phillip Signed-off-by: Hannah Hunter --- daprdocs/content/en/reference/environment/_index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/environment/_index.md b/daprdocs/content/en/reference/environment/_index.md index 064b0b16a..bd1225b5c 100644 --- a/daprdocs/content/en/reference/environment/_index.md +++ b/daprdocs/content/en/reference/environment/_index.md @@ -25,4 +25,5 @@ The following table lists the environment variables used by the Dapr runtime, CL | OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry Tracing | Sets the Open Telemetry (OTEL) server address, turns on tracing. (Example: `http://localhost:4318`) | | OTEL_EXPORTER_OTLP_INSECURE | OpenTelemetry Tracing | Sets the connection to the endpoint as unencrypted. (`true`, `false`) | | OTEL_EXPORTER_OTLP_PROTOCOL | OpenTelemetry Tracing | The OTLP protocol to use Transport protocol. (`grpc`, `http/protobuf`, `http/json`) | -| DAPR_COMPONENTS_SOCKET_FOLDER | Pluggable component | The location for the `.sock` file for the shared directory location socket | +| DAPR_COMPONENTS_SOCKETS_FOLDER | Dapr runtime and the .NET, Go, and Java pluggable component SDKs | The location or path where Dapr will look for Pluggable Components Unix Domain Socket files. If unset this location defaults to `/tmp/dapr-components-sockets` | +| DAPR_COMPONENTS_SOCKETS_EXTENSION | .NET and Java pluggable component SDKs | A per-SDK configuration that indicates the default file extension applied to socket files created by the SDKs. Not a Dapr-enforced behavior. | \ No newline at end of file From d978f4d1603091848eb07ed255b6e234cb083de0 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 11:16:02 -0400 Subject: [PATCH 17/31] kicking off a build Signed-off-by: Hannah Hunter --- daprdocs/content/en/reference/environment/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/environment/_index.md b/daprdocs/content/en/reference/environment/_index.md index bd1225b5c..524de0492 100644 --- a/daprdocs/content/en/reference/environment/_index.md +++ b/daprdocs/content/en/reference/environment/_index.md @@ -12,7 +12,7 @@ The following table lists the environment variables used by the Dapr runtime, CL | -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | APP_ID | Your application | The id for your application, used for service discovery | | APP_PORT | Dapr sidecar | The port your application is listening on | -| APP_API_TOKEN | Your application | The token used by the application to authenticate requests from Dapr API. Read [authenticate requests from Dapr using token authentication]({{< ref app-api-token >}}) for more information. | +| APP_API_TOKEN | Your application | The token used by the application to authenticate requests from Dapr API. Read [authenticate requests from Dapr using token authentication]({{< ref app-api-token >}}) for more information. | | DAPR_HTTP_PORT | Your application | The HTTP port that the Dapr sidecar is listening on. Your application should use this variable to connect to Dapr sidecar instead of hardcoding the port value. Set by the Dapr CLI run command for self-hosted or injected by the `dapr-sidecar-injector` into all the containers in the pod. | | DAPR_GRPC_PORT | Your application | The gRPC port that the Dapr sidecar is listening on. Your application should use this variable to connect to Dapr sidecar instead of hardcoding the port value. Set by the Dapr CLI run command for self-hosted or injected by the `dapr-sidecar-injector` into all the containers in the pod. | | DAPR_API_TOKEN | Dapr sidecar | The token used for Dapr API authentication for requests from the application. [Enable API token authentication in Dapr]({{< ref api-token >}}). | From 377c92ff7185af1ff76da1ec6890932610f3e678 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 11:48:59 -0400 Subject: [PATCH 18/31] interrupted need to save Signed-off-by: Hannah Hunter --- .../content/en/reference/resource-specs/subscription-schema.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/resource-specs/subscription-schema.md b/daprdocs/content/en/reference/resource-specs/subscription-schema.md index 6d79c7c77..906be4a63 100644 --- a/daprdocs/content/en/reference/resource-specs/subscription-schema.md +++ b/daprdocs/content/en/reference/resource-specs/subscription-schema.md @@ -6,7 +6,7 @@ weight: 2000 description: "The basic spec for a Dapr subscription" --- - +The `Subscription` is a Dapr resource that is used to . ```yml apiVersion: apiextensions.k8s.io/v1 From a229194a359d36411e365d4cf487e69ad635dad3 Mon Sep 17 00:00:00 2001 From: Josh van Leeuwen Date: Mon, 19 Jun 2023 17:07:19 +0100 Subject: [PATCH 19/31] Fix JSON in pubsub reference API docs (#3558) Signed-off-by: joshvanl Co-authored-by: Mark Fussell --- 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 68619a753..03068cc3b 100644 --- a/daprdocs/content/en/reference/api/pubsub_api.md +++ b/daprdocs/content/en/reference/api/pubsub_api.md @@ -179,7 +179,7 @@ Example: "topic": "newOrder", "route": "/orders", "metadata": { - "rawPayload": "true", + "rawPayload": "true" } } ] From 26686e627b990d72e1a2c86196867bfbfa1a3298 Mon Sep 17 00:00:00 2001 From: Mark Fussell Date: Mon, 19 Jun 2023 09:14:55 -0700 Subject: [PATCH 20/31] Update daprdocs/content/en/reference/environment/_index.md Signed-off-by: Mark Fussell --- daprdocs/content/en/reference/environment/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/environment/_index.md b/daprdocs/content/en/reference/environment/_index.md index 524de0492..762bb3592 100644 --- a/daprdocs/content/en/reference/environment/_index.md +++ b/daprdocs/content/en/reference/environment/_index.md @@ -25,5 +25,5 @@ The following table lists the environment variables used by the Dapr runtime, CL | OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry Tracing | Sets the Open Telemetry (OTEL) server address, turns on tracing. (Example: `http://localhost:4318`) | | OTEL_EXPORTER_OTLP_INSECURE | OpenTelemetry Tracing | Sets the connection to the endpoint as unencrypted. (`true`, `false`) | | OTEL_EXPORTER_OTLP_PROTOCOL | OpenTelemetry Tracing | The OTLP protocol to use Transport protocol. (`grpc`, `http/protobuf`, `http/json`) | -| DAPR_COMPONENTS_SOCKETS_FOLDER | Dapr runtime and the .NET, Go, and Java pluggable component SDKs | The location or path where Dapr will look for Pluggable Components Unix Domain Socket files. If unset this location defaults to `/tmp/dapr-components-sockets` | +| DAPR_COMPONENTS_SOCKETS_FOLDER | Dapr runtime and the .NET, Go, and Java pluggable component SDKs | The location or path where Dapr looks for Pluggable Components Unix Domain Socket files. If unset this location defaults to `/tmp/dapr-components-sockets` | | DAPR_COMPONENTS_SOCKETS_EXTENSION | .NET and Java pluggable component SDKs | A per-SDK configuration that indicates the default file extension applied to socket files created by the SDKs. Not a Dapr-enforced behavior. | \ No newline at end of file From 9d2ba33fd43def44371f414ea53c2b54c0936d37 Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Mon, 19 Jun 2023 10:28:17 -0700 Subject: [PATCH 21/31] Add skip on missing secrets config Signed-off-by: Aaron Crawfis --- .github/workflows/website-root.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index ed8c3b491..0e160a426 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -61,6 +61,7 @@ jobs: api_location: "daprdocs/public/" output_location: "" skip_app_build: true + skip_deploy_on_missing_secretsL: true - name: Upload Hugo artifacts uses: actions/upload-artifact@v3 with: From a0e76ec1e0c7195cf2f8c2de440bae87751af75a Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Mon, 19 Jun 2023 10:28:49 -0700 Subject: [PATCH 22/31] Remove erroneous character Signed-off-by: Aaron Crawfis --- .github/workflows/website-root.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index 0e160a426..4e22b2c59 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -61,7 +61,7 @@ jobs: api_location: "daprdocs/public/" output_location: "" skip_app_build: true - skip_deploy_on_missing_secretsL: true + skip_deploy_on_missing_secrets: true - name: Upload Hugo artifacts uses: actions/upload-artifact@v3 with: From d1b94e4faa97206a713a6f4180ca72179de6a6a2 Mon Sep 17 00:00:00 2001 From: Aaron Crawfis Date: Mon, 19 Jun 2023 10:59:12 -0700 Subject: [PATCH 23/31] Skip on close without secret Signed-off-by: Aaron Crawfis --- .github/workflows/website-root.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/website-root.yml b/.github/workflows/website-root.yml index 4e22b2c59..1f8e503e4 100644 --- a/.github/workflows/website-root.yml +++ b/.github/workflows/website-root.yml @@ -80,6 +80,7 @@ jobs: with: azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_PROUD_BAY_0E9E0E81E }} action: "close" + skip_deploy_on_missing_secrets: true algolia_index: name: Index site for Algolia From bfa2a66a27b78cde2d60b6b37f542ddd467a1359 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 17:44:34 -0400 Subject: [PATCH 24/31] update examples Signed-off-by: Hannah Hunter --- .../howto-invoke-non-dapr-endpoints.md | 4 +- ...s-reference.md => httpendpoints-schema.md} | 0 .../resource-specs/resiliency-schema.md | 179 ++++--------- .../resource-specs/subscription-schema.md | 245 ++++++------------ 4 files changed, 123 insertions(+), 305 deletions(-) rename daprdocs/content/en/reference/resource-specs/{httpendpoints-reference.md => httpendpoints-schema.md} (100%) diff --git a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-non-dapr-endpoints.md b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-non-dapr-endpoints.md index 8196bd0b1..4d365c733 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-non-dapr-endpoints.md +++ b/daprdocs/content/en/developing-applications/building-blocks/service-invocation/howto-invoke-non-dapr-endpoints.md @@ -47,7 +47,7 @@ The diagram below is an overview of how Dapr's service invocation works when inv ## Using an HTTPEndpoint resource or FQDN URL for non-Dapr endpoints There are two ways to invoke a non-Dapr endpoint when communicating either to Dapr applications or non-Dapr applications. A Dapr application can invoke a non-Dapr endpoint by providing one of the following: -- A named `HTTPEndpoint` resource, including defining an `HTTPEndpoint` resource type. See the [HTTPEndpoint reference]({{< ref httpendpoints-reference.md >}}) guide for an example. +- A named `HTTPEndpoint` resource, including defining an `HTTPEndpoint` resource type. See the [HTTPEndpoint reference]({{< ref httpendpoints-schema.md >}}) guide for an example. ```sh localhost:3500/v1.0/invoke//method/ @@ -81,7 +81,7 @@ curl http://localhost:3602/v1.0/invoke/orderprocessor/method/checkout ## Related Links -- [HTTPEndpoint reference]({{< ref httpendpoints-reference.md >}}) +- [HTTPEndpoint reference]({{< ref httpendpoints-schema.md >}}) - [Service invocation overview]({{< ref service-invocation-overview.md >}}) - [Service invocation API specification]({{< ref service_invocation_api.md >}}) diff --git a/daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md b/daprdocs/content/en/reference/resource-specs/httpendpoints-schema.md similarity index 100% rename from daprdocs/content/en/reference/resource-specs/httpendpoints-reference.md rename to daprdocs/content/en/reference/resource-specs/httpendpoints-schema.md diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index c3ba272c9..8b2def056 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -6,138 +6,55 @@ weight: 3000 description: "The basic spec for a Dapr resiliency resource" --- +The `Resiliency` Dapr resource allows you to define and apply fault tolerance resiliency polcies. Resiliency specs are applied with the Dapr sidecar starts. ```yml -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition +apiVersion: dapr.io/v1alpha1 +kind: Resiliency metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.5.0 - creationTimestamp: null - name: resiliencies.dapr.io - labels: - app.kubernetes.io/part-of: "dapr" + name: +scopes: + - spec: - group: dapr.io - names: - kind: Resiliency - listKind: ResiliencyList - plural: resiliencies - singular: resiliency - categories: - - dapr - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - scopes: - items: - type: string - type: array - spec: - properties: - policies: - properties: - circuitBreakers: - additionalProperties: - properties: - interval: - type: string - maxRequests: - type: integer - timeout: - type: string - trip: - type: string - type: object - type: object - retries: - additionalProperties: - properties: - duration: - type: string - maxInterval: - type: string - maxRetries: - type: integer - policy: - type: string - type: object - type: object - timeouts: - additionalProperties: - type: string - type: object - type: object - targets: - properties: - actors: - additionalProperties: - properties: - circuitBreaker: - type: string - circuitBreakerCacheSize: - type: integer - circuitBreakerScope: - type: string - retry: - type: string - timeout: - type: string - type: object - type: object - apps: - additionalProperties: - properties: - circuitBreaker: - type: string - circuitBreakerCacheSize: - type: integer - retry: - type: string - timeout: - type: string - type: object - type: object - components: - additionalProperties: - properties: - inbound: - properties: - circuitBreaker: - type: string - retry: - type: string - timeout: - type: string - type: object - outbound: - properties: - circuitBreaker: - type: string - retry: - type: string - timeout: - type: string - type: object - type: object - type: object - type: object - required: - - policies - - targets - type: object - type: object - served: true - storage: true -``` \ No newline at end of file + policies: # Required + timeouts: # Replce with any unique name + timeoutName: + retries: + retryName: # Replace with any unique name + policy: exponential + maxInterval: + maxRetries: + circuitBreakers: + circuitBreakerName: # Replace with any unique name + maxRequests: + timeout: + trip: +targets: # Required + apps: + appID: # Replace with scoped app ID + timeout: + retry: + circuitBreaker: + actors: + myActorType: + timeout: + retry: + circuitBreaker: + circuitBreakerCacheSize: + components: + componentName: # Replace with your component name + outbound: + timeout: + retry: + circuitBreaker: +``` + +## Spec fields + +| Field | Required | Details | Example | +|--------------------|:--------:|---------|---------| +| policies | Y | The configuration of resiliency policies, including:
  • `timeouts`
  • `retries`
  • `circuitBreakers`
| timeout: `general`
retry: `retryForever`
circuit breaker: `simpleCB` | +| targets | Y | The configuration for the applications, actors, or components that use the resiliency policies. | | + +## Related links +[Learn more about resiliency policies and targets]({{< ref resiliency >}}) \ No newline at end of file diff --git a/daprdocs/content/en/reference/resource-specs/subscription-schema.md b/daprdocs/content/en/reference/resource-specs/subscription-schema.md index 906be4a63..c18dd43cb 100644 --- a/daprdocs/content/en/reference/resource-specs/subscription-schema.md +++ b/daprdocs/content/en/reference/resource-specs/subscription-schema.md @@ -6,179 +6,80 @@ weight: 2000 description: "The basic spec for a Dapr subscription" --- -The `Subscription` is a Dapr resource that is used to . +The `Subscription` Dapr resource allows you to subscribe declaratively to a topic using an external component YAML file. + +## `v1alpha1` + +The following is the basic version `v1alpha1` spec for a `Subscription` resource. ```yml -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition +apiVersion: dapr.io/v1alpha1 +kind: Subscription metadata: - name: subscriptions.dapr.io - labels: - app.kubernetes.io/part-of: "dapr" + name: spec: - group: dapr.io - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: replaceme # Patched by post-install webhook - name: dapr-webhook - path: /convert - #caBundle: Patched by post-install webhook - conversionReviewVersions: - - v1 - - v2alpha1 - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Subscription describes an pub/sub event subscription. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - scopes: - items: - type: string - type: array - spec: - description: SubscriptionSpec is the spec for an event subscription. - properties: - pubsubname: - type: string - route: - type: string - topic: - type: string - deadLetterTopic: - type: string - bulkSubscribe: - description: Represents bulk subscribe properies - properties: - enabled: - type: boolean - maxMessagesCount: - type: integer - maxAwaitDurationMs: - type: integer - required: - - enabled - type: object - metadata: - additionalProperties: - type: string - type: object - required: - - pubsubname - - route - - topic - type: object - type: object - served: true - storage: false - - name: v2alpha1 - schema: - openAPIV3Schema: - description: Subscription describes an pub/sub event subscription. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - scopes: - items: - type: string - type: array - spec: - description: SubscriptionSpec is the spec for an event subscription. - properties: - metadata: - additionalProperties: - type: string - description: The optional metadata to provide the subscription. - type: object - pubsubname: - description: The PubSub component name. - type: string - routes: - description: The Routes configuration for this topic. - properties: - default: - type: string - rules: - description: The list of rules for this topic. - items: - description: Rule is used to specify the condition for sending - a message to a specific path. - properties: - match: - description: The optional CEL expression used to match the - event. If the match is not specified, then the route is - considered the default. The rules are tested in the order - specified, so they should be define from most-to-least - specific. The default route should appear last in the - list. - type: string - path: - description: The path for events that match this rule. - type: string - required: - - match - - path - type: object - type: array - type: object - topic: - description: The topic name to subscribe to. - type: string - deadLetterTopic: - description: The optional dead letter queue for this topic to send events to. - type: string - bulkSubscribe: - description: Represents bulk subscribe properies - properties: - enabled: - type: boolean - maxMessagesCount: - type: integer - maxAwaitDurationMs: - type: integer - required: - - enabled - type: object - required: - - pubsubname - - routes - - topic - type: object - type: object - served: true - storage: true - names: - kind: Subscription - listKind: SubscriptionList - plural: subscriptions - singular: subscription - categories: - - all - - dapr - scope: Namespaced -``` \ No newline at end of file + version: v1alpha1 + topic: # Required + route: # Required + pubsubname: # Required + deadLetterTopic: # Optional + bulkSubscribe: # Optional + - enabled: + - maxmessages: + - maxawaitduration: +scopes: +- +``` + +### Spec fields + +| Field | Required | Details | Example | +|--------------------|:--------:|---------|---------| +| topic | Y | The name of the topic to which your component subscribes. | `orders` | +| route | Y | The endpoint to which all topic messages are sent. | `/checkout` | +| pubsubname | N | The name of your pub/sub component. | `pubsub` | +| deadlettertopic | N | The name of the dead letter topic that forwards undeliverable messages. | `poisonMessages` | +| bulksubscribe | N | Enable bulk subscribe properties. | `true`, `false` | + +## `v2alpha1` + +The following the basic `v2alpha1` spec for a `Subscription` resource. + +```yml +apiVersion: dapr.io/v2alpha1 +kind: Subscription +metadata: + name: +spec: + version: v2alpha1 + topic: # Required + routes: # Required + - rules: + - match: + path: + pubsubname: # Required + deadlettertopic: # Optional + bulksubscribe: # Optional + - enabled: + - maxmessages: + - maxawaitduration: +scopes: +- +``` + +### Spec fields + +| Field | Required | Details | Example | +|--------------------|:--------:|---------|---------| +| topic | Y | The name of the topic to which your component subscribes. | `orders` | +| routes | Y | The routes configuration for this topic, including specifying the condition for sending a message to a specific path. Includes the following fields:
  • match: _Optional._ The CEL expression used to match the event. If not specified, the route is considered the default.
  • path: The path for events that match this rule.
The endpoint to which all topic messages are sent. | `match: event.type == "widget"`
`path: /widgets` | +| pubsubname | N | The name of your pub/sub component. | `pubsub` | +| deadlettertopic | N | The name of the dead letter topic that forwards undeliverable messages. | `poisonMessages` | +| bulksubscribe | N | Enable bulk subscribe properties. | `true`, `false` | + + +## Related links +- [Learn more about the declarative subscription method]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) +- [Learn more about dead letter topics]({{< ref pubsub-deadletter.md >}}) +- [Learn more about routing messages]({{< ref "howto-route-messages.md#declarative-subscription" >}}) +- [Learn more about bulk subscribing]({{< ref pubsub-bulk.md >}}) \ No newline at end of file From f3a5d4e4bdd7f5c15842720c953b29726bfd9630 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Mon, 19 Jun 2023 17:48:53 -0400 Subject: [PATCH 25/31] fix Signed-off-by: Hannah Hunter --- .../content/en/reference/resource-specs/resiliency-schema.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index 8b2def056..546a1c5d6 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -57,4 +57,4 @@ targets: # Required | targets | Y | The configuration for the applications, actors, or components that use the resiliency policies. | | ## Related links -[Learn more about resiliency policies and targets]({{< ref resiliency >}}) \ No newline at end of file +[Learn more about resiliency policies and targets]({{< ref resiliency-overview.md >}}) \ No newline at end of file From 55a9c26ab61239e081a2eb9dcc50e489a05884cc Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Tue, 20 Jun 2023 11:14:43 -0400 Subject: [PATCH 26/31] updates from mark pt 1 Signed-off-by: Hannah Hunter --- .../pubsub/pubsub-deadletter.md | 12 ++-- .../building-blocks/pubsub/pubsub-raw.md | 5 +- .../pubsub/subscription-methods.md | 5 +- .../resource-specs/resiliency-schema.md | 13 ++-- .../resource-specs/subscription-schema.md | 71 ++++++++++--------- daprdocs/package-lock.json | 6 +- 6 files changed, 62 insertions(+), 50 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-deadletter.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-deadletter.md index 1f46bf62b..97c9a0db4 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-deadletter.md +++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-deadletter.md @@ -25,13 +25,14 @@ The diagram below is an example of how dead letter topics work. First a message The following YAML shows how to configure a subscription with a dead letter topic named `poisonMessages` for messages consumed from the `orders` topic. This subscription is scoped to an app with a `checkout` ID. ```yaml -apiVersion: dapr.io/v1alpha1 +apiVersion: dapr.io/v2alpha1 kind: Subscription metadata: name: order spec: topic: orders - route: /checkout + routes: + default: /checkout pubsubname: pubsub deadLetterTopic: poisonMessages scopes: @@ -86,13 +87,16 @@ spec: Remember to now configure a subscription to handling the dead letter topics. For example you can create another declarative subscription to receive these on the same or a different application. The example below shows the checkout application subscribing to the `poisonMessages` topic with another subscription and sending these to be handled by the `/failedmessages` endpoint. ```yaml -apiVersion: dapr.io/v1alpha1 +apiVersion: dapr.io/v2alpha1 kind: Subscription metadata: name: deadlettertopics spec: topic: poisonMessages - route: /failedMessages + routes: + rules: + - match: + path: /failedMessages pubsubname: pubsub scopes: - checkout diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-raw.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-raw.md index d5a0fbe61..6e518fa96 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-raw.md +++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-raw.md @@ -141,13 +141,14 @@ $app->start(); Similarly, you can subscribe to raw events declaratively by adding the `rawPayload` metadata entry to your subscription specification. ```yaml -apiVersion: dapr.io/v1alpha1 +apiVersion: dapr.io/v2alpha1 kind: Subscription metadata: name: myevent-subscription spec: topic: deathStarStatus - route: /dsstatus + routes: + default: /dsstatus pubsubname: pubsub metadata: rawPayload: "true" diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/subscription-methods.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/subscription-methods.md index 965647b92..52747ce9f 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/subscription-methods.md +++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/subscription-methods.md @@ -22,13 +22,14 @@ The examples below demonstrate pub/sub messaging between a `checkout` app and an You can subscribe declaratively to a topic using an external component file. This example uses a YAML component file named `subscription.yaml`: ```yaml -apiVersion: dapr.io/v1alpha1 +apiVersion: dapr.io/v2alpha1 kind: Subscription metadata: name: order spec: topic: orders - route: /checkout + routes: + default: /checkout pubsubname: pubsub scopes: - orderprocessing diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index 546a1c5d6..a17a9fccb 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -6,22 +6,24 @@ weight: 3000 description: "The basic spec for a Dapr resiliency resource" --- -The `Resiliency` Dapr resource allows you to define and apply fault tolerance resiliency polcies. Resiliency specs are applied with the Dapr sidecar starts. +The `Resiliency` Dapr resource allows you to define and apply fault tolerance resiliency policies. Resiliency specs are applied when the Dapr sidecar starts. ```yml apiVersion: dapr.io/v1alpha1 kind: Resiliency metadata: name: +version: v1alpha1 scopes: - spec: policies: # Required - timeouts: # Replce with any unique name + timeouts: # Replace with any unique name timeoutName: retries: retryName: # Replace with any unique name - policy: exponential + policy: + duration: maxInterval: maxRetries: circuitBreakers: @@ -53,8 +55,9 @@ targets: # Required | Field | Required | Details | Example | |--------------------|:--------:|---------|---------| -| policies | Y | The configuration of resiliency policies, including:
  • `timeouts`
  • `retries`
  • `circuitBreakers`
| timeout: `general`
retry: `retryForever`
circuit breaker: `simpleCB` | -| targets | Y | The configuration for the applications, actors, or components that use the resiliency policies. | | +| policies | Y | The configuration of resiliency policies, including:
  • `timeouts`
  • `retries`
  • `circuitBreakers`

[See more examples with all of the built-in policies]({{< ref policies.md >}}) | timeout: `general`
retry: `retryForever`
circuit breaker: `simpleCB` | +| targets | Y | The configuration for the applications, actors, or components that use the resiliency policies.
[See more examples in the resiliency targets guide]({{< ref targets.md >}}) | `apps`
`components`
`actors` | + ## Related links [Learn more about resiliency policies and targets]({{< ref resiliency-overview.md >}}) \ No newline at end of file diff --git a/daprdocs/content/en/reference/resource-specs/subscription-schema.md b/daprdocs/content/en/reference/resource-specs/subscription-schema.md index c18dd43cb..a14aca415 100644 --- a/daprdocs/content/en/reference/resource-specs/subscription-schema.md +++ b/daprdocs/content/en/reference/resource-specs/subscription-schema.md @@ -6,44 +6,14 @@ weight: 2000 description: "The basic spec for a Dapr subscription" --- -The `Subscription` Dapr resource allows you to subscribe declaratively to a topic using an external component YAML file. +The `Subscription` Dapr resource allows you to subscribe declaratively to a topic using an external component YAML file. This guide demonstrates two subscription API versions: -## `v1alpha1` - -The following is the basic version `v1alpha1` spec for a `Subscription` resource. - -```yml -apiVersion: dapr.io/v1alpha1 -kind: Subscription -metadata: - name: -spec: - version: v1alpha1 - topic: # Required - route: # Required - pubsubname: # Required - deadLetterTopic: # Optional - bulkSubscribe: # Optional - - enabled: - - maxmessages: - - maxawaitduration: -scopes: -- -``` - -### Spec fields - -| Field | Required | Details | Example | -|--------------------|:--------:|---------|---------| -| topic | Y | The name of the topic to which your component subscribes. | `orders` | -| route | Y | The endpoint to which all topic messages are sent. | `/checkout` | -| pubsubname | N | The name of your pub/sub component. | `pubsub` | -| deadlettertopic | N | The name of the dead letter topic that forwards undeliverable messages. | `poisonMessages` | -| bulksubscribe | N | Enable bulk subscribe properties. | `true`, `false` | +- `v2alpha` (default spec) +- `v1alpha1` (deprecated) ## `v2alpha1` -The following the basic `v2alpha1` spec for a `Subscription` resource. +The following is the basic `v2alpha1` spec for a `Subscription` resource. `v2alpha1` is the default spec for the subscription API. ```yml apiVersion: dapr.io/v2alpha1 @@ -78,6 +48,39 @@ scopes: | bulksubscribe | N | Enable bulk subscribe properties. | `true`, `false` | +## `v1alpha1` + +The following is the basic version `v1alpha1` spec for a `Subscription` resource. `v1alpha1` is now deprecated. + +```yml +apiVersion: dapr.io/v1alpha1 +kind: Subscription +metadata: + name: +spec: + version: v1alpha1 + topic: # Required + route: # Required + pubsubname: # Required + deadLetterTopic: # Optional + bulkSubscribe: # Optional + - enabled: + - maxmessages: + - maxawaitduration: +scopes: +- +``` + +### Spec fields + +| Field | Required | Details | Example | +|--------------------|:--------:|---------|---------| +| topic | Y | The name of the topic to which your component subscribes. | `orders` | +| route | Y | The endpoint to which all topic messages are sent. | `/checkout` | +| pubsubname | N | The name of your pub/sub component. | `pubsub` | +| deadlettertopic | N | The name of the dead letter topic that forwards undeliverable messages. | `poisonMessages` | +| bulksubscribe | N | Enable bulk subscribe properties. | `true`, `false` | + ## Related links - [Learn more about the declarative subscription method]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) - [Learn more about dead letter topics]({{< ref pubsub-deadletter.md >}}) diff --git a/daprdocs/package-lock.json b/daprdocs/package-lock.json index adc813bba..1a80bae53 100644 --- a/daprdocs/package-lock.json +++ b/daprdocs/package-lock.json @@ -90,9 +90,9 @@ "dev": true }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" From 9f60dacf0f71e50f81e626b22df41e573008c380 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Tue, 20 Jun 2023 13:35:50 -0400 Subject: [PATCH 27/31] make workflow quickstart intro more general Signed-off-by: Hannah Hunter --- .../quickstarts/workflow-quickstart.md | 24 +++++++++++++----- .../images/workflow-quickstart-overview.png | Bin 56951 -> 32186 bytes 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/daprdocs/content/en/getting-started/quickstarts/workflow-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/workflow-quickstart.md index 0e428007d..d139561cb 100644 --- a/daprdocs/content/en/getting-started/quickstarts/workflow-quickstart.md +++ b/daprdocs/content/en/getting-started/quickstarts/workflow-quickstart.md @@ -12,12 +12,6 @@ The workflow building block is currently in **alpha**. Let's take a look at the Dapr [Workflow building block]({{< ref workflow >}}). In this Quickstart, you'll create a simple console application to demonstrate Dapr's workflow programming model and the workflow management APIs. -The `order-processor` console app starts and manages the lifecycle of the `OrderProcessingWorkflow` workflow that stores and retrieves data in a state store. The workflow consists of four workflow activities, or tasks: -- `NotifyActivity`: Utilizes a logger to print out messages throughout the workflow -- `ReserveInventoryActivity`: Checks the state store to ensure that there is enough inventory for the purchase -- `ProcessPaymentActivity`: Processes and authorizes the payment -- `UpdateInventoryActivity`: Removes the requested items from the state store and updates the store with the new remaining inventory value - In this guide, you'll: - Run the `order-processor` application. @@ -26,13 +20,19 @@ In this guide, you'll: -Currently, you can experience the Dapr Workflow using the .NET SDK. {{< tabs ".NET" "Python" >}} {{% codetab %}} +The `order-processor` console app starts and manages the lifecycle of an order processing workflow that stores and retrieves data in a state store. The workflow consists of four workflow activities, or tasks: +- `NotifyActivity`: Utilizes a logger to print out messages throughout the workflow +- `ReserveInventoryActivity`: Checks the state store to ensure that there is enough inventory for the purchase +- `ProcessPaymentActivity`: Processes and authorizes the payment +- `UpdateInventoryActivity`: Removes the requested items from the state store and updates the store with the new remaining inventory value + + ### Step 1: Pre-requisites For this example, you will need: @@ -259,6 +259,16 @@ The `Activities` directory holds the four workflow activities used by the workfl {{% codetab %}} +The `order-processor` console app starts and manages the `order_processing_workflow`, which simulates purchasing items from a store. The workflow consists of five unique workflow activities, or tasks: + +- `notify_activity`: Utilizes a logger to print out messages throughout the workflow. These messages notify you when: + - You have insufficient inventory + - Your payment couldn't be processed, etc. +- `process_payment_activity`: Processes and authorizes the payment. +- `verify_inventory_activity`: Checks the state store to ensure there is enough inventory present for purchase. +- `update_inventory_activity`: Removes the requested items from the state store and updates the store with the new remaining inventory value. +- `request_approval_activity`: Seeks approval from the manager if payment is greater than 50,000 USD. + ### Step 1: Pre-requisites For this example, you will need: diff --git a/daprdocs/static/images/workflow-quickstart-overview.png b/daprdocs/static/images/workflow-quickstart-overview.png index c526a0486add6ee779647746f8528545f2de227a..d616f210622a0c051777f4e0b55e9e7715d0c086 100644 GIT binary patch literal 32186 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 H83q0?^N`v6 literal 56951 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%0AY~|K-Xsa=$Ge1tWCv?f94o$s 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

wfLRl`>OAWC-Q3m(160!LCTbv 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 O4OuBg$>Nu9eg797R&x0O From 81b243389d566513562894d1b492cb995433684e Mon Sep 17 00:00:00 2001 From: Fabian Steinbach <63794579+fabistb@users.noreply.github.com> Date: Wed, 21 Jun 2023 05:01:05 +0000 Subject: [PATCH 28/31] update otel collector appinsights version (#3571) Signed-off-by: fabistb --- .../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 81979ba9b..4a1e7aae3 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:0.50.0 + image: otel/opentelemetry-collector-contrib:0.77.0 command: - "/otelcol-contrib" - "--config=/conf/otel-collector-config.yaml" From 323d3a2ef779ec3ccf46a09d7256b2909ac29271 Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 21 Jun 2023 09:41:58 -0400 Subject: [PATCH 29/31] remove file from PR Signed-off-by: Hannah Hunter --- daprdocs/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daprdocs/package-lock.json b/daprdocs/package-lock.json index 1a80bae53..adc813bba 100644 --- a/daprdocs/package-lock.json +++ b/daprdocs/package-lock.json @@ -90,9 +90,9 @@ "dev": true }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true, "engines": { "node": ">=8" From 0ad633bf665a4f8e11cdf20f101541bc28287dae Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Wed, 21 Jun 2023 09:43:30 -0400 Subject: [PATCH 30/31] update toc Signed-off-by: Hannah Hunter --- .../content/en/reference/resource-specs/resiliency-schema.md | 2 +- .../content/en/reference/resource-specs/subscription-schema.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md index a17a9fccb..58d60cb20 100644 --- a/daprdocs/content/en/reference/resource-specs/resiliency-schema.md +++ b/daprdocs/content/en/reference/resource-specs/resiliency-schema.md @@ -1,7 +1,7 @@ --- type: docs title: "Resiliency spec" -linkTitle: "Resiliency spec" +linkTitle: "Resiliency" weight: 3000 description: "The basic spec for a Dapr resiliency resource" --- diff --git a/daprdocs/content/en/reference/resource-specs/subscription-schema.md b/daprdocs/content/en/reference/resource-specs/subscription-schema.md index a14aca415..b3a4e638a 100644 --- a/daprdocs/content/en/reference/resource-specs/subscription-schema.md +++ b/daprdocs/content/en/reference/resource-specs/subscription-schema.md @@ -1,7 +1,7 @@ --- type: docs title: "Subscription spec" -linkTitle: "Subscription spec" +linkTitle: "Subscription" weight: 2000 description: "The basic spec for a Dapr subscription" --- From d1c5df533d3c785cb74dcda5683fed644aecaf41 Mon Sep 17 00:00:00 2001 From: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Date: Wed, 21 Jun 2023 19:13:34 -0400 Subject: [PATCH 31/31] [state store ttl] Add context to persisting state (#3546) * add context from bernd to ttl Signed-off-by: Hannah Hunter * fix typo Signed-off-by: Hannah Hunter * clean up wording Signed-off-by: Hannah Hunter * update/clarify per bernd Signed-off-by: Hannah Hunter * Update daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> * Update daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> * Update daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> * Update daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md Co-authored-by: Mark Fussell Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> --------- Signed-off-by: Hannah Hunter Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com> Co-authored-by: Mark Fussell --- .../state-management/state-store-ttl.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md b/daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md index 4717a1889..2f7ecbf26 100644 --- a/daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md +++ b/daprdocs/content/en/developing-applications/building-blocks/state-management/state-store-ttl.md @@ -16,9 +16,15 @@ When state TTL has native support in the state store component, Dapr forwards th When a TTL is not specified, the default behavior of the state store is retained. -## Persisting state (ignoring an existing TTL) +## Explicit persistence bypassing globally defined TTL -To explicitly persist a state (ignoring any TTLs set for the key), specify a `ttlInSeconds` value of `-1`. +Persisting state applies to all state stores that let you specify a default TTL used for all data, either: +- Setting a global TTL value via a Dapr component, or +- When creating the state store outside of Dapr and setting a global TTL value. + +When no specific TTL is specified, the data expires after that global TTL period of time. This is not facilitated by Dapr. + +In addition, all state stores also support the option to _explicitly_ persist data. This means you can ignore the default database policy (which may have been set outside of Dapr or via a Dapr Component) to indefinitely retain a given database record. You can do this by setting `ttlInSeconds` to the value of `-1`. This value indicates to ignore any TTL value set. ## Supported components