Skip to content

Commit f239fab

Browse files
authored
Sample - exclude workflow/activity types from interceptors (temporalio#658)
* Sample - exclude workflow/activity types from interceptors Signed-off-by: Tihomir Surdilovic <tihomir@temporal.io> * changed activity check event type in test Signed-off-by: Tihomir Surdilovic <tihomir@temporal.io> --------- Signed-off-by: Tihomir Surdilovic <tihomir@temporal.io>
1 parent e7db2a1 commit f239fab

17 files changed

+741
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ See the README.md file in each main sample directory for cut/paste Gradle comman
108108
- [**Updatable Timer**](/core/src/main/java/io/temporal/samples/updatabletimer): Demonstrates the use of a helper class which relies on `Workflow.await` to implement a blocking sleep that can be updated at any moment.
109109

110110
- [**Workflow Count Interceptor**](/core/src/main/java/io/temporal/samples/countinterceptor): Demonstrates how to create and register a simple Workflow Count Interceptor.
111-
-
111+
112112
- [**Workflow Retry On Signal Interceptor**](/core/src/main/java/io/temporal/samples/retryonsignalinterceptor): Demonstrates how to create and register an interceptor that retries an activity on a signal.
113113

114114
- [**List Workflows**](/core/src/main/java/io/temporal/samples/listworkflows): Demonstrates the use of custom search attributes and ListWorkflowExecutionsRequest with custom queries.
@@ -129,6 +129,8 @@ See the README.md file in each main sample directory for cut/paste Gradle comman
129129

130130
- [**Payload Codec**](/core/src/main/java/io/temporal/samples/encodefailures): Demonstrates how to use simple codec to encode/decode failure messages.
131131

132+
- [**Exclude Workflow/ActivityTypes from Interceptors**](/core/src/main/java/io/temporal/samples/excludefrominterceptor): Demonstrates how to exclude certain workflow / activity types from interceptors.
133+
132134
#### SDK Metrics
133135

134136
- [**Set up SDK metrics**](/core/src/main/java/io/temporal/samples/metrics): Demonstrates how to set up and scrape SDK metrics.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Excluding certain Workflow and Activity Types from interceptors
2+
3+
This sample shows how to exclude certain workflow types and Activity types from Workflow and Activity Interceptors.
4+
5+
1. Start the Sample:
6+
```bash
7+
./gradlew -q execute -PmainClass=io.temporal.samples.excludefrominterceptor.RunMyWorkflows
8+
```
9+
10+
Observe the event histories of MyWorkflowOne and MyWorkflowTwo in your Temporal Web UI.
11+
You should see that even tho both executions were served by same worker so both had the interceptors applied,
12+
MyWorkflowTwo was excluded from being applied by these interceptors.
13+
14+
Also from the Activity interceptor logs (System.out prints during sample run) note that
15+
only ActivityOne activity is being intercepted and not ActivityTwo or the "ForInterceptor" activities.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor;
21+
22+
import io.temporal.client.WorkflowClient;
23+
import io.temporal.client.WorkflowOptions;
24+
import io.temporal.client.WorkflowStub;
25+
import io.temporal.samples.excludefrominterceptor.activities.ForInterceptorActivitiesImpl;
26+
import io.temporal.samples.excludefrominterceptor.activities.MyActivitiesImpl;
27+
import io.temporal.samples.excludefrominterceptor.interceptor.MyWorkerInterceptor;
28+
import io.temporal.samples.excludefrominterceptor.workflows.*;
29+
import io.temporal.serviceclient.WorkflowServiceStubs;
30+
import io.temporal.worker.Worker;
31+
import io.temporal.worker.WorkerFactory;
32+
import io.temporal.worker.WorkerFactoryOptions;
33+
import java.util.Arrays;
34+
import java.util.concurrent.CompletableFuture;
35+
36+
public class RunMyWorkflows {
37+
public static void main(String[] args) {
38+
WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
39+
WorkflowClient client = WorkflowClient.newInstance(service);
40+
41+
WorkerFactoryOptions wfo =
42+
WorkerFactoryOptions.newBuilder()
43+
// exclude MyWorkflowTwo from interceptor
44+
.setWorkerInterceptors(
45+
new MyWorkerInterceptor(
46+
// exclude MyWorkflowTwo from workflow interceptors
47+
Arrays.asList(MyWorkflowTwo.class.getSimpleName()),
48+
// exclude ActivityTwo and the "ForInterceptor" activities from activity
49+
// interceptor
50+
// note with SpringBoot starter you could use bean names here, we use strings to
51+
// not have
52+
// to reflect on the activity impl class in sample
53+
Arrays.asList(
54+
"ActivityTwo", "ForInterceptorActivityOne", "ForInterceptorActivityTwo")))
55+
.validateAndBuildWithDefaults();
56+
57+
WorkerFactory factory = WorkerFactory.newInstance(client, wfo);
58+
Worker worker = factory.newWorker("exclude-from-interceptor-queue");
59+
worker.registerWorkflowImplementationTypes(MyWorkflowOneImpl.class, MyWorkflowTwoImpl.class);
60+
worker.registerActivitiesImplementations(
61+
new MyActivitiesImpl(), new ForInterceptorActivitiesImpl());
62+
63+
factory.start();
64+
65+
MyWorkflow myWorkflow =
66+
client.newWorkflowStub(
67+
MyWorkflowOne.class,
68+
WorkflowOptions.newBuilder()
69+
.setWorkflowId("MyWorkflowOne")
70+
.setTaskQueue("exclude-from-interceptor-queue")
71+
.build());
72+
73+
MyWorkflowTwo myWorkflowTwo =
74+
client.newWorkflowStub(
75+
MyWorkflowTwo.class,
76+
WorkflowOptions.newBuilder()
77+
.setWorkflowId("MyWorkflowTwo")
78+
.setTaskQueue("exclude-from-interceptor-queue")
79+
.build());
80+
81+
WorkflowClient.start(myWorkflow::execute, "my workflow input");
82+
WorkflowClient.start(myWorkflowTwo::execute, "my workflow two input");
83+
84+
// wait for both execs to complete
85+
try {
86+
CompletableFuture.allOf(
87+
WorkflowStub.fromTyped(myWorkflow).getResultAsync(String.class),
88+
WorkflowStub.fromTyped(myWorkflowTwo).getResultAsync(String.class))
89+
.get();
90+
} catch (Exception e) {
91+
System.out.println("Error: " + e.getMessage());
92+
}
93+
94+
System.exit(0);
95+
}
96+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.activities;
21+
22+
import io.temporal.activity.ActivityInterface;
23+
24+
@ActivityInterface
25+
public interface ForInterceptorActivities {
26+
void forInterceptorActivityOne(Object output);
27+
28+
void forInterceptorActivityTwo(Object output);
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.activities;
21+
22+
public class ForInterceptorActivitiesImpl implements ForInterceptorActivities {
23+
@Override
24+
public void forInterceptorActivityOne(Object output) {}
25+
26+
@Override
27+
public void forInterceptorActivityTwo(Object output) {}
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.activities;
21+
22+
import io.temporal.activity.ActivityInterface;
23+
24+
@ActivityInterface
25+
public interface MyActivities {
26+
void activityOne(String input);
27+
28+
void activityTwo(String input);
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.activities;
21+
22+
public class MyActivitiesImpl implements MyActivities {
23+
@Override
24+
public void activityOne(String input) {}
25+
26+
@Override
27+
public void activityTwo(String input) {}
28+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.interceptor;
21+
22+
import io.temporal.activity.ActivityExecutionContext;
23+
import io.temporal.common.interceptors.ActivityInboundCallsInterceptor;
24+
import io.temporal.common.interceptors.ActivityInboundCallsInterceptorBase;
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
28+
public class MyActivityInboundCallsInterceptor extends ActivityInboundCallsInterceptorBase {
29+
30+
private ActivityExecutionContext activityExecutionContext;
31+
private List<String> excludeActivityTypes = new ArrayList<>();
32+
33+
public MyActivityInboundCallsInterceptor(ActivityInboundCallsInterceptor next) {
34+
super(next);
35+
}
36+
37+
public MyActivityInboundCallsInterceptor(
38+
List<String> excludeActivityTypes, ActivityInboundCallsInterceptor next) {
39+
super(next);
40+
this.excludeActivityTypes = excludeActivityTypes;
41+
}
42+
43+
@Override
44+
public void init(ActivityExecutionContext context) {
45+
this.activityExecutionContext = context;
46+
super.init(context);
47+
}
48+
49+
@Override
50+
public ActivityOutput execute(ActivityInput input) {
51+
if (!excludeActivityTypes.contains(activityExecutionContext.getInfo().getActivityType())) {
52+
// If activity retry attempt is > X then we want to log this (or push to metrics or similar)
53+
// for demo we just use >=1 just to log and dont have to explicitly fail our sample activities
54+
if (activityExecutionContext.getInfo().getAttempt() >= 1) {
55+
System.out.println(
56+
"Activity retry attempt noted - "
57+
+ activityExecutionContext.getInfo().getWorkflowType()
58+
+ " - "
59+
+ activityExecutionContext.getInfo().getActivityType());
60+
}
61+
}
62+
return super.execute(input);
63+
}
64+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
3+
*
4+
* Copyright 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"). You may not
9+
* use this file except in compliance with the License. A copy of the License is
10+
* located at
11+
*
12+
* http://aws.amazon.com/apache2.0
13+
*
14+
* or in the "license" file accompanying this file. This file is distributed on
15+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16+
* express or implied. See the License for the specific language governing
17+
* permissions and limitations under the License.
18+
*/
19+
20+
package io.temporal.samples.excludefrominterceptor.interceptor;
21+
22+
import io.temporal.common.interceptors.ActivityInboundCallsInterceptor;
23+
import io.temporal.common.interceptors.WorkerInterceptor;
24+
import io.temporal.common.interceptors.WorkflowInboundCallsInterceptor;
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
28+
public class MyWorkerInterceptor implements WorkerInterceptor {
29+
private List<String> excludeWorkflowTypes = new ArrayList<>();
30+
private List<String> excludeActivityTypes = new ArrayList<>();
31+
32+
public MyWorkerInterceptor() {}
33+
34+
public MyWorkerInterceptor(List<String> excludeWorkflowTypes) {
35+
this.excludeWorkflowTypes = excludeWorkflowTypes;
36+
}
37+
38+
public MyWorkerInterceptor(List<String> excludeWorkflowTypes, List<String> excludeActivityTypes) {
39+
this.excludeWorkflowTypes = excludeWorkflowTypes;
40+
this.excludeActivityTypes = excludeActivityTypes;
41+
}
42+
43+
@Override
44+
public WorkflowInboundCallsInterceptor interceptWorkflow(WorkflowInboundCallsInterceptor next) {
45+
return new MyWorkflowInboundCallsInterceptor(excludeWorkflowTypes, next);
46+
}
47+
48+
@Override
49+
public ActivityInboundCallsInterceptor interceptActivity(ActivityInboundCallsInterceptor next) {
50+
return new MyActivityInboundCallsInterceptor(excludeActivityTypes, next);
51+
}
52+
}

0 commit comments

Comments
 (0)