From 74f6b0127fb33d72ff1c62aecfce8b1694a6b334 Mon Sep 17 00:00:00 2001 From: Phillip Hoff Date: Wed, 21 Aug 2024 23:47:39 -0700 Subject: [PATCH] Merge 1.14 release branch back into `master`. (#1337) --- .devcontainer/localinit.sh | 2 +- .github/workflows/itests.yml | 6 +- daprdocs/content/en/dotnet-sdk-docs/_index.md | 2 +- .../dotnet-actors/dotnet-actors-howto.md | 2 +- examples/Actor/README.md | 4 +- .../BulkPublishEventExample/README.md | 2 +- .../PublishEventExample/README.md | 2 +- samples/Client/README.md | 2 +- .../Protos/dapr/proto/common/v1/common.proto | 2 +- .../dapr/proto/dapr/v1/appcallback.proto | 32 ++- .../Protos/dapr/proto/dapr/v1/dapr.proto | 187 ++++++++++++++++-- 11 files changed, 212 insertions(+), 31 deletions(-) diff --git a/.devcontainer/localinit.sh b/.devcontainer/localinit.sh index 80b27e4f4..69c4c1274 100644 --- a/.devcontainer/localinit.sh +++ b/.devcontainer/localinit.sh @@ -6,4 +6,4 @@ az extension add --name containerapp --yes nvm install v18.12.1 # initialize Dapr -dapr init --runtime-version=1.10.0-rc.2 \ No newline at end of file +dapr init --runtime-version=1.14.0 \ No newline at end of file diff --git a/.github/workflows/itests.yml b/.github/workflows/itests.yml index 00121c9f5..36741ce7c 100644 --- a/.github/workflows/itests.yml +++ b/.github/workflows/itests.yml @@ -42,9 +42,9 @@ jobs: GOOS: linux GOARCH: amd64 GOPROXY: https://proxy.golang.org - DAPR_CLI_VER: 1.13.0 - DAPR_RUNTIME_VER: 1.13.2 - DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/release-1.12/install/install.sh + DAPR_CLI_VER: 1.14.0 + DAPR_RUNTIME_VER: 1.14.0 + DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/release-1.14/install/install.sh DAPR_CLI_REF: '' steps: - name: Set up Dapr CLI diff --git a/daprdocs/content/en/dotnet-sdk-docs/_index.md b/daprdocs/content/en/dotnet-sdk-docs/_index.md index e823ca29f..121dde310 100644 --- a/daprdocs/content/en/dotnet-sdk-docs/_index.md +++ b/daprdocs/content/en/dotnet-sdk-docs/_index.md @@ -18,7 +18,7 @@ Dapr offers a variety of packages to help with the development of .NET applicati - [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed - Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}}) -- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed +- [.NET 6+](https://dotnet.microsoft.com/download) installed ## Installation diff --git a/daprdocs/content/en/dotnet-sdk-docs/dotnet-actors/dotnet-actors-howto.md b/daprdocs/content/en/dotnet-sdk-docs/dotnet-actors/dotnet-actors-howto.md index 8229d6820..eaa13625d 100644 --- a/daprdocs/content/en/dotnet-sdk-docs/dotnet-actors/dotnet-actors-howto.md +++ b/daprdocs/content/en/dotnet-sdk-docs/dotnet-actors/dotnet-actors-howto.md @@ -45,7 +45,7 @@ This project contains the implementation of the actor client which calls MyActor - [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed. - Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}}). -- [.NET Core 3.1 or .NET 6+](https://dotnet.microsoft.com/download) installed. Dapr .NET SDK uses [ASP.NET Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-6.0). +- [.NET 6+](https://dotnet.microsoft.com/download) installed. Dapr .NET SDK uses [ASP.NET Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-6.0). ## Step 0: Prepare diff --git a/examples/Actor/README.md b/examples/Actor/README.md index a7bb46c03..89b6bf0bb 100644 --- a/examples/Actor/README.md +++ b/examples/Actor/README.md @@ -4,7 +4,7 @@ The Actor example shows how to create a virtual actor (`DemoActor`) and invoke i ## Prerequisites -- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed +- [.NET 6+](https://dotnet.microsoft.com/download) installed - [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/) - [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/) - [Dapr .NET SDK](https://github.com/dapr/dotnet-sdk/) @@ -102,7 +102,7 @@ docker push /demo-actor:latest ### Deploy the Actor service to Kubernetes #### Prerequisites - A Kubernetes cluster with `kubectl` configured to access it. -- Dapr v1.13+ installed on the Kubernetes cluster. Follow the instructions [here](https://docs.dapr.io/getting-started/install-dapr-kubernetes/). +- Dapr v1.14+ installed on the Kubernetes cluster. Follow the instructions [here](https://docs.dapr.io/getting-started/install-dapr-kubernetes/). - A Docker registry where you pushed the `DemoActor` image. #### Deploy the Actor service diff --git a/examples/Client/PublishSubscribe/BulkPublishEventExample/README.md b/examples/Client/PublishSubscribe/BulkPublishEventExample/README.md index dfcc99ca6..39d206fa2 100644 --- a/examples/Client/PublishSubscribe/BulkPublishEventExample/README.md +++ b/examples/Client/PublishSubscribe/BulkPublishEventExample/README.md @@ -2,7 +2,7 @@ ## Prerequisites -- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed +- [.NET 6+](https://dotnet.microsoft.com/download) installed - [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/) - [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/) - [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/) diff --git a/examples/Client/PublishSubscribe/PublishEventExample/README.md b/examples/Client/PublishSubscribe/PublishEventExample/README.md index 455fc2537..9f3af565f 100644 --- a/examples/Client/PublishSubscribe/PublishEventExample/README.md +++ b/examples/Client/PublishSubscribe/PublishEventExample/README.md @@ -2,7 +2,7 @@ ## Prerequisites -- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed +- [.NET 6+](https://dotnet.microsoft.com/download) installed - [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/) - [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/) - [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/) diff --git a/samples/Client/README.md b/samples/Client/README.md index 2501bfadc..2bb738d89 100644 --- a/samples/Client/README.md +++ b/samples/Client/README.md @@ -8,7 +8,7 @@ The following examples will show you how to: ## Prerequisites -* [.Net Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) +* [.NET 6+](https://dotnet.microsoft.com/download) * [Dapr CLI](https://github.com/dapr/cli) * [Dapr DotNet SDK](https://github.com/dapr/dotnet-sdk) diff --git a/src/Dapr.Client/Protos/dapr/proto/common/v1/common.proto b/src/Dapr.Client/Protos/dapr/proto/common/v1/common.proto index 1e63b885d..4acf9159d 100644 --- a/src/Dapr.Client/Protos/dapr/proto/common/v1/common.proto +++ b/src/Dapr.Client/Protos/dapr/proto/common/v1/common.proto @@ -157,4 +157,4 @@ message ConfigurationItem { // the metadata which will be passed to/from configuration store component. map metadata = 3; -} +} \ No newline at end of file diff --git a/src/Dapr.Client/Protos/dapr/proto/dapr/v1/appcallback.proto b/src/Dapr.Client/Protos/dapr/proto/dapr/v1/appcallback.proto index 823c0aae4..a86040364 100644 --- a/src/Dapr.Client/Protos/dapr/proto/dapr/v1/appcallback.proto +++ b/src/Dapr.Client/Protos/dapr/proto/dapr/v1/appcallback.proto @@ -15,6 +15,7 @@ syntax = "proto3"; package dapr.proto.runtime.v1; +import "google/protobuf/any.proto"; import "google/protobuf/empty.proto"; import "dapr/proto/common/v1/common.proto"; import "google/protobuf/struct.proto"; @@ -59,8 +60,37 @@ service AppCallbackHealthCheck { service AppCallbackAlpha { // Subscribes bulk events from Pubsub rpc OnBulkTopicEventAlpha1(TopicEventBulkRequest) returns (TopicEventBulkResponse) {} + + // Sends job back to the app's endpoint at trigger time. + rpc OnJobEventAlpha1 (JobEventRequest) returns (JobEventResponse); +} + +message JobEventRequest { + // Job name. + string name = 1; + + // Job data to be sent back to app. + google.protobuf.Any data = 2; + + // Required. method is a method name which will be invoked by caller. + string method = 3; + + // The type of data content. + // + // This field is required if data delivers http request body + // Otherwise, this is optional. + string content_type = 4; + + // HTTP specific fields if request conveys http-compatible request. + // + // This field is required for http-compatible request. Otherwise, + // this field is optional. + common.v1.HTTPExtension http_extension = 5; } +// JobEventResponse is the response from the app when a job is triggered. +message JobEventResponse {} + // TopicEventRequest message is compatible with CloudEvent spec v1.0 // https://github.com/cloudevents/spec/blob/v1.0/spec.md message TopicEventRequest { @@ -310,4 +340,4 @@ message ListInputBindingsResponse { // HealthCheckResponse is the message with the response to the health check. // This message is currently empty as used as placeholder. -message HealthCheckResponse {} +message HealthCheckResponse {} \ No newline at end of file diff --git a/src/Dapr.Client/Protos/dapr/proto/dapr/v1/dapr.proto b/src/Dapr.Client/Protos/dapr/proto/dapr/v1/dapr.proto index 5ec1cc9d8..4185fb391 100644 --- a/src/Dapr.Client/Protos/dapr/proto/dapr/v1/dapr.proto +++ b/src/Dapr.Client/Protos/dapr/proto/dapr/v1/dapr.proto @@ -19,6 +19,7 @@ import "google/protobuf/any.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; import "dapr/proto/common/v1/common.proto"; +import "dapr/proto/dapr/v1/appcallback.proto"; option csharp_namespace = "Dapr.Client.Autogen.Grpc.v1"; option java_outer_classname = "DaprProtos"; @@ -58,6 +59,10 @@ service Dapr { // Bulk Publishes multiple events to the specified topic. rpc BulkPublishEventAlpha1(BulkPublishRequest) returns (BulkPublishResponse) {} + // SubscribeTopicEventsAlpha1 subscribes to a PubSub topic and receives topic + // events from it. + rpc SubscribeTopicEventsAlpha1(stream SubscribeTopicEventsRequestAlpha1) returns (stream TopicEventRequest) {} + // Invokes binding data to specific output bindings rpc InvokeBinding(InvokeBindingRequest) returns (InvokeBindingResponse) {} @@ -188,6 +193,15 @@ service Dapr { rpc RaiseEventWorkflowBeta1 (RaiseEventWorkflowRequest) returns (google.protobuf.Empty) {} // Shutdown the sidecar rpc Shutdown (ShutdownRequest) returns (google.protobuf.Empty) {} + + // Create and schedule a job + rpc ScheduleJobAlpha1(ScheduleJobRequest) returns (ScheduleJobResponse) {} + + // Gets a scheduled job + rpc GetJobAlpha1(GetJobRequest) returns (GetJobResponse) {} + + // Delete a job + rpc DeleteJobAlpha1(DeleteJobRequest) returns (DeleteJobResponse) {} } // InvokeServiceRequest represents the request message for Service invocation. @@ -411,6 +425,47 @@ message BulkPublishResponseFailedEntry { string error = 2; } +// SubscribeTopicEventsRequestAlpha1 is a message containing the details for +// subscribing to a topic via streaming. +// The first message must always be the initial request. All subsequent +// messages must be event responses. +message SubscribeTopicEventsRequestAlpha1 { + oneof subscribe_topic_events_request_type { + SubscribeTopicEventsInitialRequestAlpha1 initial_request = 1; + SubscribeTopicEventsResponseAlpha1 event_response = 2; + } +} + +// SubscribeTopicEventsInitialRequestAlpha1 is the initial message containing the +// details for subscribing to a topic via streaming. +message SubscribeTopicEventsInitialRequestAlpha1 { + // The name of the pubsub component + string pubsub_name = 1; + + // The pubsub topic + string topic = 2; + + // The metadata passing to pub components + // + // metadata property: + // - key : the key of the message. + map metadata = 3; + + // dead_letter_topic is the topic to which messages that fail to be processed + // are sent. + optional string dead_letter_topic = 4; +} + +// SubscribeTopicEventsResponseAlpha1 is a message containing the result of a +// subscription to a topic. +message SubscribeTopicEventsResponseAlpha1 { + // id is the unique identifier for the subscription request. + string id = 1; + + // status is the result of the subscription request. + TopicEventResponse status = 2; +} + // InvokeBindingRequest is the message to send data to output bindings message InvokeBindingRequest { // The name of the output binding to invoke. @@ -504,45 +559,45 @@ message ExecuteStateTransactionRequest { // RegisterActorTimerRequest is the message to register a timer for an actor of a given type and id. message RegisterActorTimerRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string name = 3; - string due_time = 4; + string due_time = 4 [json_name = "dueTime"]; string period = 5; string callback = 6; - bytes data = 7; + bytes data = 7; string ttl = 8; } // UnregisterActorTimerRequest is the message to unregister an actor timer message UnregisterActorTimerRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string name = 3; } // RegisterActorReminderRequest is the message to register a reminder for an actor of a given type and id. message RegisterActorReminderRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string name = 3; - string due_time = 4; + string due_time = 4 [json_name = "dueTime"]; string period = 5; - bytes data = 6; + bytes data = 6; string ttl = 7; } // UnregisterActorReminderRequest is the message to unregister an actor reminder. message UnregisterActorReminderRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string name = 3; } // GetActorStateRequest is the message to get key-value states from specific actor. message GetActorStateRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string key = 3; } @@ -556,8 +611,8 @@ message GetActorStateResponse { // ExecuteActorStateTransactionRequest is the message to execute multiple operations on a specified actor. message ExecuteActorStateTransactionRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; repeated TransactionalActorStateOperation operations = 3; } @@ -575,8 +630,8 @@ message TransactionalActorStateOperation { // InvokeActorRequest is the message to call an actor. message InvokeActorRequest { - string actor_type = 1; - string actor_id = 2; + string actor_type = 1 [json_name = "actorType"]; + string actor_id = 2 [json_name = "actorId"]; string method = 3; bytes data = 4; map metadata = 5; @@ -605,6 +660,7 @@ message GetMetadataResponse { string runtime_version = 8 [json_name = "runtimeVersion"]; repeated string enabled_features = 9 [json_name = "enabledFeatures"]; ActorRuntime actor_runtime = 10 [json_name = "actorRuntime"]; + //TODO: Cassie: probably add scheduler runtime status } message ActorRuntime { @@ -665,6 +721,19 @@ message PubsubSubscription { map metadata = 3 [json_name = "metadata"]; PubsubSubscriptionRules rules = 4 [json_name = "rules"]; string dead_letter_topic = 5 [json_name = "deadLetterTopic"]; + PubsubSubscriptionType type = 6 [json_name = "type"]; +} + +// PubsubSubscriptionType indicates the type of subscription +enum PubsubSubscriptionType { + // UNKNOWN is the default value for the subscription type. + UNKNOWN = 0; + // Declarative subscription (k8s CRD) + DECLARATIVE = 1; + // Programmatically created subscription + PROGRAMMATIC = 2; + // Bidirectional Streaming subscription + STREAMING = 3; } message PubsubSubscriptionRules { @@ -1108,3 +1177,85 @@ message PurgeWorkflowRequest { message ShutdownRequest { // Empty } + +// Job is the definition of a job. At least one of schedule or due_time must be +// provided but can also be provided together. +message Job { + // The unique name for the job. + string name = 1 [json_name = "name"]; + + // schedule is an optional schedule at which the job is to be run. + // Accepts both systemd timer style cron expressions, as well as human + // readable '@' prefixed period strings as defined below. + // + // Systemd timer style cron accepts 6 fields: + // seconds | minutes | hours | day of month | month | day of week + // 0-59 | 0-59 | 0-23 | 1-31 | 1-12/jan-dec | 0-7/sun-sat + // + // "0 30 * * * *" - every hour on the half hour + // "0 15 3 * * *" - every day at 03:15 + // + // Period string expressions: + // Entry | Description | Equivalent To + // ----- | ----------- | ------------- + // @every | Run every (e.g. '@every 1h30m') | N/A + // @yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 * + // @monthly | Run once a month, midnight, first of month | 0 0 0 1 * * + // @weekly | Run once a week, midnight on Sunday | 0 0 0 * * 0 + // @daily (or @midnight) | Run once a day, midnight | 0 0 0 * * * + // @hourly | Run once an hour, beginning of hour | 0 0 * * * * + optional string schedule = 2 [json_name = "schedule"]; + + // repeats is the optional number of times in which the job should be + // triggered. If not set, the job will run indefinitely or until expiration. + optional uint32 repeats = 3 [json_name = "repeats"]; + + // due_time is the optional time at which the job should be active, or the + // "one shot" time if other scheduling type fields are not provided. Accepts + // a "point in time" string in the format of RFC3339, Go duration string + // (calculated from job creation time), or non-repeating ISO8601. + optional string due_time = 4 [json_name = "dueTime"]; + + // ttl is the optional time to live or expiration of the job. Accepts a + // "point in time" string in the format of RFC3339, Go duration string + // (calculated from job creation time), or non-repeating ISO8601. + optional string ttl = 5 [json_name = "ttl"]; + + // payload is the serialized job payload that will be sent to the recipient + // when the job is triggered. + google.protobuf.Any data = 6 [json_name = "data"]; +} + +// ScheduleJobRequest is the message to create/schedule the job. +message ScheduleJobRequest { + // The job details. + Job job = 1; +} + +// ScheduleJobResponse is the message response to create/schedule the job. +message ScheduleJobResponse { + // Empty +} + +// GetJobRequest is the message to retrieve a job. +message GetJobRequest { + // The name of the job. + string name = 1; +} + +// GetJobResponse is the message's response for a job retrieved. +message GetJobResponse { + // The job details. + Job job = 1; +} + +// DeleteJobRequest is the message to delete the job by name. +message DeleteJobRequest { + // The name of the job. + string name = 1; +} + +// DeleteJobResponse is the message response to delete the job by name. +message DeleteJobResponse { + // Empty +}