Merge branch 'v1.15' into issue_4521

This commit is contained in:
Mark Fussell 2025-02-12 22:00:45 -08:00 committed by GitHub
commit d8c2f9b4b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 519 additions and 47 deletions

View File

@ -20,7 +20,7 @@ Not using CloudEvents disables support for tracing, event deduplication per mess
To disable CloudEvent wrapping, set the `rawPayload` metadata to `true` as part of the publishing request. This allows subscribers to receive these messages without having to parse the CloudEvent schema.
{{< tabs curl "Python SDK" "PHP SDK">}}
{{< tabs curl ".NET" "Python" "PHP">}}
{{% codetab %}}
```bash
@ -28,6 +28,43 @@ curl -X "POST" http://localhost:3500/v1.0/publish/pubsub/TOPIC_A?metadata.rawPay
```
{{% /codetab %}}
{{% codetab %}}
```csharp
using Dapr.Client;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddDapr();
var app = builder.Build();
app.MapPost("/publish", async (DaprClient daprClient) =>
{
var message = new Message(
Guid.NewGuid().ToString(),
$"Hello at {DateTime.UtcNow}",
DateTime.UtcNow
);
await daprClient.PublishEventAsync(
"pubsub", // pubsub name
"messages", // topic name
message, // message data
new Dictionary<string, string>
{
{ "rawPayload", "true" },
{ "content-type", "application/json" }
}
);
return Results.Ok(message);
});
app.Run();
```
{{% /codetab %}}
{{% codetab %}}
```python
from dapr.clients import DaprClient
@ -74,9 +111,52 @@ Dapr apps are also able to subscribe to raw events coming from existing pub/sub
### Programmatically subscribe to raw events
When subscribing programmatically, add the additional metadata entry for `rawPayload` so the Dapr sidecar automatically wraps the payloads into a CloudEvent that is compatible with current Dapr SDKs.
When subscribing programmatically, add the additional metadata entry for `rawPayload` to allow the subscriber to receive a message that is not wrapped by a CloudEvent. For .NET, this metadata entry is called `isRawPayload`.
{{< tabs "Python" "PHP SDK" >}}
{{< tabs ".NET" "Python" "PHP" >}}
{{% codetab %}}
```csharp
using System.Text.Json;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/dapr/subscribe", () =>
{
var subscriptions = new[]
{
new
{
pubsubname = "pubsub",
topic = "messages",
route = "/messages",
metadata = new Dictionary<string, string>
{
{ "isRawPayload", "true" },
{ "content-type", "application/json" }
}
}
};
return Results.Ok(subscriptions);
});
app.MapPost("/messages", async (HttpContext context) =>
{
using var reader = new StreamReader(context.Request.Body);
var json = await reader.ReadToEndAsync();
Console.WriteLine($"Raw message received: {json}");
return Results.Ok();
});
app.Run();
```
{{% /codetab %}}
{{% codetab %}}
@ -151,7 +231,7 @@ spec:
default: /dsstatus
pubsubname: pubsub
metadata:
rawPayload: "true"
isRawPayload: "true"
scopes:
- app1
- app2
@ -161,4 +241,5 @@ scopes:
- Learn more about [publishing and subscribing messages]({{< ref pubsub-overview.md >}})
- List of [pub/sub components]({{< ref supported-pubsub >}})
- Read the [API reference]({{< ref pubsub_api.md >}})
- Read the [API reference]({{< ref pubsub_api.md >}})
- Read the .NET sample on how to [consume Kafka messages without CloudEvents](https://github.com/dapr/samples/pubsub-raw-payload)

View File

@ -80,10 +80,16 @@ In production scenarios, it is recommended to use a solution such as:
If running on AWS EKS, you can [link an IAM role to a Kubernetes service account](https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html), which your pod can use.
All of these solutions solve the same problem: They allow the Dapr runtime process (or sidecar) to retrive credentials dynamically, so that explicit credentials aren't needed. This provides several benefits, such as automated key rotation, and avoiding having to manage secrets.
All of these solutions solve the same problem: They allow the Dapr runtime process (or sidecar) to retrieve credentials dynamically, so that explicit credentials aren't needed. This provides several benefits, such as automated key rotation, and avoiding having to manage secrets.
Both Kiam and Kube2IAM work by intercepting calls to the [instance metadata service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html).
### Setting Up Dapr with AWS EKS Pod Identity
EKS Pod Identities provide the ability to manage credentials for your applications, similar to the way that Amazon EC2 instance profiles provide credentials to Amazon EC2 instances. Instead of creating and distributing your AWS credentials to the containers or using the Amazon EC2 instances role, you associate an IAM role with a Kubernetes service account and configure your Pods to use the service account.
To see a comprehensive example on how to authorize pod access to AWS Secrets Manager from EKS using AWS EKS Pod Identity, [follow the sample in this repository](https://github.com/dapr/samples/tree/master/dapr-eks-podidentity).
### Use an instance profile when running in stand-alone mode on AWS EC2
If running Dapr directly on an AWS EC2 instance in stand-alone mode, you can use instance profiles.
@ -130,7 +136,6 @@ On Windows, the environment variable needs to be set before starting the `dapr`
{{< /tabs >}}
### Authenticate to AWS if using AWS SSO based profiles
If you authenticate to AWS using [AWS SSO](https://aws.amazon.com/single-sign-on/), some AWS SDKs (including the Go SDK) don't yet support this natively. There are several utilities you can use to "bridge the gap" between AWS SSO-based credentials and "legacy" credentials, such as:
@ -157,7 +162,7 @@ AWS_PROFILE=myprofile awshelper daprd...
<!-- windows -->
{{% codetab %}}
On Windows, the environment variable needs to be set before starting the `awshelper` command, doing it inline (like in Linxu/MacOS) is not supported.
On Windows, the environment variable needs to be set before starting the `awshelper` command; doing it inline (like in Linux/MacOS) is not supported.
{{% /codetab %}}
@ -169,4 +174,7 @@ On Windows, the environment variable needs to be set before starting the `awshel
## Related links
For more information, see [how the AWS SDK (which Dapr uses) handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials).
- For more information, see [how the AWS SDK (which Dapr uses) handles credentials](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials).
- [EKS Pod Identity Documentation](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html)
- [AWS SDK Credentials Configuration](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials)
- [Set up an Elastic Kubernetes Service (EKS) cluster](https://docs.dapr.io/operations/hosting/kubernetes/cluster/setup-eks/)

View File

@ -1,21 +0,0 @@
---
type: docs
title: "How to: Integrate using Testcontainers Dapr Module"
linkTitle: "Dapr Testcontainers"
weight: 3000
description: "Use the Dapr Testcontainer module from your Java application"
---
You can use the Testcontainers Dapr Module provided by Diagrid to set up Dapr locally for your Java applications. Simply add the following dependency to your Maven project:
```xml
<dependency>
<groupId>io.diagrid.dapr</groupId>
<artifactId>testcontainers-dapr</artifactId>
<version>0.10.x</version>
</dependency>
```
[If you're using Spring Boot, you can also use the Spring Boot Starter.](https://github.com/diagridio/spring-boot-starter-dapr)
{{< button text="Use the Testcontainers Dapr Module" link="https://github.com/diagridio/testcontainers-dapr" >}}

View File

@ -10,7 +10,7 @@ no_list: true
Hit the ground running with our Dapr quickstarts, complete with code samples aimed to get you started quickly with Dapr.
{{% alert title="Note" color="primary" %}}
We are actively working on adding to our quickstart library. In the meantime, you can explore Dapr through our [tutorials]({{< ref "getting-started/tutorials/_index.md" >}}).
Each release, the quickstart library has new examples added for the APIs and SDKs. You can also explore Dapr through the [tutorials]({{< ref "getting-started/tutorials/_index.md" >}}).
{{% /alert %}}
@ -33,4 +33,4 @@ Hit the ground running with our Dapr quickstarts, complete with code samples aim
| [Resiliency]({{< ref resiliency >}}) | Define and apply fault-tolerance policies to your Dapr API requests. |
| [Cryptography]({{< ref cryptography-quickstart.md >}}) | Encrypt and decrypt data using Dapr's cryptographic APIs. |
| [Jobs]({{< ref jobs-quickstart.md >}}) | Schedule, retrieve, and delete jobs using Dapr's jobs APIs. |
| [Conversation]({{< ref conversation-quickstart.md >}}) | Securely and reliably interact with Large Language Models (LLMs). |

View File

@ -17,10 +17,276 @@ You can try out this conversation quickstart by either:
- [Running the application in this sample with the Multi-App Run template file]({{< ref "#run-the-app-with-the-template-file" >}}), or
- [Running the application without the template]({{< ref "#run-the-app-without-the-template" >}})
{{% alert title="Note" color="primary" %}}
Currently, only the HTTP quickstart sample is available in Python and JavaScript.
{{% /alert %}}
## Run the app with the template file
{{< tabs ".NET" Go >}}
{{< tabs Python JavaScript ".NET" Go >}}
<!-- Python -->
{{% codetab %}}
### Step 1: Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Python 3.7+ installed](https://www.python.org/downloads/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 2: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation).
```bash
git clone https://github.com/dapr/quickstarts.git
```
From the root of the Quickstarts directory, navigate into the conversation directory:
```bash
cd conversation/python/http/conversation
```
Install the dependencies:
```bash
pip3 install -r requirements.txt
```
### Step 3: Launch the conversation service
Navigate back to the `http` directory and start the conversation service with the following command:
```bash
dapr run -f .
```
**Expected output**
```
== APP - conversation == Input sent: What is dapr?
== APP - conversation == Output response: What is dapr?
```
### What happened?
When you ran `dapr init` during Dapr install, the [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) was generated in the `.dapr/components` directory.
Running `dapr run -f .` in this Quickstart started [conversation.go]({{< ref "#programcs-conversation-app" >}}).
#### `dapr.yaml` Multi-App Run template file
Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. This Quickstart has only one application, so the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../components/
apps:
- appID: conversation
appDirPath: ./conversation/
command: ["python3", "app.py"]
```
#### Echo mock LLM component
In [`conversation/components`](https://github.com/dapr/quickstarts/tree/master/conversation/components) directly of the quickstart, the [`conversation.yaml` file](https://github.com/dapr/quickstarts/tree/master/conversation/components/conversation.yml) configures the echo LLM component.
```yml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: echo
spec:
type: conversation.echo
version: v1
```
To interface with a real LLM, swap out the mock component with one of [the supported conversation components]({{< ref "supported-conversation" >}}). For example, to use an OpenAI component, see the [example in the conversation how-to guide]({{< ref "howto-conversation-layer.md#use-the-openai-component" >}})
#### `app.py` conversation app
In the application code:
- The app sends an input "What is dapr?" to the echo mock LLM component.
- The mock LLM echoes "What is dapr?".
```python
import logging
import requests
import os
logging.basicConfig(level=logging.INFO)
base_url = os.getenv('BASE_URL', 'http://localhost') + ':' + os.getenv(
'DAPR_HTTP_PORT', '3500')
CONVERSATION_COMPONENT_NAME = 'echo'
input = {
'name': 'echo',
'inputs': [{'message':'What is dapr?'}],
'parameters': {},
'metadata': {}
}
# Send input to conversation endpoint
result = requests.post(
url='%s/v1.0-alpha1/conversation/%s/converse' % (base_url, CONVERSATION_COMPONENT_NAME),
json=input
)
logging.info('Input sent: What is dapr?')
# Parse conversation output
data = result.json()
output = data["outputs"][0]["result"]
logging.info('Output response: ' + output)
```
{{% /codetab %}}
<!-- JavaScript -->
{{% codetab %}}
### Step 1: Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest Node.js installed](https://nodejs.org/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 2: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation).
```bash
git clone https://github.com/dapr/quickstarts.git
```
From the root of the Quickstarts directory, navigate into the conversation directory:
```bash
cd conversation/javascript/http/conversation
```
Install the dependencies:
```bash
npm install
```
### Step 3: Launch the conversation service
Navigate back to the `http` directory and start the conversation service with the following command:
```bash
dapr run -f .
```
**Expected output**
```
== APP - conversation == Input sent: What is dapr?
== APP - conversation == Output response: What is dapr?
```
### What happened?
When you ran `dapr init` during Dapr install, the [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) was generated in the `.dapr/components` directory.
Running `dapr run -f .` in this Quickstart started [conversation.go]({{< ref "#programcs-conversation-app" >}}).
#### `dapr.yaml` Multi-App Run template file
Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. This Quickstart has only one application, so the `dapr.yaml` file contains the following:
```yml
version: 1
common:
resourcesPath: ../../components/
apps:
- appID: conversation
appDirPath: ./conversation/
daprHTTPPort: 3502
command: ["npm", "run", "start"]
```
#### Echo mock LLM component
In [`conversation/components`](https://github.com/dapr/quickstarts/tree/master/conversation/components) directly of the quickstart, the [`conversation.yaml` file](https://github.com/dapr/quickstarts/tree/master/conversation/components/conversation.yml) configures the echo LLM component.
```yml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: echo
spec:
type: conversation.echo
version: v1
```
To interface with a real LLM, swap out the mock component with one of [the supported conversation components]({{< ref "supported-conversation" >}}). For example, to use an OpenAI component, see the [example in the conversation how-to guide]({{< ref "howto-conversation-layer.md#use-the-openai-component" >}})
#### `index.js` conversation app
In the application code:
- The app sends an input "What is dapr?" to the echo mock LLM component.
- The mock LLM echoes "What is dapr?".
```javascript
const conversationComponentName = "echo";
async function main() {
const daprHost = process.env.DAPR_HOST || "http://localhost";
const daprHttpPort = process.env.DAPR_HTTP_PORT || "3500";
const inputBody = {
name: "echo",
inputs: [{ message: "What is dapr?" }],
parameters: {},
metadata: {},
};
const reqURL = `${daprHost}:${daprHttpPort}/v1.0-alpha1/conversation/${conversationComponentName}/converse`;
try {
const response = await fetch(reqURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(inputBody),
});
console.log("Input sent: What is dapr?");
const data = await response.json();
const result = data.outputs[0].result;
console.log("Output response:", result);
} catch (error) {
console.error("Error:", error.message);
process.exit(1);
}
}
main().catch((error) => {
console.error("Unhandled error:", error);
process.exit(1);
});
```
{{% /codetab %}}
<!-- .NET -->
{{% codetab %}}
@ -282,7 +548,111 @@ func main() {
## Run the app without the template
{{< tabs ".NET" Go >}}
{{< tabs Python JavaScript ".NET" Go >}}
<!-- Python -->
{{% codetab %}}
### Step 1: Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Python 3.7+ installed](https://www.python.org/downloads/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 2: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation).
```bash
git clone https://github.com/dapr/quickstarts.git
```
From the root of the Quickstarts directory, navigate into the conversation directory:
```bash
cd conversation/python/http/conversation
```
Install the dependencies:
```bash
pip3 install -r requirements.txt
```
### Step 3: Launch the conversation service
Navigate back to the `http` directory and start the conversation service with the following command:
```bash
dapr run --app-id conversation --resources-path ../../../components -- python3 app.py
```
> **Note**: Since Python3.exe is not defined in Windows, you may need to use `python app.py` instead of `python3 app.py`.
**Expected output**
```
== APP - conversation == Input sent: What is dapr?
== APP - conversation == Output response: What is dapr?
```
{{% /codetab %}}
<!-- JavaScript -->
{{% codetab %}}
### Step 1: Pre-requisites
For this example, you will need:
- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started).
- [Latest Node.js installed](https://nodejs.org/).
<!-- IGNORE_LINKS -->
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
<!-- END_IGNORE -->
### Step 2: Set up the environment
Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/conversation).
```bash
git clone https://github.com/dapr/quickstarts.git
```
From the root of the Quickstarts directory, navigate into the conversation directory:
```bash
cd conversation/javascript/http/conversation
```
Install the dependencies:
```bash
npm install
```
### Step 3: Launch the conversation service
Navigate back to the `http` directory and start the conversation service with the following command:
```bash
dapr run --app-id conversation --resources-path ../../../components/ -- npm run start
```
**Expected output**
```
== APP - conversation == Input sent: What is dapr?
== APP - conversation == Output response: What is dapr?
```
{{% /codetab %}}
<!-- .NET -->
{{% codetab %}}

View File

@ -442,13 +442,11 @@ app.MapPost("/orders", (Order order) =>
In the Program.cs file for the `checkout` service, you'll notice there's no need to rewrite your app code to use Dapr's service invocation. You can enable service invocation by simply adding the `dapr-app-id` header, which specifies the ID of the target service.
```csharp
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var client = DaprClient.CreateInvokeHttpClient(appId: "order-processor");
var cts = new CancellationTokenSource();
client.DefaultRequestHeaders.Add("dapr-app-id", "order-processor");
var response = await client.PostAsync($"{baseURL}/orders", content);
Console.WriteLine("Order passed: " + order);
var response = await client.PostAsJsonAsync("/orders", order, cts.Token);
Console.WriteLine("Order passed: " + order);
```
{{% /codetab %}}
@ -1092,13 +1090,11 @@ dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 -- dotnet r
In the Program.cs file for the `checkout` service, you'll notice there's no need to rewrite your app code to use Dapr's service invocation. You can enable service invocation by simply adding the `dapr-app-id` header, which specifies the ID of the target service.
```csharp
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var client = DaprClient.CreateInvokeHttpClient(appId: "order-processor");
var cts = new CancellationTokenSource();
client.DefaultRequestHeaders.Add("dapr-app-id", "order-processor");
var response = await client.PostAsync($"{baseURL}/orders", content);
Console.WriteLine("Order passed: " + order);
var response = await client.PostAsJsonAsync("/orders", order, cts.Token);
Console.WriteLine("Order passed: " + order);
```
### Step 5: Use with Multi-App Run

View File

@ -66,7 +66,7 @@ This guide walks you through installing an Elastic Kubernetes Service (EKS) clus
1. Create the cluster by running the following command:
```bash
eksctl create cluster -f cluster.yaml
eksctl create cluster -f cluster-config.yaml
```
1. Verify the kubectl context:

View File

@ -198,6 +198,44 @@ Entity management is only possible when using [Microsoft Entra ID Authentication
> Dapr passes the name of the consumer group to the Event Hub, so this is not supplied in the metadata.
## Receiving custom properties
By default, Dapr does not forward [custom properties](https://learn.microsoft.com/azure/event-hubs/add-custom-data-event). However, by setting the subscription metadata `requireAllProperties` to `"true"`, you can receive custom properties as HTTP headers.
```yaml
apiVersion: dapr.io/v2alpha1
kind: Subscription
metadata:
name: order-pub-sub
spec:
topic: orders
routes:
default: /checkout
pubsubname: order-pub-sub
metadata:
requireAllProperties: "true"
```
The same can be achieved using the Dapr SDK:
{{< tabs ".NET" >}}
{{% codetab %}}
```csharp
[Topic("order-pub-sub", "orders")]
[TopicMetadata("requireAllProperties", "true")]
[HttpPost("checkout")]
public ActionResult Checkout(Order order, [FromHeader] int priority)
{
return Ok();
}
```
{{% /codetab %}}
{{< /tabs >}}
## Subscribing to Azure IoT Hub Events
Azure IoT Hub provides an [endpoint that is compatible with Event Hubs](https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-read-builtin#read-from-the-built-in-endpoint), so the Azure Event Hubs pubsub component can also be used to subscribe to Azure IoT Hub events.