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

temporalio / sdk-java / #333

16 Oct 2024 07:28PM UTC coverage: 78.65% (+0.6%) from 78.085%
#333

push

github

web-flow
Fix code coverage (#2275)

22670 of 28824 relevant lines covered (78.65%)

0.79 hits per line

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

91.62
/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 com.uber.m3.tally.Scope;
24
import io.temporal.activity.ActivityOptions;
25
import io.temporal.activity.LocalActivityOptions;
26
import io.temporal.api.common.v1.WorkflowExecution;
27
import io.temporal.common.Experimental;
28
import io.temporal.common.SearchAttributeUpdate;
29
import io.temporal.workflow.*;
30
import io.temporal.workflow.Functions.Func;
31
import java.lang.reflect.Type;
32
import java.time.Duration;
33
import java.util.*;
34
import java.util.function.BiPredicate;
35
import java.util.function.Supplier;
36
import javax.annotation.Nullable;
37

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

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

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

84
    public String getActivityName() {
85
      return activityName;
1✔
86
    }
87

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

92
    public Type getResultType() {
93
      return resultType;
1✔
94
    }
95

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

100
    public ActivityOptions getOptions() {
101
      return options;
1✔
102
    }
103

104
    public Header getHeader() {
105
      return header;
1✔
106
    }
107
  }
108

109
  final class ActivityOutput<R> {
110
    private final String activityId;
111
    private final Promise<R> result;
112

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

118
    public String getActivityId() {
119
      return activityId;
1✔
120
    }
121

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

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

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

150
    public String getActivityName() {
151
      return activityName;
1✔
152
    }
153

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

158
    public Type getResultType() {
159
      return resultType;
1✔
160
    }
161

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

166
    public LocalActivityOptions getOptions() {
167
      return options;
1✔
168
    }
169

170
    public Header getHeader() {
171
      return header;
1✔
172
    }
173
  }
174

175
  final class LocalActivityOutput<R> {
176
    private final Promise<R> result;
177

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

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

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

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

213
    public String getWorkflowId() {
214
      return workflowId;
1✔
215
    }
216

217
    public String getWorkflowType() {
218
      return workflowType;
1✔
219
    }
220

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

225
    public Type getResultType() {
226
      return resultType;
1✔
227
    }
228

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

233
    public ChildWorkflowOptions getOptions() {
234
      return options;
1✔
235
    }
236

237
    public Header getHeader() {
238
      return header;
1✔
239
    }
240
  }
241

242
  final class ChildWorkflowOutput<R> {
243

244
    private final Promise<R> result;
245
    private final Promise<WorkflowExecution> workflowExecution;
246

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

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

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

261
  @Experimental
262
  final class ExecuteNexusOperationInput<R> {
263
    private final String endpoint;
264
    private final String service;
265
    private final String operation;
266
    private final Class<R> resultClass;
267
    private final Type resultType;
268
    private final Object arg;
269
    private final NexusOperationOptions options;
270
    private final Map<String, String> headers;
271

272
    public ExecuteNexusOperationInput(
273
        String endpoint,
274
        String service,
275
        String operation,
276
        Class<R> resultClass,
277
        Type resultType,
278
        Object arg,
279
        NexusOperationOptions options,
280
        Map<String, String> headers) {
1✔
281
      this.endpoint = endpoint;
1✔
282
      this.service = service;
1✔
283
      this.operation = operation;
1✔
284
      this.resultClass = resultClass;
1✔
285
      this.resultType = resultType;
1✔
286
      this.arg = arg;
1✔
287
      this.options = options;
1✔
288
      this.headers = headers;
1✔
289
    }
1✔
290

291
    public String getService() {
292
      return service;
1✔
293
    }
294

295
    public String getOperation() {
296
      return operation;
1✔
297
    }
298

299
    public Object getArg() {
300
      return arg;
1✔
301
    }
302

303
    public Class<R> getResultClass() {
304
      return resultClass;
1✔
305
    }
306

307
    public Type getResultType() {
308
      return resultType;
1✔
309
    }
310

311
    public String getEndpoint() {
312
      return endpoint;
1✔
313
    }
314

315
    public NexusOperationOptions getOptions() {
316
      return options;
1✔
317
    }
318

319
    public Map<String, String> getHeaders() {
320
      return headers;
1✔
321
    }
322
  }
323

324
  @Experimental
325
  final class ExecuteNexusOperationOutput<R> {
326
    private final Promise<R> result;
327
    private final Promise<NexusOperationExecution> operationExecution;
328

329
    public ExecuteNexusOperationOutput(
330
        Promise<R> result, Promise<NexusOperationExecution> operationExecution) {
1✔
331
      this.result = result;
1✔
332
      this.operationExecution = operationExecution;
1✔
333
    }
1✔
334

335
    public Promise<R> getResult() {
336
      return result;
1✔
337
    }
338

339
    public Promise<NexusOperationExecution> getOperationExecution() {
340
      return operationExecution;
1✔
341
    }
342
  }
343

344
  final class SignalExternalInput {
345
    private final WorkflowExecution execution;
346
    private final String signalName;
347
    private final Header header;
348
    private final Object[] args;
349

350
    public SignalExternalInput(
351
        WorkflowExecution execution, String signalName, Header header, Object[] args) {
1✔
352
      this.execution = execution;
1✔
353
      this.signalName = signalName;
1✔
354
      this.header = header;
1✔
355
      this.args = args;
1✔
356
    }
1✔
357

358
    public WorkflowExecution getExecution() {
359
      return execution;
1✔
360
    }
361

362
    public String getSignalName() {
363
      return signalName;
1✔
364
    }
365

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

370
    public Object[] getArgs() {
371
      return args;
1✔
372
    }
373
  }
374

375
  final class SignalExternalOutput {
376
    private final Promise<Void> result;
377

378
    public SignalExternalOutput(Promise<Void> result) {
1✔
379
      this.result = result;
1✔
380
    }
1✔
381

382
    public Promise<Void> getResult() {
383
      return result;
1✔
384
    }
385
  }
386

387
  final class CancelWorkflowInput {
388
    private final WorkflowExecution execution;
389

390
    public CancelWorkflowInput(WorkflowExecution execution) {
×
391
      this.execution = execution;
×
392
    }
×
393

394
    public WorkflowExecution getExecution() {
395
      return execution;
×
396
    }
397
  }
398

399
  final class CancelWorkflowOutput {
400
    private final Promise<Void> result;
401

402
    public CancelWorkflowOutput(Promise<Void> result) {
×
403
      this.result = result;
×
404
    }
×
405

406
    public Promise<Void> getResult() {
407
      return result;
×
408
    }
409
  }
410

411
  final class ContinueAsNewInput {
412
    private final @Nullable String workflowType;
413
    private final @Nullable ContinueAsNewOptions options;
414
    private final Object[] args;
415
    private final Header header;
416

417
    public ContinueAsNewInput(
418
        @Nullable String workflowType,
419
        @Nullable ContinueAsNewOptions options,
420
        Object[] args,
421
        Header header) {
1✔
422
      this.workflowType = workflowType;
1✔
423
      this.options = options;
1✔
424
      this.args = args;
1✔
425
      this.header = header;
1✔
426
    }
1✔
427

428
    /**
429
     * @return workflowType for the continue-as-new workflow run. null if continue-as-new should
430
     *     inherit the type of the original workflow run.
431
     */
432
    public @Nullable String getWorkflowType() {
433
      return workflowType;
1✔
434
    }
435

436
    /**
437
     * @return options for the continue-as-new workflow run. Can be null, in that case the values
438
     *     will be taken from the original workflow run.
439
     */
440
    public @Nullable ContinueAsNewOptions getOptions() {
441
      return options;
1✔
442
    }
443

444
    public Object[] getArgs() {
445
      return args;
1✔
446
    }
447

448
    public Header getHeader() {
449
      return header;
1✔
450
    }
451
  }
452

453
  final class SignalRegistrationRequest {
454
    private final String signalType;
455
    private final HandlerUnfinishedPolicy unfinishedPolicy;
456
    private final Class<?>[] argTypes;
457
    private final Type[] genericArgTypes;
458
    private final Functions.Proc1<Object[]> callback;
459

460
    // Kept for backward compatibility
461
    public SignalRegistrationRequest(
462
        String signalType,
463
        Class<?>[] argTypes,
464
        Type[] genericArgTypes,
465
        Functions.Proc1<Object[]> callback) {
×
466
      this.signalType = signalType;
×
467
      this.unfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON;
×
468
      this.argTypes = argTypes;
×
469
      this.genericArgTypes = genericArgTypes;
×
470
      this.callback = callback;
×
471
    }
×
472

473
    public SignalRegistrationRequest(
474
        String signalType,
475
        HandlerUnfinishedPolicy unfinishedPolicy,
476
        Class<?>[] argTypes,
477
        Type[] genericArgTypes,
478
        Functions.Proc1<Object[]> callback) {
1✔
479
      this.signalType = signalType;
1✔
480
      this.unfinishedPolicy = unfinishedPolicy;
1✔
481
      this.argTypes = argTypes;
1✔
482
      this.genericArgTypes = genericArgTypes;
1✔
483
      this.callback = callback;
1✔
484
    }
1✔
485

486
    public String getSignalType() {
487
      return signalType;
1✔
488
    }
489

490
    public HandlerUnfinishedPolicy getUnfinishedPolicy() {
491
      return unfinishedPolicy;
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.Proc1<Object[]> getCallback() {
503
      return callback;
1✔
504
    }
505
  }
506

507
  final class RegisterSignalHandlersInput {
508
    private final List<SignalRegistrationRequest> requests;
509

510
    public RegisterSignalHandlersInput(List<SignalRegistrationRequest> requests) {
1✔
511
      this.requests = requests;
1✔
512
    }
1✔
513

514
    public List<SignalRegistrationRequest> getRequests() {
515
      return requests;
1✔
516
    }
517
  }
518

519
  @Experimental
520
  final class UpdateRegistrationRequest {
521
    private final String updateName;
522
    private final HandlerUnfinishedPolicy unfinishedPolicy;
523
    private final Class<?>[] argTypes;
524
    private final Type[] genericArgTypes;
525
    private final Functions.Func1<Object[], Object> executeCallback;
526
    private final Functions.Proc1<Object[]> validateCallback;
527

528
    public UpdateRegistrationRequest(
529
        String updateName,
530
        HandlerUnfinishedPolicy unfinishedPolicy,
531
        Class<?>[] argTypes,
532
        Type[] genericArgTypes,
533
        Functions.Proc1<Object[]> validateCallback,
534
        Functions.Func1<Object[], Object> executeCallback) {
1✔
535
      this.updateName = updateName;
1✔
536
      this.unfinishedPolicy = unfinishedPolicy;
1✔
537
      this.argTypes = argTypes;
1✔
538
      this.genericArgTypes = genericArgTypes;
1✔
539
      this.validateCallback = validateCallback;
1✔
540
      this.executeCallback = executeCallback;
1✔
541
    }
1✔
542

543
    public String getUpdateName() {
544
      return updateName;
1✔
545
    }
546

547
    public HandlerUnfinishedPolicy getUnfinishedPolicy() {
548
      return unfinishedPolicy;
1✔
549
    }
550

551
    public Class<?>[] getArgTypes() {
552
      return argTypes;
1✔
553
    }
554

555
    public Type[] getGenericArgTypes() {
556
      return genericArgTypes;
1✔
557
    }
558

559
    public Functions.Proc1<Object[]> getValidateCallback() {
560
      return validateCallback;
1✔
561
    }
562

563
    public Functions.Func1<Object[], Object> getExecuteCallback() {
564
      return executeCallback;
1✔
565
    }
566
  }
567

568
  @Experimental
569
  final class RegisterUpdateHandlersInput {
570
    private final List<UpdateRegistrationRequest> requests;
571

572
    public RegisterUpdateHandlersInput(List<UpdateRegistrationRequest> requests) {
1✔
573
      this.requests = requests;
1✔
574
    }
1✔
575

576
    public List<UpdateRegistrationRequest> getRequests() {
577
      return requests;
1✔
578
    }
579
  }
580

581
  final class RegisterQueryInput {
582
    private final String queryType;
583
    private final Class<?>[] argTypes;
584
    private final Type[] genericArgTypes;
585
    private final Functions.Func1<Object[], Object> callback;
586

587
    public RegisterQueryInput(
588
        String queryType,
589
        Class<?>[] argTypes,
590
        Type[] genericArgTypes,
591
        Functions.Func1<Object[], Object> callback) {
1✔
592
      this.queryType = queryType;
1✔
593
      this.argTypes = argTypes;
1✔
594
      this.genericArgTypes = genericArgTypes;
1✔
595
      this.callback = callback;
1✔
596
    }
1✔
597

598
    public String getQueryType() {
599
      return queryType;
1✔
600
    }
601

602
    public Class<?>[] getArgTypes() {
603
      return argTypes;
1✔
604
    }
605

606
    public Type[] getGenericArgTypes() {
607
      return genericArgTypes;
1✔
608
    }
609

610
    public Functions.Func1<Object[], Object> getCallback() {
611
      return callback;
1✔
612
    }
613
  }
614

615
  final class RegisterDynamicQueryHandlerInput {
616
    private final DynamicQueryHandler handler;
617

618
    public RegisterDynamicQueryHandlerInput(DynamicQueryHandler handler) {
1✔
619
      this.handler = handler;
1✔
620
    }
1✔
621

622
    public DynamicQueryHandler getHandler() {
623
      return handler;
1✔
624
    }
625
  }
626

627
  final class RegisterDynamicSignalHandlerInput {
628
    private final DynamicSignalHandler handler;
629

630
    public RegisterDynamicSignalHandlerInput(DynamicSignalHandler handler) {
1✔
631
      this.handler = handler;
1✔
632
    }
1✔
633

634
    public DynamicSignalHandler getHandler() {
635
      return handler;
1✔
636
    }
637
  }
638

639
  @Experimental
640
  final class RegisterDynamicUpdateHandlerInput {
641
    private final DynamicUpdateHandler handler;
642

643
    public RegisterDynamicUpdateHandlerInput(DynamicUpdateHandler handler) {
1✔
644
      this.handler = handler;
1✔
645
    }
1✔
646

647
    public DynamicUpdateHandler getHandler() {
648
      return handler;
1✔
649
    }
650
  }
651

652
  <R> ActivityOutput<R> executeActivity(ActivityInput<R> input);
653

654
  <R> LocalActivityOutput<R> executeLocalActivity(LocalActivityInput<R> input);
655

656
  <R> ChildWorkflowOutput<R> executeChildWorkflow(ChildWorkflowInput<R> input);
657

658
  @Experimental
659
  <R> ExecuteNexusOperationOutput<R> executeNexusOperation(ExecuteNexusOperationInput<R> input);
660

661
  Random newRandom();
662

663
  SignalExternalOutput signalExternalWorkflow(SignalExternalInput input);
664

665
  CancelWorkflowOutput cancelWorkflow(CancelWorkflowInput input);
666

667
  void sleep(Duration duration);
668

669
  boolean await(Duration timeout, String reason, Supplier<Boolean> unblockCondition);
670

671
  void await(String reason, Supplier<Boolean> unblockCondition);
672

673
  Promise<Void> newTimer(Duration duration);
674

675
  Promise<Void> newTimer(Duration duration, TimerOptions options);
676

677
  <R> R sideEffect(Class<R> resultClass, Type resultType, Func<R> func);
678

679
  <R> R mutableSideEffect(
680
      String id, Class<R> resultClass, Type resultType, BiPredicate<R, R> updated, Func<R> func);
681

682
  int getVersion(String changeId, int minSupported, int maxSupported);
683

684
  void continueAsNew(ContinueAsNewInput input);
685

686
  void registerQuery(RegisterQueryInput input);
687

688
  void registerSignalHandlers(RegisterSignalHandlersInput input);
689

690
  @Experimental
691
  void registerUpdateHandlers(RegisterUpdateHandlersInput input);
692

693
  void registerDynamicSignalHandler(RegisterDynamicSignalHandlerInput handler);
694

695
  void registerDynamicQueryHandler(RegisterDynamicQueryHandlerInput input);
696

697
  @Experimental
698
  void registerDynamicUpdateHandler(RegisterDynamicUpdateHandlerInput input);
699

700
  UUID randomUUID();
701

702
  void upsertSearchAttributes(Map<String, ?> searchAttributes);
703

704
  void upsertTypedSearchAttributes(SearchAttributeUpdate<?>... searchAttributeUpdates);
705

706
  void upsertMemo(Map<String, Object> memo);
707

708
  /** Intercepts call to get the metric scope in a workflow. */
709
  Scope getMetricsScope();
710

711
  /**
712
   * Intercepts creation of a workflow child thread.
713
   *
714
   * <p>Please note, that "workflow child thread" and "child workflow" are different and independent
715
   * concepts.
716
   *
717
   * @param runnable thread function to run
718
   * @param detached if this thread is detached from the parent {@link CancellationScope}
719
   * @param name name of the thread
720
   * @return created WorkflowThread
721
   */
722
  Object newChildThread(Runnable runnable, boolean detached, String name);
723

724
  long currentTimeMillis();
725
}
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