-
Notifications
You must be signed in to change notification settings - Fork 372
Workflow Management - Initial Methods #1003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c2a41d9
8cd0f0e
b4498cc
94cea4d
ba0d6b8
9d2db44
3fa3012
211224d
01f257c
6688012
68e1450
f005729
3ba809f
51e4349
aaf7dcc
a704c02
e49ef1b
cff1801
dc309c3
e086a4a
bd8f2ea
770f96e
989d7c4
fba845f
f713701
55856e2
b737575
43b2035
aedece7
654b5e4
49a0c94
09e6bbf
938e349
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1462,6 +1462,120 @@ public async override Task<UnlockResponse> Unlock( | |
|
|
||
| #endregion | ||
|
|
||
|
|
||
| #region Workflow API | ||
| /// <inheritdoc/> | ||
| [Obsolete] | ||
| public async override Task<WorkflowReference> StartWorkflowAsync( | ||
| string instanceId, | ||
| string workflowComponent, | ||
| string workflowName, | ||
| Object input, | ||
| IReadOnlyDictionary<string, string> workflowOptions = default, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(workflowName, nameof(workflowName)); | ||
| ArgumentVerifier.ThrowIfNull(input, nameof(input)); | ||
|
|
||
| // Serialize json data. Converts input object to bytes and then bytestring inside the request. | ||
| byte[] jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(input); | ||
|
|
||
| var request = new Autogenerated.StartWorkflowRequest() | ||
| { | ||
| InstanceId = instanceId, | ||
| WorkflowComponent = workflowComponent, | ||
| WorkflowName = workflowName, | ||
| Input = ByteString.CopyFrom(jsonUtf8Bytes), | ||
| }; | ||
|
|
||
| if (workflowOptions?.Count > 0) | ||
| { | ||
| foreach (var item in workflowOptions) | ||
|
Comment on lines
+1493
to
+1495
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need this
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you need it for the null check.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is here to check against the possibility of workflowOptions being Null. |
||
| { | ||
| request.Options[item.Key] = item.Value; | ||
| } | ||
| } | ||
|
|
||
| try | ||
| { | ||
| var options = CreateCallOptions(headers: null, cancellationToken); | ||
| var response = await client.StartWorkflowAlpha1Async(request, options); | ||
| return new WorkflowReference(response.InstanceId); | ||
|
|
||
| } | ||
| catch (RpcException ex) | ||
| { | ||
| throw new DaprException("Start Workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); | ||
| } | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| [Obsolete] | ||
| public async override Task<GetWorkflowResponse> GetWorkflowAsync( | ||
| string instanceId, | ||
| string workflowComponent, | ||
| string workflowName, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); | ||
|
|
||
| var request = new Autogenerated.GetWorkflowRequest() | ||
| { | ||
| InstanceId = instanceId, | ||
| WorkflowComponent = workflowComponent, | ||
| WorkflowType = workflowName //TODO: Change 'WorkflowType' to 'WorkflowName' once changes go through dapr/dapr | ||
| }; | ||
|
|
||
| try | ||
| { | ||
| var options = CreateCallOptions(headers: null, cancellationToken); | ||
| var response = await client.GetWorkflowAlpha1Async(request, options); | ||
| var dateTimeValue = new DateTime(response.StartTime, DateTimeKind.Utc); | ||
| return new GetWorkflowResponse(response.InstanceId, dateTimeValue, response.Metadata); | ||
| } | ||
| catch (RpcException ex) | ||
| { | ||
| throw new DaprException("Get workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); | ||
| } | ||
|
|
||
| } | ||
|
|
||
|
|
||
| /// <inheritdoc/> | ||
| [Obsolete] | ||
| public async override Task TerminateWorkflowAsync( | ||
| string instanceId, | ||
| string workflowComponent, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(instanceId, nameof(instanceId)); | ||
| ArgumentVerifier.ThrowIfNullOrEmpty(workflowComponent, nameof(workflowComponent)); | ||
|
|
||
| var request = new Autogenerated.TerminateWorkflowRequest() | ||
| { | ||
| InstanceId = instanceId, | ||
| WorkflowComponent = workflowComponent | ||
| }; | ||
|
|
||
| var options = CreateCallOptions(headers: null, cancellationToken); | ||
|
|
||
| try | ||
| { | ||
| await client.TerminateWorkflowAlpha1Async(request, options); | ||
| } | ||
| catch (RpcException ex) | ||
| { | ||
| throw new DaprException("Terminate workflow operation failed: the Dapr endpoint indicated a failure. See InnerException for details.", ex); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| #endregion | ||
|
|
||
|
|
||
| #region Dapr Sidecar Methods | ||
|
|
||
| /// <inheritdoc/> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // ------------------------------------------------------------------------ | ||
| // Copyright 2021 The Dapr Authors | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // ------------------------------------------------------------------------ | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Dapr.Client | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new <see cref="GetWorkflowResponse" />. | ||
| /// </summary> | ||
| /// <param name="instanceId">The instance ID assocated with this response.</param> | ||
| /// <param name="startTime">The time at which the workflow started executing.</param> | ||
| /// <param name="metadata">The response metadata.</param> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: the whitespace needs to be fixed here too. |
||
| public record GetWorkflowResponse(string instanceId, DateTime startTime, IReadOnlyDictionary<string, string> metadata); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ package dapr.proto.runtime.v1; | |
|
|
||
| import "google/protobuf/any.proto"; | ||
| import "google/protobuf/empty.proto"; | ||
| import "google/protobuf/timestamp.proto"; | ||
| import "dapr/proto/common/v1/common.proto"; | ||
|
|
||
| option csharp_namespace = "Dapr.Client.Autogen.Grpc.v1"; | ||
|
|
@@ -110,6 +111,15 @@ service Dapr { | |
| // Sets value in extended metadata of the sidecar | ||
| rpc SetMetadata (SetMetadataRequest) returns (google.protobuf.Empty) {} | ||
|
|
||
| // Start Workflow | ||
| rpc StartWorkflowAlpha1 (StartWorkflowRequest) returns (WorkflowReference) {} | ||
|
|
||
| // Get Workflow details | ||
| rpc GetWorkflowAlpha1 (GetWorkflowRequest) returns (GetWorkflowResponse) {} | ||
|
|
||
| // Terminate Workflow | ||
| rpc TerminateWorkflowAlpha1 (TerminateWorkflowRequest) returns (TerminateWorkflowResponse) {} | ||
|
|
||
| // Shutdown the sidecar | ||
| rpc Shutdown (google.protobuf.Empty) returns (google.protobuf.Empty) {} | ||
| } | ||
|
|
@@ -345,10 +355,10 @@ message InvokeBindingRequest { | |
| bytes data = 2; | ||
|
|
||
| // The metadata passing to output binding components | ||
| // | ||
| // | ||
| // Common metadata property: | ||
| // - ttlInSeconds : the time to live in seconds for the message. | ||
| // If set in the binding definition will cause all messages to | ||
| // - ttlInSeconds : the time to live in seconds for the message. | ||
| // If set in the binding definition will cause all messages to | ||
| // have a default time to live. The message ttl overrides any value | ||
| // in the binding definition. | ||
| map<string, string> metadata = 3; | ||
|
|
@@ -411,7 +421,7 @@ message TransactionalStateOperation { | |
| // The type of operation to be executed | ||
| string operationType = 1; | ||
|
|
||
| // State values to be operated on | ||
| // State values to be operated on | ||
| common.v1.StateItem request = 2; | ||
| } | ||
|
|
||
|
|
@@ -504,6 +514,7 @@ message InvokeActorRequest { | |
| string actor_id = 2; | ||
| string method = 3; | ||
| bytes data = 4; | ||
| map<string, string> metadata = 5; | ||
| } | ||
|
|
||
| // InvokeActorResponse is the method that returns an actor invocation response. | ||
|
|
@@ -517,6 +528,7 @@ message GetMetadataResponse { | |
| repeated ActiveActorsCount active_actors_count = 2; | ||
| repeated RegisteredComponents registered_components = 3; | ||
| map<string, string> extended_metadata = 4; | ||
| repeated PubsubSubscription subscriptions = 5; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like there are several unrelated pubsub changes in this PR? |
||
| } | ||
|
|
||
| message ActiveActorsCount { | ||
|
|
@@ -531,6 +543,23 @@ message RegisteredComponents { | |
| repeated string capabilities = 4; | ||
| } | ||
|
|
||
| message PubsubSubscription { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yash-nisar - Does this impact your changes in #1009?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @halspang Nope, I don't think we're calling any auto generated code for bulk subscribe but I'll update the proto anyway just to be consistent with what we have in dapr/dapr. |
||
| string pubsub_name = 1; | ||
| string topic = 2; | ||
| map<string,string> metadata = 3; | ||
| PubsubSubscriptionRules rules = 4; | ||
| string dead_letter_topic = 5; | ||
| } | ||
|
|
||
| message PubsubSubscriptionRules { | ||
| repeated PubsubSubscriptionRule rules = 1; | ||
| } | ||
|
|
||
| message PubsubSubscriptionRule { | ||
| string match = 1; | ||
| string path = 2; | ||
| } | ||
|
|
||
| message SetMetadataRequest { | ||
| string key = 1; | ||
| string value = 2; | ||
|
|
@@ -644,4 +673,36 @@ message UnlockResponse { | |
| } | ||
|
|
||
| Status status = 1; | ||
| } | ||
| } | ||
|
|
||
| message WorkflowReference { | ||
| string instance_id = 1; | ||
| } | ||
|
|
||
| message GetWorkflowRequest { | ||
| string instance_id = 1; | ||
| string workflow_type = 2; | ||
| string workflow_component = 3; | ||
| } | ||
|
|
||
| message GetWorkflowResponse { | ||
| string instance_id = 1; | ||
| int64 start_time = 2; | ||
| map<string, string> metadata = 3; | ||
| } | ||
|
|
||
| message StartWorkflowRequest { | ||
| string instance_id = 1; | ||
| string workflow_component = 2; | ||
| string workflow_name = 3; | ||
| map<string, string> options = 4; | ||
| bytes input = 5; | ||
| } | ||
|
|
||
| message TerminateWorkflowRequest { | ||
| string instance_id = 1; | ||
| string workflow_component = 2; | ||
| } | ||
|
|
||
| message TerminateWorkflowResponse { | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // ------------------------------------------------------------------------ | ||
| // Copyright 2021 The Dapr Authors | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // ------------------------------------------------------------------------ | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Dapr.Client | ||
| { | ||
| /// <summary> | ||
| /// Represents the response from invoking a workflow. | ||
| /// </summary> | ||
| public sealed class WorkflowReference | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new <see cref="WorkflowReference" />.` | ||
| /// </summary> | ||
| /// <param name="instanceId">The instance ID assocated with this response.</param> | ||
| public WorkflowReference(string instanceId) | ||
| { | ||
| ArgumentVerifier.ThrowIfNull(instanceId, nameof(instanceId)); | ||
| this.InstanceId = instanceId; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// The instance ID assocated with this workflow. | ||
| /// </summary> | ||
| public string InstanceId { set; get; } | ||
|
|
||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we've had this conversation, so forgive me. But is there a reason we went with Object instead of just a Generic? Is it just because we don't have a good means of using the generic so we get nothing from the type checking side of the world?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, there's no benefit to using a generic here. We don't really care what the type of the input is. We just need to be able to serialize it to JSON.