Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sample - exclude workflow/activity types from interceptors #658

Merged
merged 2 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ See the README.md file in each main sample directory for cut/paste Gradle comman
- [**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.

- [**Workflow Count Interceptor**](/core/src/main/java/io/temporal/samples/countinterceptor): Demonstrates how to create and register a simple Workflow Count Interceptor.
-

- [**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.

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

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

- [**Exclude Workflow/ActivityTypes from Interceptors**](/core/src/main/java/io/temporal/samples/excludefrominterceptor): Demonstrates how to exclude certain workflow / activity types from interceptors.

#### SDK Metrics

- [**Set up SDK metrics**](/core/src/main/java/io/temporal/samples/metrics): Demonstrates how to set up and scrape SDK metrics.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Excluding certain Workflow and Activity Types from interceptors

This sample shows how to exclude certain workflow types and Activity types from Workflow and Activity Interceptors.

1. Start the Sample:
```bash
./gradlew -q execute -PmainClass=io.temporal.samples.excludefrominterceptor.RunMyWorkflows
```

Observe the event histories of MyWorkflowOne and MyWorkflowTwo in your Temporal Web UI.
You should see that even tho both executions were served by same worker so both had the interceptors applied,
MyWorkflowTwo was excluded from being applied by these interceptors.

Also from the Activity interceptor logs (System.out prints during sample run) note that
only ActivityOne activity is being intercepted and not ActivityTwo or the "ForInterceptor" activities.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.client.WorkflowStub;
import io.temporal.samples.excludefrominterceptor.activities.ForInterceptorActivitiesImpl;
import io.temporal.samples.excludefrominterceptor.activities.MyActivitiesImpl;
import io.temporal.samples.excludefrominterceptor.interceptor.MyWorkerInterceptor;
import io.temporal.samples.excludefrominterceptor.workflows.*;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.worker.Worker;
import io.temporal.worker.WorkerFactory;
import io.temporal.worker.WorkerFactoryOptions;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;

public class RunMyWorkflows {
public static void main(String[] args) {
WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
WorkflowClient client = WorkflowClient.newInstance(service);

WorkerFactoryOptions wfo =
WorkerFactoryOptions.newBuilder()
// exclude MyWorkflowTwo from interceptor
.setWorkerInterceptors(
new MyWorkerInterceptor(
// exclude MyWorkflowTwo from workflow interceptors
Arrays.asList(MyWorkflowTwo.class.getSimpleName()),
// exclude ActivityTwo and the "ForInterceptor" activities from activity
// interceptor
// note with SpringBoot starter you could use bean names here, we use strings to
// not have
// to reflect on the activity impl class in sample
Arrays.asList(
"ActivityTwo", "ForInterceptorActivityOne", "ForInterceptorActivityTwo")))
.validateAndBuildWithDefaults();

WorkerFactory factory = WorkerFactory.newInstance(client, wfo);
Worker worker = factory.newWorker("exclude-from-interceptor-queue");
worker.registerWorkflowImplementationTypes(MyWorkflowOneImpl.class, MyWorkflowTwoImpl.class);
worker.registerActivitiesImplementations(
new MyActivitiesImpl(), new ForInterceptorActivitiesImpl());

factory.start();

MyWorkflow myWorkflow =
client.newWorkflowStub(
MyWorkflowOne.class,
WorkflowOptions.newBuilder()
.setWorkflowId("MyWorkflowOne")
.setTaskQueue("exclude-from-interceptor-queue")
.build());

MyWorkflowTwo myWorkflowTwo =
client.newWorkflowStub(
MyWorkflowTwo.class,
WorkflowOptions.newBuilder()
.setWorkflowId("MyWorkflowTwo")
.setTaskQueue("exclude-from-interceptor-queue")
.build());

WorkflowClient.start(myWorkflow::execute, "my workflow input");
WorkflowClient.start(myWorkflowTwo::execute, "my workflow two input");

// wait for both execs to complete
try {
CompletableFuture.allOf(
WorkflowStub.fromTyped(myWorkflow).getResultAsync(String.class),
WorkflowStub.fromTyped(myWorkflowTwo).getResultAsync(String.class))
.get();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}

System.exit(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.activities;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface ForInterceptorActivities {
void forInterceptorActivityOne(Object output);

void forInterceptorActivityTwo(Object output);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.activities;

public class ForInterceptorActivitiesImpl implements ForInterceptorActivities {
@Override
public void forInterceptorActivityOne(Object output) {}

@Override
public void forInterceptorActivityTwo(Object output) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.activities;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface MyActivities {
void activityOne(String input);

void activityTwo(String input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.activities;

public class MyActivitiesImpl implements MyActivities {
@Override
public void activityOne(String input) {}

@Override
public void activityTwo(String input) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.interceptor;

import io.temporal.activity.ActivityExecutionContext;
import io.temporal.common.interceptors.ActivityInboundCallsInterceptor;
import io.temporal.common.interceptors.ActivityInboundCallsInterceptorBase;
import java.util.ArrayList;
import java.util.List;

public class MyActivityInboundCallsInterceptor extends ActivityInboundCallsInterceptorBase {

private ActivityExecutionContext activityExecutionContext;
private List<String> excludeActivityTypes = new ArrayList<>();

public MyActivityInboundCallsInterceptor(ActivityInboundCallsInterceptor next) {
super(next);
}

public MyActivityInboundCallsInterceptor(
List<String> excludeActivityTypes, ActivityInboundCallsInterceptor next) {
super(next);
this.excludeActivityTypes = excludeActivityTypes;
}

@Override
public void init(ActivityExecutionContext context) {
this.activityExecutionContext = context;
super.init(context);
}

@Override
public ActivityOutput execute(ActivityInput input) {
if (!excludeActivityTypes.contains(activityExecutionContext.getInfo().getActivityType())) {
// If activity retry attempt is > X then we want to log this (or push to metrics or similar)
// for demo we just use >=1 just to log and dont have to explicitly fail our sample activities
if (activityExecutionContext.getInfo().getAttempt() >= 1) {
System.out.println(
"Activity retry attempt noted - "
+ activityExecutionContext.getInfo().getWorkflowType()
+ " - "
+ activityExecutionContext.getInfo().getActivityType());
}
}
return super.execute(input);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.excludefrominterceptor.interceptor;

import io.temporal.common.interceptors.ActivityInboundCallsInterceptor;
import io.temporal.common.interceptors.WorkerInterceptor;
import io.temporal.common.interceptors.WorkflowInboundCallsInterceptor;
import java.util.ArrayList;
import java.util.List;

public class MyWorkerInterceptor implements WorkerInterceptor {
private List<String> excludeWorkflowTypes = new ArrayList<>();
private List<String> excludeActivityTypes = new ArrayList<>();

public MyWorkerInterceptor() {}

public MyWorkerInterceptor(List<String> excludeWorkflowTypes) {
this.excludeWorkflowTypes = excludeWorkflowTypes;
}

public MyWorkerInterceptor(List<String> excludeWorkflowTypes, List<String> excludeActivityTypes) {
this.excludeWorkflowTypes = excludeWorkflowTypes;
this.excludeActivityTypes = excludeActivityTypes;
}

@Override
public WorkflowInboundCallsInterceptor interceptWorkflow(WorkflowInboundCallsInterceptor next) {
return new MyWorkflowInboundCallsInterceptor(excludeWorkflowTypes, next);
}

@Override
public ActivityInboundCallsInterceptor interceptActivity(ActivityInboundCallsInterceptor next) {
return new MyActivityInboundCallsInterceptor(excludeActivityTypes, next);
}
}
Loading
Loading