mirror of https://github.com/dapr/quickstarts.git
Merge pull request #1176 from alicejgibbons/release-1.15
Re-merge 1.15 release branch into master
This commit is contained in:
commit
55d7dc2a37
|
@ -1,5 +1,5 @@
|
|||
DAPR_CLI_VERSION: 1.15.0
|
||||
DAPR_RUNTIME_VERSION: 1.15.0
|
||||
DAPR_RUNTIME_VERSION: 1.15.2
|
||||
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/v${DAPR_CLI_VERSION}/install/
|
||||
DAPR_DEFAULT_IMAGE_REGISTRY: ghcr
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages HTTP `requests` only. If you are looking for the example using the Dapr Client SDK (recommended) [click here](../sdk/).
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template file](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) and Dapr CLI with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Integrate with popular LLM models by using one of the other [supported conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Integrate with popular LLM models by using one of the other [supported conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
Open a new terminal window and run the multi app run template:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages the Dapr SDK. If you are looking for the example using the HTTP API [click here](../http/).
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template file](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) and Dapr CLI with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Integrate with popular LLM models by using one of the other [supported conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Integrate with popular LLM models by using one of the other [supported conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
Open a new terminal window and run the multi app run template:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages HTTP `requests` only. If you are looking for the example using the Dapr Client SDK (recommended) [click here](../sdk/).
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
Open a new terminal window and run the multi app run template:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages the Dapr SDK. If you are looking for the example using the HTTP API [click here](../http/).
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
Open a new terminal window and run the multi app run template:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages HTTP `requests` only.
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
1. Install dependencies:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
> **Note:** This example leverages HTTP `requests` only.
|
||||
|
||||
|
@ -14,7 +14,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
1. Install dependencies:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
In this quickstart, you'll send an input to a mock Large Language Model (LLM) using Dapr's Conversation API. This API is responsible for providing one consistent API entry point to talk to underlying LLM providers.
|
||||
|
||||
Visit [this](https://v1-15.docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/conversation/conversation-overview/) link for more information about Dapr and the Conversation API.
|
||||
|
||||
This quickstart includes one app:
|
||||
|
||||
|
@ -12,7 +12,7 @@ This quickstart includes one app:
|
|||
|
||||
This section shows how to run the application using the [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`.
|
||||
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://v1-15.docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
This example uses the default LLM Component provided by Dapr which simply echoes the input provided, for testing purposes. Here are other [supported Conversation components](https://docs.dapr.io/reference/components-reference/supported-conversation/).
|
||||
|
||||
1. Install dependencies:
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ expected_stdout_lines:
|
|||
expected_stderr_lines:
|
||||
output_match_mode: substring
|
||||
match_order: none
|
||||
background: false
|
||||
background: true
|
||||
sleep: 60
|
||||
timeout_seconds: 120
|
||||
-->
|
||||
|
@ -95,6 +95,18 @@ After 20 seconds, the terminal output should present the `C-3PO` job being proce
|
|||
|
||||
<!-- END_STEP -->
|
||||
|
||||
3. Stop and clean up application processes.
|
||||
|
||||
<!-- STEP
|
||||
name: Stop multi-app run
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop -f .
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
## Run apps individually
|
||||
|
||||
### Schedule Jobs
|
||||
|
|
|
@ -19,7 +19,6 @@ var r2d2JobBody = new
|
|||
|
||||
var daprHost = Environment.GetEnvironmentVariable("DAPR_HOST") ?? "http://localhost";
|
||||
var jobServiceDaprHttpPort = "6280";
|
||||
|
||||
var httpClient = new HttpClient();
|
||||
|
||||
await Task.Delay(5000); // Wait for job-service to start
|
||||
|
@ -65,7 +64,6 @@ async Task ScheduleJob(string jobName, object jobBody)
|
|||
async Task GetJobDetails(string jobName)
|
||||
{
|
||||
var reqURL = $"{daprHost}:{jobServiceDaprHttpPort}/v1.0-alpha1/jobs/{jobName}";
|
||||
|
||||
var response = await httpClient.GetAsync(reqURL);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
# Dapr Jobs API (SDK)
|
||||
|
||||
In this quickstart, you'll schedule, get, and delete a job using Dapr's Job API. This API is responsible for scheduling and running jobs at a specific time or interval.
|
||||
|
||||
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/jobs/) link for more information about Dapr and the Jobs API.
|
||||
|
||||
> **Note:** This example leverages the Dotnet SDK. If you are looking for the example using only HTTP requests, [click here](../http/).
|
||||
|
||||
This quickstart includes two apps:
|
||||
|
||||
- Jobs Scheduler, responsible for scheduling, retrieving and deleting jobs.
|
||||
- Jobs Service, responsible for handling the triggered jobs.
|
||||
|
||||
## Run all apps with multi-app run template file
|
||||
|
||||
This section shows how to run both applications at once using [multi-app run template files](https://docs.dapr.io/developing-applications/local-development/multi-app-dapr-run/multi-app-overview/) with `dapr run -f .`. This enables to you test the interactions between multiple applications and will `schedule`, `run`, `get`, and `delete` jobs within a single process.
|
||||
|
||||
1. Build the apps:
|
||||
|
||||
<!-- STEP
|
||||
name: Build dependencies for job-service
|
||||
sleep: 1
|
||||
-->
|
||||
|
||||
```bash
|
||||
cd ./job-service
|
||||
dotnet build
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
<!-- STEP
|
||||
name: Build dependencies for job-scheduler
|
||||
sleep: 1
|
||||
-->
|
||||
|
||||
```bash
|
||||
cd ./job-scheduler
|
||||
dotnet build
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
2. Run the multi app run template:
|
||||
|
||||
<!-- STEP
|
||||
name: Run multi app run template
|
||||
expected_stdout_lines:
|
||||
- '== APP - job-service-sdk == Job Scheduled: R2-D2'
|
||||
- '== APP - job-service-sdk == Job Scheduled: C-3PO'
|
||||
- '== APP - job-service-sdk == Starting droid: R2-D2'
|
||||
- '== APP - job-service-sdk == Executing maintenance job: Oil Change'
|
||||
- '== APP - job-service-sdk == Starting droid: C-3PO'
|
||||
- '== APP - job-service-sdk == Executing maintenance job: Limb Calibration'
|
||||
expected_stderr_lines:
|
||||
output_match_mode: substring
|
||||
match_order: none
|
||||
background: true
|
||||
sleep: 60
|
||||
timeout_seconds: 120
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run -f .
|
||||
```
|
||||
|
||||
The terminal console output should look similar to this, where:
|
||||
|
||||
- The `R2-D2` job is being scheduled.
|
||||
- The `R2-D2` job is being retrieved.
|
||||
- The `C-3PO` job is being scheduled.
|
||||
- The `C-3PO` job is being retrieved.
|
||||
- The `R2-D2` job is being executed after 15 seconds.
|
||||
- The `C-3PO` job is being executed after 20 seconds.
|
||||
|
||||
```text
|
||||
== APP - job-scheduler-sdk == Scheduling job...
|
||||
== APP - job-service-sdk == Job Scheduled: R2-D2
|
||||
== APP - job-scheduler-sdk == Job scheduled: {"name":"R2-D2","job":"Oil Change","dueTime":15}
|
||||
== APP - job-scheduler-sdk == Getting job: R2-D2
|
||||
== APP - job-service-sdk == Getting job...
|
||||
== APP - job-scheduler-sdk == Job details: {"schedule":"@every 15s","repeatCount":1,"dueTime":null,"ttl":null,"payload":"ChtkYXByLmlvL3NjaGVkdWxlL2pvYnBheWxvYWQSJXsiZHJvaWQiOiJSMi1EMiIsInRhc2siOiJPaWwgQ2hhbmdlIn0="}
|
||||
== APP - job-scheduler-sdk == Scheduling job...
|
||||
== APP - job-service-sdk == Job Scheduled: C-3PO
|
||||
== APP - job-scheduler-sdk == Job scheduled: {"name":"C-3PO","job":"Limb Calibration","dueTime":20}
|
||||
== APP - job-scheduler-sdk == Getting job: C-3PO
|
||||
== APP - job-service-sdk == Getting job...
|
||||
== APP - job-scheduler-sdk == Job details: {"schedule":"@every 20s","repeatCount":1,"dueTime":null,"ttl":null,"payload":"ChtkYXByLmlvL3NjaGVkdWxlL2pvYnBheWxvYWQSK3siZHJvaWQiOiJDLTNQTyIsInRhc2siOiJMaW1iIENhbGlicmF0aW9uIn0="}
|
||||
== APP - job-service-sdk == Handling job...
|
||||
== APP - job-service-sdk == Starting droid: R2-D2
|
||||
== APP - job-service-sdk == Executing maintenance job: Oil Change
|
||||
```
|
||||
|
||||
After 20 seconds, the terminal output should present the `C-3PO` job being processed:
|
||||
|
||||
```text
|
||||
== APP - job-service-sdk == Handling job...
|
||||
== APP - job-service-sdk == Starting droid: C-3PO
|
||||
== APP - job-service-sdk == Executing maintenance job: Limb Calibration
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
3. Stop and clean up application processes.
|
||||
|
||||
<!-- STEP
|
||||
name: Stop multi-app run
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr stop -f .
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
## Run apps individually
|
||||
|
||||
### Schedule Jobs
|
||||
|
||||
1. Open a terminal and run the `job-service` app. Build the dependencies if you haven't already.
|
||||
|
||||
```bash
|
||||
cd ./job-service
|
||||
dotnet build
|
||||
```
|
||||
|
||||
```bash
|
||||
dapr run --app-id job-service-sdk --app-port 6200 --dapr-http-port 6280 -- dotnet run
|
||||
```
|
||||
|
||||
2. In a new terminal window, schedule the `R2-D2` Job using the Jobs API.
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
http://localhost:6200/scheduleJob \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "R2-D2",
|
||||
"job": "Oil Change",
|
||||
"dueTime": 2
|
||||
}'
|
||||
```
|
||||
|
||||
In the `job-service` terminal window, the output should be:
|
||||
|
||||
```text
|
||||
== APP - job-app == Received job request...
|
||||
== APP - job-app == Starting droid: R2-D2
|
||||
== APP - job-app == Executing maintenance job: Oil Change
|
||||
```
|
||||
|
||||
3. On the same terminal window, schedule the `C-3PO` Job using the Jobs API.
|
||||
|
||||
```bash
|
||||
curl -X POST \
|
||||
http://localhost:6200/scheduleJob \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "C-3PO",
|
||||
"job": "Limb Calibration",
|
||||
"dueTime": 30
|
||||
}'
|
||||
```
|
||||
|
||||
### Get a scheduled job
|
||||
|
||||
1. On the same terminal window, run the command below to get the recently scheduled `C-3PO` job.
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:6200/getJob/C-3PO -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
You should see the following:
|
||||
|
||||
```text
|
||||
{"name":"c-3po", "dueTime":"30s", "data":{"@type":"type.googleapis.com/google.protobuf.Value", "value":{"Value":"C-3PO:Limb Calibration"}}}
|
||||
```
|
||||
|
||||
### Delete a scheduled job
|
||||
|
||||
1. On the same terminal window, run the command below to deleted the recently scheduled `C-3PO` job.
|
||||
|
||||
```bash
|
||||
curl -X DELETE http://localhost:6200/deleteJob/C-3PO -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
2. Run the command below to attempt to retrieve the deleted job:
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:6200/getJob/C-3PO -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
In the `job-service` terminal window, the output should be similar to the following:
|
||||
|
||||
```text
|
||||
ERRO[0157] Error getting job C-3PO due to: rpc error: code = NotFound desc = job not found: C-3PO instance=local scope=dapr.api type=log ver=1.15.0
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
version: 1
|
||||
apps:
|
||||
- appDirPath: ./job-service/
|
||||
appID: job-service-sdk
|
||||
appPort: 6200
|
||||
daprHTTPPort: 6280
|
||||
command: ["dotnet", "run"]
|
||||
appLogDestination: console
|
||||
daprdLogDestination: console
|
||||
- appDirPath: ./job-scheduler/
|
||||
appID: job-scheduler-sdk
|
||||
appPort: 6300
|
||||
daprHTTPPort: 6380
|
||||
command: ["dotnet", "run"]
|
||||
appLogDestination: console
|
||||
daprdLogDestination: console
|
|
@ -0,0 +1,101 @@
|
|||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using Dapr.Client;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var app = builder.Build();
|
||||
|
||||
await Task.Delay(5000); // Allow time for the job-service-sdk to start
|
||||
|
||||
// Instantiate an HTTP client for invoking the job-service-sdk application
|
||||
var httpClient = DaprClient.CreateInvokeHttpClient(appId: "job-service-sdk");
|
||||
|
||||
// Job details
|
||||
var r2d2Job = new DroidJob
|
||||
{
|
||||
Name = "R2-D2",
|
||||
Job = "Oil Change",
|
||||
DueTime = 15
|
||||
};
|
||||
|
||||
var c3poJob = new DroidJob
|
||||
{
|
||||
Name = "C-3PO",
|
||||
Job = "Limb Calibration",
|
||||
DueTime = 20
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
// Schedule R2-D2 job
|
||||
await ScheduleJob(r2d2Job);
|
||||
await Task.Delay(5000);
|
||||
// Get R2-D2 job details
|
||||
await GetJobDetails(r2d2Job);
|
||||
|
||||
// Schedule C-3PO job
|
||||
await ScheduleJob(c3poJob);
|
||||
await Task.Delay(5000);
|
||||
// Get C-3PO job details
|
||||
await GetJobDetails(c3poJob);
|
||||
|
||||
await Task.Delay(30000); // Allow time for jobs to complete
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error: {ex.Message}");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
async Task ScheduleJob(DroidJob job)
|
||||
{
|
||||
Console.WriteLine($"Scheduling job...");
|
||||
|
||||
try
|
||||
{
|
||||
var response = await httpClient.PostAsJsonAsync("/scheduleJob", job);
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
Console.WriteLine($"Job scheduled: {result}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error scheduling job: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
async Task GetJobDetails(DroidJob job)
|
||||
{
|
||||
Console.WriteLine($"Getting job: " + job.Name);
|
||||
|
||||
try
|
||||
{
|
||||
var response = await httpClient.GetAsync($"/getJob/{job.Name}");
|
||||
var jobDetails = await response.Content.ReadAsStringAsync();
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
Console.WriteLine($"Job details: {jobDetails}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error getting job: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
await app.RunAsync();
|
||||
|
||||
public class DroidJob
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("job")]
|
||||
public string? Job { get; set; }
|
||||
|
||||
[JsonPropertyName("dueTime")]
|
||||
public int DueTime { get; set; }
|
||||
}
|
||||
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>jobs_scheduler</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapr.Client" Version="1.15.0-rc07" />
|
||||
<PackageReference Include="Dapr.Jobs" Version="1.15.0-rc07" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,163 @@
|
|||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
using Dapr.Jobs;
|
||||
using Dapr.Jobs.Extensions;
|
||||
using Dapr.Jobs.Models;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
// The jobs host is a background service that connects to the sidecar over gRPC
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddDaprJobsClient();
|
||||
var app = builder.Build();
|
||||
|
||||
var appPort = Environment.GetEnvironmentVariable("APP_PORT") ?? "6200";
|
||||
var jobsClient = app.Services.GetRequiredService<DaprJobsClient>();
|
||||
|
||||
app.MapPost("/scheduleJob", async (HttpContext context) =>
|
||||
{
|
||||
var droidJob = await JsonSerializer.DeserializeAsync<DroidJob>(context.Request.Body);
|
||||
if (droidJob?.Name is null || droidJob?.Job is null)
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync("Job must contain a name and a task " + context.Request.Body);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var jobData = new JobData
|
||||
{
|
||||
Droid = droidJob.Name,
|
||||
Task = droidJob.Job
|
||||
};
|
||||
|
||||
await jobsClient.ScheduleJobWithPayloadAsync(droidJob.Name, DaprJobSchedule.FromDuration(TimeSpan.FromSeconds(droidJob.DueTime)), payload: jobData, repeats: 1); //Schedule cron job that repeats once
|
||||
|
||||
Console.WriteLine($"Job Scheduled: {droidJob.Name}");
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsJsonAsync(droidJob);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error scheduling job: " + e);
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
app.MapGet("/getJob/{name}", async (HttpContext context) =>
|
||||
{
|
||||
var jobName = context.Request.RouteValues["name"]?.ToString();
|
||||
Console.WriteLine($"Getting job...");
|
||||
|
||||
if (string.IsNullOrEmpty(jobName))
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync("Job name required");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var jobDetails = await jobsClient.GetJobAsync(jobName);
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsJsonAsync(jobDetails);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error getting job: " + e);
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync($"Error getting job");
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
app.MapDelete("/deleteJob/{name}", async (HttpContext context) =>
|
||||
{
|
||||
var jobName = context.Request.RouteValues["name"]?.ToString();
|
||||
Console.WriteLine($"Deleting job: " + jobName);
|
||||
|
||||
if (string.IsNullOrEmpty(jobName))
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync("Job name required");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await jobsClient.DeleteJobAsync(jobName);
|
||||
Console.WriteLine($"Job deleted: {jobName}");
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
await context.Response.WriteAsync("Job deleted");
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Error deleting job: " + e);
|
||||
context.Response.StatusCode = 400;
|
||||
await context.Response.WriteAsync($"Error deleting job");
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
// Job handler route to capture incoming jobs
|
||||
app.MapDaprScheduledJobHandler((string jobName, ReadOnlyMemory<byte> jobPayload) =>
|
||||
{
|
||||
Console.WriteLine("Handling job...");
|
||||
var deserializedPayload = Encoding.UTF8.GetString(jobPayload.Span);
|
||||
|
||||
try
|
||||
{
|
||||
if (deserializedPayload is null)
|
||||
{
|
||||
throw new Exception("Payload is null");
|
||||
}
|
||||
|
||||
var jobData = JsonSerializer.Deserialize<JobData>(deserializedPayload);
|
||||
if (jobData?.Droid is null || jobData?.Task is null)
|
||||
{
|
||||
throw new Exception("Invalid format of job data.");
|
||||
}
|
||||
|
||||
// Handling Droid Job from decoded value
|
||||
Console.WriteLine($"Starting droid: {jobData.Droid}");
|
||||
Console.WriteLine($"Executing maintenance job: {jobData.Task}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to handle job {jobName}");
|
||||
Console.Error.WriteLine($"Error handling job: {ex.Message}");
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
app.Run($"http://*:{appPort}");
|
||||
|
||||
// Classes for request and response models
|
||||
public class JobData
|
||||
{
|
||||
[JsonPropertyName("droid")]
|
||||
public string? Droid { get; set; }
|
||||
|
||||
[JsonPropertyName("task")]
|
||||
public string? Task { get; set; }
|
||||
}
|
||||
|
||||
public class DroidJob
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("job")]
|
||||
public string? Job { get; set; }
|
||||
|
||||
[JsonPropertyName("dueTime")]
|
||||
public int DueTime { get; set; }
|
||||
}
|
||||
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:5305",
|
||||
"sslPort": 44346
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5023",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:7073;http://localhost:5023",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapr.Jobs" Version="1.15.0-rc07" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,2 @@
|
|||
include ../../../docker.mk
|
||||
include ../../../validate.mk
|
|
@ -240,4 +240,4 @@ When you ran `dapr run -f .`:
|
|||
8. The `NotifyActivity` workflow activity sends a notification saying that order `571a6e25` has completed.
|
||||
9. The workflow terminates as completed and the OrderResult is set to processed.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://v1-15.docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
|
|
|
@ -95,4 +95,4 @@ When you ran the above comands:
|
|||
8. The `NotifyActivity` workflow activity sends a notification saying that order `b4cb2687-1af0-4f8d-9659-eb6389c07ade` has completed.
|
||||
9. The workflow terminates as completed and the OrderResult is set to processed.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://v1-15.docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
|
@ -122,4 +122,5 @@ When you ran `dapr run -f .`:
|
|||
8. The `NotifyActivity` workflow activity sends a notification saying that order `d1bf548b-c854-44af-978e-90c61ed88e3c` has completed.
|
||||
9. The workflow terminates as completed and the orderResult is set to processed.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://v1-15.docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `RequestApprovalActivity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
|
|
|
@ -174,4 +174,4 @@ When you ran `dapr run -f .`
|
|||
8. The `notifyActivity` workflow activity sends a notification saying that order `f5087775-779c-4e73-ac77-08edfcb375f4` has completed and processed.
|
||||
9. The workflow terminates as completed and processed.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `requestApprovalActivity` activity nor wait for an approval event. The dapr.yaml multi-app run file starts a console application and can't accept incoming events easily. The dapr-AppWithDaprServer.yaml and dapr-AppWithExpressServer.yaml files start a service that can accept incoming events. Use the [raise event API](https://v1-15.docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client in the server apps to send an event to the workflow.
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `requestApprovalActivity` activity nor wait for an approval event. The dapr.yaml multi-app run file starts a console application and can't accept incoming events easily. The dapr-AppWithDaprServer.yaml and dapr-AppWithExpressServer.yaml files start a service that can accept incoming events. Use the [raise event API](https://docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client in the server apps to send an event to the workflow.
|
|
@ -124,4 +124,4 @@ When you ran `dapr run -f .`
|
|||
8. The `notify_activity` workflow activity sends a notification saying that order `fc8a507e4a2246d2917d3ad4e3111240` has completed.
|
||||
9. The workflow terminates as completed and the OrderResult is set to processed.
|
||||
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `request_approval_activity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://v1-15.docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
> **Note:** This quickstart uses an OrderPayload of one car with a total cost of $5000. Since the total order cost is not over 5000, the workflow will not call the `request_approval_activity` activity nor wait for an approval event. Since the quickstart is a console application, it can't accept incoming events easily. If you want to test this scenario, convert the console app to a service and use the [raise event API](https://docs.dapr.io/reference/api/workflow_api/#raise-event-request) via HTTP/gRPC or via the Dapr Workflow client to send an event to the workflow instance.
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
dapr-ext-workflow>=1.15.0
|
||||
dapr>=1.15.0
|
||||
dapr>=1.15.0
|
||||
|
|
Loading…
Reference in New Issue