7
7
import io .temporal .api .enums .v1 .EventType ;
8
8
import io .temporal .api .enums .v1 .WorkflowTaskFailedCause ;
9
9
import io .temporal .api .history .v1 .HistoryEvent ;
10
- import io .temporal .client .WorkflowClient ;
11
- import io .temporal .client .WorkflowFailedException ;
12
- import io .temporal .client .WorkflowOptions ;
13
- import io .temporal .client .WorkflowServiceException ;
10
+ import io .temporal .client .*;
14
11
import io .temporal .failure .ApplicationFailure ;
15
12
import io .temporal .failure .TimeoutFailure ;
13
+ import io .temporal .internal .replay .ReplayWorkflowTaskHandler ;
16
14
import io .temporal .internal .retryer .GrpcMessageTooLargeException ;
15
+ import io .temporal .internal .worker .PollerOptions ;
16
+ import io .temporal .testUtils .LoggerUtils ;
17
17
import io .temporal .testing .internal .SDKTestWorkflowRule ;
18
18
import io .temporal .workflow .shared .TestActivities ;
19
- import io .temporal .workflow .shared .TestWorkflows ;
20
19
import java .time .Duration ;
21
20
import java .util .List ;
22
21
import org .junit .Rule ;
23
22
import org .junit .Test ;
24
23
25
24
public class GrpcMessageTooLargeTest {
25
+ private static final String QUERY_ERROR_MESSAGE =
26
+ "Failed to send query response: RESOURCE_EXHAUSTED: grpc: received message larger than max" ;
26
27
private static final String VERY_LARGE_DATA ;
27
28
28
29
static {
@@ -36,16 +37,27 @@ public class GrpcMessageTooLargeTest {
36
37
}
37
38
38
39
@ Rule
39
- public SDKTestWorkflowRule testWorkflowRule =
40
+ public SDKTestWorkflowRule activityStartWorkflowRule =
40
41
SDKTestWorkflowRule .newBuilder ()
41
- .setWorkflowTypes (TestWorkflowImpl .class )
42
+ .setWorkflowTypes (ActivityStartWorkflowImpl .class )
42
43
.setActivityImplementations (new TestActivityImpl ())
43
44
.build ();
44
45
46
+ @ Rule
47
+ public SDKTestWorkflowRule failureWorkflowRule =
48
+ SDKTestWorkflowRule .newBuilder ().setWorkflowTypes (FailureWorkflowImpl .class ).build ();
49
+
50
+ @ Rule
51
+ public SDKTestWorkflowRule querySuccessWorkflowRule =
52
+ SDKTestWorkflowRule .newBuilder ().setWorkflowTypes (QuerySuccessWorkflowImpl .class ).build ();
53
+
54
+ @ Rule
55
+ public SDKTestWorkflowRule queryFailureWorkflowRule =
56
+ SDKTestWorkflowRule .newBuilder ().setWorkflowTypes (QueryFailureWorkflowImpl .class ).build ();
57
+
45
58
@ Test
46
59
public void workflowStartTooLarge () {
47
- TestWorkflows .TestWorkflowStringArg workflow =
48
- testWorkflowRule .newWorkflowStub (TestWorkflows .TestWorkflowStringArg .class );
60
+ TestWorkflow workflow = createWorkflowStub (TestWorkflow .class , activityStartWorkflowRule );
49
61
WorkflowServiceException e =
50
62
assertThrows (
51
63
WorkflowServiceException .class ,
@@ -55,40 +67,137 @@ public void workflowStartTooLarge() {
55
67
56
68
@ Test
57
69
public void activityStartTooLarge () {
58
- WorkflowOptions options =
59
- WorkflowOptions .newBuilder ()
60
- .setWorkflowRunTimeout (Duration .ofSeconds (1 ))
61
- .setTaskQueue (testWorkflowRule .getTaskQueue ())
62
- .build ();
63
- TestWorkflows .TestWorkflowStringArg workflow =
64
- testWorkflowRule
65
- .getWorkflowClient ()
66
- .newWorkflowStub (TestWorkflows .TestWorkflowStringArg .class , options );
70
+ TestWorkflow workflow = createWorkflowStub (TestWorkflow .class , activityStartWorkflowRule );
67
71
68
72
WorkflowFailedException e =
69
73
assertThrows (WorkflowFailedException .class , () -> workflow .execute ("" ));
70
74
assertTrue (e .getCause () instanceof TimeoutFailure );
71
75
76
+ String workflowId = WorkflowStub .fromTyped (workflow ).getExecution ().getWorkflowId ();
77
+ assertTrue (
78
+ activityStartWorkflowRule
79
+ .getHistoryEvents (workflowId , EventType .EVENT_TYPE_ACTIVITY_TASK_FAILED )
80
+ .isEmpty ());
72
81
List <HistoryEvent > events =
73
- testWorkflowRule .getHistoryEvents (
74
- e .getExecution ().getWorkflowId (), EventType .EVENT_TYPE_WORKFLOW_TASK_FAILED );
75
- assertFalse (events .isEmpty ());
76
- for (HistoryEvent event : events ) {
82
+ activityStartWorkflowRule .getHistoryEvents (
83
+ workflowId , EventType .EVENT_TYPE_WORKFLOW_TASK_FAILED );
84
+ assertEquals (1 , events .size ());
85
+ assertEquals (
86
+ WorkflowTaskFailedCause .WORKFLOW_TASK_FAILED_CAUSE_GRPC_MESSAGE_TOO_LARGE ,
87
+ events .get (0 ).getWorkflowTaskFailedEventAttributes ().getCause ());
88
+ }
89
+
90
+ @ Test
91
+ public void workflowFailureTooLarge () {
92
+ // Avoding logging exception with very large data
93
+ try (LoggerUtils .SilenceLoggers sl =
94
+ LoggerUtils .silenceLoggers (ReplayWorkflowTaskHandler .class , PollerOptions .class )) {
95
+ TestWorkflow workflow = createWorkflowStub (TestWorkflow .class , failureWorkflowRule );
96
+
97
+ WorkflowFailedException e =
98
+ assertThrows (WorkflowFailedException .class , () -> workflow .execute ("" ));
99
+
100
+ assertTrue (e .getCause () instanceof TimeoutFailure );
101
+ String workflowId = WorkflowStub .fromTyped (workflow ).getExecution ().getWorkflowId ();
102
+ List <HistoryEvent > events =
103
+ failureWorkflowRule .getHistoryEvents (
104
+ workflowId , EventType .EVENT_TYPE_WORKFLOW_TASK_FAILED );
105
+ assertEquals (1 , events .size ());
77
106
assertEquals (
78
107
WorkflowTaskFailedCause .WORKFLOW_TASK_FAILED_CAUSE_GRPC_MESSAGE_TOO_LARGE ,
79
- event .getWorkflowTaskFailedEventAttributes ().getCause ());
108
+ events .get (0 ).getWorkflowTaskFailedEventAttributes ().getCause ());
109
+ }
110
+ }
111
+
112
+ @ Test
113
+ public void queryResultTooLarge () {
114
+ TestWorkflowWithQuery workflow =
115
+ createWorkflowStub (TestWorkflowWithQuery .class , querySuccessWorkflowRule );
116
+ workflow .execute ();
117
+
118
+ WorkflowQueryException e = assertThrows (WorkflowQueryException .class , workflow ::query );
119
+
120
+ assertNotNull (e .getCause ());
121
+ // The exception will not contain the original failure object, so instead of type check we're
122
+ // checking the message to ensure the correct error is being sent.
123
+ assertTrue (e .getCause ().getMessage ().contains (QUERY_ERROR_MESSAGE ));
124
+ }
125
+
126
+ @ Test
127
+ public void queryErrorTooLarge () {
128
+ TestWorkflowWithQuery workflow =
129
+ createWorkflowStub (TestWorkflowWithQuery .class , queryFailureWorkflowRule );
130
+ workflow .execute ();
131
+
132
+ WorkflowQueryException e = assertThrows (WorkflowQueryException .class , workflow ::query );
133
+
134
+ assertNotNull (e .getCause ());
135
+ assertTrue (e .getCause ().getMessage ().contains (QUERY_ERROR_MESSAGE ));
136
+ }
137
+
138
+ private static <T > T createWorkflowStub (Class <T > clazz , SDKTestWorkflowRule workflowRule ) {
139
+ WorkflowOptions options =
140
+ WorkflowOptions .newBuilder ()
141
+ .setWorkflowRunTimeout (Duration .ofSeconds (1 ))
142
+ .setWorkflowTaskTimeout (Duration .ofMillis (250 ))
143
+ .setTaskQueue (workflowRule .getTaskQueue ())
144
+ .build ();
145
+ return workflowRule .getWorkflowClient ().newWorkflowStub (clazz , options );
146
+ }
147
+
148
+ @ WorkflowInterface
149
+ public interface TestWorkflow {
150
+ @ WorkflowMethod
151
+ void execute (String arg );
152
+ }
153
+
154
+ @ WorkflowInterface
155
+ public interface TestWorkflowWithQuery {
156
+ @ WorkflowMethod
157
+ void execute ();
158
+
159
+ @ QueryMethod
160
+ String query ();
161
+ }
162
+
163
+ public static class ActivityStartWorkflowImpl implements TestWorkflow {
164
+ private final TestActivities .TestActivity1 activity =
165
+ Workflow .newActivityStub (
166
+ TestActivities .TestActivity1 .class ,
167
+ ActivityOptions .newBuilder ()
168
+ .setStartToCloseTimeout (Duration .ofSeconds (1 ))
169
+ .validateAndBuildWithDefaults ());
170
+
171
+ @ Override
172
+ public void execute (String arg ) {
173
+ activity .execute (VERY_LARGE_DATA );
80
174
}
81
175
}
82
176
83
- public static class TestWorkflowImpl implements TestWorkflows . TestWorkflowStringArg {
177
+ public static class FailureWorkflowImpl implements TestWorkflow {
84
178
@ Override
85
179
public void execute (String arg ) {
86
- Workflow .newActivityStub (
87
- TestActivities .TestActivity1 .class ,
88
- ActivityOptions .newBuilder ()
89
- .setStartToCloseTimeout (Duration .ofSeconds (1 ))
90
- .validateAndBuildWithDefaults ())
91
- .execute (VERY_LARGE_DATA );
180
+ throw new RuntimeException (VERY_LARGE_DATA );
181
+ }
182
+ }
183
+
184
+ public static class QuerySuccessWorkflowImpl implements TestWorkflowWithQuery {
185
+ @ Override
186
+ public void execute () {}
187
+
188
+ @ Override
189
+ public String query () {
190
+ return VERY_LARGE_DATA ;
191
+ }
192
+ }
193
+
194
+ public static class QueryFailureWorkflowImpl implements TestWorkflowWithQuery {
195
+ @ Override
196
+ public void execute () {}
197
+
198
+ @ Override
199
+ public String query () {
200
+ throw new RuntimeException (VERY_LARGE_DATA );
92
201
}
93
202
}
94
203
0 commit comments