mirror of https://github.com/dapr/docs.git
Merge branch 'v1.11' into issue_3216
This commit is contained in:
commit
eb863609c6
|
@ -27,7 +27,7 @@ The following are the building blocks provided by Dapr:
|
|||
| [**Actors**]({{< ref "actors-overview.md" >}}) | `/v1.0/actors` | An actor is an isolated, independent unit of compute and state with single-threaded execution. Dapr provides an actor implementation based on the virtual actor pattern which provides a single-threaded programming model and where actors are garbage collected when not in use.
|
||||
| [**Observability**]({{< ref "observability-concept.md" >}}) | `N/A` | Dapr system components and runtime emit metrics, logs, and traces to debug, operate and monitor Dapr system services, components and user applications.
|
||||
| [**Secrets**]({{< ref "secrets-overview.md" >}}) | `/v1.0/secrets` | Dapr provides a secrets building block API and integrates with secret stores such as public cloud stores, local stores and Kubernetes to store the secrets. Services can call the secrets API to retrieve secrets, for example to get a connection string to a database.
|
||||
| [**Configuration**]({{< ref "configuration-api-overview.md" >}}) | `/v1.0-alpha1/configuration` | The Configuration API enables you to retrieve and subscribe to application configuration items for supported configuration stores. This enables an application to retrieve specific configuration information, for example, at start up or when configuration changes are made in the store.
|
||||
| [**Configuration**]({{< ref "configuration-api-overview.md" >}}) | `/v1.0/configuration` | The Configuration API enables you to retrieve and subscribe to application configuration items for supported configuration stores. This enables an application to retrieve specific configuration information, for example, at start up or when configuration changes are made in the store.
|
||||
| [**Distributed lock**]({{< ref "distributed-lock-api-overview.md" >}}) | `/v1.0-alpha1/lock` | The distributed lock API enables you to take a lock on a resource so that multiple instances of an application can access the resource without conflicts and provide consistency guarantees.
|
||||
| [**Workflows**]({{< ref "workflow-overview.md" >}}) | `/v1.0-alpha1/workflow` | The Workflow API enables you to define long running, persistent processes or data flows that span multiple microservices using Dapr workflows or workflow components. The Workflow API can be combined with other Dapr API building blocks. For example, a workflow can call another service with service invocation or retrieve secrets, providing flexibility and portability.
|
||||
| [**Cryptography**]({{< ref "cryptography-overview.md" >}}) | `/v1.0-alpha1/crypto` | The Cryptography API enables you to perform cryptographic operations, such as encrypting and decrypting messages, without exposing keys to your application.
|
|
@ -90,15 +90,6 @@ The Dapr actor runtime provides a simple turn-based access model for accessing a
|
|||
|
||||
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.
|
||||
|
||||
#### Time to Live (TTL) on state
|
||||
You should always set the TTL metadata field (`ttlInSeconds`), or the equivalent API call in your chosen SDK when saving actor state to ensure that state eventually removed. Read [actors overview]({{< ref actors-overview.md >}}) for more information.
|
||||
|
||||
#### Demo
|
||||
|
||||
Watch this video for a demo on [Actor State TTL](https://youtu.be/kVpQYkGemRc?t=20) from the Dapr Community Call #80:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/kVpQYkGemRc?start=20" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
### Actor timers and reminders
|
||||
|
||||
Actors can schedule periodic work on themselves by registering either timers or reminders.
|
||||
|
|
|
@ -40,6 +40,11 @@ Want to put the Dapr configuration API to the test? Walk through the following q
|
|||
|
||||
Want to skip the quickstarts? Not a problem. You can try out the configuration building block directly in your application to read and manage configuration data. After [Dapr is installed]({{< ref "getting-started/_index.md" >}}), you can begin using the configuration API starting with [the configuration how-to guide]({{< ref howto-manage-configuration.md >}}).
|
||||
|
||||
## Watch the demo
|
||||
|
||||
Watch [this demo of using the Dapr Configuration building block](https://youtu.be/tNq-n1XQuLA?t=496)
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/tNq-n1XQuLA?start=496" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
## Next steps
|
||||
Follow these guides on:
|
||||
|
|
|
@ -67,9 +67,11 @@ spec:
|
|||
```
|
||||
|
||||
## Retrieve Configuration Items
|
||||
### Get configuration items using Dapr SDKs
|
||||
### Get configuration items
|
||||
|
||||
{{< tabs ".NET" Java Python>}}
|
||||
The following example shows how to get a saved configuration item using the Dapr Configuration API.
|
||||
|
||||
{{< tabs ".NET" Java Python Go Javascript "HTTP API (BASH)" "HTTP API (Powershell)">}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
|
@ -87,7 +89,6 @@ namespace ConfigurationApi
|
|||
{
|
||||
private static readonly string CONFIG_STORE_NAME = "configstore";
|
||||
|
||||
[Obsolete]
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
@ -105,7 +106,7 @@ namespace ConfigurationApi
|
|||
```java
|
||||
//dependencies
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprPreviewClient;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.client.domain.GetConfigurationRequest;
|
||||
import io.dapr.client.domain.SubscribeConfigurationRequest;
|
||||
|
@ -116,7 +117,7 @@ import reactor.core.publisher.Mono;
|
|||
private static final String CONFIG_STORE_NAME = "configstore";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (DaprPreviewClient client = (new DaprClientBuilder()).buildPreviewClient()) {
|
||||
try (DaprClient client = (new DaprClientBuilder()).build()) {
|
||||
List<String> keys = new ArrayList<>();
|
||||
keys.add("orderId1");
|
||||
keys.add("orderId2");
|
||||
|
@ -150,79 +151,31 @@ with DaprClient() as d:
|
|||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
### Get configuration items using gRPC API
|
||||
|
||||
Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto). The following examples show Java, C#, Python and Javascript clients.
|
||||
|
||||
{{< tabs Java Dotnet Python Javascript >}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```java
|
||||
```go
|
||||
package main
|
||||
|
||||
Dapr.ServiceBlockingStub stub = Dapr.newBlockingStub(channel);
|
||||
stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} });
|
||||
```
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
{{% /codetab %}}
|
||||
dapr "github.com/dapr/go-sdk/client"
|
||||
)
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```csharp
|
||||
|
||||
var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} });
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```python
|
||||
response = stub.GetConfigurationAlpha1(request={ StoreName: 'redisconfigstore', Keys = ['myconfig'] })
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```javascript
|
||||
client.GetConfigurationAlpha1({ StoreName: 'redisconfigstore', Keys = ['myconfig'] })
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
### Watch configuration items using Dapr SDKs
|
||||
|
||||
{{< tabs "Dotnet Extension" "Dotnet Client">}}
|
||||
{{% codetab %}}
|
||||
|
||||
```csharp
|
||||
[Obsolete("Configuration API is an Alpha API. Obsolete will be removed when the API is no longer Alpha")]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
return Host.CreateDefaultBuilder(args)
|
||||
.ConfigureAppConfiguration(config =>
|
||||
{
|
||||
// Get the initial value from the configuration component.
|
||||
config.AddDaprConfigurationStore("redisconfig", new List<string>() { "withdrawVersion" }, client, TimeSpan.FromSeconds(20));
|
||||
|
||||
// Watch the keys in the configuration component and update it in local configurations.
|
||||
config.AddStreamingDaprConfigurationStore("redisconfig", new List<string>() { "withdrawVersion", "source" }, client, TimeSpan.FromSeconds(20));
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
client, err := dapr.NewClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
items, err := client.GetConfigurationItems(ctx, "configstore", ["orderId1","orderId2"])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for key, item := range items {
|
||||
fmt.Printf("get config: key = %s value = %s version = %s",key,(*item).Value, (*item).Version)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -230,106 +183,502 @@ public static IHostBuilder CreateHostBuilder(string[] args)
|
|||
|
||||
{{% codetab %}}
|
||||
|
||||
```js
|
||||
import { CommunicationProtocolEnum, DaprClient } from "@dapr/dapr";
|
||||
|
||||
// JS SDK does not support Configuration API over HTTP protocol yet
|
||||
const protocol = CommunicationProtocolEnum.GRPC;
|
||||
const host = process.env.DAPR_HOST ?? "localhost";
|
||||
const port = process.env.DAPR_GRPC_PORT ?? 3500;
|
||||
|
||||
const DAPR_CONFIGURATION_STORE = "configstore";
|
||||
const CONFIGURATION_ITEMS = ["orderId1", "orderId2"];
|
||||
|
||||
async function main() {
|
||||
const client = new DaprClient(host, port, protocol);
|
||||
// Get config items from the config store
|
||||
try {
|
||||
const config = await client.configuration.get(DAPR_CONFIGURATION_STORE, CONFIGURATION_ITEMS);
|
||||
Object.keys(config.items).forEach((key) => {
|
||||
console.log("Configuration for " + key + ":", JSON.stringify(config.items[key]));
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("Could not get config item, err:" + error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => console.error(e));
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
Launch a dapr sidecar:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing --dapr-http-port 3601
|
||||
```
|
||||
|
||||
In a separate terminal, get the configuration item saved earlier:
|
||||
|
||||
```bash
|
||||
curl http://localhost:3601/v1.0/configuration/configstore?key=orderId1
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
Launch a Dapr sidecar:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing --dapr-http-port 3601
|
||||
```
|
||||
|
||||
In a separate terminal, get the configuration item saved earlier:
|
||||
|
||||
```powershell
|
||||
Invoke-RestMethod -Uri 'http://localhost:3601/v1.0/configuration/configstore?key=orderId1'
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
### Subscribe to configuration item updates
|
||||
|
||||
Below are code examples that leverage SDKs to subscribe to keys `[orderId1, orderId2]` using `configstore` store component.
|
||||
|
||||
{{< tabs ".NET" "ASP.NET Core" Java Python Go Javascript>}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```csharp
|
||||
public IDictionary<string, string> Data { get; set; } = new Dictionary<string, string>();
|
||||
public string Id { get; set; } = string.Empty;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Dapr.Client;
|
||||
|
||||
public async Task WatchConfiguration(DaprClient daprClient, string store, IReadOnlyList<string> keys, Dictionary<string, string> metadata, CancellationToken token = default)
|
||||
const string DAPR_CONFIGURATION_STORE = "configstore";
|
||||
var CONFIGURATION_KEYS = new List<string> { "orderId1", "orderId2" };
|
||||
var client = new DaprClientBuilder().Build();
|
||||
|
||||
// Subscribe for configuration changes
|
||||
SubscribeConfigurationResponse subscribe = await client.SubscribeConfiguration(DAPR_CONFIGURATION_STORE, CONFIGURATION_ITEMS);
|
||||
|
||||
// Print configuration changes
|
||||
await foreach (var items in subscribe.Source)
|
||||
{
|
||||
// Initialize the gRPC Stream that will provide configuration updates.
|
||||
var subscribeConfigurationResponse = await daprClient.SubscribeConfiguration(store, keys, metadata, token);
|
||||
// First invocation when app subscribes to config changes only returns subscription id
|
||||
if (items.Keys.Count == 0)
|
||||
{
|
||||
Console.WriteLine("App subscribed to config changes with subscription id: " + subscribe.Id);
|
||||
subscriptionId = subscribe.Id;
|
||||
continue;
|
||||
}
|
||||
var cfg = System.Text.Json.JsonSerializer.Serialize(items);
|
||||
Console.WriteLine("Configuration update " + cfg);
|
||||
}
|
||||
```
|
||||
|
||||
// The response contains a data source which is an IAsyncEnumerable, so it can be iterated through via an awaited foreach.
|
||||
await foreach (var items in subscribeConfigurationResponse.Source.WithCancellation(token))
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing -- dotnet run
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Dapr.Client;
|
||||
using Dapr.Extensions.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace ConfigurationApi
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// Each iteration from the stream can contain all the keys that were queried for, so it must be individually iterated through.
|
||||
var data = new Dictionary<string, string>(Data);
|
||||
foreach (var item in items)
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// The Id in the response is used to unsubscribe.
|
||||
Id = subscribeConfigurationResponse.Id;
|
||||
data[item.Key] = item.Value;
|
||||
Console.WriteLine("Starting application.");
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
Console.WriteLine("Closing application.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates WebHost Builder.
|
||||
/// </summary>
|
||||
/// <param name="args">Arguments.</param>
|
||||
/// <returns>Returns IHostbuilder.</returns>
|
||||
public static IHostBuilder CreateHostBuilder(string[] args)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
return Host.CreateDefaultBuilder(args)
|
||||
.ConfigureAppConfiguration(config =>
|
||||
{
|
||||
// Get the initial value and continue to watch it for changes.
|
||||
config.AddDaprConfigurationStore("configstore", new List<string>() { "orderId1","orderId2" }, client, TimeSpan.FromSeconds(20));
|
||||
config.AddStreamingDaprConfigurationStore("configstore", new List<string>() { "orderId1","orderId2" }, client, TimeSpan.FromSeconds(20));
|
||||
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing -- dotnet run
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### Watch configuration items using gRPC API
|
||||
{{% codetab %}}
|
||||
|
||||
Create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) using your [preferred language](https://grpc.io/docs/languages/). Use the `SubscribeConfigurationAlpha1` proto method on your client stub to start subscribing to events. The method accepts the following request object:
|
||||
```java
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.client.domain.GetConfigurationRequest;
|
||||
import io.dapr.client.domain.SubscribeConfigurationRequest;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
```proto
|
||||
message SubscribeConfigurationRequest {
|
||||
// The name of configuration store.
|
||||
string store_name = 1;
|
||||
//code
|
||||
private static final String CONFIG_STORE_NAME = "configstore";
|
||||
private static String subscriptionId = null;
|
||||
|
||||
// Optional. The key of the configuration item to fetch.
|
||||
// If set, only query for the specified configuration items.
|
||||
// Empty list means fetch all.
|
||||
repeated string keys = 2;
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (DaprClient client = (new DaprClientBuilder()).build()) {
|
||||
// Subscribe for config changes
|
||||
List<String> keys = new ArrayList<>();
|
||||
keys.add("orderId1");
|
||||
keys.add("orderId2");
|
||||
Flux<SubscribeConfigurationResponse> subscription = client.subscribeConfiguration(DAPR_CONFIGURATON_STORE,keys);
|
||||
|
||||
// The metadata which will be sent to configuration store components.
|
||||
map<string,string> metadata = 3;
|
||||
// Read config changes for 20 seconds
|
||||
subscription.subscribe((response) -> {
|
||||
// First ever response contains the subscription id
|
||||
if (response.getItems() == null || response.getItems().isEmpty()) {
|
||||
subscriptionId = response.getSubscriptionId();
|
||||
System.out.println("App subscribed to config changes with subscription id: " + subscriptionId);
|
||||
} else {
|
||||
response.getItems().forEach((k, v) -> {
|
||||
System.out.println("Configuration update for " + k + ": {'value':'" + v.getValue() + "'}");
|
||||
});
|
||||
}
|
||||
});
|
||||
Thread.sleep(20000);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
Below are the examples in sdks:
|
||||
```bash
|
||||
dapr run --app-id orderprocessing -- -- mvn spring-boot:run
|
||||
|
||||
{{< tabs Python>}}
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```python
|
||||
#dependencies
|
||||
from dapr.clients import DaprClient
|
||||
#code
|
||||
|
||||
def handler(id: str, resp: ConfigurationResponse):
|
||||
for key in resp.items:
|
||||
print(f"Subscribed item received key={key} value={resp.items[key].value} "
|
||||
f"version={resp.items[key].version} "
|
||||
f"metadata={resp.items[key].metadata}", flush=True)
|
||||
|
||||
def executeConfiguration():
|
||||
with DaprClient() as d:
|
||||
storeName = 'configurationstore'
|
||||
keys = ['orderId1', 'orderId2']
|
||||
id = d.subscribe_configuration(store_name=storeName, keys=keys,
|
||||
handler=handler, config_metadata={})
|
||||
print("Subscription ID is", id, flush=True)
|
||||
sleep(20)
|
||||
|
||||
executeConfiguration()
|
||||
```
|
||||
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing -- python3 OrderProcessingService.py
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dapr "github.com/dapr/go-sdk/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
client, err := dapr.NewClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
subscribeID, err := client.SubscribeConfigurationItems(ctx, "configstore", []string{"orderId1", "orderId2"}, func(id string, items map[string]*dapr.ConfigurationItem) {
|
||||
for k, v := range items {
|
||||
fmt.Printf("get updated config key = %s, value = %s version = %s \n", k, v.Value, v.Version)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(20*time.Second)
|
||||
}
|
||||
```
|
||||
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing -- go run main.go
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
```js
|
||||
import { CommunicationProtocolEnum, DaprClient } from "@dapr/dapr";
|
||||
|
||||
// JS SDK does not support Configuration API over HTTP protocol yet
|
||||
const protocol = CommunicationProtocolEnum.GRPC;
|
||||
const host = process.env.DAPR_HOST ?? "localhost";
|
||||
const port = process.env.DAPR_GRPC_PORT ?? 3500;
|
||||
|
||||
const DAPR_CONFIGURATION_STORE = "configstore";
|
||||
const CONFIGURATION_ITEMS = ["orderId1", "orderId2"];
|
||||
|
||||
async function main() {
|
||||
const client = new DaprClient(host, port, protocol);
|
||||
// Subscribe to config updates
|
||||
try {
|
||||
const stream = await client.configuration.subscribeWithKeys(
|
||||
DAPR_CONFIGURATION_STORE,
|
||||
CONFIGURATION_ITEMS,
|
||||
(config) => {
|
||||
console.log("Configuration update", JSON.stringify(config.items));
|
||||
}
|
||||
);
|
||||
// Unsubscribe to config updates and exit app after 20 seconds
|
||||
setTimeout(() => {
|
||||
stream.stop();
|
||||
console.log("App unsubscribed to config changes");
|
||||
process.exit(0);
|
||||
}, 20000);
|
||||
} catch (error) {
|
||||
console.log("Error subscribing to config updates, err:" + error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
main().catch((e) => console.error(e));
|
||||
```
|
||||
|
||||
Navigate to the directory containing the above code, then run the following command to launch both a Dapr sidecar and the subscriber application:
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing --app-protocol grpc --dapr-grpc-port 3500 -- node index.js
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
### Unsubscribe from configuration item updates
|
||||
|
||||
After you've subscribed to watch configuration items, you will receive updates for all of the subscribed keys. To stop receiving updates, you need to explicitly call the unsubscribe API.
|
||||
|
||||
Following are the code examples showing how you can unsubscribe to configuration updates using unsubscribe API.
|
||||
|
||||
{{< tabs ".NET" Java Python Go Javascript "HTTP API (BASH)" "HTTP API (Powershell)">}}
|
||||
|
||||
{{% codetab %}}
|
||||
```csharp
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Dapr.Client;
|
||||
|
||||
const string DAPR_CONFIGURATION_STORE = "configstore";
|
||||
var client = new DaprClientBuilder().Build();
|
||||
|
||||
// Unsubscribe to config updates and exit the app
|
||||
async Task unsubscribe(string subscriptionId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await client.UnsubscribeConfiguration(DAPR_CONFIGURATION_STORE, subscriptionId);
|
||||
Console.WriteLine("App unsubscribed from config changes");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error unsubscribing from config updates: " + ex.Message);
|
||||
}
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```java
|
||||
import io.dapr.client.DaprClientBuilder;
|
||||
import io.dapr.client.DaprClient;
|
||||
import io.dapr.client.domain.ConfigurationItem;
|
||||
import io.dapr.client.domain.GetConfigurationRequest;
|
||||
import io.dapr.client.domain.SubscribeConfigurationRequest;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
//code
|
||||
private static final String CONFIG_STORE_NAME = "configstore";
|
||||
private static String subscriptionId = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (DaprClient client = (new DaprClientBuilder()).build()) {
|
||||
// Unsubscribe from config changes
|
||||
UnsubscribeConfigurationResponse unsubscribe = client
|
||||
.unsubscribeConfiguration(subscriptionId, DAPR_CONFIGURATON_STORE).block();
|
||||
if (unsubscribe.getIsUnsubscribed()) {
|
||||
System.out.println("App unsubscribed to config changes");
|
||||
} else {
|
||||
System.out.println("Error unsubscribing to config updates, err:" + unsubscribe.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error unsubscribing to config updates," + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```python
|
||||
#dependencies
|
||||
import asyncio
|
||||
import time
|
||||
import logging
|
||||
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())
|
||||
```
|
||||
subscriptionID = ""
|
||||
|
||||
```bash
|
||||
dapr run --app-id orderprocessing --resources-path components/ -- python3 OrderProcessingService.py
|
||||
with DaprClient() as d:
|
||||
isSuccess = d.unsubscribe_configuration(store_name='configstore', id=subscriptionID)
|
||||
print(f"Unsubscribed successfully? {isSuccess}", flush=True)
|
||||
```
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
{{% codetab %}}
|
||||
```go
|
||||
package main
|
||||
|
||||
#### Stop watching configuration items
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
After you've subscribed to watch configuration items, the gRPC-server stream starts. Since this stream thread does not close itself, you have to explicitly call the `UnSubscribeConfigurationRequest` API to unsubscribe. This method accepts the following request object:
|
||||
dapr "github.com/dapr/go-sdk/client"
|
||||
)
|
||||
|
||||
```proto
|
||||
// UnSubscribeConfigurationRequest is the message to stop watching the key-value configuration.
|
||||
message UnSubscribeConfigurationRequest {
|
||||
// The name of configuration store.
|
||||
string store_name = 1;
|
||||
// Optional. The keys of the configuration item to stop watching.
|
||||
// Store_name and keys should match previous SubscribeConfigurationRequest's keys and store_name.
|
||||
// Once invoked, the subscription that is watching update for the key-value event is stopped
|
||||
repeated string keys = 2;
|
||||
var DAPR_CONFIGURATION_STORE = "configstore"
|
||||
var subscriptionID = ""
|
||||
|
||||
func main() {
|
||||
client, err := dapr.NewClient()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := client.UnsubscribeConfigurationItems(ctx, DAPR_CONFIGURATION_STORE , subscriptionID); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
Using this unsubscribe method, you can stop watching configuration update events. Dapr locates the subscription stream based on the `store_name` and any optional keys supplied and closes it.
|
||||
{{% codetab %}}
|
||||
```js
|
||||
import { CommunicationProtocolEnum, DaprClient } from "@dapr/dapr";
|
||||
|
||||
// JS SDK does not support Configuration API over HTTP protocol yet
|
||||
const protocol = CommunicationProtocolEnum.GRPC;
|
||||
const host = process.env.DAPR_HOST ?? "localhost";
|
||||
const port = process.env.DAPR_GRPC_PORT ?? 3500;
|
||||
|
||||
const DAPR_CONFIGURATION_STORE = "configstore";
|
||||
const CONFIGURATION_ITEMS = ["orderId1", "orderId2"];
|
||||
|
||||
async function main() {
|
||||
const client = new DaprClient(host, port, protocol);
|
||||
|
||||
try {
|
||||
const stream = await client.configuration.subscribeWithKeys(
|
||||
DAPR_CONFIGURATION_STORE,
|
||||
CONFIGURATION_ITEMS,
|
||||
(config) => {
|
||||
console.log("Configuration update", JSON.stringify(config.items));
|
||||
}
|
||||
);
|
||||
setTimeout(() => {
|
||||
// Unsubscribe to config updates
|
||||
stream.stop();
|
||||
console.log("App unsubscribed to config changes");
|
||||
process.exit(0);
|
||||
}, 20000);
|
||||
} catch (error) {
|
||||
console.log("Error subscribing to config updates, err:" + error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => console.error(e));
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl 'http://localhost:<DAPR_HTTP_PORT>/v1.0/configuration/configstore/<subscription-id>/unsubscribe'
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```powershell
|
||||
Invoke-RestMethod -Uri 'http://localhost:<DAPR_HTTP_PORT>/v1.0/configuration/configstore/<subscription-id>/unsubscribe'
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
## Next steps
|
||||
|
||||
* Read [configuration API overview]({{< ref configuration-api-overview.md >}})
|
||||
* Read [configuration API overview]({{< ref configuration-api-overview.md >}})
|
||||
|
|
|
@ -16,17 +16,7 @@ In this tutorial, you will create a component definition file to interact with t
|
|||
|
||||
## Step 1: Create a JSON secret store
|
||||
|
||||
Dapr supports [many types of secret stores]({{< ref supported-secret-stores >}}), but for this tutorial, create a local JSON file named `mysecrets.json` with the following secret:
|
||||
|
||||
```json
|
||||
{
|
||||
"my-secret" : "I'm Batman"
|
||||
}
|
||||
```
|
||||
|
||||
## Step 2: Create a secret store Dapr component
|
||||
|
||||
1. Create a new directory named `my-components` to hold the new component file:
|
||||
1. Create a new directory named `my-components` to hold the new secret and component file:
|
||||
|
||||
```bash
|
||||
mkdir my-components
|
||||
|
@ -38,6 +28,16 @@ Dapr supports [many types of secret stores]({{< ref supported-secret-stores >}})
|
|||
cd my-components
|
||||
```
|
||||
|
||||
1. Dapr supports [many types of secret stores]({{< ref supported-secret-stores >}}), but for this tutorial, create a local JSON file named `mysecrets.json` with the following secret:
|
||||
|
||||
```json
|
||||
{
|
||||
"my-secret" : "I'm Batman"
|
||||
}
|
||||
```
|
||||
|
||||
## Step 2: Create a secret store Dapr component
|
||||
|
||||
1. Create a new file `localSecretStore.yaml` with the following contents:
|
||||
|
||||
```yaml
|
||||
|
@ -51,13 +51,13 @@ Dapr supports [many types of secret stores]({{< ref supported-secret-stores >}})
|
|||
version: v1
|
||||
metadata:
|
||||
- name: secretsFile
|
||||
value: <PATH TO SECRETS FILE>/mysecrets.json
|
||||
value: ./mysecrets.json
|
||||
- name: nestedSeparator
|
||||
value: ":"
|
||||
```
|
||||
|
||||
In the above file definition:
|
||||
- `type: secretstores.local.file` tells Dapr to use the local file component as a secret store.
|
||||
- `type: secretstores.local.file` tells Dapr to use the local file component as a secret store.
|
||||
- The metadata fields provide component-specific information needed to work with this component. In this case, the secret store JSON path is relative to where you call `dapr run`.
|
||||
|
||||
## Step 3: Run the Dapr sidecar
|
||||
|
@ -65,7 +65,7 @@ In the above file definition:
|
|||
Launch a Dapr sidecar that will listen on port 3500 for a blank application named `myapp`:
|
||||
|
||||
```bash
|
||||
dapr run --app-id myapp --dapr-http-port 3500 --resources-path ./my-components
|
||||
dapr run --app-id myapp --dapr-http-port 3500 --resources-path .
|
||||
```
|
||||
|
||||
{{% alert title="Tip" color="primary" %}}
|
||||
|
@ -104,4 +104,4 @@ Invoke-RestMethod -Uri 'http://localhost:3500/v1.0/secrets/my-secret-store/my-se
|
|||
{"my-secret":"I'm Batman"}
|
||||
```
|
||||
|
||||
{{< button text="Next step: Set up a Pub/sub broker >>" page="pubsub-quickstart" >}}
|
||||
{{< button text="Next step: Set up a Pub/sub broker >>" page="pubsub-quickstart" >}}
|
||||
|
|
|
@ -22,6 +22,7 @@ For CLI there is no explicit opt-in, just the version that this was first made a
|
|||
| **Workflows** | Author workflows as code to automate and orchestrate tasks within your application, like messaging, state management, and failure handling | N/A | [Workflows concept]({{< ref "components-concept#workflows" >}})| v1.10 |
|
||||
| **Cryptography** | Encrypt or decrypt data without having to manage secrets keys | N/A | [Cryptography concept]({{< ref "components-concept#cryptography" >}})| v1.11 |
|
||||
| **Service invocation for non-Dapr endpoints** | Allow the invocation of non-Dapr endpoints by Dapr using the [Service invocation API]({{< ref service_invocation_api.md >}}). Read ["How-To: Invoke Non-Dapr Endpoints using HTTP"]({{< ref howto-invoke-non-dapr-endpoints.md >}}) for more information. | N/A | [Service invocation API]({{< ref service_invocation_api.md >}}) | v1.11 |
|
||||
| **Actor State TTL** | Allow actors to save records to state stores with Time To Live (TTL) set to automatically clean up old data. In its current implementation, actor state with TTL may not be reflected correctly by clients, read [Actor State Transactions]({{< ref actors_api.md >}}) for more information. | `ActorStateTTL` | [Actor State Transactions]({{< ref actors_api.md >}}) | v1.11 |
|
||||
|
||||
### Streaming for HTTP service invocation
|
||||
|
||||
|
@ -44,7 +45,7 @@ Important notes:
|
|||
|
||||
- `ServiceInvocationStreaming` needs to be applied on caller sidecars only.
|
||||
In the example above, streams are used for HTTP service invocation if `ServiceInvocationStreaming` is applied to the configuration of "app A" and its Dapr sidecar, regardless of whether the feature flag is enabled for "app B" and its sidecar.
|
||||
- When `ServiceInvocationStreaming` is enabled, you should make sure that all services your app invokes using Dapr ("app B") are updated to Dapr 1.10, even if `ServiceInvocationStreaming` is not enabled for those sidecars.
|
||||
Invoking an app using Dapr 1.9 or older is still possible, but those calls may fail if you have applied a Dapr Resiliency policy with retries enabled.
|
||||
- When `ServiceInvocationStreaming` is enabled, you should make sure that all services your app invokes using Dapr ("app B") are updated to Dapr 1.10 or higher, even if `ServiceInvocationStreaming` is not enabled for those sidecars.
|
||||
Invoking an app using Dapr 1.9 or older is still possible, but those calls may fail unless you have applied a Dapr Resiliency policy with retries enabled.
|
||||
|
||||
> Full support for streaming for HTTP service invocation will be completed in a future Dapr version.
|
||||
|
|
|
@ -75,10 +75,15 @@ Persists the change to the state for an actor as a multi-item transaction.
|
|||
|
||||
***Note that this operation is dependant on a using state store component that supports multi-item transactions.***
|
||||
|
||||
When putting state, _always_ set the `ttlInSeconds` field in the
|
||||
metadata for each value, unless there is a state clean up process out of band of
|
||||
Dapr. Omitting this field will result in the underlying Actor state store to
|
||||
grow indefinitely.
|
||||
#### TTL
|
||||
|
||||
With the [`ActorStateTTL` feature enabled]]({{< ref
|
||||
"support-preview-features.md" >}}), actor clients can set the `ttlInSeconds`
|
||||
field in the transaction metadata to have the state expire after that many
|
||||
seconds. If the `ttlInSeconds` field is not set, the state will not expire.
|
||||
|
||||
Keep in mind when building actor applications with this feature enabled;
|
||||
Currently, all actor SDKs will preserve the actor state in their local cache even after the state has expired. This means that the actor state will not be removed from the local cache if the TTL has expired until the actor is restarted or deactivated. This behaviour will be changed in a future release.
|
||||
|
||||
See the Dapr Community Call 80 recording for more details on actor state TTL.
|
||||
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/kVpQYkGemRc?start=28" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
@ -109,6 +114,8 @@ Parameter | Description
|
|||
|
||||
#### Examples
|
||||
|
||||
> Note, the following example uses the `ttlInSeconds` field, which requires the [`ActorStateTTL` feature enabled]]({{< ref "support-preview-features.md" >}}).
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3500/v1.0/actors/stormtrooper/50/state \
|
||||
-H "Content-Type: application/json" \
|
||||
|
|
|
@ -13,7 +13,7 @@ This endpoint lets you get configuration from a store.
|
|||
### HTTP Request
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/<storename>
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/<storename>
|
||||
```
|
||||
|
||||
#### URL Parameters
|
||||
|
@ -29,13 +29,13 @@ If no query parameters are provided, all configuration items are returned.
|
|||
To specify the keys of the configuration items to get, use one or more `key` query parameters. For example:
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/mystore?key=config1&key=config2
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/mystore?key=config1&key=config2
|
||||
```
|
||||
|
||||
To retrieve all configuration items:
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/mystore
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/mystore
|
||||
```
|
||||
|
||||
#### Request Body
|
||||
|
@ -59,7 +59,7 @@ JSON-encoded value of key/value pairs for each configuration item.
|
|||
### Example
|
||||
|
||||
```shell
|
||||
curl -X GET 'http://localhost:3500/v1.0-alpha1/configuration/mystore?key=myConfigKey'
|
||||
curl -X GET 'http://localhost:3500/v1.0/configuration/mystore?key=myConfigKey'
|
||||
```
|
||||
|
||||
> The above command returns the following JSON:
|
||||
|
@ -75,7 +75,7 @@ This endpoint lets you subscribe to configuration changes. Notifications happen
|
|||
### HTTP Request
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/<storename>/subscribe
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/<storename>/subscribe
|
||||
```
|
||||
|
||||
#### URL Parameters
|
||||
|
@ -91,13 +91,13 @@ If no query parameters are provided, all configuration items are subscribed to.
|
|||
To specify the keys of the configuration items to subscribe to, use one or more `key` query parameters. For example:
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/mystore/subscribe?key=config1&key=config2
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/mystore/subscribe?key=config1&key=config2
|
||||
```
|
||||
|
||||
To subscribe to all changes:
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/mystore/subscribe
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/mystore/subscribe
|
||||
```
|
||||
|
||||
#### Request Body
|
||||
|
@ -121,7 +121,7 @@ JSON-encoded value
|
|||
### Example
|
||||
|
||||
```shell
|
||||
curl -X GET 'http://localhost:3500/v1.0-alpha1/configuration/mystore/subscribe?key=myConfigKey'
|
||||
curl -X GET 'http://localhost:3500/v1.0/configuration/mystore/subscribe?key=myConfigKey'
|
||||
```
|
||||
|
||||
> The above command returns the following JSON:
|
||||
|
@ -141,7 +141,7 @@ This endpoint lets you unsubscribe to configuration changes.
|
|||
### HTTP Request
|
||||
|
||||
```
|
||||
GET http://localhost:<daprPort>/v1.0-alpha1/configuration/<storename>/<subscription-id>/unsubscribe
|
||||
GET http://localhost:<daprPort>/v1.0/configuration/<storename>/<subscription-id>/unsubscribe
|
||||
```
|
||||
|
||||
#### URL Parameters
|
||||
|
@ -181,7 +181,7 @@ Code | Description
|
|||
### Example
|
||||
|
||||
```shell
|
||||
curl -X GET 'http://localhost:3500/v1.0-alpha1/configuration/mystore/bf3aa454-312d-403c-af95-6dec65058fa2/unsubscribe'
|
||||
curl -X GET 'http://localhost:3500/v1.0/configuration/mystore/bf3aa454-312d-403c-af95-6dec65058fa2/unsubscribe'
|
||||
```
|
||||
|
||||
## Optional application (user code) routes
|
||||
|
|
|
@ -25,11 +25,11 @@ spec:
|
|||
- name: url
|
||||
value: http://something.com
|
||||
- name: MTLSRootCA
|
||||
value: /Users/somepath/root.pem # OPTIONAL <path to root CA> or <pem encoded string>
|
||||
value: /Users/somepath/root.pem # OPTIONAL Secret store ref, <path to root CA>, or <pem encoded string>
|
||||
- name: MTLSClientCert
|
||||
value: /Users/somepath/client.pem # OPTIONAL <path to client cert> or <pem encoded string>
|
||||
value: /Users/somepath/client.pem # OPTIONAL Secret store ref, <path to client cert>, or <pem encoded string>
|
||||
- name: MTLSClientKey
|
||||
value: /Users/somepath/client.key # OPTIONAL <path to client key> or <pem encoded string>
|
||||
value: /Users/somepath/client.key # OPTIONAL Secret store ref, <path to client key>, or <pem encoded string>
|
||||
- name: MTLSRenegotiation
|
||||
value: RenegotiateOnceAsClient # OPTIONAL one of: RenegotiateNever, RenegotiateOnceAsClient, RenegotiateFreelyAsClient
|
||||
- name: securityToken # OPTIONAL <token to include as a header on HTTP requests>
|
||||
|
@ -45,13 +45,43 @@ spec:
|
|||
| Field | Required | Binding support | Details | Example |
|
||||
|--------------------|:--------:|--------|--------|---------|
|
||||
| url | Y | Output |The base URL of the HTTP endpoint to invoke | `http://host:port/path`, `http://myservice:8000/customers`
|
||||
| MTLSRootCA | N | Output |Path to root ca certificate or pem encoded string |
|
||||
| MTLSClientCert | N | Output |Path to client certificate or pem encoded string |
|
||||
| MTLSClientKey | N | Output |Path client private key or pem encoded string |
|
||||
| MTLSRootCA | N | Output |Secret store reference, path to root ca certificate, or pem encoded string |
|
||||
| MTLSClientCert | N | Output |Secret store reference, path to client certificate, or pem encoded string |
|
||||
| MTLSClientKey | N | Output |Secret store reference, path client private key, or pem encoded string |
|
||||
| MTLSRenegotiation | N | Output |Type of TLS renegotiation to be used | `RenegotiateOnceAsClient`
|
||||
| securityToken | N | Output |The value of a token to be added to an HTTP request as a header. Used together with `securityTokenHeader` |
|
||||
| securityTokenHeader| N | Output |The name of the header for `securityToken` on an HTTP request that |
|
||||
|
||||
### How to configure MTLS related fields in Metadata
|
||||
The values for **MTLSRootCA**, **MTLSClientCert** and **MTLSClientKey** can be provided in three ways:
|
||||
1. Secret store reference
|
||||
```yaml
|
||||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: <NAME>
|
||||
spec:
|
||||
type: bindings.http
|
||||
version: v1
|
||||
metadata:
|
||||
- name: url
|
||||
value: http://something.com
|
||||
- name: MTLSRootCA
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: myrootca
|
||||
auth:
|
||||
secretStore: <NAME_OF_SECRET_STORE_COMPONENT>
|
||||
```
|
||||
2. Path to the file: The absolute path to the file can be provided as a value for the field.
|
||||
3. PEM encoded string: The PEM encoded string can also be provided as a value for the field.
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
Metadata fields **MTLSRootCA**, **MTLSClientCert** and **MTLSClientKey** are used to configure TLS(m) authentication.
|
||||
To use mTLS authentication, you must provide all three fields. See [mTLS]({{< ref "#using-mtls-or-enabling-client-tls-authentication-along-with-https" >}}) for more details. You can also provide only **MTLSRootCA**, to enable **HTTPS** connection. See [HTTPS]({{< ref "#install-the-ssl-certificate-in-the-sidecar" >}}) section for more details.
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following [HTTP methods/verbs](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html):
|
||||
|
@ -316,6 +346,10 @@ curl -d '{ "operation": "get" }' \
|
|||
|
||||
{{< /tabs >}}
|
||||
|
||||
{{% alert title="Note" color="primary" %}}
|
||||
HTTPS binding support can also be configured using the **MTLSRootCA** metadata option. This will add the specified certificate to the list of trusted certificates for the binding. There's no specific preference for either method. While the **MTLSRootCA** option is easy to use and doesn't require any changes to the sidecar, it accepts only one certificate. If you need to trust multiple certificates, you need to [install them in the sidecar by following the steps above]({{< ref "#install-the-ssl-certificate-in-the-sidecar" >}}).
|
||||
{{% /alert %}}
|
||||
|
||||
## Using mTLS or enabling client TLS authentication along with HTTPS
|
||||
You can configure the HTTP binding to use mTLS or client TLS authentication along with HTTPS by providing the `MTLSRootCA`, `MTLSClientCert`, and `MTLSClientKey` metadata fields in the binding component.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
type: docs
|
||||
title: "MySQL binding spec"
|
||||
linkTitle: "MySQL"
|
||||
title: "MySQL & MariaDB binding spec"
|
||||
linkTitle: "MySQL & MariaDB"
|
||||
description: "Detailed documentation on the MySQL binding component"
|
||||
aliases:
|
||||
- "/operations/components/setup-bindings/supported-bindings/mysql/"
|
||||
|
@ -9,7 +9,9 @@ aliases:
|
|||
|
||||
## Component format
|
||||
|
||||
To setup MySQL binding create a component of type `bindings.mysql`. See [this guide]({{< ref "howto-bindings.md#1-create-a-binding" >}}) on how to create and apply a binding configuration.
|
||||
The MySQL binding allows connecting to both MySQL and MariaDB databases. In this document, we refer to "MySQL" to indicate both databases.
|
||||
|
||||
To setup a MySQL binding create a component of type `bindings.mysql`. See [this guide]({{< ref "howto-bindings.md#1-create-a-binding" >}}) on how to create and apply a binding configuration.
|
||||
|
||||
The MySQL binding uses [Go-MySQL-Driver](https://github.com/go-sql-driver/mysql) internally.
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ The Azure App Configuration store component supports the following optional `lab
|
|||
The label can be populated using query parameters in the request URL:
|
||||
|
||||
```bash
|
||||
GET curl http://localhost:<daprPort>/v1.0-alpha1/configuration/<store-name>?key=<key name>&metadata.label=<label value>
|
||||
GET curl http://localhost:<daprPort>/v1.0/configuration/<store-name>?key=<key name>&metadata.label=<label value>
|
||||
```
|
||||
|
||||
## Related links
|
||||
|
|
|
@ -39,7 +39,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|---------|---------|
|
||||
| connectionString | Y | The connection string for PostgreSQL. Default pool_max_conns = 5 | `"host=localhost user=postgres password=example port=5432 connect_timeout=10 database=dapr_test pool_max_conns=10"`
|
||||
| table | Y | table name for configuration information. | `configTable`
|
||||
| table | Y | Table name for configuration information, must be lowercased. | `configtable`
|
||||
|
||||
## Set up PostgreSQL as Configuration Store
|
||||
|
||||
|
@ -96,7 +96,7 @@ notification = json_build_object(
|
|||
6. Since this is a generic created trigger, map this trigger to `configuration table`
|
||||
```console
|
||||
CREATE TRIGGER config
|
||||
AFTER INSERT OR UPDATE OR DELETE ON configTable
|
||||
AFTER INSERT OR UPDATE OR DELETE ON configtable
|
||||
FOR EACH ROW EXECUTE PROCEDURE notify_event();
|
||||
```
|
||||
7. In the subscribe request add an additional metadata field with key as `pgNotifyChannel` and value should be set to same `channel name` mentioned in `pg_notify`. From the above example, it should be set to `config`
|
||||
|
|
|
@ -20,19 +20,11 @@ spec:
|
|||
version: v1
|
||||
metadata:
|
||||
- name: redisHost
|
||||
value: <HOST>
|
||||
value: <address>:6379
|
||||
- name: redisPassword
|
||||
value: <PASSWORD>
|
||||
value: **************
|
||||
- name: enableTLS
|
||||
value: <bool> # Optional. Allowed: true, false.
|
||||
- name: failover
|
||||
value: <bool> # Optional. Allowed: true, false.
|
||||
- name: sentinelMasterName
|
||||
value: <string> # Optional
|
||||
- name: maxRetries
|
||||
value: # Optional
|
||||
- name: maxRetryBackoff
|
||||
value: # Optional
|
||||
value: <bool>
|
||||
|
||||
```
|
||||
|
||||
|
@ -45,14 +37,26 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
|
||||
| Field | Required | Details | Example |
|
||||
|--------------------|:--------:|---------|---------|
|
||||
| redisHost | Y | Connection-string for the redis host | `localhost:6379`, `redis-master.default.svc.cluster.local:6379`
|
||||
| redisPassword | Y | Password for Redis host. No Default. Can be `secretKeyRef` to use a secret reference | `""`, `"KeFg23!"`
|
||||
| enableTLS | N | If the Redis instance supports TLS with public certificates, can be configured to be enabled or disabled. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| maxRetries | N | Maximum number of retries before giving up. Defaults to `3` | `5`, `10`
|
||||
| maxRetryBackoff | N | Maximum backoff between each retry. Defaults to `2` seconds; `"-1"` disables backoff. | `3000000000`
|
||||
| failover | N | Property to enabled failover configuration. Needs sentinalMasterName to be set. The redisHost should be the sentinel host address. See [Redis Sentinel Documentation](https://redis.io/docs/manual/sentinel/). Defaults to `"false"` | `"true"`, `"false"`
|
||||
| sentinelMasterName | N | The sentinel master name. See [Redis Sentinel Documentation](https://redis.io/docs/manual/sentinel/) | `""`, `"127.0.0.1:6379"`
|
||||
|
||||
| redisHost | Y | Output | The Redis host address | `"localhost:6379"` |
|
||||
| redisPassword | Y | Output | The Redis password | `"password"` |
|
||||
| redisUsername | N | Output | Username for Redis host. Defaults to empty. Make sure your Redis server version is 6 or above, and have created acl rule correctly. | `"username"` |
|
||||
| enableTLS | N | Output | If the Redis instance supports TLS with public certificates it can be configured to enable or disable TLS. Defaults to `"false"` | `"true"`, `"false"` |
|
||||
| failover | N | Output | Property to enabled failover configuration. Needs sentinelMasterName to be set. Defaults to `"false"` | `"true"`, `"false"`
|
||||
| sentinelMasterName | N | Output | The Sentinel master name. See [Redis Sentinel Documentation](https://redis.io/docs/reference/sentinel-clients/) | `""`, `"127.0.0.1:6379"`
|
||||
| redisType | N | Output | The type of Redis. There are two valid values, one is `"node"` for single node mode, the other is `"cluster"` for Redis cluster mode. Defaults to `"node"`. | `"cluster"`
|
||||
| redisDB | N | Output | Database selected after connecting to Redis. If `"redisType"` is `"cluster"`, this option is ignored. Defaults to `"0"`. | `"0"`
|
||||
| redisMaxRetries | N | Output | Maximum number of times to retry commands before giving up. Default is to not retry failed commands. | `"5"`
|
||||
| redisMinRetryInterval | N | Output | Minimum backoff for Redis commands between each retry. Default is `"8ms"`; `"-1"` disables backoff. | `"8ms"`
|
||||
| redisMaxRetryInterval | N | Output | Maximum backoff for Redis commands between each retry. Default is `"512ms"`;`"-1"` disables backoff. | `"5s"`
|
||||
| dialTimeout | N | Output | Dial timeout for establishing new connections. Defaults to `"5s"`. | `"5s"`
|
||||
| readTimeout | N | Output | Timeout for socket reads. If reached, Redis commands fail with a timeout instead of blocking. Defaults to `"3s"`, `"-1"` for no timeout. | `"3s"`
|
||||
| writeTimeout | N | Output | Timeout for socket writes. If reached, Redis commands fail with a timeout instead of blocking. Defaults is readTimeout. | `"3s"`
|
||||
| poolSize | N | Output | Maximum number of socket connections. Default is 10 connections per every CPU as reported by runtime.NumCPU. | `"20"`
|
||||
| poolTimeout | N | Output | Amount of time client waits for a connection if all connections are busy before returning an error. Default is readTimeout + 1 second. | `"5s"`
|
||||
| maxConnAge | N | Output | Connection age at which the client retires (closes) the connection. Default is to not close aged connections. | `"30m"`
|
||||
| minIdleConns | N | Output | Minimum number of idle connections to keep open in order to avoid the performance degradation associated with creating new connections. Defaults to `"0"`. | `"2"`
|
||||
| idleCheckFrequency | N | Output | Frequency of idle checks made by idle connections reaper. Default is `"1m"`. `"-1"` disables idle connections reaper. | `"-1"`
|
||||
| idleTimeout | N | Output | Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is `"5m"`. `"-1"` disables idle timeout check. | `"10m"`
|
||||
|
||||
## Setup Redis
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
type: docs
|
||||
title: "MySQL"
|
||||
linkTitle: "MySQL"
|
||||
title: "MySQL & MariaDB"
|
||||
linkTitle: "MySQL & MariaDB"
|
||||
description: Detailed information on the MySQL state store component
|
||||
aliases:
|
||||
- "/operations/components/setup-state-store/supported-state-stores/setup-mysql/"
|
||||
|
@ -9,6 +9,8 @@ aliases:
|
|||
|
||||
## Component format
|
||||
|
||||
The MySQL state store components allows connecting to both MySQL and MariaDB databases. In this document, we refer to "MySQL" to indicate both databases.
|
||||
|
||||
To setup MySQL state store create a component of type `state.mysql`. See [this guide]({{< ref "howto-get-save-state.md#step-1-setup-a-state-store" >}}) on how to create and apply a state store configuration.
|
||||
|
||||
|
||||
|
|
|
@ -10,13 +10,11 @@ The following table lists the environment variables used by the Dapr runtime, CL
|
|||
|
||||
| Environment Variable | Used By | Description |
|
||||
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| APP_ID | Your application | The id for your application, used for service discovery |
|
||||
| APP_PORT | Your application | The port your application is listening on |
|
||||
| APP_ID | Your application | The id for your application, used for service discovery |
|
||||
| APP_PORT | Dapr sidecar | The port your application is listening on |
|
||||
| APP_API_TOKEN | Your application | The token used by the application to authenticate requests from Dapr API. Read [authenticate requests from Dapr using token authentication]({{< ref app-api-token >}}) for more information. |
|
||||
| DAPR_HTTP_PORT | Your application | The HTTP port that the Dapr sidecar is listening on. Your application should use this variable to connect to Dapr sidecar instead of hardcoding the port value. Set by the Dapr CLI run command for self-hosted or injected by the `dapr-sidecar-injector` into all the containers in the pod. |
|
||||
| DAPR_GRPC_PORT | Your application | The gRPC port that the Dapr sidecar is listening on. Your application should use this variable to connect to Dapr sidecar instead of hardcoding the port value. Set by the Dapr CLI run command for self-hosted or injected by the `dapr-sidecar-injector` into all the containers in the pod. |
|
||||
| DAPR_METRICS_PORT | Your application | The HTTP [Prometheus]({{< ref prometheus >}}) port to which Dapr sends its metrics information. With this variable, your application sends its application-specific metrics to have both Dapr metrics and application metrics together. See [metrics-port]({{< ref arguments-annotations-overview>}}) for more information |
|
||||
| DAPR_PROFILE_PORT | Your application | The [profiling port]({{< ref profiling-debugging >}}) through which Dapr lets you enable profiling and track possible CPU/memory/resource spikes in your application's behavior. Enabled by `--enable-profiling` command in Dapr CLI for self-hosted or `dapr.io/enable-profiling` annotation in Dapr annotated pod. |
|
||||
| DAPR_API_TOKEN | Dapr sidecar | The token used for Dapr API authentication for requests from the application. [Enable API token authentication in Dapr]({{< ref api-token >}}). |
|
||||
| NAMESPACE | Dapr sidecar | Used to specify a component's [namespace in self-hosted mode]({{< ref component-scopes >}}). |
|
||||
| DAPR_DEFAULT_IMAGE_REGISTRY | Dapr CLI | In self-hosted mode, it is used to specify the default container registry to pull images from. When its value is set to `GHCR` or `ghcr`, it pulls the required images from Github container registry. To default to Docker hub, unset this environment variable. |
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
features:
|
||||
input: true
|
||||
output: true
|
||||
- component: MySQL
|
||||
- component: MySQL & MariaDB
|
||||
link: mysql
|
||||
state: Alpha
|
||||
version: v1
|
||||
|
|
Loading…
Reference in New Issue