• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

temporalio / sdk-java / #188

25 Sep 2023 04:42PM UTC coverage: 77.369% (-0.3%) from 77.663%
#188

push

github-actions

web-flow
Fix null pointer on trigger immediately (#1865)

4 of 4 new or added lines in 1 file covered. (100.0%)

18670 of 24131 relevant lines covered (77.37%)

0.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/temporal-sdk/src/main/java/io/temporal/common/interceptors/WorkflowOutboundCallsInterceptor.java
1
/*
2
 * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3
 *
4
 * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
 *
6
 * Modifications copyright (C) 2017 Uber Technologies, Inc.
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this material except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20

21
package io.temporal.common.interceptors;
22

23
import io.temporal.activity.ActivityOptions;
24
import io.temporal.activity.LocalActivityOptions;
25
import io.temporal.api.common.v1.WorkflowExecution;
26
import io.temporal.common.Experimental;
27
import io.temporal.common.SearchAttributeUpdate;
28
import io.temporal.workflow.*;
29
import io.temporal.workflow.Functions.Func;
30
import java.lang.reflect.Type;
31
import java.time.Duration;
32
import java.util.List;
33
import java.util.Map;
34
import java.util.Random;
35
import java.util.UUID;
36
import java.util.function.BiPredicate;
37
import java.util.function.Supplier;
38
import javax.annotation.Nullable;
39

40
/**
41
 * Can be used to intercept calls from to workflow code into the Temporal APIs.
42
 *
43
 * <p>The calls to the interceptor are executed in the context of a workflow and must follow the
44
 * same rules all the other workflow code follows.
45
 *
46
 * <p>Prefer extending {@link WorkflowOutboundCallsInterceptorBase} and overriding only the methods
47
 * you need instead of implementing this interface directly. {@link
48
 * WorkflowOutboundCallsInterceptorBase} provides correct default implementations to all the methods
49
 * of this interface.
50
 *
51
 * <p>An instance may be created in {@link
52
 * WorkflowInboundCallsInterceptor#init(WorkflowOutboundCallsInterceptor)} and set by passing it
53
 * into {@code init} method of the {@code next} {@link WorkflowInboundCallsInterceptor} The
54
 * implementation must forward all the calls to the outbound interceptor passed as a {@code
55
 * outboundCalls} parameter to the {@code init} call.
56
 *
57
 * @see WorkerInterceptor#interceptWorkflow for the definition of "next" {@link
58
 *     WorkflowInboundCallsInterceptor}.
59
 */
60
@Experimental
61
public interface WorkflowOutboundCallsInterceptor {
62

63
  final class ActivityInput<R> {
64
    private final String activityName;
65
    private final Class<R> resultClass;
66
    private final Type resultType;
67
    private final Object[] args;
68
    private final ActivityOptions options;
69
    private final Header header;
70

71
    public ActivityInput(
72
        String activityName,
73
        Class<R> resultClass,
74
        Type resultType,
75
        Object[] args,
76
        ActivityOptions options,
77
        Header header) {
1✔
78
      this.activityName = activityName;
1✔
79
      this.resultClass = resultClass;
1✔
80
      this.resultType = resultType;
1✔
81
      this.args = args;
1✔
82
      this.options = options;
1✔
83
      this.header = header;
1✔
84
    }
1✔
85

86
    public String getActivityName() {
87
      return activityName;
1✔
88
    }
89

90
    public Class<R> getResultClass() {
91
      return resultClass;
1✔
92
    }
93

94
    public Type getResultType() {
95
      return resultType;
1✔
96
    }
97

98
    public Object[] getArgs() {
99
      return args;
1✔
100
    }
101

102
    public ActivityOptions getOptions() {
103
      return options;
1✔
104
    }
105

106
    public Header getHeader() {
107
      return header;
1✔
108
    }
109
  }
110

111
  final class ActivityOutput<R> {
112
    private final String activityId;
113
    private final Promise<R> result;
114

115
    public ActivityOutput(String activityId, Promise<R> result) {
1✔
116
      this.activityId = activityId;
1✔
117
      this.result = result;
1✔
118
    }
1✔
119

120
    public String getActivityId() {
121
      return activityId;
1✔
122
    }
123

124
    public Promise<R> getResult() {
125
      return result;
1✔
126
    }
127
  }
128

129
  final class LocalActivityInput<R> {
130
    private final String activityName;
131
    private final Class<R> resultClass;
132
    private final Type resultType;
133
    private final Object[] args;
134
    private final LocalActivityOptions options;
135
    private final Header header;
136

137
    public LocalActivityInput(
138
        String activityName,
139
        Class<R> resultClass,
140
        Type resultType,
141
        Object[] args,
142
        LocalActivityOptions options,
143
        Header header) {
1✔
144
      this.activityName = activityName;
1✔
145
      this.resultClass = resultClass;
1✔
146
      this.resultType = resultType;
1✔
147
      this.args = args;
1✔
148
      this.options = options;
1✔
149
      this.header = header;
1✔
150
    }
1✔
151

152
    public String getActivityName() {
153
      return activityName;
1✔
154
    }
155

156
    public Class<R> getResultClass() {
157
      return resultClass;
1✔
158
    }
159

160
    public Type getResultType() {
161
      return resultType;
1✔
162
    }
163

164
    public Object[] getArgs() {
165
      return args;
1✔
166
    }
167

168
    public LocalActivityOptions getOptions() {
169
      return options;
1✔
170
    }
171

172
    public Header getHeader() {
173
      return header;
1✔
174
    }
175
  }
176

177
  final class LocalActivityOutput<R> {
178
    private final Promise<R> result;
179

180
    public LocalActivityOutput(Promise<R> result) {
1✔
181
      this.result = result;
1✔
182
    }
1✔
183

184
    public Promise<R> getResult() {
185
      return result;
1✔
186
    }
187
  }
188

189
  final class ChildWorkflowInput<R> {
190
    private final String workflowId;
191
    private final String workflowType;
192
    private final Class<R> resultClass;
193
    private final Type resultType;
194
    private final Object[] args;
195
    private final ChildWorkflowOptions options;
196
    private final Header header;
197

198
    public ChildWorkflowInput(
199
        String workflowId,
200
        String workflowType,
201
        Class<R> resultClass,
202
        Type resultType,
203
        Object[] args,
204
        ChildWorkflowOptions options,
205
        Header header) {
1✔
206
      this.workflowId = workflowId;
1✔
207
      this.workflowType = workflowType;
1✔
208
      this.resultClass = resultClass;
1✔
209
      this.resultType = resultType;
1✔
210
      this.args = args;
1✔
211
      this.options = options;
1✔
212
      this.header = header;
1✔
213
    }
1✔
214

215
    public String getWorkflowId() {
216
      return workflowId;
1✔
217
    }
218

219
    public String getWorkflowType() {
220
      return workflowType;
1✔
221
    }
222

223
    public Class<R> getResultClass() {
224
      return resultClass;
1✔
225
    }
226

227
    public Type getResultType() {
228
      return resultType;
1✔
229
    }
230

231
    public Object[] getArgs() {
232
      return args;
1✔
233
    }
234

235
    public ChildWorkflowOptions getOptions() {
236
      return options;
1✔
237
    }
238

239
    public Header getHeader() {
240
      return header;
1✔
241
    }
242
  }
243

244
  final class ChildWorkflowOutput<R> {
245

246
    private final Promise<R> result;
247
    private final Promise<WorkflowExecution> workflowExecution;
248

249
    public ChildWorkflowOutput(Promise<R> result, Promise<WorkflowExecution> workflowExecution) {
1✔
250
      this.result = result;
1✔
251
      this.workflowExecution = workflowExecution;
1✔
252
    }
1✔
253

254
    public Promise<R> getResult() {
255
      return result;
1✔
256
    }
257

258
    public Promise<WorkflowExecution> getWorkflowExecution() {
259
      return workflowExecution;
1✔
260
    }
261
  }
262

263
  final class SignalExternalInput {
264
    private final WorkflowExecution execution;
265
    private final String signalName;
266
    private final Header header;
267
    private final Object[] args;
268

269
    public SignalExternalInput(
270
        WorkflowExecution execution, String signalName, Header header, Object[] args) {
1✔
271
      this.execution = execution;
1✔
272
      this.signalName = signalName;
1✔
273
      this.header = header;
1✔
274
      this.args = args;
1✔
275
    }
1✔
276

277
    public WorkflowExecution getExecution() {
278
      return execution;
1✔
279
    }
280

281
    public String getSignalName() {
282
      return signalName;
1✔
283
    }
284

285
    public Header getHeader() {
286
      return header;
1✔
287
    }
288

289
    public Object[] getArgs() {
290
      return args;
1✔
291
    }
292
  }
293

294
  final class SignalExternalOutput {
295
    private final Promise<Void> result;
296

297
    public SignalExternalOutput(Promise<Void> result) {
1✔
298
      this.result = result;
1✔
299
    }
1✔
300

301
    public Promise<Void> getResult() {
302
      return result;
1✔
303
    }
304
  }
305

306
  final class CancelWorkflowInput {
307
    private final WorkflowExecution execution;
308

309
    public CancelWorkflowInput(WorkflowExecution execution) {
×
310
      this.execution = execution;
×
311
    }
×
312

313
    public WorkflowExecution getExecution() {
314
      return execution;
×
315
    }
316
  }
317

318
  final class CancelWorkflowOutput {
319
    private final Promise<Void> result;
320

321
    public CancelWorkflowOutput(Promise<Void> result) {
×
322
      this.result = result;
×
323
    }
×
324

325
    public Promise<Void> getResult() {
326
      return result;
×
327
    }
328
  }
329

330
  final class ContinueAsNewInput {
331
    private final @Nullable String workflowType;
332
    private final @Nullable ContinueAsNewOptions options;
333
    private final Object[] args;
334
    private final Header header;
335

336
    public ContinueAsNewInput(
337
        @Nullable String workflowType,
338
        @Nullable ContinueAsNewOptions options,
339
        Object[] args,
340
        Header header) {
1✔
341
      this.workflowType = workflowType;
1✔
342
      this.options = options;
1✔
343
      this.args = args;
1✔
344
      this.header = header;
1✔
345
    }
1✔
346

347
    /**
348
     * @return workflowType for the continue-as-new workflow run. null if continue-as-new should
349
     *     inherit the type of the original workflow run.
350
     */
351
    public @Nullable String getWorkflowType() {
352
      return workflowType;
1✔
353
    }
354

355
    /**
356
     * @return options for the continue-as-new workflow run. Can be null, in that case the values
357
     *     will be taken from the original workflow run.
358
     */
359
    public @Nullable ContinueAsNewOptions getOptions() {
360
      return options;
1✔
361
    }
362

363
    public Object[] getArgs() {
364
      return args;
1✔
365
    }
366

367
    public Header getHeader() {
368
      return header;
1✔
369
    }
370
  }
371

372
  final class SignalRegistrationRequest {
373
    private final String signalType;
374
    private final Class<?>[] argTypes;
375
    private final Type[] genericArgTypes;
376
    private final Functions.Proc1<Object[]> callback;
377

378
    public SignalRegistrationRequest(
379
        String signalType,
380
        Class<?>[] argTypes,
381
        Type[] genericArgTypes,
382
        Functions.Proc1<Object[]> callback) {
1✔
383
      this.signalType = signalType;
1✔
384
      this.argTypes = argTypes;
1✔
385
      this.genericArgTypes = genericArgTypes;
1✔
386
      this.callback = callback;
1✔
387
    }
1✔
388

389
    public String getSignalType() {
390
      return signalType;
1✔
391
    }
392

393
    public Class<?>[] getArgTypes() {
394
      return argTypes;
1✔
395
    }
396

397
    public Type[] getGenericArgTypes() {
398
      return genericArgTypes;
1✔
399
    }
400

401
    public Functions.Proc1<Object[]> getCallback() {
402
      return callback;
1✔
403
    }
404
  }
405

406
  final class RegisterSignalHandlersInput {
407
    private final List<SignalRegistrationRequest> requests;
408

409
    public RegisterSignalHandlersInput(List<SignalRegistrationRequest> requests) {
1✔
410
      this.requests = requests;
1✔
411
    }
1✔
412

413
    public List<SignalRegistrationRequest> getRequests() {
414
      return requests;
1✔
415
    }
416
  }
417

418
  @Experimental
419
  final class UpdateRegistrationRequest {
420
    private final Functions.Func1<Object[], Object> executeCallback;
421
    private final Functions.Proc1<Object[]> validateCallback;
422
    private final String updateName;
423
    private final Class<?>[] argTypes;
424
    private final Type[] genericArgTypes;
425

426
    public UpdateRegistrationRequest(
427
        String updateName,
428
        Class<?>[] argTypes,
429
        Type[] genericArgTypes,
430
        Functions.Proc1<Object[]> validateCallback,
431
        Functions.Func1<Object[], Object> executeCallback) {
1✔
432
      this.updateName = updateName;
1✔
433
      this.argTypes = argTypes;
1✔
434
      this.genericArgTypes = genericArgTypes;
1✔
435
      this.validateCallback = validateCallback;
1✔
436
      this.executeCallback = executeCallback;
1✔
437
    }
1✔
438

439
    public String getUpdateName() {
440
      return updateName;
1✔
441
    }
442

443
    public Functions.Proc1<Object[]> getValidateCallback() {
444
      return validateCallback;
1✔
445
    }
446

447
    public Functions.Func1<Object[], Object> getExecuteCallback() {
448
      return executeCallback;
1✔
449
    }
450

451
    public Class<?>[] getArgTypes() {
452
      return argTypes;
1✔
453
    }
454

455
    public Type[] getGenericArgTypes() {
456
      return genericArgTypes;
1✔
457
    }
458
  }
459

460
  @Experimental
461
  final class RegisterUpdateHandlersInput {
462
    private final List<UpdateRegistrationRequest> requests;
463

464
    public RegisterUpdateHandlersInput(List<UpdateRegistrationRequest> requests) {
1✔
465
      this.requests = requests;
1✔
466
    }
1✔
467

468
    public List<UpdateRegistrationRequest> getRequests() {
469
      return requests;
1✔
470
    }
471
  }
472

473
  final class RegisterQueryInput {
474
    private final String queryType;
475
    private final Class<?>[] argTypes;
476
    private final Type[] genericArgTypes;
477
    private final Functions.Func1<Object[], Object> callback;
478

479
    public RegisterQueryInput(
480
        String queryType,
481
        Class<?>[] argTypes,
482
        Type[] genericArgTypes,
483
        Functions.Func1<Object[], Object> callback) {
1✔
484
      this.queryType = queryType;
1✔
485
      this.argTypes = argTypes;
1✔
486
      this.genericArgTypes = genericArgTypes;
1✔
487
      this.callback = callback;
1✔
488
    }
1✔
489

490
    public String getQueryType() {
491
      return queryType;
1✔
492
    }
493

494
    public Class<?>[] getArgTypes() {
495
      return argTypes;
1✔
496
    }
497

498
    public Type[] getGenericArgTypes() {
499
      return genericArgTypes;
1✔
500
    }
501

502
    public Functions.Func1<Object[], Object> getCallback() {
503
      return callback;
1✔
504
    }
505
  }
506

507
  final class RegisterDynamicQueryHandlerInput {
508
    private final DynamicQueryHandler handler;
509

510
    public RegisterDynamicQueryHandlerInput(DynamicQueryHandler handler) {
1✔
511
      this.handler = handler;
1✔
512
    }
1✔
513

514
    public DynamicQueryHandler getHandler() {
515
      return handler;
1✔
516
    }
517
  }
518

519
  final class RegisterDynamicSignalHandlerInput {
520
    private final DynamicSignalHandler handler;
521

522
    public RegisterDynamicSignalHandlerInput(DynamicSignalHandler handler) {
1✔
523
      this.handler = handler;
1✔
524
    }
1✔
525

526
    public DynamicSignalHandler getHandler() {
527
      return handler;
1✔
528
    }
529
  }
530

531
  @Experimental
532
  final class RegisterDynamicUpdateHandlerInput {
533
    private final DynamicUpdateHandler handler;
534

535
    public RegisterDynamicUpdateHandlerInput(DynamicUpdateHandler handler) {
×
536
      this.handler = handler;
×
537
    }
×
538

539
    public DynamicUpdateHandler getHandler() {
540
      return handler;
×
541
    }
542
  }
543

544
  <R> ActivityOutput<R> executeActivity(ActivityInput<R> input);
545

546
  <R> LocalActivityOutput<R> executeLocalActivity(LocalActivityInput<R> input);
547

548
  <R> ChildWorkflowOutput<R> executeChildWorkflow(ChildWorkflowInput<R> input);
549

550
  Random newRandom();
551

552
  SignalExternalOutput signalExternalWorkflow(SignalExternalInput input);
553

554
  CancelWorkflowOutput cancelWorkflow(CancelWorkflowInput input);
555

556
  void sleep(Duration duration);
557

558
  boolean await(Duration timeout, String reason, Supplier<Boolean> unblockCondition);
559

560
  void await(String reason, Supplier<Boolean> unblockCondition);
561

562
  Promise<Void> newTimer(Duration duration);
563

564
  <R> R sideEffect(Class<R> resultClass, Type resultType, Func<R> func);
565

566
  <R> R mutableSideEffect(
567
      String id, Class<R> resultClass, Type resultType, BiPredicate<R, R> updated, Func<R> func);
568

569
  int getVersion(String changeId, int minSupported, int maxSupported);
570

571
  void continueAsNew(ContinueAsNewInput input);
572

573
  void registerQuery(RegisterQueryInput input);
574

575
  void registerSignalHandlers(RegisterSignalHandlersInput input);
576

577
  @Experimental
578
  void registerUpdateHandlers(RegisterUpdateHandlersInput input);
579

580
  void registerDynamicSignalHandler(RegisterDynamicSignalHandlerInput handler);
581

582
  void registerDynamicQueryHandler(RegisterDynamicQueryHandlerInput input);
583

584
  @Experimental
585
  void registerDynamicUpdateHandler(RegisterDynamicUpdateHandlerInput input);
586

587
  UUID randomUUID();
588

589
  void upsertSearchAttributes(Map<String, ?> searchAttributes);
590

591
  void upsertTypedSearchAttributes(SearchAttributeUpdate<?>... searchAttributeUpdates);
592

593
  /**
594
   * Intercepts creation of a workflow child thread.
595
   *
596
   * <p>Please note, that "workflow child thread" and "child workflow" are different and independent
597
   * concepts.
598
   *
599
   * @param runnable thread function to run
600
   * @param detached if this thread is detached from the parent {@link CancellationScope}
601
   * @param name name of the thread
602
   * @return created WorkflowThread
603
   */
604
  Object newChildThread(Runnable runnable, boolean detached, String name);
605

606
  long currentTimeMillis();
607
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc