Merge pull request #2625 from greenie-msft/upmerge_of_1.7_into_1.8_20220706

Upmerge of 1.7 into 1.8 20220706
This commit is contained in:
greenie-msft 2022-07-06 20:55:45 -07:00 committed by GitHub
commit eeb968c721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1754 additions and 414 deletions

View File

@ -6,49 +6,72 @@ weight: 100
description: Overview of the bindings API building block
---
## Introduction
Using Dapr's bindings API, you can trigger your app with events coming in from external systems and interface with external systems. With the bindings API, you can:
Using bindings, you can trigger your app with events coming in from external systems, or interface with external systems. This building block provides several benefits for you and your code:
- Avoid the complexities of connecting to and polling from messaging systems, such as queues and message buses.
- Focus on business logic, instead of the implementation details of interacting with a system.
- Keep your code free from SDKs or libraries.
- Handle retries and failure recovery.
- Switch between bindings at runtime.
- Build portable applications with environment-specific bindings set-up and no required code changes.
- Remove the complexities of connecting to, and polling from, messaging systems such as queues and message buses
- Focus on business logic and not implementation details of how to interact with a system
- Keep your code free from SDKs or libraries
- Handle retries and failure recovery
- Switch between bindings at run time
- Build portable applications where environment-specific bindings are set-up and no code changes are required
For example, with bindings, your microservice can respond to incoming Twilio/SMS messages without:
For a specific example, bindings would allow your microservice to respond to incoming Twilio/SMS messages without adding or configuring a third-party Twilio SDK, worrying about polling from Twilio (or using websockets, etc.).
- Adding or configuring a third-party Twilio SDK
- Worrying about polling from Twilio (or using WebSockets, etc.)
Bindings are developed independently of Dapr runtime. You can view and contribute to the bindings [here](https://github.com/dapr/components-contrib/tree/master/bindings).
{{% alert title="Note" color="primary" %}}
Bindings are developed independently of Dapr runtime. You can [view and contribute to the bindings](https://github.com/dapr/components-contrib/tree/master/bindings).
{{% /alert %}}
## Input bindings
Input bindings are used to trigger your application when an event from an external resource has occurred.
An optional payload and metadata may be sent with the request.
With input bindings, you can trigger your application when an event from an external resource occurs. An optional payload and metadata may be sent with the request.
In order to receive events from an input binding:
To receive events from an input binding:
1. Define the component YAML that describes the type of binding and its metadata (connection info, etc.)
2. Listen on an HTTP endpoint for the incoming event, or use the gRPC proto library to get incoming events
1. Define the component YAML that describes the binding type and its metadata (connection info, etc.).
1. Listen for the incoming event using:
- An HTTP endpoint
- The gRPC proto library to get incoming events.
> On startup Dapr sends a `OPTIONS` request for all defined input bindings to the application and expects a status code other than `NOT FOUND (404)` if this application wants to subscribe to the binding.
{{% alert title="Note" color="primary" %}}
On startup, Dapr sends [an OPTIONS request]({{< ref "bindings_api.md#invoking-service-code-through-input-bindings" >}}) for all defined input bindings to the application. If the application wants to subscribe to the binding, Dapr expects a status code of 2xx or 405.
Read the [Create an event-driven app using input bindings]({{< ref howto-triggers.md >}}) page to get started with input bindings.
{{% /alert %}}
Read the [Create an event-driven app using input bindings guide]({{< ref howto-triggers.md >}}) to get started with input bindings.
## Output bindings
Output bindings allow you to invoke external resources. An optional payload and metadata can be sent with the invocation request.
With output bindings, you can invoke external resources. An optional payload and metadata can be sent with the invocation request.
In order to invoke an output binding:
To invoke an output binding:
1. Define the component YAML that describes the type of binding and its metadata (connection info, etc.)
2. Use the HTTP endpoint or gRPC method to invoke the binding with an optional payload
1. Define the component YAML that describes the binding type and its metadata (connection info, etc.).
2. Use the HTTP endpoint or gRPC method to invoke the binding with an optional payload.
Read the [Use output bindings to interface with external resources]({{< ref howto-bindings.md >}}) page to get started with output bindings.
Read the [Use output bindings to interface with external resources guide]({{< ref howto-bindings.md >}}) to get started with output bindings.
## Try out bindings
### Quickstarts and tutorials
Want to put the Dapr bindings API to the test? Walk through the following quickstart and tutorials to see bindings in action:
| Quickstart/tutorial | Description |
| ------------------- | ----------- |
| [Bindings quickstart]({{< ref bindings-quickstart.md >}}) | Work with external systems using input bindings to respond to events and output bindings to call operations. |
| [Bindings tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings) | Demonstrates how to use Dapr to create input and output bindings to other components. Uses bindings to Kafka. |
### Start using bindings directly in your app
Want to skip the quickstarts? Not a problem. You can try out the bindings building block directly in your application to invoke output bindings and trigger input bindings. After [Dapr is installed]({{< ref "getting-started/_index.md" >}}), you can begin using the bindings API starting with [the input bindings how-to guide]({{< ref howto-triggers.md >}}).
## Next Steps
* Follow these guides on:
* [How-To: Trigger a service from different resources with input bindings]({{< ref howto-triggers.md >}})
* [How-To: Use output bindings to interface with external resources]({{< ref howto-bindings.md >}})
* Try out the [bindings quickstart](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings/README.md) which shows how to bind to a Kafka queue
* Read the [bindings API specification]({{< ref bindings_api.md >}})
- Follow these guides on:
- [How-To: Trigger a service from different resources with input bindings]({{< ref howto-triggers.md >}})
- [How-To: Use output bindings to interface with external resources]({{< ref howto-bindings.md >}})
- Try out the [bindings tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings/README.md) to experiment with binding to a Kafka queue.
- Read the [bindings API specification]({{< ref bindings_api.md >}})

View File

@ -6,23 +6,31 @@ description: "Invoke external systems with output bindings"
weight: 300
---
With output bindings, you can invoke external resources without depending on special SDK or libraries. An output binding represents a resource that Dapr uses to invoke and send messages to. For a complete sample showing output bindings, [walk through the tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings).
With output bindings, you can invoke external resources. An optional payload and metadata can be sent with the invocation request.
<img src="/images/building-block-output-binding-example.png" width=1000 alt="Diagram showing bindings of example service">
<img src="/images/howto-bindings/kafka-output-binding.png" width=1000 alt="Diagram showing bindings of example service">
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}).
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}). In this guide:
1. The example invokes the `/binding` endpoint with `checkout`, the name of the binding to invoke.
1. The payload goes inside the mandatory `data` field, and can be any JSON serializable value.
1. The `operation` field tells the binding what action it needs to take. For example, [the Kafka binding supports the `create` operation]({{< ref "kafka.md#binding-support" >}}).
- You can check [which operations (specific to each component) are supported for every output binding]({{< ref supported-bindings >}}).
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out the bindings quickstart]({{< ref bindings-quickstart.md >}}) for a quick walk-through on how to use the bindings API.
{{% /alert %}}
## Create a binding
Create a new binding component with the name of `checkout`.
Create a `binding.yaml` file and save to a `components` sub-folder in your application directory.
Within the `metadata` section, configure Kafka-related properties, such as:
Create a new binding component named `checkout`. Within the `metadata` section, configure the following Kafka-related properties:
- The topic to which you'll publish the message
- The broker
Create the following `binding.yaml` file and save to a `components` sub-folder in your application directory.
{{< tabs "Self-Hosted (CLI)" Kubernetes >}}
{{% codetab %}}
@ -89,7 +97,7 @@ spec:
## Send an event (output binding)
Below are code examples that leverage Dapr SDKs to interact with an output binding.
The code examples below leverage Dapr SDKs to invoke the output bindings endpoint on a running Dapr instance.
{{< tabs Dotnet Java Python Go JavaScript>}}
@ -277,22 +285,12 @@ function sleep(ms) {
{{< /tabs >}}
Invoke the output bindings endpoint on a running Dapr instance.
You can also invoke the output bindings endpoint using HTTP:
```bash
curl -X POST -H 'Content-Type: application/json' http://localhost:3601/v1.0/bindings/checkout -d '{ "data": 100, "operation": "create" }'
```
As seen above:
1. The example invoked the `/binding` endpoint with `checkout`, the name of the binding to invoke.
1. The payload goes inside the mandatory `data` field, and can be any JSON serializable value.
1. The `operation` field tells the binding what action it needs to take. For example, [the Kafka binding supports the `create` operation]({{< ref "kafka.md#binding-support" >}}).
You can check [which operations (specific to each component) are supported for every output binding]({{< ref supported-bindings >}}).
Watch this [video](https://www.youtube.com/watch?v=ysklxm81MTs&feature=youtu.be&t=1960) on how to use bi-directional output bindings.
<div class="embed-responsive embed-responsive-16by9">

View File

@ -6,29 +6,36 @@ description: "Use Dapr input bindings to trigger event driven applications"
weight: 200
---
Using bindings, your code can be triggered with incoming events from different resources which can be anything: a queue, messaging pipeline, cloud-service, filesystem etc.
With input bindings, you can trigger your application when an event from an external resource occurs. An external resource could be a queue, messaging pipeline, cloud-service, filesystem, etc. An optional payload and metadata may be sent with the request.
This is ideal for event-driven processing, data pipelines, or generally reacting to events and performing further processing.
Input bindings are ideal for event-driven processing, data pipelines, or generally reacting to events and performing further processing. Dapr input bindings allow you to:
Dapr bindings allow you to:
- Receive events without including specific SDKs or libraries
- Replace bindings without changing your code
- Focus on business logic and not the event resource implementation
* Receive events without including specific SDKs or libraries
* Replace bindings without changing your code
* Focus on business logic and not the event resource implementation
<img src="/images/howto-triggers/kafka-input-binding.png" width=1000 alt="Diagram showing bindings of example service">
An input binding represents a resource that Dapr uses to read events from and push to your application. Read the [bindings overview for more information]({{<ref bindings-overview.md>}}).
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}). In this guide:
<img src="/images/building-block-input-binding-example.png" width=1000 alt="Diagram showing bindings of example service">
1. The example invokes the `/binding` endpoint with `checkout`, the name of the binding to invoke.
1. The payload goes inside the mandatory `data` field, and can be any JSON serializable value.
1. The `operation` field tells the binding what action it needs to take. For example, [the Kafka binding supports the `create` operation]({{< ref "kafka.md#binding-support" >}}).
- You can check [which operations (specific to each component) are supported for every output binding]({{< ref supported-bindings >}}).
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}).
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out the bindings quickstart]({{< ref bindings-quickstart.md >}}) for a quick walk-through on how to use the bindings API.
{{% /alert %}}
## Create a binding
Create a new binding component with the name of `checkout`.
Create a `binding.yaml` file and save to a `components` sub-folder in your application directory.
Inside the `metadata` section, configure Kafka-related properties, such as the topic to publish the message to and the broker.
Create a new binding component named `checkout`. Within the `metadata` section, configure the following Kafka-related properties:
Create the following `binding.yaml` file and save it to a `components` sub-folder in your application directory.
- The topic to which you'll publish the message
- The broker
{{< tabs "Self-Hosted (CLI)" Kubernetes >}}
@ -96,7 +103,9 @@ spec:
## Listen for incoming events (input binding)
Configure your application to receive incoming events. If using HTTP, you need to listen on a `POST` endpoint with the name of the binding, as specified in `metadata.name` in the `binding.yaml` file.
Configure your application to receive incoming events. If you're using HTTP, you need to:
- Listen on a `POST` endpoint with the name of the binding, as specified in `metadata.name` in the `binding.yaml` file.
- Verify your application allows Dapr to make an `OPTIONS` request for this endpoint.
Below are code examples that leverage Dapr SDKs to demonstrate an output binding.
@ -249,8 +258,7 @@ Tell Dapr the event was not processed correctly in your application and schedule
### Specifying a custom route
By default, incoming events will be sent to an HTTP endpoint that corresponds to the name of the input binding.
You can override this by setting the following metadata property in `binding.yaml`:
By default, incoming events will be sent to an HTTP endpoint that corresponds to the name of the input binding. You can override this by setting the following metadata property in `binding.yaml`:
```yaml
name: mybinding
@ -267,7 +275,7 @@ Event delivery guarantees are controlled by the binding implementation. Dependin
## References
* [Bindings building block]({{< ref bindings >}})
* [Bindings API]({{< ref bindings_api.md >}})
* [Components concept]({{< ref components-concept.md >}})
* [Supported bindings]({{< ref supported-bindings >}})
- [Bindings building block]({{< ref bindings >}})
- [Bindings API]({{< ref bindings_api.md >}})
- [Components concept]({{< ref components-concept.md >}})
- [Supported bindings]({{< ref supported-bindings >}})

View File

@ -276,7 +276,40 @@ message SubscribeConfigurationRequest {
}
```
Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language. [See the gRPC examples](https://grpc.io/docs/languages/) for usage.
Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language - see the [gRPC examples here](https://grpc.io/docs/languages/) for usage.
Below are the examples in sdks:
{{< tabs Python>}}
{{% codetab %}}
```python
#dependencies
import asyncio
from dapr.clients import DaprClient
#code
async def executeConfiguration():
with DaprClient() as d:
CONFIG_STORE_NAME = 'configstore'
key = 'orderId'
# Subscribe to configuration by key.
configuration = await d.subscribe_configuration(store_name=CONFIG_STORE_NAME, keys=[key], config_metadata={})
if configuration != None:
items = configuration.get_items()
for item in items:
print(f"Subscribe key={item.key} value={item.value} version={item.version}", flush=True)
else:
print("Nothing yet")
asyncio.run(executeConfiguration())
```
```bash
dapr run --app-id orderprocessing --components-path components/ -- python3 OrderProcessingService.py
```
{{% /codetab %}}
{{< /tabs >}}
#### Stop watching configuration items

View File

@ -191,15 +191,25 @@ The programmatic approach returns the `routes` JSON structure within the code, u
{{% codetab %}}
```csharp
[Topic("pubsub", "checkout", event.type ==\"order\"")]
[HttpPost("orders")]
public async Task<ActionResult<Stock>> HandleCheckout(Checkout checkout, [FromServices] DaprClient daprClient)
[Topic("pubsub", "orders")]
[HttpPost("/checkout")]
public async Task<ActionResult<Order>>Checkout(Order order, [FromServices] DaprClient daprClient)
{
// Logic
return stock;
return order;
}
```
or
```csharp
// Dapr subscription in [Topic] routes orders topic to this route
app.MapPost("/checkout", [Topic("pubsub", "orders")] (Order order) => {
Console.WriteLine("Subscriber received : " + order);
return Results.Ok(order);
});
```
{{% /codetab %}}
{{% codetab %}}

View File

@ -10,6 +10,11 @@ This guide demonstrates how to use Dapr's secrets API in your code to leverage t
<img src="/images/building-block-secrets-management-example.png" width=1000 alt="Diagram showing secrets management of example service">
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out the secrets management quickstart]({{< ref secrets-quickstart.md >}}) for a quick walk-through on how to use the secrets API.
{{% /alert %}}
## Set up a secret store
Before retrieving secrets in your application's code, you must configure a secret store component. This example configures a local secret store which uses a local JSON file to store secrets.

View File

@ -10,7 +10,10 @@ This article demonstrates how to deploy services each with an unique application
<img src="/images/building-block-service-invocation-example.png" width=1000 height=500 alt="Diagram showing service invocation of example service">
For a complete sample demonstrating service invocation, [walk through the service invocation quickstart](https://github.com/dapr/quickstarts/tree/master/service_invocation).
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out the service invocation quickstart]({{< ref serviceinvocation-quickstart.md >}}) for a quick walk-through on how to use the service invocation API.
{{% /alert %}}
## Choose an ID for your service

View File

@ -7,18 +7,15 @@ description: "Automatically encrypt state and manage key rotations"
---
## Introduction
Encrypt application state at rest to provide stronger security in enterprise workloads or regulated environments. Dapr offers automatic client-side encryption based on [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) in [Galois/Counter Mode (GCM)](https://en.wikipedia.org/wiki/Galois/Counter_Mode), supporting keys of 128, 192, and 256-bits.
Application state often needs to get encrypted at rest to provide stronger security in enterprise workloads or regulated environments. Dapr offers automatic client side encryption based on [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) in [Galois/Counter Mode (GCM)](https://en.wikipedia.org/wiki/Galois/Counter_Mode), supporting keys of 128, 192, and 256-bits.
In addition to automatic encryption, Dapr supports primary and secondary encryption keys to make it easier for developers and ops teams to enable a key rotation strategy.
This feature is supported by all Dapr state stores.
In addition to automatic encryption, Dapr supports primary and secondary encryption keys to make it easier for developers and ops teams to enable a key rotation strategy. This feature is supported by all Dapr state stores.
The encryption keys are always fetched from a secret, and cannot be supplied as plaintext values on the `metadata` section.
## Enabling automatic encryption
1. Add the following `metadata` section to any Dapr supported state store:
Add the following `metadata` section to any Dapr supported state store:
```yaml
metadata:
@ -28,7 +25,7 @@ metadata:
key: mykey # key is optional.
```
For example, this is the full YAML of a Redis encrypted state store
For example, this is the full YAML of a Redis encrypted state store:
```yaml
apiVersion: dapr.io/v1alpha1
@ -49,18 +46,18 @@ spec:
key: mykey
```
You now have a Dapr state store that's configured to fetch the encryption key from a secret named `mysecret`, containing the actual encryption key in a key named `mykey`.
You now have a Dapr state store configured to fetch the encryption key from a secret named `mysecret`, containing the actual encryption key in a key named `mykey`.
The actual encryption key *must* be a valid, hex-encoded encryption key. We recommend using 128-bit encryption keys; 192-bit and 256-bit keys are supported too. Dapr errors and exists if the encryption key is invalid.
The actual encryption key *must* be a valid, hex-encoded encryption key. While 192-bit and 256-bit keys are supported, it's recommended you use 128-bit encryption keys. Dapr errors and exists if the encryption key is invalid.
> As an example, you can generate a random, hex-encoded 128-bit (16-byte) key with:
>
> ```sh
> openssl rand 16 | hexdump -v -e '/1 "%02x"'
> # Result will be similar to "cb321007ad11a9d23f963bff600d58e0"
> ```
For example, you can generate a random, hex-encoded 128-bit (16-byte) key with:
*Note that the secret store does not have to support keys*
```sh
openssl rand 16 | hexdump -v -e '/1 "%02x"'
# Result will be similar to "cb321007ad11a9d23f963bff600d58e0"
```
*Note that the secret store does not have to support keys.*
## Key rotation
@ -78,11 +75,24 @@ metadata:
key: mykey2
```
When Dapr starts, it will fetch the secrets containing the encryption keys listed in the `metadata` section. Dapr knows which state item has been encrypted with which key automatically, as it appends the `secretKeyRef.name` field to the end of the actual state key.
When Dapr starts, it fetches the secrets containing the encryption keys listed in the `metadata` section. Dapr automatically knows which state item has been encrypted with which key, as it appends the `secretKeyRef.name` field to the end of the actual state key.
To rotate a key, change the `primaryEncryptionKey` to point to a secret containing your new key, and move the old primary encryption key to the `secondaryEncryptionKey`. New data will be encrypted using the new key, and old data that's retrieved will be decrypted using the secondary key. Any updates to data items encrypted using the old key will be re-encrypted using the new key. Note that when you rotate a key, data encrypted with the old key is not automatically re-encrypted unless your application writes it again. If you remove the rotated key (the now-secondary encryption key), you will not be able to access data that was encrypted with that.
To rotate a key,
1. Change the `primaryEncryptionKey` to point to a secret containing your new key.
1. Move the old primary encryption key to the `secondaryEncryptionKey`.
New data will be encrypted using the new key, and any retrieved old data will be decrypted using the secondary key.
Any updates to data items encrypted with the old key will be re-encrypted using the new key.
{{% alert title="Note" color="primary" %}}
when you rotate a key, data encrypted with the old key is not automatically re-encrypted unless your application writes it again. If you remove the rotated key (the now-secondary encryption key), you will not be able to access data that was encrypted with that.
{{% /alert %}}
## Related links
- [Security overview]({{< ref "security-concept.md" >}})
- [State store query API implementation guide](https://github.com/dapr/components-contrib/blob/master/state/Readme.md#implementing-state-query-api)
- [State store components]({{< ref "supported-state-stores.md" >}})
- [Security overview]({{< ref "security-concept.md" >}})
- [State store query API implementation guide](https://github.com/dapr/components-contrib/blob/master/state/Readme.md#implementing-state-query-api)
- [State store components]({{< ref "supported-state-stores.md" >}})

View File

@ -6,26 +6,17 @@ weight: 200
description: "Use key value pairs to persist a state"
---
## Introduction
State management is one of the most common needs of any new, legacy, monolith, or microservice application. Dealing with and testing different database libraries and handling retries and faults can be both difficult and time consuming.
State management is one of the most common needs of any application: new or legacy, monolith or microservice.
Dealing with different databases libraries, testing them, handling retries and faults can be time consuming and hard.
In this guide, you'll learn the basics of using the key/value state API to allow an application to save, get, and delete state.
Dapr provides state management capabilities that include consistency and concurrency options.
In this guide we'll start of with the basics: Using the key/value state API to allow an application to save, get and delete state.
## Example
## Pre-requisites
- [Dapr CLI]({{< ref install-dapr-cli.md >}})
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}})
## Example:
The below code examples loosely describe an application that processes orders. In the examples, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to store state in a Redis state store.
The code example below _loosely_ describes an application that processes orders with an order processing service which has a Dapr sidecar. The order processing service uses Dapr to store state in a Redis state store.
<img src="/images/building-block-state-management-example.png" width=1000 alt="Diagram showing state management of example service">
## Step 1: Setup a state store
## Set up a state store
A state store component represents a resource that Dapr uses to communicate with a database.
@ -34,14 +25,19 @@ For the purpose of this guide we'll use a Redis state store, but any state store
{{< tabs "Self-Hosted (CLI)" Kubernetes>}}
{{% codetab %}}
When using `dapr init` in Standalone mode, the Dapr CLI automatically provisions a state store (Redis) and creates the relevant YAML in a `components` directory, which for Linux/MacOS is `$HOME/.dapr/components` and for Windows is `%USERPROFILE%\.dapr\components`
To optionally change the state store being used, replace the YAML file `statestore.yaml` under `/components` with the file of your choice.
When you run `dapr init` in self-hosted mode, Dapr creates a default Redis `statestore.yaml` and runs a Redis state store on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out underlying components without application code changes.
{{% /codetab %}}
{{% codetab %}}
To deploy this into a Kubernetes cluster, fill in the `metadata` connection details of your [desired statestore component]({{< ref supported-state-stores >}}) in the yaml below, save as `statestore.yaml`, and run `kubectl apply -f statestore.yaml`.
To deploy this into a Kubernetes cluster, fill in the `metadata` connection details of your [state store component]({{< ref supported-state-stores >}}) in the YAML below, save as `statestore.yaml`, and run `kubectl apply -f statestore.yaml`.
```yaml
apiVersion: dapr.io/v1alpha1
@ -58,21 +54,20 @@ spec:
- name: redisPassword
value: ""
```
See the instructions [here]({{< ref "setup-state-store" >}}) on how to setup different state stores on Kubernetes.
See [how to setup different state stores on Kubernetes]({{< ref "setup-state-store" >}}).
{{% /codetab %}}
{{< /tabs >}}
## Step 2: Save and retrieve a single state
The following example shows how to save and retrieve a single key/value pair using the Dapr state building block.
{{% alert title="Note" color="warning" %}}
It is important to set an app-id, as the state keys are prefixed with this value. If you don't set it one is generated for you at runtime, and the next time you run the command a new one will be generated and you will no longer be able to access previously saved state.
{{% alert title="Important" color="warning" %}}
Set an `app-id`, as the state keys are prefixed with this value. If you don't set an `app-id`, one is generated for you at runtime. The next time you run the command, a new `app-id` is generated and you will no longer have access to the previously saved state.
{{% /alert %}}
Below are code examples that leverage Dapr SDKs for saving and retrieving a single state.
## Save and retrieve a single state
The following example shows how to save and retrieve a single key/value pair using the Dapr state management API.
{{< tabs Dotnet Java Python Go Javascript "HTTP API (Bash)" "HTTP API (PowerShell)">}}
@ -115,7 +110,7 @@ namespace EventService
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
@ -123,7 +118,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```java
@ -164,7 +158,7 @@ public class OrderProcessingServiceApplication {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
@ -172,7 +166,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```python
@ -198,7 +191,7 @@ while True:
logging.info('Result after get: ' + result.data.decode('utf-8'))
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
@ -206,7 +199,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```go
@ -247,7 +239,7 @@ func main() {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go
@ -255,7 +247,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```javascript
@ -300,7 +291,7 @@ function sleep(ms) {
main();
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
@ -308,41 +299,46 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
Begin by launching a Dapr sidecar:
Launch a Dapr sidecar:
```bash
dapr run --app-id orderprocessing --dapr-http-port 3601
```
Then in a separate terminal save a key/value pair into your statestore:
In a separate terminal, save a key/value pair into your statestore:
```bash
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "order_1", "value": "250"}]' http://localhost:3601/v1.0/state/statestore
```
Now get the state you just saved:
```bash
curl http://localhost:3601/v1.0/state/statestore/order_1
```
Restart your sidecar and try retrieving state again to observe that state persists separately from the app.
{{% /codetab %}}
{{% codetab %}}
Begin by launching a Dapr sidecar:
Launch a Dapr sidecar:
```bash
dapr --app-id orderprocessing --dapr-http-port 3601 run
```
Then in a separate terminal save a key/value pair into your statestore:
In a separate terminal, save a key/value pair into your statestore:
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '[{"key": "order_1", "value": "250"}]' -Uri 'http://localhost:3601/v1.0/state/statestore'
```
Now get the state you just saved:
```powershell
Invoke-RestMethod -Uri 'http://localhost:3601/v1.0/state/statestore/order_1'
```
@ -353,8 +349,7 @@ Restart your sidecar and try retrieving state again to observe that state persis
{{< /tabs >}}
## Step 3: Delete state
## Delete state
Below are code examples that leverage Dapr SDKs for deleting the state.
@ -382,7 +377,7 @@ namespace EventService
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
@ -390,7 +385,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```java
@ -413,7 +407,7 @@ public class OrderProcessingServiceApplication {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
@ -421,7 +415,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```python
@ -437,7 +430,7 @@ with DaprClient() as client:
client.delete_state(store_name=DAPR_STORE_NAME, key="order_1")
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
@ -445,7 +438,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```go
@ -473,7 +465,7 @@ func main() {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go
@ -481,7 +473,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```javascript
@ -500,7 +491,7 @@ var main = function() {
main();
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
@ -509,24 +500,32 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above run:
With the same Dapr instance running from above, run:
```bash
curl -X DELETE 'http://localhost:3601/v1.0/state/statestore/order_1'
```
Try getting state again and note that no value is returned.
Try getting state again. Note that no value is returned.
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above run:
With the same Dapr instance running from above, run:
```powershell
Invoke-RestMethod -Method Delete -Uri 'http://localhost:3601/v1.0/state/statestore/order_1'
```
Try getting state again and note that no value is returned.
Try getting state again. Note that no value is returned.
{{% /codetab %}}
{{< /tabs >}}
## Step 4: Save and retrieve multiple states
## Save and retrieve multiple states
Below are code examples that leverage Dapr SDKs for saving and retrieving multiple states.
@ -553,7 +552,7 @@ namespace EventService
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
@ -586,7 +585,7 @@ public class OrderProcessingServiceApplication {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
@ -612,7 +611,7 @@ with DaprClient() as client:
logging.info('Result after get bulk: ' + str(result))
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
@ -649,7 +648,7 @@ var main = function() {
main();
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
@ -658,24 +657,31 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above save two key/value pairs into your statestore:
With the same Dapr instance running from above, save two key/value pairs into your statestore:
```bash
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "order_1", "value": "250"}, { "key": "order_2", "value": "550"}]' http://localhost:3601/v1.0/state/statestore
```
Now get the states you just saved:
```bash
curl -X POST -H "Content-Type: application/json" -d '{"keys":["order_1", "order_2"]}' http://localhost:3601/v1.0/state/statestore/bulk
```
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above save two key/value pairs into your statestore:
With the same Dapr instance running from above, save two key/value pairs into your statestore:
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '[{ "key": "order_1", "value": "250"}, { "key": "order_2", "value": "550"}]' -Uri 'http://localhost:3601/v1.0/state/statestore'
```
Now get the states you just saved:
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"keys":["order_1", "order_2"]}' -Uri 'http://localhost:3601/v1.0/state/statestore/bulk'
```
@ -684,10 +690,10 @@ Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"keys":["
{{< /tabs >}}
## Step 5: Perform state transactions
## Perform state transactions
{{% alert title="Note" color="warning" %}}
State transactions require a state store that supports multi-item transactions. Visit the [supported state stores page]({{< ref supported-state-stores >}}) page for a full list. Note that the default Redis container created in a self-hosted environment supports them.
{{% alert title="Note" color="primary" %}}
State transactions require a state store that supports multi-item transactions. See the [supported state stores page]({{< ref supported-state-stores >}}) for a full list.
{{% /alert %}}
Below are code examples that leverage Dapr SDKs for performing state transactions.
@ -738,7 +744,7 @@ namespace EventService
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 dotnet run
@ -746,7 +752,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```java
@ -792,7 +797,7 @@ public class OrderProcessingServiceApplication {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
@ -838,7 +843,7 @@ while True:
logging.info('Result: ' + str(result))
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
@ -846,7 +851,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```javascript
@ -894,7 +898,7 @@ function sleep(ms) {
main();
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar for the above example application, run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
@ -903,24 +907,31 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above perform two state transactions:
With the same Dapr instance running from above, perform two state transactions:
```bash
curl -X POST -H "Content-Type: application/json" -d '{"operations": [{"operation":"upsert", "request": {"key": "order_1", "value": "250"}}, {"operation":"delete", "request": {"key": "order_2"}}]}' http://localhost:3601/v1.0/state/statestore/transaction
```
Now see the results of your state transactions:
```bash
curl -X POST -H "Content-Type: application/json" -d '{"keys":["order_1", "order_2"]}' http://localhost:3601/v1.0/state/statestore/bulk
```
{{% /codetab %}}
{{% codetab %}}
With the same Dapr instance running from above save two key/value pairs into your statestore:
With the same Dapr instance running from above, save two key/value pairs into your statestore:
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"operations": [{"operation":"upsert", "request": {"key": "order_1", "value": "250"}}, {"operation":"delete", "request": {"key": "order_2"}}]}' -Uri 'http://localhost:3601/v1.0/state/statestore'
```
Now see the results of your state transactions:
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '{"keys":["order_1", "order_2"]}' -Uri 'http://localhost:3601/v1.0/state/statestore/bulk'
```

View File

@ -3,24 +3,26 @@ type: docs
title: "How-To: Share state between applications"
linkTitle: "How-To: Share state between applications"
weight: 400
description: "Choose different strategies for sharing state between different applications"
description: "Learn the strategies for sharing state between different applications"
---
## Introduction
Dapr provides different ways to share state between applications.
Dapr offers developers different ways to share state between applications.
Different architectures might have different needs when it comes to sharing state. In one scenario, you may want to:
Different architectures might have different needs when it comes to sharing state. For example, in one scenario you may want to encapsulate all state within a given application and have Dapr manage the access for you. In a different scenario, you may need to have two applications working on the same state be able to get and save the same keys.
- Encapsulate all state within a given application
- Have Dapr manage the access for you
In a different scenario, you may need two applications working on the same state to get and save the same keys.
To enable state sharing, Dapr supports the following key prefixes strategies:
* **`appid`** - This is the default strategy. the `appid` prefix allows state to be managed only by the app with the specified `appid`. All state keys will be prefixed with the `appid`, and are scoped for the application.
* **`namespace`** - If set, this setting prefixes the `appid` key with the configured namespace, resulting in a key that is scoped to a given namespace. This allows apps in different namespace with the same `appid` to reuse the same state store. If a namespace is not configured, the setting fallbacks to the `appid` strategy. For more information on namespaces in Dapr see [How-To: Scope components to one or more applications]({{< ref component-scopes.md >}})
* **`name`** - This setting uses the name of the state store component as the prefix. Multiple applications can share the same state for a given state store.
* **`none`** - This setting uses no prefixing. Multiple applications share state across different state stores.
| Key prefixes | Description |
| ------------ | ----------- |
| `appid` | The default strategy allowing you to manage state only by the app with the specified `appid`. All state keys will be prefixed with the `appid`, and are scoped for the application. |
| `name` | Uses the name of the state store component as the prefix. Multiple applications can share the same state for a given state store. |
| `namespace` | If set, this setting prefixes the `appid` key with the configured namespace, resulting in a key that is scoped to a given namespace. This allows apps in different namespace with the same `appid` to reuse the same state store. If a namespace is not configured, the setting fallbacks to the `appid` strategy. For more information on namespaces in Dapr see [How-To: Scope components to one or more applications]({{< ref component-scopes.md >}}) |
| `none` | Uses no prefixing. Multiple applications share state across different state stores. |
## Specifying a state prefix strategy
@ -42,11 +44,11 @@ spec:
## Examples
The following examples will show you how state retrieval looks like with each of the supported prefix strategies:
The following examples demonstrate what state retrieval looks like with each of the supported prefix strategies.
### `appid` (default)
A Dapr application with app id `myApp` is saving state into a state store named `redis`:
In the example below, a Dapr application with app id `myApp` is saving state into a state store named `redis`:
```shell
curl -X POST http://localhost:3500/v1.0/state/redis \
@ -80,7 +82,7 @@ The key will be saved as `production.myApp||darth`.
### `name`
A Dapr application with app id `myApp` is saving state into a state store named `redis`:
In the example below, a Dapr application with app id `myApp` is saving state into a state store named `redis`:
```shell
curl -X POST http://localhost:3500/v1.0/state/redis \
@ -97,7 +99,7 @@ The key will be saved as `redis||darth`.
### `none`
A Dapr application with app id `myApp` is saving state into a state store named `redis`:
In the example below, a Dapr application with app id `myApp` is saving state into a state store named `redis`:
```shell
curl -X POST http://localhost:3500/v1.0/state/redis \
@ -110,5 +112,4 @@ curl -X POST http://localhost:3500/v1.0/state/redis \
]'
```
The key will be saved as `darth`.
The key will be saved as `darth`.

View File

@ -3,36 +3,28 @@ type: docs
title: "How-To: Query state"
linkTitle: "How-To: Query state"
weight: 250
description: "API for querying state stores"
description: "Use the Query API for querying state stores"
---
{{% alert title="alpha" color="warning" %}}
The state query API is in **alpha** stage.
{{% /alert %}}
## Introduction
With the state query API, you can retrieve, filter, and sort the key/value data stored in state store components. The query API is not a replacement for a complete query language.
The state query API provides a way of querying the key/value data stored in state store components. This query API is not a replacement for a complete query language, and is focused on retrieving, filtering and sorting key/value data that you have saved through the state management APIs.
Even though the state store is a key/value store, the `value` might be a JSON document with its own hierarchy, keys, and values.
The query API allows you to use those keys and values to retrive corresponding documents.
### Limitations
The state query API has the following limitations:
- The API does not support querying of actor state stored in a state store. For that you need to use the query API for the specific database. See [querying actor state]({{< ref "state-management-overview.md#querying-actor-state" >}}).
- The API does not work with Dapr [encrypted state stores]({{<ref howto-encrypt-state>}}) capability. Since the encryption is done by the Dapr runtime and stored as encrypted data, then this effectively prevents server side querying.
You can find additional information in the [related links]({{< ref "#related-links" >}}) section.
Even though the state store is a key/value store, the `value` might be a JSON document with its own hierarchy, keys, and values. The query API allows you to use those keys/values to retrieve corresponding documents.
## Querying the state
You submit query requests via HTTP POST/PUT or gRPC.
The body of the request is the JSON map with 3 entries: `filter`, `sort`, and `page`.
Submit query requests via HTTP POST/PUT or gRPC. The body of the request is the JSON map with 3 _optional_ entries:
The `filter` is an optional section. It specifies the query conditions in the form of a tree, where each node represents either unary or multi-operand operation.
- `filter`
- `sort`
- `page`
### `filter`
The `filter` specifies the query conditions in the form of a tree, where each node represents either unary or multi-operand operation.
The following operations are supported:
@ -43,7 +35,8 @@ The following operations are supported:
| `AND` | []operation | operation[0] AND operation[1] AND ... AND operation[n] |
| `OR` | []operation | operation[0] OR operation[1] OR ... OR operation[n] |
The `key` in the operand is similar to the JSONPath notation. Each dot in the key indicates a nested JSON structure. Consider for example this structure:
The `key` in the operand is similar to the JSONPath notation. Each dot in the key indicates a nested JSON structure. For example, consider this structure:
```json
{
"shape": {
@ -59,53 +52,72 @@ The `key` in the operand is similar to the JSONPath notation. Each dot in the ke
}
}
```
If you want to compare the value of the color code, the key will be `shape.color.code`
If `filter` section is omitted, the query returns all entries.
To compare the value of the color code, the key will be `shape.color.code`.
The `sort` is an optional section and is an ordered array of `key:order` pairs, where `key` is a key in the state store, and the `order` is an optional string indicating sorting order: `"ASC"` for ascending and `"DESC"` for descending. If omitted, ascending order is the default.
If the `filter` section is omitted, the query returns all entries.
The `page` is an optional section containing `limit` and `token` parameters. `limit` sets the page size. `token` is an iteration token returned by the component, and is used in subsequent queries.
### `sort`
For some background understanding, this query request is translated into the native query language and executed by the state store component.
The `sort` is an ordered array of `key:order` pairs, where:
- `key` is a key in the state store
- `order` is an optional string indicating sorting order:
- `"ASC"` for ascending
- `"DESC"` for descending
If omitted, ascending order is the default.
### `page`
The `page` contains `limit` and `token` parameters.
- `limit` sets the page size.
- `token` is an iteration token returned by the component, used in subsequent queries.
Behind the scenes, this query request is translated into the native query language and executed by the state store component.
## Example data and query
Let's look at some real examples, starting with simple and progressing towards more complex ones.
Let's look at some real examples, ranging from simple to complex.
As a dataset, let's consider a [collection of with employee records](../query-api-examples/dataset.json) containing employee ID, organization, state, and city.
Notice that this dataset is an array of key/value pairs where `key` is the unique ID, and the `value` is the JSON object with employee record.
To better illustrate functionality, let's have organization name (org) and employee ID (id) as a nested JSON person object.
As a dataset, consider a [collection of employee records](../query-api-examples/dataset.json) containing employee ID, organization, state, and city. Notice that this dataset is an array of key/value pairs, where:
- `key` is the unique ID
- `value` is the JSON object with employee record.
To better illustrate functionality, organization name (org) and employee ID (id) are a nested JSON person object.
Get started by creating an instance of MongoDB, which is your state store.
First, you need to create an instance of MongoDB, which is your state store.
```bash
docker run -d --rm -p 27017:27017 --name mongodb mongo:5
```
Next is to start a Dapr application. Refer to this [component configuration file](../query-api-examples/components/mongodb/mongodb.yml), which instructs Dapr to use MongoDB as its state store.
Next, start a Dapr application. Refer to the [component configuration file](../query-api-examples/components/mongodb/mongodb.yml), which instructs Dapr to use MongoDB as its state store.
```bash
dapr run --app-id demo --dapr-http-port 3500 --components-path query-api-examples/components/mongodb
```
Now populate the state store with the employee dataset, so you can then query it later.
Populate the state store with the employee dataset, so you can query it later.
```bash
curl -X POST -H "Content-Type: application/json" -d @query-api-examples/dataset.json http://localhost:3500/v1.0/state/statestore
```
Once populated, you can examine the data in the state store. The image below a section of the MongoDB UI displaying employee records.
<table><tr><td>
<img src="/images/state-management-query-mongodb-dataset.png" width=500 alt="Sample dataset" class="center">
</td></tr></table>
Once populated, you can examine the data in the state store. In the image below, a section of the MongoDB UI displays employee records.
<img src="/images/state-management-query-mongodb-dataset.png" width=500 alt="Sample dataset" class="center">
Each entry has the `_id` member as a concatenated object key, and the `value` member containing the JSON record.
The query API allows you to select records from this JSON structure.
Now you can run the queries.
Now you can run the example queries.
### Example 1
First, let's find all employees in the state of California and sort them by their employee ID in descending order.
First, find all employees in the state of California and sort them by their employee ID in descending order.
This is the [query](../query-api-examples/query1.json):
```json
@ -123,6 +135,7 @@ This is the [query](../query-api-examples/query1.json):
```
An equivalent of this query in SQL is:
```sql
SELECT * FROM c WHERE
state = "CA"
@ -131,20 +144,29 @@ ORDER BY
```
Execute the query with the following command:
{{< tabs "HTTP API (Bash)" "HTTP API (PowerShell)" >}}
{{% codetab %}}
```bash
curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query1.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
```
{{% /codetab %}}
{{% codetab %}}
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query1.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'
```
{{% /codetab %}}
{{< /tabs >}}
The query result is an array of matching key/value pairs in the requested order:
```json
{
"results": [
@ -202,9 +224,10 @@ The query result is an array of matching key/value pairs in the requested order:
### Example 2
Let's now find all employees from the "Dev Ops" and "Hardware" organizations.
Now, find all employees from the "Dev Ops" and "Hardware" organizations.
This is the [query](../query-api-examples/query2.json):
```json
{
"filter": {
@ -214,34 +237,44 @@ This is the [query](../query-api-examples/query2.json):
```
An equivalent of this query in SQL is:
```sql
SELECT * FROM c WHERE
person.org IN ("Dev Ops", "Hardware")
```
Execute the query with the following command:
{{< tabs "HTTP API (Bash)" "HTTP API (PowerShell)" >}}
{{% codetab %}}
```bash
curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query2.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
```
{{% /codetab %}}
{{% codetab %}}
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query2.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'
```
{{% /codetab %}}
{{< /tabs >}}
Similar to the previous example, the result is an array of matching key/value pairs.
### Example 3
In this example let's find all employees from the "Dev Ops" department
and those employees from the "Finance" departing residing in the states of Washington and California.
In this example, find:
In addition, let's sort the results first by state in descending alphabetical order, and then by employee ID in ascending order.
Also, let's process up to 3 records at a time.
- All employees from the "Dev Ops" department.
- Employees from the "Finance" departing residing in the states of Washington and California.
In addition, sort the results first by state in descending alphabetical order, then by employee ID in ascending order. Let's process up to 3 records at a time.
This is the [query](../query-api-examples/query3.json):
@ -280,6 +313,7 @@ This is the [query](../query-api-examples/query3.json):
```
An equivalent of this query in SQL is:
```sql
SELECT * FROM c WHERE
person.org = "Dev Ops" OR
@ -291,20 +325,29 @@ LIMIT 3
```
Execute the query with the following command:
{{< tabs "HTTP API (Bash)" "HTTP API (PowerShell)" >}}
{{% codetab %}}
```bash
curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query3.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
```
{{% /codetab %}}
{{% codetab %}}
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query3.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'
```
{{% /codetab %}}
{{< /tabs >}}
Upon successful execution, the state store returns a JSON object with a list of matching records and the pagination token:
```json
{
"results": [
@ -387,19 +430,27 @@ The pagination token is used "as is" in the [subsequent query](../query-api-exam
```
{{< tabs "HTTP API (Bash)" "HTTP API (PowerShell)" >}}
{{% codetab %}}
```bash
curl -s -X POST -H "Content-Type: application/json" -d @query-api-examples/query3-token.json http://localhost:3500/v1.0-alpha1/state/statestore/query | jq .
```
{{% /codetab %}}
{{% codetab %}}
```powershell
Invoke-RestMethod -Method Post -ContentType 'application/json' -InFile query-api-examples/query3-token.json -Uri 'http://localhost:3500/v1.0-alpha1/state/statestore/query'
```
{{% /codetab %}}
{{< /tabs >}}
And the result of this query is:
```json
{
"results": [
@ -443,10 +494,21 @@ And the result of this query is:
"token": "6"
}
```
That way you can update the pagination token in the query and iterate through the results until no more records are returned.
## Limitations
The state query API has the following limitations:
- To query actor states stored in a state store, you need to use the query API for the specific database. See [querying actor state]({{< ref "state-management-overview.md#querying-actor-state" >}}).
- The API does not work with Dapr [encrypted state stores]({{< ref howto-encrypt-state >}}) capability. Since the encryption is done by the Dapr runtime and stored as encrypted data, then this effectively prevents server side querying.
You can find additional information in the [related links]({{< ref "#related-links" >}}) section.
## Related links
- [Query API reference ]({{< ref "state_api.md#state-query" >}})
- [State store components with those that implement query support]({{< ref supported-state-stores.md >}})
- [State store query API implementation guide](https://github.com/dapr/components-contrib/blob/master/state/Readme.md#implementing-state-query-api)
- [Querying Redis state store]({{< ref "setup-redis.md#querying-json-objects" >}})
- Refer to the [query API reference]({{< ref "state_api.md#state-query" >}}).
- See the [state store components that implement query support]({{< ref supported-state-stores.md >}}).
- View the [state store query API implementation guide](https://github.com/dapr/components-contrib/blob/master/state/Readme.md#implementing-state-query-api).
- See how to [query Redis state store]({{< ref "setup-redis.md#querying-json-objects" >}}).

View File

@ -6,39 +6,41 @@ weight: 300
description: "Use state management with a scaled, replicated service"
---
In this article you'll learn how you can create a stateful service which can be horizontally scaled, using opt-in concurrency and consistency models.
In this article, you'll learn how to create a stateful service which can be horizontally scaled, using opt-in concurrency and consistency models. Consuming the state management API frees developers from difficult state coordination, conflict resolution, and failure handling.
This frees developers from difficult state coordination, conflict resolution and failure handling, and allows them instead to consume these capabilities as APIs from Dapr.
## Setup a state store
## Set up a state store
A state store component represents a resource that Dapr uses to communicate with a database.
For the purpose of this guide, we'll use a Redis state store.
See a list of supported state stores [here]({{< ref supported-state-stores >}})
For the purpose of this guide, we'll use the default Redis state store.
### Using the Dapr CLI
The Dapr CLI automatically provisions a state store (Redis) and creates the relevant YAML when running your app with `dapr run`.
To change the state store being used, replace the YAML under `/components` with the file of your choice.
When you run `dapr init` in self-hosted mode, Dapr creates a default Redis `statestore.yaml` and runs a Redis state store on your local machine, located:
- On Windows, under `%UserProfile%\.dapr\components\statestore.yaml`
- On Linux/MacOS, under `~/.dapr/components/statestore.yaml`
With the `statestore.yaml` component, you can easily swap out underlying components without application code changes.
See a [list of supported state stores]({{< ref supported-state-stores >}}).
### Kubernetes
See the instructions [here]({{<ref setup-state-store>}}) on how to setup different state stores on Kubernetes.
See [how to setup different state stores on Kubernetes]({{<ref setup-state-store>}}).
## Strong and Eventual consistency
## Strong and eventual consistency
Using strong consistency, Dapr will make sure the underlying state store returns the response once the data has been written to all replicas or received an ack from a quorum before writing or deleting state.
Using strong consistency, Dapr makes sure that the underlying state store:
For get requests, Dapr will make sure the store returns the most up to date data consistently among replicas.
The default is eventual consistency, unless specified otherwise in the request to the state API.
- Returns the response once the data has been written to all replicas.
- Receives an ACK from a quorum before writing or deleting state.
The following examples illustrates using strong consistency:
For get requests, Dapr ensures the store returns the most up-to-date data consistently among replicas. The default is eventual consistency, unless specified otherwise in the request to the state API.
The following examples illustrate how to save, get, and delete state using strong consistency. The example is written in Python, but is applicable to any programming language.
### Saving state
*The following example is written in Python, but is applicable to any programming language*
```python
import requests
import json
@ -51,8 +53,6 @@ response = requests.post(dapr_state_url, json=stateReq)
### Getting state
*The following example is written in Python, but is applicable to any programming language*
```python
import requests
import json
@ -65,8 +65,6 @@ print(response.headers['ETag'])
### Deleting state
*The following example is written in Python, but is applicable to any programming language*
```python
import requests
import json
@ -76,24 +74,31 @@ dapr_state_url = "http://localhost:3500/v1.0/state/{}".format(store_name)
response = requests.delete(dapr_state_url + "/key1", headers={"consistency":"strong"})
```
Last-write concurrency is the default concurrency mode if the `concurrency` option is not specified.
If the `concurrency` option hasn't been specified, the default is last-write concurrency mode.
## First-write-wins and Last-write-wins
## First-write-wins and last-write-wins
Dapr allows developers to opt-in for two common concurrency patterns when working with data stores: First-write-wins and Last-write-wins.
First-Write-Wins is useful in situations where you have multiple instances of an application, all writing to the same key concurrently.
Dapr allows developers to opt-in for two common concurrency patterns when working with data stores:
The default mode for Dapr is Last-write-wins.
- **First-write-wins**: useful in situations where you have multiple instances of an application, all writing to the same key concurrently.
- **Last-write-wins**: Default mode for Dapr.
Dapr uses version numbers to determine whether a specific key has been updated. Clients retain the version number when reading the data for a key and then use the version number during updates such as writes and deletes. If the version information has changed since the client retrieved, an error is thrown, which then requires the client to perform a read again to get the latest version information and state.
Dapr uses version numbers to determine whether a specific key has been updated. You can:
Dapr utilizes ETags to determine the state's version number. ETags are returned from state requests in an `ETag` header.
1. Retain the version number when reading the data for a key.
1. Use the version number during updates such as writes and deletes.
Using ETags, clients know that a resource has been updated since the last time they checked by erroring when there's an ETag mismatch.
If the version information has changed since the version number was retrieved, an error is thrown, requiring you to perform another read to get the latest version information and state.
The following example shows how to get an ETag, and then use it to save state and then delete the state:
Dapr utilizes ETags to determine the state's version number. ETags are returned from state requests in an `ETag` header. Using ETags, your application knows that a resource has been updated since the last time they checked by erroring during an ETag mismatch.
*The following example is written in Python, but is applicable to any programming language*
The following example shows how to:
- Get an ETag.
- Use the ETag to save state.
- Delete the state.
The following example is written in Python, but is applicable to any programming language.
```python
import requests
@ -111,7 +116,7 @@ response = requests.delete(dapr_state_url + "/key1", headers={"If-Match": "{}".f
### Handling version mismatch failures
In this example, we'll see how to retry a save state operation when the version has changed:
In the following example, you'll see how to retry a save state operation when the version has changed:
```python
import requests

View File

@ -6,4 +6,4 @@ weight: 500
description: "Guides for working with specific backend states stores"
---
Explore the **Operations** section to see a list of [supported state stores]({{<ref supported-state-stores.md>}}) and how to setup [state store components]({{<ref setup-state-store.md>}}).
Explore the **Operations** section to see a list of [supported state stores]({{< ref supported-state-stores.md >}}) and how to setup [state store components]({{< ref setup-state-store.md >}}).

View File

@ -3,20 +3,33 @@ type: docs
title: "Azure Cosmos DB"
linkTitle: "Azure Cosmos DB"
weight: 1000
description: "Use Azure Cosmos DB as a backend state store"
description: "Use Azure Cosmos DB as a state store"
---
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [Dapr state management spec]({{< ref state_api.md >}}). You can directly interact with the underlying store to manipulate the state data, such querying states, creating aggregated views and making backups.
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [the state management spec]({{< ref state_api.md >}}). You can directly interact with the underlying store to manipulate the state data, such as:
> **NOTE:** Azure Cosmos DB is a multi-modal database that supports multiple APIs. The default Dapr Cosmos DB state store implementation uses the [Azure Cosmos DB SQL API](https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started).
- Querying states.
- Creating aggregated views.
- Making backups.
## 1. Connect to Azure Cosmos DB
{{% alert title="Note" color="primary" %}}
Azure Cosmos DB is a multi-modal database that supports multiple APIs. The default Dapr Cosmos DB state store implementation uses the [Azure Cosmos DB SQL API](https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started).
The easiest way to connect to your Cosmos DB instance is to use the Data Explorer on [Azure Management Portal](https://portal.azure.com). Alternatively, you can use [various SDKs and tools](https://docs.microsoft.com/azure/cosmos-db/mongodb-introduction).
{{% /alert %}}
> **NOTE:** The following samples use Cosmos DB [SQL API](https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started). When you configure an Azure Cosmos DB for Dapr, you need to specify the exact database and collection to use. The follow samples assume you've already connected to the right database and a collection named "states".
## Connect to Azure Cosmos DB
## 2. List keys by App ID
To connect to your Cosmos DB instance, you can either:
- Use the Data Explorer on [Azure Management Portal](https://portal.azure.com).
- Use [various SDKs and tools](https://docs.microsoft.com/azure/cosmos-db/mongodb-introduction).
{{% alert title="Note" color="primary" %}}
When you configure an Azure Cosmos DB for Dapr, specify the exact database and collection to use. The following Cosmos DB [SQL API](https://docs.microsoft.com/azure/cosmos-db/sql-query-getting-started) samples assume you've already connected to the right database and a collection named "states".
{{% /alert %}}
## List keys by App ID
To get all state keys associated with application "myapp", use the query:
@ -24,9 +37,9 @@ To get all state keys associated with application "myapp", use the query:
SELECT * FROM states WHERE CONTAINS(states.id, 'myapp||')
```
The above query returns all documents with id containing "myapp-", which is the prefix of the state keys.
The above query returns all documents with an id containing "myapp-", which is the prefix of the state keys.
## 3. Get specific state data
## Get specific state data
To get the state data by a key "balance" for the application "myapp", use the query:
@ -34,15 +47,13 @@ To get the state data by a key "balance" for the application "myapp", use the qu
SELECT * FROM states WHERE states.id = 'myapp||balance'
```
Then, read the **value** field of the returned document.
To get the state version/ETag, use the command:
Read the **value** field of the returned document. To get the state version/ETag, use the command:
```sql
SELECT states._etag FROM states WHERE states.id = 'myapp||balance'
```
## 4. Read actor state
## Read actor state
To get all the state keys associated with an actor with the instance ID "leroy" of actor type "cat" belonging to the application with ID "mypets", use the command:
@ -56,4 +67,7 @@ And to get a specific actor state such as "food", use the command:
SELECT * FROM states WHERE states.id = 'mypets||cat||leroy||food'
```
> **WARNING:** You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime.
{{% alert title="Warning" color="warning" %}}
You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime. **The only exception:** it is often required to delete actor records in a state store, _once you know that these are no longer in use_, to prevent a build up of unused actor instances that may never be loaded again.
{{% /alert %}}

View File

@ -3,22 +3,29 @@ type: docs
title: "Redis"
linkTitle: "Redis"
weight: 2000
description: "Use Redis as a backend state store"
description: "Use Redis as a state store"
---
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [Dapr state management spec]({{<ref state_api.md>}}). You can directly interact with the underlying store to manipulate the state data, such as querying states, creating aggregated views and making backups.
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [the state management spec]({{< ref state_api.md >}}). You can directly interact with the underlying store to manipulate the state data, such as:
>**NOTE:** The following examples uses Redis CLI against a Redis store using the default Dapr state store implementation.
- Querying states.
- Creating aggregated views.
- Making backups.
## 1. Connect to Redis
{{% alert title="Note" color="primary" %}}
The following examples uses Redis CLI against a Redis store using the default Dapr state store implementation.
You can use the official [redis-cli](https://redis.io/topics/rediscli) or any other Redis compatible tools to connect to the Redis state store to directly query Dapr states. If you are running Redis in a container, the easiest way to use redis-cli is to use a container:
{{% /alert %}}
## Connect to Redis
You can use the official [redis-cli](https://redis.io/topics/rediscli) or any other Redis compatible tools to connect to the Redis state store to query Dapr states directly. If you are running Redis in a container, the easiest way to use redis-cli is via a container:
```bash
docker run --rm -it --link <name of the Redis container> redis redis-cli -h <name of the Redis container>
```
## 2. List keys by App ID
## List keys by App ID
To get all state keys associated with application "myapp", use the command:
@ -33,9 +40,12 @@ The above command returns a list of existing keys, for example:
2) "myapp||amount"
```
## 3. Get specific state data
## Get specific state data
Dapr saves state values as hash values. Each hash value contains a "data" field, which contains the state data and a "version" field, which contains an ever-incrementing version serving as the ETag.
Dapr saves state values as hash values. Each hash value contains a "data" field, which contains:
- The state data.
- A "version" field, with an ever-incrementing version serving as the ETag.
For example, to get the state data by a key "balance" for the application "myapp", use the command:
@ -49,7 +59,7 @@ To get the state version/ETag, use the command:
HGET myapp||balance version
```
## 4. Read actor state
## Read actor state
To get all the state keys associated with an actor with the instance ID "leroy" of actor type "cat" belonging to the application with ID "mypets", use the command:
@ -57,10 +67,13 @@ To get all the state keys associated with an actor with the instance ID "leroy"
KEYS mypets||cat||leroy*
```
And to get a specific actor state such as "food", use the command:
To get a specific actor state such as "food", use the command:
```bash
HGET mypets||cat||leroy||food value
```
> **WARNING:** You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime.
{{% alert title="Warning" color="warning" %}}
You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime. **The only exception:** it is often required to delete actor records in a state store, _once you know that these are no longer in use_, to prevent a build up of unused actor instances that may never be loaded again.
{{% /alert %}}

View File

@ -6,15 +6,25 @@ weight: 3000
description: "Use SQL server as a backend state store"
---
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [Dapr state management spec]({{< ref state_api.md >}}). You can directly interact with the underlying store to manipulate the state data, such querying states, creating aggregated views and making backups.
Dapr doesn't transform state values while saving and retrieving states. Dapr requires all state store implementations to abide by a certain key format scheme (see [the state management spec]({{< ref state_api.md >}}). You can directly interact with the underlying store to manipulate the state data, such as:
## 1. Connect to SQL Server
- Querying states.
- Creating aggregated views.
- Making backups.
The easiest way to connect to your SQL Server instance is to use the [Azure Data Studio](https://docs.microsoft.com/sql/azure-data-studio/download-azure-data-studio) (Windows, macOS, Linux) or [SQL Server Management Studio](https://docs.microsoft.com/sql/ssms/download-sql-server-management-studio-ssms) (Windows).
## Connect to SQL Server
> **NOTE:** The following samples use Azure SQL. When you configure an Azure SQL database for Dapr, you need to specify the exact table name to use. The follow samples assume you've already connected to the right database with a table named "states".
The easiest way to connect to your SQL Server instance is to use the:
## 2. List keys by App ID
- [Azure Data Studio](https://docs.microsoft.com/sql/azure-data-studio/download-azure-data-studio) (Windows, macOS, Linux)
- [SQL Server Management Studio](https://docs.microsoft.com/sql/ssms/download-sql-server-management-studio-ssms) (Windows)
{{% alert title="Note" color="primary" %}}
When you configure an Azure SQL database for Dapr, you need to specify the exact table name to use. The following Azure SQL samples assume you've already connected to the right database with a table named "states".
{{% /alert %}}
## List keys by App ID
To get all state keys associated with application "myapp", use the query:
@ -24,7 +34,7 @@ SELECT * FROM states WHERE [Key] LIKE 'myapp||%'
The above query returns all rows with id containing "myapp||", which is the prefix of the state keys.
## 3. Get specific state data
## Get specific state data
To get the state data by a key "balance" for the application "myapp", use the query:
@ -32,15 +42,13 @@ To get the state data by a key "balance" for the application "myapp", use the qu
SELECT * FROM states WHERE [Key] = 'myapp||balance'
```
Then, read the **Data** field of the returned row.
To get the state version/ETag, use the command:
Read the **Data** field of the returned row. To get the state version/ETag, use the command:
```sql
SELECT [RowVersion] FROM states WHERE [Key] = 'myapp||balance'
```
## 4. Get filtered state data
## Get filtered state data
To get all state data where the value "color" in json data equals to "blue", use the query:
@ -48,7 +56,7 @@ To get all state data where the value "color" in json data equals to "blue", use
SELECT * FROM states WHERE JSON_VALUE([Data], '$.color') = 'blue'
```
## 5. Read actor state
## Read actor state
To get all the state keys associated with an actor with the instance ID "leroy" of actor type "cat" belonging to the application with ID "mypets", use the command:
@ -56,10 +64,13 @@ To get all the state keys associated with an actor with the instance ID "leroy"
SELECT * FROM states WHERE [Key] LIKE 'mypets||cat||leroy||%'
```
And to get a specific actor state such as "food", use the command:
To get a specific actor state such as "food", use the command:
```sql
SELECT * FROM states WHERE [Key] = 'mypets||cat||leroy||food'
```
> **WARNING:** You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime.
{{% alert title="Warning" color="warning" %}}
You should not manually update or delete states in the store. All writes and delete operations should be done via the Dapr runtime. **The only exception:** it is often required to delete actor records in a state store, _once you know that these are no longer in use_, to prevent a build up of unused actor instances that may never be loaded again.
{{% /alert %}}

View File

@ -6,65 +6,76 @@ weight: 100
description: "Overview of the state management API building block"
---
## Introduction
Your application can use Dapr's state management API to save, read, and query key/value pairs in the [supported state stores]({{< ref supported-state-stores.md >}}). Using a state store component, you can build stateful, long running applications that save and retrieve their state (like a shopping cart or a game's session state). For example, in the diagram below:
Using state management, your application can store and query data as key/value pairs in the [supported state stores]({{< ref supported-state-stores.md >}}). This enables you to build stateful, long running applications that can save and retrieve their state, for example a shopping cart or a game's session state.
- Use **HTTP POST** to save or query key/value pairs.
- Use **HTTP GET** to read a specific key and have its value returned.
When using state management, your application can leverage features that would otherwise be complicated and error-prone to build yourself such as:
<img src="/images/state-management-overview.png" width=1000>
## Features
With state management, your application can leverage features that are typically complicated and error-prone to build, including:
- Setting the choices on concurrency control and data consistency.
- Performing bulk update operations [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) including multiple transactional operations.
- Querying and filtering the key/value data.
Your application can use Dapr's state management API to save, read and query key/value pairs using a state store component, as shown in the diagram below. For example, by using HTTP POST you can save or query key/value pairs and by using HTTP GET you can read a specific key and have its value returned.
<img src="/images/state-management-overview.png" width=1000>
## Features
These are the features available as part of the state management API:
### Pluggable state stores
Dapr data stores are modeled as components, which can be swapped out without any changes to your service code. See [supported state stores]({{< ref supported-state-stores >}}) to see the list.
### Configurable state store behaviors
Dapr allows you to include additional metadata in a state operation request that describes how the request is expected to be handled. You can attach:
With Dapr, you can include additional metadata in a state operation request that describes how you expect the request to be handled. You can attach:
- Concurrency requirements
- Consistency requirements
By default, your application should assume a data store is **eventually consistent** and uses a **last-write-wins** concurrency pattern.
By default, your application should assume a data store is **eventually consistent** and uses a **last-write-wins concurrency pattern**.
[Not all stores are created equal]({{< ref supported-state-stores.md >}}). To ensure portability of your application you can query the metadata capabilities of the store and make your code adaptive to different store capabilities.
[Not all stores are created equal]({{< ref supported-state-stores.md >}}). To ensure your application's portability, you can query the metadata capabilities of the store and make your code adaptive to different store capabilities.
### Concurrency
Dapr supports Optimistic Concurrency Control (OCC) using ETags. When a state value is requested, Dapr always attaches an ETag property to the returned state. When the user code tries to update or delete a state, its expected to attach the ETag either through the request body for updates or the `If-Match` header for deletes. The write operation can succeed only when the provided ETag matches with the ETag in the state store.
#### Concurrency
Dapr chooses OCC because in many applications, data update conflicts are rare because clients are naturally partitioned by business contexts to operate on different data. However, if your application chooses to use ETags, a request may get rejected because of mismatched ETags. It's recommended that you use a retry policy in your code to compensate for such conflicts when using ETags.
Dapr supports Optimistic Concurrency Control (OCC) using ETags. When a state value is requested, Dapr always attaches an ETag property to the returned state. When the user code:
If your application omits ETags in writing requests, Dapr skips ETag checks while handling the requests. This essentially enables the **last-write-wins** pattern, compared to the **first-write-wins** pattern with ETags.
- **Updates a state**, it's expected to attach the ETag through the request body.
- **Deletes a state**, its expected to attach the ETag through the `If-Match` header.
The `write` operation succeeds when the provided ETag matches the ETag in the state store.
##### Why Dapr chooses optimistic concurrency control (OCC)
Data update conflicts are rare in many applications, since clients are naturally partitioned by business contexts to operate on different data. However, if your application chooses to use ETags, mismatched ETags may cause a request rejection. It's recommended you use a retry policy in your code to compensate for conflicts when using ETags.
If your application omits ETags in writing requests, Dapr skips ETag checks while handling the requests. This enables the **last-write-wins** pattern, compared to the **first-write-wins** pattern with ETags.
{{% alert title="Note on ETags" color="primary" %}}
For stores that don't natively support ETags, it's expected that the corresponding Dapr state store implementation simulates ETags and follows the Dapr state management API specification when handling states. Because Dapr state store implementations are technically clients to the underlying data store, such simulation should be straightforward using the concurrency control mechanisms provided by the store.
For stores that don't natively support ETags, the corresponding Dapr state store implementation is expected to simulate ETags and follow the Dapr state management API specification when handling states. Since Dapr state store implementations are technically clients to the underlying data store, simulation should be straightforward, using the concurrency control mechanisms provided by the store.
{{% /alert %}}
Read the [API reference]({{< ref state_api.md >}}) to learn how to set concurrency options.
### Consistency
#### Consistency
Dapr supports both **strong consistency** and **eventual consistency**, with eventual consistency as the default behavior.
When strong consistency is used, Dapr waits for all replicas (or designated quorums) to acknowledge before it acknowledges a write request. When eventual consistency is used, Dapr returns as soon as the write request is accepted by the underlying data store, even if this is a single replica.
- **Strong consistency**: Dapr waits for all replicas (or designated quorums) to acknowledge before it acknowledges a write request.
- **Eventual consistency**: Dapr returns as soon as the write request is accepted by the underlying data store, even if this is a single replica.
Read the [API reference]({{< ref state_api.md >}}) to learn how to set consistency options.
### Setting content type
Some state store components might have different ways of maintaining and manipulating data, depending on its type.
Dapr supports passing content type in [State management API](#state-management-api) as part of request metadata.
State store components may maintain and manipulate data differently, depending on the content type. Dapr supports passing content type in [state management API](#state-management-api) as part of request metadata.
Setting the content type is optional, and it is up to the component to make use of it. Dapr only provides the means of passing this information to the component.
Setting the content type is _optional_, and the component decides whether to make use of it. Dapr only provides the means of passing this information to the component.
With the HTTP API, you can set content type via URL query parameter `metadata.contentType`. For example, `http://localhost:3500/v1.0/state/store?metadata.contentType=application/json`
With the gRPC API, you can set content type by adding key/value pair `"contentType" : <content type>` to the request metadata.
- **With the HTTP API**: Set content type via URL query parameter `metadata.contentType`. For example, `http://localhost:3500/v1.0/state/store?metadata.contentType=application/json`.
- **With the gRPC API**: Set content type by adding key/value pair `"contentType" : <content type>` to the request metadata.
### Multiple operations
@ -76,26 +87,41 @@ You can group multiple read requests into a bulk (or batch) operation. In the bu
#### Transactional operations
You can group write, update and delete operations into a request, which are then handled as an atomic transaction. The request will succeed or fail as a transactional set of operations.
You can group write, update, and delete operations into a request, which are then handled as an atomic transaction. The request will succeed or fail as a transactional set of operations.
### Actor state
Transactional state stores can be used to store actor state. To specify which state store to use for actors, specify value of property `actorStateStore` as `true` in the state store component's metadata section. Actors state is stored with a specific scheme in transactional state stores, allowing for consistent querying. Only a single state store component can be used as the state store for all actors. Read the [state API reference]({{< ref state_api.md >}}) and the [actors API reference]({{< ref actors_api.md >}}) to learn more about state stores for actors.
### State encryption
Dapr supports automatic client encryption of application state with support for key rotations. This is supported on all Dapr state stores. For more info, read the [How-To: Encrypt application state]({{< ref howto-encrypt-state.md >}}) topic.
### Shared state between applications
Different applications might have different needs when it comes to sharing state. For example, in one scenario you may want to encapsulate all state within a given application and have Dapr manage the access for you. In a different scenario, you may need to have two applications working on the same state be able to get and save the same keys. Dapr enable states to be isolated to an application, shared in a state store between applications or have multiple applications share state across different state stores. For more details read [How-To: Share state between applications]({{< ref howto-share-state.md >}}),
### Actor state
Transactional state stores can be used to store actor state. To specify which state store to be used for actors, specify value of property `actorStateStore` as `true` in the metadata section of the state store component. Actors state is stored with a specific scheme in transactional state stores, which allows for consistent querying. Only a single state store component can be used as the state store for all actors. Read the [API reference]({{< ref state_api.md >}}) to learn more about state stores for actors and the [actors API reference]({{< ref actors_api.md >}})
Different applications' needs vary when it comes to sharing state. In one scenario, you may want to encapsulate all state within a given application and have Dapr manage the access for you. In another scenario, you may want two applications working on the same state to get and save the same keys.
Dapr enables states to be:
- Isolated to an application.
- Shared in a state store between applications.
- Shared between multiple applications across different state stores.
For more details read [How-To: Share state between applications]({{< ref howto-share-state.md >}}),
### Querying state
### Querying state
There are two ways to query the state:
* Using the state management query API provided in Dapr runtime.
* Querying state store directly with the store's native SDK.
- Using the state management query API provided in Dapr runtime.
- Querying state store directly with the store's native SDK.
#### Query API
The [query API]({{< ref "reference/api/state_api.md#query-state" >}}) provides a way of querying the key/value data saved using state management in state stores regardless of underlying database or storage technology. It is an optional state management API. Using the state management query API you can filter, sort and paginate the key/value data. For more details read [How-To: Query state]({{< ref howto-state-query-api.md >}}).
Using the _optional_ state management [query API]({{< ref "reference/api/state_api.md#query-state" >}}), you can query the key/value data saved in state stores, regardless of underlying database or storage technology. With the state management query API, you can filter, sort, and paginate the key/value data. For more details read [How-To: Query state]({{< ref howto-state-query-api.md >}}).
#### Querying state store directly
Dapr saves and retrieves state values without any transformation. You can query and aggregate state directly from the [underlying state store]({{< ref query-state-store >}}).
For example, to get all state keys associated with an application ID "myApp" in Redis, use:
@ -104,37 +130,52 @@ KEYS "myApp*"
```
{{% alert title="Note on direct queries" color="primary" %}}
Direct queries of the state store are not governed by Dapr concurrency control, since you are not calling through the Dapr runtime. What you see are snapshots of committed data which are acceptable for read-only queries across multiple actors, however writes should be done via the Dapr state management or actors APIs.
Since you aren't calling through the Dapr runtime, direct queries of the state store are not governed by Dapr concurrency control. What you see are snapshots of committed data acceptable for read-only queries across multiple actors. Writes should be done via the Dapr state management or actors APIs.
{{% /alert %}}
##### Querying actor state
If the data store supports SQL queries, you can query an actor's state using SQL queries. For example use:
If the data store supports SQL queries, you can query an actor's state using SQL queries. For example:
```sql
SELECT * FROM StateTable WHERE Id='<app-id>||<actor-type>||<actor-id>||<key>'
```
You can also perform aggregate queries across actor instances, avoiding the common turn-based concurrency limitations of actor frameworks. For example, to calculate the average temperature of all thermometer actors, use:
You can also avoid the common turn-based concurrency limitations of actor frameworks by performing aggregate queries across actor instances. For example, to calculate the average temperature of all thermometer actors, use:
```sql
SELECT AVG(value) FROM StateTable WHERE Id LIKE '<app-id>||<thermometer>||*||temperature'
```
### State Time-to-Live (TTL)
Dapr enables per state set request time-to-live (TTL). This means that applications can set time-to-live per state stored, and these states cannot be retrieved after expiration.
Dapr enables [per state set request time-to-live (TTL)]({{< ref state-store-ttl.md >}}). This means that applications can set time-to-live per state stored, and these states cannot be retrieved after expiration.
### State management API
The state management API can be found in the [state management API reference]({{< ref state_api.md >}}) which describes how to retrieve, save, delete and query state values by providing keys.
The state management API can be found in the [state management API reference]({{< ref state_api.md >}}), which describes how to retrieve, save, delete, and query state values by providing keys.
## Try out state management
### Quickstarts and tutorials
Want to put the Dapr state management API to the test? Walk through the following quickstart and tutorials to see state management in action:
| Quickstart/tutorial | Description |
| ------------------- | ----------- |
| [State management quickstart]({{< ref statemanagement-quickstart.md >}}) | Create stateful applications using the state management API. |
| [Hello World](https://github.com/dapr/quickstarts/tree/master/tutorials/hello-world) | _Recommended_ <br> Demonstrates how to run Dapr locally. Highlights service invocation and state management. |
| [Hello World Kubernetes](https://github.com/dapr/quickstarts/tree/master/tutorials/hello-kubernetes) | _Recommended_ <br> Demonstrates how to run Dapr in Kubernetes. Highlights service invocation and _state management_. |
### Start using state management directly in your app
Want to skip the quickstarts? Not a problem. You can try out the state management building block directly in your application. After [Dapr is installed]({{< ref "getting-started/_index.md" >}}), you can begin using the state management API starting with [the state management how-to guide]({{< ref howto-get-save-state.md >}}).
## Next steps
* Follow these guides on:
* [How-To: Save and get state]({{< ref howto-get-save-state.md >}})
* [How-To: Build a stateful service]({{< ref howto-stateful-service.md >}})
* [How-To: Share state between applications]({{< ref howto-share-state.md >}})
* [How-To: Query state]({{< ref howto-state-query-api.md >}})
* [How-To: Encrypt application state]({{< ref howto-encrypt-state.md >}})
* [State Time-to-Live]({{< ref state-store-ttl.md >}})
* Try out the [hello world quickstart](https://github.com/dapr/quickstarts/blob/master/tutorials/hello-world/README.md) which shows how to use state management or try the samples in the [Dapr SDKs]({{< ref sdks >}})
* List of [state store components]({{< ref supported-state-stores.md >}})
* Read the [state management API reference]({{< ref state_api.md >}})
* Read the [actors API reference]({{< ref actors_api.md >}})
- Start working through the state management how-to guides, starting with:
- [How-To: Save and get state]({{< ref howto-get-save-state.md >}})
- [How-To: Build a stateful service]({{< ref howto-stateful-service.md >}})
- Review the list of [state store components]({{< ref supported-state-stores.md >}})
- Read the [state management API reference]({{< ref state_api.md >}})
- Read the [actors API reference]({{< ref actors_api.md >}})

View File

@ -1,23 +1,20 @@
---
type: docs
title: "How-To: Set state Time-to-Live (TTL)"
linkTitle: "How-To: Set state TTL"
title: "State Time-to-Live (TTL)"
linkTitle: "State TTL"
weight: 500
description: "Manage state with time-to-live."
description: "Manage state with TTL."
---
## Introduction
Dapr enables per state set request time-to-live (TTL). This means that applications can set time-to-live per state stored, and these states cannot be retrieved after expiration.
Only a subset of Dapr [state store components]({{< ref supported-state-stores >}}) are compatible with state TTL. For supported state stores simply set the `ttlInSeconds` metadata when publishing a message. Other state stores will ignore this value.
Some state stores can specify a default expiration on a per-table/container basis. Please refer to the official documentation of these state stores to utilize this feature of desired. Dapr support per-state TTLs for supported state stores.
For [supported state stores]({{< ref supported-state-stores >}}), you simply set the `ttlInSeconds` metadata when publishing a message. Other state stores will ignore this value. For some state stores, you can specify a default expiration on a per-table/container basis.
## Native state TTL support
When state time-to-live has native support in the state store component, Dapr simply forwards the time-to-live configuration without adding any extra logic, keeping predictable behavior. This is helpful when the expired state is handled differently by the component.
When a TTL is not specified the default behavior of the state store is retained.
When state TTL has native support in the state store component, Dapr forwards the TTL configuration without adding any extra logic, maintaining predictable behavior. This is helpful when the expired state is handled differently by the component.
When a TTL is not specified, the default behavior of the state store is retained.
## Persisting state (ignoring an existing TTL)
@ -25,11 +22,11 @@ To explicitly persist a state (ignoring any TTLs set for the key), specify a `tt
## Supported components
Please refer to the TTL column in the tables at [state store components]({{< ref supported-state-stores >}}).
Refer to the TTL column in the [state store components guide]({{< ref supported-state-stores >}}).
## Example
State TTL can be set in the metadata as part of the state store set request:
You can set state TTL in the metadata as part of the state store set request:
{{< tabs Python "HTTP API (Bash)" "HTTP API (PowerShell)">}}
@ -51,7 +48,7 @@ with DaprClient() as client:
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
To launch a Dapr sidecar and run the above example application, you'd then run a command similar to the following:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 -- python3 OrderProcessingService.py
@ -77,10 +74,9 @@ Invoke-RestMethod -Method Post -ContentType 'application/json' -Body '[{"key": "
{{< /tabs >}}
See [this guide]({{< ref state_api.md >}}) for a reference on the state API.
## Related links
- Learn [how to use key value pairs to persist a state]({{< ref howto-get-save-state.md >}})
- List of [state store components]({{< ref supported-state-stores >}})
- Read the [API reference]({{< ref state_api.md >}})
- See [the state API reference guide]({{< ref state_api.md >}}).
- Learn [how to use key value pairs to persist a state]({{< ref howto-get-save-state.md >}}).
- List of [state store components]({{< ref supported-state-stores >}}).
- Read the [API reference]({{< ref state_api.md >}}).

View File

@ -49,6 +49,8 @@ Install the latest windows Dapr cli to `C:\dapr` and add this directory to the U
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
```
**Note:** Updates to PATH might not be visible until you restart your terminal application.
#### Install without administrative rights
If you do not have admin rights, you can install Dapr to an alternate directory via the `DAPR_INSTALL_DIR` environment variable. The script below creates the directory if it does not exist.

View File

@ -22,12 +22,12 @@ Hit the ground running with our Dapr quickstarts, complete with code samples aim
| Quickstarts | Description |
| ----------- | ----------- |
| [Service Invocation]({{< ref serviceinvocation-quickstart.md >}}) | Call a method on another service using the service invocation API. |
| [State Management]({{< ref statemanagement-quickstart.md >}}) | Create stateful applications using the state management API. |
| [Publish and Subscribe]({{< ref pubsub-quickstart.md >}}) | Send and receive messages using the publish and subscribe API. |
| [Secrets Management]({{< ref secrets-quickstart.md >}}) | Retrieve secrets in the application code from a configured secret store using the secrets management API. |
| Bindings | Coming soon. |
| Actors | Coming soon. |
| Observability | Coming soon. |
| Configuration | Coming soon. |
| [Publish and Subscribe]({{< ref pubsub-quickstart.md >}}) | Asynchronous communication between two services using messaging. |
| [Service Invocation]({{< ref serviceinvocation-quickstart.md >}}) | Asynchronous communication between two services using HTTP. |
| [State Management]({{< ref statemanagement-quickstart.md >}}) | Store a service's data as key/value pairs in supported state stores. |
| [Bindings]({{< ref bindings-quickstart.md >}}) | Work with external systems using input bindings to respond to events and output bindings to call operations. |
| [Secrets Management]({{< ref secrets-quickstart.md >}}) | Securely fetch secrets. |
| Actors | Coming soon. |
| Observability | Coming soon. |
| Configuration | Coming soon. |
| Distributed Lock | Coming soon. |

File diff suppressed because it is too large Load Diff

View File

@ -508,7 +508,7 @@ For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 11 (or greater):
- [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or
- [OpenJDK](https://jdk.java.net/13/)
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)

View File

@ -2,7 +2,7 @@
type: docs
title: "Quickstart: Secrets Management"
linkTitle: "Secrets Management"
weight: 74
weight: 75
description: "Get started with Dapr's Secrets Management building block"
---
@ -352,7 +352,7 @@ For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 11 (or greater):
- [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or
- [OpenJDK](https://jdk.java.net/13/)
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)

View File

@ -388,7 +388,7 @@ For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 11 (or greater):
- [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or
- [OpenJDK](https://jdk.java.net/13/)
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)

View File

@ -386,7 +386,7 @@ For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- Java JDK 11 (or greater):
- [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or
- [OpenJDK](https://jdk.java.net/13/)
- OpenJDK
- [Apache Maven](https://maven.apache.org/install.html), version 3.x.
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)

View File

@ -51,14 +51,6 @@ az aks create --resource-group [your_resource_group] --name [your_aks_cluster_na
az aks get-credentials -n [your_aks_cluster_name] -g [your_resource_group]
```
## (optional) Install Helm v3
## Next steps
1. [Install Helm v3 client](https://helm.sh/docs/intro/install/)
> **Note:** The latest Dapr helm chart no longer supports Helm v2. Please migrate from helm v2 to helm v3 by following [this guide](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/).
2. In case you need permissions the kubernetes dashboard (i.e. configmaps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list configmaps in the namespace "default", etc.) execute this command
```bash
kubectl create clusterrolebinding kubernetes-dashboard -n kube-system --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard
```
{{< button text="Install Dapr using the AKS Dapr extension >>" page="azure-kubernetes-service-extension" >}}

View File

@ -99,7 +99,7 @@ OPTIONS http://localhost:<appPort>/<name>
Code | Description
---- | -----------
404 | Application does not want to bind to the binding
all others | Application wants to bind to the binding
2xx or 405 | Application wants to bind to the binding
#### URL Parameters

View File

@ -82,6 +82,16 @@ Field | Description
> **ETag format:** Dapr runtime treats ETags as opaque strings. The exact ETag format is defined by the corresponding data store.
#### Metadata
Metadata can be sent via query parameters in the request's URL. It must be prefixed with `metadata.`, as shown below.
Parameter | Description
--------- | -----------
`metadata.ttlInSeconds` | The number of seconds for the message to expire, as [described here]({{< ref state-store-ttl.md >}})
> **TTL:** Only certain state stores support the TTL option, according the [supported state stores]({{< ref supported-state-stores.md >}}).
### HTTP Response
#### Response Codes

View File

@ -51,14 +51,20 @@ spec:
|--------------------|:--------:|------------|-----|---------|
| topics | N | Input | A comma-separated string of topics. | `"mytopic1,topic2"` |
| brokers | Y | Input/Output | A comma-separated string of Kafka brokers. | `"localhost:9092,dapr-kafka.myapp.svc.cluster.local:9093"` |
| clientID | N | Input/Output | A user-provided string sent with every request to the Kafka brokers for logging, debugging, and auditing purposes. | `"my-dapr-app"` |
| consumerGroup | N | Input | A kafka consumer group to listen on. Each record published to a topic is delivered to one consumer within each consumer group subscribed to the topic. | `"group1"` |
| consumeRetryEnabled | N | Input/Output | Enable consume retry by setting to `"true"`. Default to `false` in Kafka binding component. | `"true"`, `"false"` |
| publishTopic | Y | Output | The topic to publish to. | `"mytopic"` |
| authRequired | Y | Input/Output | Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"` |
| authRequired | N | *Deprecated* | Enable [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication with the Kafka brokers. | `"true"`, `"false"` |
| 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!"` |
| 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` |
| version | N | Input/Output | Kafka cluster version. Defaults to 1.0.0 | `1.0.0`
| 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" |
| oidcClientID | N | Input/Output | The OAuth2 client ID that has been provisioned in the identity provider. Required when `authType` is set to `oidc` | `dapr-kafka` |
| oidcClientSecret | N | Input/Output | The OAuth2 client secret that has been provisioned in the identity provider: Required when `authType` is set to `oidc` | `"KeFg23!"` |
| oidcScopes | N | Input/Output | Comma-delimited list of OAuth2/OIDC scopes to request with the access token. Recommended when `authType` is set to `oidc`. Defaults to `"openid"` | `"openid,kafka-prod"` |
## Binding support
@ -68,6 +74,10 @@ This component supports **output binding** with the following operations:
- `create`
## Authentication
Kafka supports a variety of authentication schemes and Dapr supports several: SASL password, mTLS, OIDC/OAuth2. [Learn more about Kafka's authentication method for both the Kafka binding and Kafka pub/sub components]({{< ref "setup-apache-kafka.md#authentication" >}}).
## Specifying a partition key
When invoking the Kafka binding, its possible to provide an optional partition key by using the `metadata` section in the request body.

View File

@ -38,7 +38,7 @@ spec:
value: false
- name: maxPriority
value: 5
- name: contentType
- name: contentType
value: "text/plain"
```

View File

@ -35,6 +35,8 @@ spec:
secretKeyRef:
name: kafka-secrets
key: saslPasswordSecret
- name: saslMechanism
value: "SHA-512"
- name: maxMessageBytes # Optional.
value: 1024
- name: consumeRetryInterval # Optional.
@ -56,20 +58,21 @@ spec:
| authType | Y | Configure or disable authentication. Supported values: `none`, `password`, `mtls`, or `oidc` | `"password"`, `"none"`
| saslUsername | N | The SASL username used for authentication. Only required if `authType` is set to `"password"`. | `"adminuser"`
| saslPassword | N | The SASL password used for authentication. Can be `secretKeyRef` to use a [secret reference]({{< ref component-secrets.md >}}). Only required if `authType is set to `"password"`. | `""`, `"KeFg23!"`
| saslMechanism | N | The SASL Authentication Mechanism you wish to use. Only required if `authType` is set to `"password"`. Defaults to `PLAINTEXT` | `"SHA-512", "SHA-256", "PLAINTEXT"`
| initialOffset | N | The initial offset to use if no offset was previously committed. Should be "newest" or "oldest". Defaults to "newest". | `"oldest"`
| maxMessageBytes | N | The maximum size in bytes allowed for a single Kafka message. Defaults to 1024. | `2048`
| consumeRetryInterval | N | The interval between retries when attempting to consume topics. Treats numbers without suffix as milliseconds. Defaults to 100ms. | `200ms`
| version | N | Kafka cluster version. Defaults to 2.0.0.0 | `0.10.2.0`
| consumeRetryInterval | N | The interval between retries when attempting to consume topics. Treats numbers without suffix as milliseconds. Defaults to 100ms. | `200ms` |
| consumeRetryEnabled | N | Disable consume retry by setting `"false"` | `"true"`, `"false"` |
| version | N | Kafka cluster version. Defaults to 2.0.0.0 | `0.10.2.0` |
| caCert | N | Certificate authority certificate, required for using TLS. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN CERTIFICATE-----\n<base64-encoded DER>\n-----END CERTIFICATE-----"`
| clientCert | N | Client certificate, required for `authType` `mtls`. Can be `secretKeyRef` to use a secret reference | `"-----BEGIN CERTIFICATE-----\n<base64-encoded DER>\n-----END CERTIFICATE-----"`
| clientKey | N | Client key, required for `authType` `mtls` Can be `secretKeyRef` to use a secret reference | `"-----BEGIN RSA PRIVATE KEY-----\n<base64-encoded PKCS8>\n-----END RSA PRIVATE KEY-----"`
| skipVerify | N | Skip TLS verification, this is not recommended for use in production. Defaults to `"false"` | `"true"`, `"false"` |
| disableTls | N | Disable TLS for transport security. This is not recommended for use in production. Defaults to `"false"` | `"true"`, `"false"` |
| disableTls | N | Disable TLS for transport security. To disable, you're not required to set value to `"true"`. This is not recommended for use in production. Defaults to `"false"`. | `"true"`, `"false"` |
| oidcTokenEndpoint | N | Full URL to an OAuth2 identity provider access token endpoint. Required when `authType` is set to `oidc` | "https://identity.example.com/v1/token" |
| oidcClientID | N | The OAuth2 client ID that has been provisioned in the identity provider. Required when `authType is set to `oidc` | `dapr-kafka` |
| oidcClientID | N | The OAuth2 client ID that has been provisioned in the identity provider. Required when `authType` is set to `oidc` | `dapr-kafka` |
| oidcClientSecret | N | The OAuth2 client secret that has been provisioned in the identity provider: Required when `authType` is set to `oidc` | `"KeFg23!"` |
| oidcScopes | N | Comma-delimited list of OAuth2/OIDC scopes to request with the access token. Recommended when `authType` is set to `oidc`. Defaults to `"openid"` | '"openid,kafka-prod"` |
| oidcScopes | N | Comma-delimited list of OAuth2/OIDC scopes to request with the access token. Recommended when `authType` is set to `oidc`. Defaults to `"openid"` | `"openid,kafka-prod"` |
The `secretKeyRef` above is referencing a [kubernetes secrets store]({{< ref kubernetes-secret-store.md >}}) to access the tls information. Visit [here]({{< ref setup-secret-store.md >}}) to learn more about how to configure a secret store component.
@ -113,8 +116,7 @@ spec:
#### SASL Password
Setting `authType` to `password` enables [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication using the **PLAIN** mechanism. This requires setting
the `saslUsername` and `saslPassword` fields.
Setting `authType` to `password` enables [SASL](https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer) authentication. This requires setting the `saslUsername` and `saslPassword` fields.
```yaml
apiVersion: dapr.io/v1alpha1
@ -140,6 +142,8 @@ spec:
secretKeyRef:
name: kafka-secrets
key: saslPasswordSecret
- name: saslMechanism
value: "SHA-512"
- name: maxMessageBytes # Optional.
value: 1024
- name: consumeRetryInterval # Optional.
@ -198,12 +202,15 @@ spec:
#### OAuth2 or OpenID Connect
Setting `authType` to `oidc` enables SASL authentication via the **OAUTHBEARER** mechanism. This supports specifying a bearer
token from an external OAuth2 or [OIDC](https://en.wikipedia.org/wiki/OpenID) identity provider. Currenly only the **client_credentials** grant is supported. Configure `oidcTokenEndpoint` to
the full URL for the identity provider access token endpoint. Set `oidcClientID` and `oidcClientSecret` to the client credentials provisioned in the identity provider. If `caCert`
is specified in the component configuration, the certificate is appended to the system CA trust for verifying the identity provider certificate. Similarly, if `skipVerify`
is specified in the component configuration, verification will also be skipped when accessing the identity provider. By default, the only scope requested for the token is `openid`; it is **highly** recommended
that additional scopes be specified via `oidcScopes` in a comma-separated list and validated by the Kafka broker. If additional scopes are not used to narrow the validity of the access token,
Setting `authType` to `oidc` enables SASL authentication via the **OAUTHBEARER** mechanism. This supports specifying a bearer token from an external OAuth2 or [OIDC](https://en.wikipedia.org/wiki/OpenID) identity provider. Currently, only the **client_credentials** grant is supported.
Configure `oidcTokenEndpoint` to the full URL for the identity provider access token endpoint.
Set `oidcClientID` and `oidcClientSecret` to the client credentials provisioned in the identity provider.
If `caCert` is specified in the component configuration, the certificate is appended to the system CA trust for verifying the identity provider certificate. Similarly, if `skipVerify` is specified in the component configuration, verification will also be skipped when accessing the identity provider.
By default, the only scope requested for the token is `openid`; it is **highly** recommended that additional scopes be specified via `oidcScopes` in a comma-separated list and validated by the Kafka broker. If additional scopes are not used to narrow the validity of the access token,
a compromised Kafka broker could replay the token to access other services as the Dapr clientID.
```yaml

View File

@ -79,11 +79,17 @@ Install NATS JetStream on Kubernetes by using the [helm](https://github.com/nats
```bash
helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm install my-nats nats/nats
helm install --set nats.jetstream.enabled=true my-nats nats/nats
```
This installs a single NATS server into the `default` namespace. To interact
with NATS, find the service with: `kubectl get svc my-nats`.
This installs a single NATS server into the `default` namespace. To interact with NATS, find the service with:
```bash
kubectl get svc my-nats
```
For more information on helm chart settings, see the [Helm chart documentation](https://helm.sh/docs/helm/helm_install/).
{{% /codetab %}}
{{< /tabs >}}

View File

@ -190,7 +190,7 @@ First, download the code of the stored procedures for the version of Dapr that y
```sh
# Set this to the version of Dapr that you're using
DAPR_VERSION="v1.7.0"
DAPR_VERSION="release-{{% dapr-latest-version short="true" %}}"
curl -LfO "https://raw.githubusercontent.com/dapr/components-contrib/${DAPR_VERSION}/state/azure/cosmosdb/storedprocedures/__daprver__.js"
curl -LfO "https://raw.githubusercontent.com/dapr/components-contrib/${DAPR_VERSION}/state/azure/cosmosdb/storedprocedures/__dapr_v2__.js"
```

View File

@ -1,16 +1,16 @@
<p>Table captions:</p>
<blockquote>
<p><code>Status</code>: <a href="http://localhost:1313/operations/components/certification-lifecycle/">Component
<p><code>Status</code>: <a href="/operations/components/certification-lifecycle/">Component
certification</a> status</p>
</blockquote>
<ul>
<li><a href="http://localhost:1313/operations/components/certification-lifecycle/#alpha">Alpha</a></li>
<li><a href="http://localhost:1313/operations/components/certification-lifecycle/#beta">Beta</a></li>
<li><a href="http://localhost:1313/operations/components/certification-lifecycle/#stable">Stable</a></li>
<li><a href="/operations/components/certification-lifecycle/#alpha">Alpha</a></li>
<li><a href="/operations/components/certification-lifecycle/#beta">Beta</a></li>
<li><a href="/operations/components/certification-lifecycle/#stable">Stable</a></li>
</ul>
<blockquote>
<p><code>Since</code>: defines from which Dapr Runtime version, the component is in the current status</p>
</blockquote>
<blockquote>
<p><code>Component version</code>: defines the version of the component</p>
</blockquote>
</blockquote>

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB