3434import java .time .Duration ;
3535import java .time .OffsetDateTime ;
3636import java .time .ZoneOffset ;
37+ import java .util .Arrays ;
38+ import java .util .List ;
39+ import java .util .StringJoiner ;
3740
3841/**
3942 * Sample Temporal workflow that demonstrates setting up, updating, and retrieving workflow search
4043 * attributes using the typed search attributes API.
44+ *
45+ * <p>NOTE: you may need to add these custom search attributes yourself before running the sample.
46+ * If you are using autosetup image for service, you will need to create the
47+ * "CustomKeywordListField" search attribute with Temporal cli, for example:
48+ *
49+ * <p>temporal operator search-attribute create -name "CustomKeywordListField" -type "KeywordList"
50+ *
51+ * <p>If you run your test and don't have some custom SA defined that are used here you would see
52+ * error like: INVALID_ARGUMENT: Namespace default has no mapping defined for search attribute
53+ * CustomBoolField when trying to start the workflow execution. In that case use cli to add the
54+ * needed search attribute with its needed type.
4155 */
4256public class HelloTypedSearchAttributes {
4357
@@ -50,6 +64,8 @@ public class HelloTypedSearchAttributes {
5064 // Define all our search attributes with appropriate types
5165 static final SearchAttributeKey <String > CUSTOM_KEYWORD_SA =
5266 SearchAttributeKey .forKeyword ("CustomKeywordField" );
67+ static final SearchAttributeKey <List <String >> CUSTOM_KEYWORD_LIST_SA =
68+ SearchAttributeKey .forKeywordList ("CustomKeywordListField" );
5369 static final SearchAttributeKey <Long > CUSTOM_LONG_SA =
5470 SearchAttributeKey .forLong ("CustomIntField" );
5571 static final SearchAttributeKey <Double > CUSTOM_DOUBLE_SA =
@@ -95,7 +111,7 @@ public interface GreetingWorkflow {
95111 @ ActivityInterface
96112 public interface GreetingActivities {
97113 @ ActivityMethod
98- String composeGreeting (String greeting , String name );
114+ String composeGreeting (String greeting , List < String > salutations , String name );
99115 }
100116
101117 // Define the workflow implementation which implements our getGreeting workflow method.
@@ -124,8 +140,9 @@ public String getGreeting(String name) {
124140 io .temporal .common .SearchAttributes searchAttributes = Workflow .getTypedSearchAttributes ();
125141 // Get a particular value out of the container using the typed key
126142 String greeting = searchAttributes .get (CUSTOM_KEYWORD_SA );
143+ List <String > salutations = searchAttributes .get (CUSTOM_KEYWORD_LIST_SA );
127144 // This is a blocking call that returns only after the activity has completed.
128- return activities .composeGreeting (greeting , name );
145+ return activities .composeGreeting (greeting , salutations , name );
129146 }
130147 }
131148
@@ -135,8 +152,13 @@ public String getGreeting(String name) {
135152 */
136153 static class GreetingActivitiesImpl implements GreetingActivities {
137154 @ Override
138- public String composeGreeting (String greeting , String name ) {
139- return greeting + " " + name + "!" ;
155+ public String composeGreeting (String greeting , List <String > salutations , String name ) {
156+ StringJoiner greetingJoiner = new StringJoiner (" " );
157+ greetingJoiner .add (greeting );
158+ greetingJoiner .add (name );
159+ salutations .forEach (s -> greetingJoiner .add (s ));
160+
161+ return greetingJoiner .toString ();
140162 }
141163 }
142164
@@ -211,6 +233,7 @@ public static void main(String[] args) {
211233 private static io .temporal .common .SearchAttributes generateTypedSearchAttributes () {
212234 return io .temporal .common .SearchAttributes .newBuilder ()
213235 .set (CUSTOM_KEYWORD_SA , "keyword" )
236+ .set (CUSTOM_KEYWORD_LIST_SA , Arrays .asList ("how" , "are" , "you" , "doing?" ))
214237 .set (CUSTOM_LONG_SA , 1l )
215238 .set (CUSTOM_DOUBLE_SA , 0.1 )
216239 .set (CUSTOM_BOOL_SA , true )
0 commit comments