2020
2121package io .temporal .common .metadata ;
2222
23- import io .temporal .workflow .QueryMethod ;
24- import io .temporal .workflow .SignalMethod ;
25- import io .temporal .workflow .WorkflowInterface ;
26- import io .temporal .workflow .WorkflowMethod ;
23+ import io .temporal .workflow .*;
2724import java .lang .reflect .Method ;
2825import java .lang .reflect .Modifier ;
2926import java .util .*;
@@ -97,7 +94,7 @@ public static POJOWorkflowInterfaceMetadata newInstanceSkipWorkflowAnnotationChe
9794 * <ul>
9895 * <li>{@code anInterface} to be annotated with {@link WorkflowInterface}
9996 * <li>All methods of {@code anInterface} to be annotated with {@link WorkflowMethod}, {@link
100- * QueryMethod} or {@link SignalMethod}
97+ * QueryMethod}, {@link UpdateMethod}, {@link UpdateValidatorMethod} or {@link SignalMethod}
10198 * </ul>
10299 *
103100 * @param anInterface interface to create metadata for
@@ -137,15 +134,17 @@ public static POJOWorkflowInterfaceMetadata newInstance(
137134 * #newInstance(Class, boolean)} is that the interfaces passing here can be not annotated with
138135 * {@link WorkflowInterface} at all and even not having {@link WorkflowInterface} as a parent. It
139136 * also can have all kinds of additional methods that are not annotated with {@link
140- * WorkflowMethod}, {@link QueryMethod} or {@link SignalMethod}. Such unannotated methods or
141- * methods that are not part of some {@link WorkflowInterface} will be ignored.
137+ * WorkflowMethod}, {@link QueryMethod}, {@link UpdateMethod}, {@link UpdateValidatorMethod} or
138+ * {@link SignalMethod}. Such unannotated methods or methods that are not part of some {@link
139+ * WorkflowInterface} will be ignored.
142140 *
143141 * @param anInterface interface to create metadata for
144142 * @param forceProcessWorkflowMethods if true, methods of the {@code anInterface} that are
145- * annotated with {@link WorkflowMethod}, {@link QueryMethod} or {@link SignalMethod} are
146- * processed like {@code current} is a workflow interface even if it is not annotated with
147- * {@link WorkflowInterface} itself. For example, this is useful when we have a query-only
148- * interface to register as a listener or call as a stub.
143+ * annotated with {@link WorkflowMethod}, {@link QueryMethod}, {@link UpdateMethod}, {@link
144+ * UpdateValidatorMethod} or {@link SignalMethod} are processed like {@code current} is a
145+ * workflow interface even if it is not annotated with {@link WorkflowInterface} itself. For
146+ * example, this is useful when we have a query-only interface to register as a listener or
147+ * call as a stub.
149148 * @return metadata for the interface
150149 */
151150 static POJOWorkflowInterfaceMetadata newImplementationInstance (
@@ -161,10 +160,11 @@ static POJOWorkflowInterfaceMetadata newImplementationInstance(
161160 * @param validateWorkflowAnnotation check if the interface has a {@link WorkflowInterface}
162161 * annotation with methods
163162 * @param forceProcessWorkflowMethods if true, methods of the {@code anInterface} that are
164- * annotated with {@link WorkflowMethod}, {@link QueryMethod} or {@link SignalMethod} are
165- * processed like {@code current} is a workflow interface even if it is not annotated with
166- * {@link WorkflowInterface} itself. For example, this is useful when we have a query-only
167- * interface to register as a listener or call as a stub.
163+ * annotated with {@link WorkflowMethod}, {@link QueryMethod}, {@link UpdateMethod}, {@link
164+ * UpdateValidatorMethod} or {@link SignalMethod} are processed like {@code current} is a
165+ * workflow interface even if it is not annotated with {@link WorkflowInterface} itself. For
166+ * example, this is useful when we have a query-only interface to register as a listener or
167+ * call as a stub.
168168 */
169169 private static POJOWorkflowInterfaceMetadata newInstanceInternal (
170170 Class <?> anInterface ,
@@ -189,6 +189,39 @@ private static POJOWorkflowInterfaceMetadata newInstanceInternal(
189189 "Interface doesn't contain any methods: " + anInterface .getName ());
190190 }
191191 }
192+ // Validate that all @UpdateValidatorMethod methods have corresponding @UpdateMethod
193+ Map <String , POJOWorkflowMethodMetadata > updateMethods = new HashMap <>();
194+ for (POJOWorkflowMethodMetadata methodMetadata : result .methods .values ()) {
195+ if (methodMetadata .getType () == WorkflowMethodType .UPDATE ) {
196+ updateMethods .put (methodMetadata .getName (), methodMetadata );
197+ }
198+ }
199+
200+ for (POJOWorkflowMethodMetadata methodMetadata : result .methods .values ()) {
201+ if (methodMetadata .getType () == WorkflowMethodType .UPDATE_VALIDATOR ) {
202+ UpdateValidatorMethod validator =
203+ methodMetadata .getWorkflowMethod ().getAnnotation (UpdateValidatorMethod .class );
204+ POJOWorkflowMethodMetadata update = updateMethods .get (validator .updateName ());
205+ if (update == null ) {
206+ throw new IllegalArgumentException (
207+ "Missing @UpdateMethod with name \" "
208+ + validator .updateName ()
209+ + "\" for @UpdateValidatorMethod \" "
210+ + methodMetadata .getWorkflowMethod ().getName ()
211+ + "\" " );
212+ }
213+ if (!Arrays .equals (
214+ update .getWorkflowMethod ().getGenericParameterTypes (),
215+ methodMetadata .getWorkflowMethod ().getGenericParameterTypes ())) {
216+ throw new IllegalArgumentException (
217+ "Update method \" "
218+ + update .getWorkflowMethod ().getName ()
219+ + "\" and Validator method \" "
220+ + methodMetadata .getWorkflowMethod ().getName ()
221+ + "\" do not have the same parameters" );
222+ }
223+ }
224+ }
192225 return result ;
193226 }
194227
0 commit comments