@@ -26,7 +26,6 @@ package frontend
26
26
27
27
import (
28
28
"context"
29
- "fmt"
30
29
"time"
31
30
32
31
"go.temporal.io/api/workflowservice/v1"
@@ -37,6 +36,7 @@ import (
37
36
"go.temporal.io/server/common/cluster"
38
37
"go.temporal.io/server/common/config"
39
38
"go.temporal.io/server/common/log"
39
+ "go.temporal.io/server/common/log/tag"
40
40
"go.temporal.io/server/common/metrics"
41
41
"go.temporal.io/server/common/namespace"
42
42
"go.temporal.io/server/common/rpc/interceptor"
@@ -45,75 +45,75 @@ import (
45
45
var (
46
46
dcRedirectionMetricsPrefix = "DCRedirection"
47
47
48
- localAPIResults = map [string ]respAllocFn {
48
+ localAPIResponses = map [string ]responseConstructorFn {
49
49
// Namespace APIs, namespace APIs does not require redirection
50
- "DeprecateNamespace" : func () interface {} { return new ( workflowservice.DeprecateNamespaceResponse ) },
51
- "DescribeNamespace" : func () interface {} { return new ( workflowservice.DescribeNamespaceResponse ) },
52
- "ListNamespaces" : func () interface {} { return new ( workflowservice.ListNamespacesResponse ) },
53
- "RegisterNamespace" : func () interface {} { return new ( workflowservice.RegisterNamespaceResponse ) },
54
- "UpdateNamespace" : func () interface {} { return new ( workflowservice.UpdateNamespaceResponse ) },
50
+ "DeprecateNamespace" : func () any { return & workflowservice.DeprecateNamespaceResponse {} },
51
+ "DescribeNamespace" : func () any { return & workflowservice.DescribeNamespaceResponse {} },
52
+ "ListNamespaces" : func () any { return & workflowservice.ListNamespacesResponse {} },
53
+ "RegisterNamespace" : func () any { return & workflowservice.RegisterNamespaceResponse {} },
54
+ "UpdateNamespace" : func () any { return & workflowservice.UpdateNamespaceResponse {} },
55
55
56
56
// Cluster info APIs, Cluster info APIs does not require redirection
57
- "GetSearchAttributes" : func () interface {} { return new ( workflowservice.GetSearchAttributesResponse ) },
58
- "GetClusterInfo" : func () interface {} { return new ( workflowservice.GetClusterInfoResponse ) },
59
- "GetSystemInfo" : func () interface {} { return new ( workflowservice.GetSystemInfoResponse ) },
57
+ "GetSearchAttributes" : func () any { return & workflowservice.GetSearchAttributesResponse {} },
58
+ "GetClusterInfo" : func () any { return & workflowservice.GetClusterInfoResponse {} },
59
+ "GetSystemInfo" : func () any { return & workflowservice.GetSystemInfoResponse {} },
60
60
}
61
61
62
- globalAPIResults = map [string ]respAllocFn {
63
- "DescribeTaskQueue" : func () interface {} { return new ( workflowservice.DescribeTaskQueueResponse ) },
64
- "DescribeWorkflowExecution" : func () interface {} { return new ( workflowservice.DescribeWorkflowExecutionResponse ) },
65
- "GetWorkflowExecutionHistory" : func () interface {} { return new ( workflowservice.GetWorkflowExecutionHistoryResponse ) },
66
- "GetWorkflowExecutionHistoryReverse" : func () interface {} { return new ( workflowservice.GetWorkflowExecutionHistoryReverseResponse ) },
67
- "ListArchivedWorkflowExecutions" : func () interface {} { return new ( workflowservice.ListArchivedWorkflowExecutionsResponse ) },
68
- "ListClosedWorkflowExecutions" : func () interface {} { return new ( workflowservice.ListClosedWorkflowExecutionsResponse ) },
69
- "ListOpenWorkflowExecutions" : func () interface {} { return new ( workflowservice.ListOpenWorkflowExecutionsResponse ) },
70
- "ListWorkflowExecutions" : func () interface {} { return new ( workflowservice.ListWorkflowExecutionsResponse ) },
71
- "ScanWorkflowExecutions" : func () interface {} { return new ( workflowservice.ScanWorkflowExecutionsResponse ) },
72
- "CountWorkflowExecutions" : func () interface {} { return new ( workflowservice.CountWorkflowExecutionsResponse ) },
73
- "PollActivityTaskQueue" : func () interface {} { return new ( workflowservice.PollActivityTaskQueueResponse ) },
74
- "PollWorkflowTaskQueue" : func () interface {} { return new ( workflowservice.PollWorkflowTaskQueueResponse ) },
75
- "QueryWorkflow" : func () interface {} { return new ( workflowservice.QueryWorkflowResponse ) },
76
- "RecordActivityTaskHeartbeat" : func () interface {} { return new ( workflowservice.RecordActivityTaskHeartbeatResponse ) },
77
- "RecordActivityTaskHeartbeatById" : func () interface {} { return new ( workflowservice.RecordActivityTaskHeartbeatByIdResponse ) },
78
- "RequestCancelWorkflowExecution" : func () interface {} { return new ( workflowservice.RequestCancelWorkflowExecutionResponse ) },
79
- "ResetStickyTaskQueue" : func () interface {} { return new ( workflowservice.ResetStickyTaskQueueResponse ) },
80
- "ResetWorkflowExecution" : func () interface {} { return new ( workflowservice.ResetWorkflowExecutionResponse ) },
81
- "RespondActivityTaskCanceled" : func () interface {} { return new ( workflowservice.RespondActivityTaskCanceledResponse ) },
82
- "RespondActivityTaskCanceledById" : func () interface {} { return new ( workflowservice.RespondActivityTaskCanceledByIdResponse ) },
83
- "RespondActivityTaskCompleted" : func () interface {} { return new ( workflowservice.RespondActivityTaskCompletedResponse ) },
84
- "RespondActivityTaskCompletedById" : func () interface {} { return new ( workflowservice.RespondActivityTaskCompletedByIdResponse ) },
85
- "RespondActivityTaskFailed" : func () interface {} { return new ( workflowservice.RespondActivityTaskFailedResponse ) },
86
- "RespondActivityTaskFailedById" : func () interface {} { return new ( workflowservice.RespondActivityTaskFailedByIdResponse ) },
87
- "RespondWorkflowTaskCompleted" : func () interface {} { return new ( workflowservice.RespondWorkflowTaskCompletedResponse ) },
88
- "RespondWorkflowTaskFailed" : func () interface {} { return new ( workflowservice.RespondWorkflowTaskFailedResponse ) },
89
- "RespondQueryTaskCompleted" : func () interface {} { return new ( workflowservice.RespondQueryTaskCompletedResponse ) },
90
- "SignalWithStartWorkflowExecution" : func () interface {} { return new ( workflowservice.SignalWithStartWorkflowExecutionResponse ) },
91
- "SignalWorkflowExecution" : func () interface {} { return new ( workflowservice.SignalWorkflowExecutionResponse ) },
92
- "StartWorkflowExecution" : func () interface {} { return new ( workflowservice.StartWorkflowExecutionResponse ) },
93
- "UpdateWorkflowExecution" : func () interface {} { return new ( workflowservice.UpdateWorkflowExecutionResponse ) },
94
- "TerminateWorkflowExecution" : func () interface {} { return new ( workflowservice.TerminateWorkflowExecutionResponse ) },
95
- "DeleteWorkflowExecution" : func () interface {} { return new ( workflowservice.DeleteWorkflowExecutionResponse ) },
96
- "ListTaskQueuePartitions" : func () interface {} { return new ( workflowservice.ListTaskQueuePartitionsResponse ) },
97
-
98
- "CreateSchedule" : func () interface {} { return new ( workflowservice.CreateScheduleResponse ) },
99
- "DescribeSchedule" : func () interface {} { return new ( workflowservice.DescribeScheduleResponse ) },
100
- "UpdateSchedule" : func () interface {} { return new ( workflowservice.UpdateScheduleResponse ) },
101
- "PatchSchedule" : func () interface {} { return new ( workflowservice.PatchScheduleResponse ) },
102
- "DeleteSchedule" : func () interface {} { return new ( workflowservice.DeleteScheduleResponse ) },
103
- "ListSchedules" : func () interface {} { return new ( workflowservice.ListSchedulesResponse ) },
104
- "ListScheduleMatchingTimes" : func () interface {} { return new ( workflowservice.ListScheduleMatchingTimesResponse ) },
105
- "UpdateWorkerBuildIdOrdering" : func () interface {} { return new ( workflowservice.UpdateWorkerBuildIdOrderingResponse ) },
106
- "GetWorkerBuildIdOrdering" : func () interface {} { return new ( workflowservice.GetWorkerBuildIdOrderingResponse ) },
107
-
108
- "StartBatchOperation" : func () interface {} { return new ( workflowservice.StartBatchOperationResponse ) },
109
- "StopBatchOperation" : func () interface {} { return new ( workflowservice.StopBatchOperationResponse ) },
110
- "DescribeBatchOperation" : func () interface {} { return new ( workflowservice.DescribeBatchOperationResponse ) },
111
- "ListBatchOperations" : func () interface {} { return new ( workflowservice.ListBatchOperationsResponse ) },
62
+ globalAPIResponses = map [string ]responseConstructorFn {
63
+ "DescribeTaskQueue" : func () any { return & workflowservice.DescribeTaskQueueResponse {} },
64
+ "DescribeWorkflowExecution" : func () any { return & workflowservice.DescribeWorkflowExecutionResponse {} },
65
+ "GetWorkflowExecutionHistory" : func () any { return & workflowservice.GetWorkflowExecutionHistoryResponse {} },
66
+ "GetWorkflowExecutionHistoryReverse" : func () any { return & workflowservice.GetWorkflowExecutionHistoryReverseResponse {} },
67
+ "ListArchivedWorkflowExecutions" : func () any { return & workflowservice.ListArchivedWorkflowExecutionsResponse {} },
68
+ "ListClosedWorkflowExecutions" : func () any { return & workflowservice.ListClosedWorkflowExecutionsResponse {} },
69
+ "ListOpenWorkflowExecutions" : func () any { return & workflowservice.ListOpenWorkflowExecutionsResponse {} },
70
+ "ListWorkflowExecutions" : func () any { return & workflowservice.ListWorkflowExecutionsResponse {} },
71
+ "ScanWorkflowExecutions" : func () any { return & workflowservice.ScanWorkflowExecutionsResponse {} },
72
+ "CountWorkflowExecutions" : func () any { return & workflowservice.CountWorkflowExecutionsResponse {} },
73
+ "PollActivityTaskQueue" : func () any { return & workflowservice.PollActivityTaskQueueResponse {} },
74
+ "PollWorkflowTaskQueue" : func () any { return & workflowservice.PollWorkflowTaskQueueResponse {} },
75
+ "QueryWorkflow" : func () any { return & workflowservice.QueryWorkflowResponse {} },
76
+ "RecordActivityTaskHeartbeat" : func () any { return & workflowservice.RecordActivityTaskHeartbeatResponse {} },
77
+ "RecordActivityTaskHeartbeatById" : func () any { return & workflowservice.RecordActivityTaskHeartbeatByIdResponse {} },
78
+ "RequestCancelWorkflowExecution" : func () any { return & workflowservice.RequestCancelWorkflowExecutionResponse {} },
79
+ "ResetStickyTaskQueue" : func () any { return & workflowservice.ResetStickyTaskQueueResponse {} },
80
+ "ResetWorkflowExecution" : func () any { return & workflowservice.ResetWorkflowExecutionResponse {} },
81
+ "RespondActivityTaskCanceled" : func () any { return & workflowservice.RespondActivityTaskCanceledResponse {} },
82
+ "RespondActivityTaskCanceledById" : func () any { return & workflowservice.RespondActivityTaskCanceledByIdResponse {} },
83
+ "RespondActivityTaskCompleted" : func () any { return & workflowservice.RespondActivityTaskCompletedResponse {} },
84
+ "RespondActivityTaskCompletedById" : func () any { return & workflowservice.RespondActivityTaskCompletedByIdResponse {} },
85
+ "RespondActivityTaskFailed" : func () any { return & workflowservice.RespondActivityTaskFailedResponse {} },
86
+ "RespondActivityTaskFailedById" : func () any { return & workflowservice.RespondActivityTaskFailedByIdResponse {} },
87
+ "RespondWorkflowTaskCompleted" : func () any { return & workflowservice.RespondWorkflowTaskCompletedResponse {} },
88
+ "RespondWorkflowTaskFailed" : func () any { return & workflowservice.RespondWorkflowTaskFailedResponse {} },
89
+ "RespondQueryTaskCompleted" : func () any { return & workflowservice.RespondQueryTaskCompletedResponse {} },
90
+ "SignalWithStartWorkflowExecution" : func () any { return & workflowservice.SignalWithStartWorkflowExecutionResponse {} },
91
+ "SignalWorkflowExecution" : func () any { return & workflowservice.SignalWorkflowExecutionResponse {} },
92
+ "StartWorkflowExecution" : func () any { return & workflowservice.StartWorkflowExecutionResponse {} },
93
+ "UpdateWorkflowExecution" : func () any { return & workflowservice.UpdateWorkflowExecutionResponse {} },
94
+ "TerminateWorkflowExecution" : func () any { return & workflowservice.TerminateWorkflowExecutionResponse {} },
95
+ "DeleteWorkflowExecution" : func () any { return & workflowservice.DeleteWorkflowExecutionResponse {} },
96
+ "ListTaskQueuePartitions" : func () any { return & workflowservice.ListTaskQueuePartitionsResponse {} },
97
+
98
+ "CreateSchedule" : func () any { return & workflowservice.CreateScheduleResponse {} },
99
+ "DescribeSchedule" : func () any { return & workflowservice.DescribeScheduleResponse {} },
100
+ "UpdateSchedule" : func () any { return & workflowservice.UpdateScheduleResponse {} },
101
+ "PatchSchedule" : func () any { return & workflowservice.PatchScheduleResponse {} },
102
+ "DeleteSchedule" : func () any { return & workflowservice.DeleteScheduleResponse {} },
103
+ "ListSchedules" : func () any { return & workflowservice.ListSchedulesResponse {} },
104
+ "ListScheduleMatchingTimes" : func () any { return & workflowservice.ListScheduleMatchingTimesResponse {} },
105
+ "UpdateWorkerBuildIdOrdering" : func () any { return & workflowservice.UpdateWorkerBuildIdOrderingResponse {} },
106
+ "GetWorkerBuildIdOrdering" : func () any { return & workflowservice.GetWorkerBuildIdOrderingResponse {} },
107
+
108
+ "StartBatchOperation" : func () any { return & workflowservice.StartBatchOperationResponse {} },
109
+ "StopBatchOperation" : func () any { return & workflowservice.StopBatchOperationResponse {} },
110
+ "DescribeBatchOperation" : func () any { return & workflowservice.DescribeBatchOperationResponse {} },
111
+ "ListBatchOperations" : func () any { return & workflowservice.ListBatchOperationsResponse {} },
112
112
}
113
113
)
114
114
115
115
type (
116
- respAllocFn func () interface {}
116
+ responseConstructorFn func () any
117
117
118
118
// RedirectionInterceptor is simple wrapper over frontend service, doing redirection based on policy
119
119
RedirectionInterceptor struct {
@@ -162,32 +162,37 @@ var _ grpc.UnaryServerInterceptor = (*RedirectionInterceptor)(nil).Intercept
162
162
163
163
func (i * RedirectionInterceptor ) Intercept (
164
164
ctx context.Context ,
165
- req interface {} ,
165
+ req any ,
166
166
info * grpc.UnaryServerInfo ,
167
167
handler grpc.UnaryHandler ,
168
- ) (_ interface {} , retError error ) {
168
+ ) (_ any , retError error ) {
169
169
defer log .CapturePanic (i .logger , & retError )
170
170
171
+ if _ , isWorkflowHandler := info .Server .(* WorkflowHandler ); ! isWorkflowHandler {
172
+ return handler (ctx , req )
173
+ }
174
+
171
175
_ , methodName := interceptor .SplitMethodName (info .FullMethod )
172
- if _ , ok := localAPIResults [methodName ]; ok {
176
+ if _ , ok := localAPIResponses [methodName ]; ok {
173
177
return i .handleLocalAPIInvocation (ctx , req , handler , methodName )
174
178
}
175
- if respAllocFn , ok := globalAPIResults [methodName ]; ok {
179
+ if raFn , ok := globalAPIResponses [methodName ]; ok {
176
180
namespaceName := interceptor .GetNamespace (i .namespaceCache , req )
177
- return i .handleRedirectAPIInvocation (ctx , req , info , handler , methodName , respAllocFn , namespaceName )
181
+ return i .handleRedirectAPIInvocation (ctx , req , info , handler , methodName , raFn , namespaceName )
178
182
}
179
183
180
- // this should not happen for frontend APIs but ok for admin and other future handlers
181
- i .logger .Debug (fmt .Sprintf ("RedirectionInterceptor encountered unknown API: %v" , info .FullMethod ))
184
+ // This should not happen unless new API is added without updating localAPIResponses and globalAPIResponses maps.
185
+ // Also covered by unit test.
186
+ i .logger .Warn ("RedirectionInterceptor encountered unknown API" , tag .Name (info .FullMethod ))
182
187
return handler (ctx , req )
183
188
}
184
189
185
190
func (i * RedirectionInterceptor ) handleLocalAPIInvocation (
186
191
ctx context.Context ,
187
- req interface {} ,
192
+ req any ,
188
193
handler grpc.UnaryHandler ,
189
194
methodName string ,
190
- ) (_ interface {} , retError error ) {
195
+ ) (_ any , retError error ) {
191
196
scope , startTime := i .beforeCall (dcRedirectionMetricsPrefix + methodName )
192
197
defer func () {
193
198
i .afterCall (scope , startTime , i .currentClusterName , retError )
@@ -197,14 +202,14 @@ func (i *RedirectionInterceptor) handleLocalAPIInvocation(
197
202
198
203
func (i * RedirectionInterceptor ) handleRedirectAPIInvocation (
199
204
ctx context.Context ,
200
- req interface {} ,
205
+ req any ,
201
206
info * grpc.UnaryServerInfo ,
202
207
handler grpc.UnaryHandler ,
203
208
methodName string ,
204
- respAllocFn func () interface {} ,
209
+ respCtorFn responseConstructorFn ,
205
210
namespaceName namespace.Name ,
206
- ) (_ interface {} , retError error ) {
207
- var resp interface {}
211
+ ) (_ any , retError error ) {
212
+ var resp any
208
213
var clusterName string
209
214
var err error
210
215
@@ -222,7 +227,7 @@ func (i *RedirectionInterceptor) handleRedirectAPIInvocation(
222
227
if err != nil {
223
228
return err
224
229
}
225
- resp = respAllocFn ()
230
+ resp = respCtorFn ()
226
231
err = remoteClient .Invoke (ctx , info .FullMethod , req , resp )
227
232
if err != nil {
228
233
return err
0 commit comments