21
21
import io .serverlessworkflow .api .Workflow ;
22
22
import io .serverlessworkflow .api .actions .Action ;
23
23
import io .serverlessworkflow .api .branches .Branch ;
24
+ import io .serverlessworkflow .api .error .Error ;
24
25
import io .serverlessworkflow .api .events .EventDefinition ;
25
26
import io .serverlessworkflow .api .events .OnEvents ;
26
27
import io .serverlessworkflow .api .functions .FunctionDefinition ;
28
+ import io .serverlessworkflow .api .interfaces .State ;
27
29
import io .serverlessworkflow .api .interfaces .WorkflowValidator ;
30
+ import io .serverlessworkflow .api .retry .RetryDefinition ;
28
31
import io .serverlessworkflow .api .states .*;
32
+ import io .serverlessworkflow .api .switchconditions .DataCondition ;
29
33
import io .serverlessworkflow .api .switchconditions .EventCondition ;
30
34
import io .serverlessworkflow .api .validation .ValidationError ;
31
35
import io .serverlessworkflow .api .validation .WorkflowSchemaLoader ;
@@ -86,10 +90,11 @@ public List<ValidationError> validate() {
86
90
.forEach (m -> {
87
91
if ((!m .equals ("#/functions: expected type: JSONObject, found: JSONArray" ) &&
88
92
!m .equals ("#/events: expected type: JSONObject, found: JSONArray" ) &&
89
- !m .equals ("#/start: expected type: JSONObject, found: String" ))) {
90
- addValidationError (m ,
91
- ValidationError .SCHEMA_VALIDATION );
92
- }});
93
+ !m .equals ("#/start: expected type: JSONObject, found: String" ) &&
94
+ !m .equals ("#/retries: expected type: JSONObject, found: JSONArray" ))) {
95
+ addValidationError (m ,
96
+ ValidationError .SCHEMA_VALIDATION );
97
+ }});
93
98
94
99
}
95
100
}
@@ -136,6 +141,21 @@ public List<ValidationError> validate() {
136
141
ValidationError .WORKFLOW_VALIDATION );
137
142
}
138
143
144
+ if (workflow .getStates () != null && !workflow .getStates ().isEmpty ()) {
145
+ boolean existingStateWithStartProperty = false ;
146
+ String startProperty = workflow .getStart ().getStateName ();
147
+ for (State s : workflow .getStates ()) {
148
+ if (s .getName ().equals (startProperty )) {
149
+ existingStateWithStartProperty = true ;
150
+ break ;
151
+ }
152
+ }
153
+ if (!existingStateWithStartProperty ) {
154
+ addValidationError ("No state name found that matches the workflow start definition" ,
155
+ ValidationError .WORKFLOW_VALIDATION );
156
+ }
157
+ }
158
+
139
159
Validation validation = new Validation ();
140
160
if (workflow .getStates () != null && !workflow .getStates ().isEmpty ()) {
141
161
workflow .getStates ().forEach (s -> {
@@ -150,12 +170,37 @@ public List<ValidationError> validate() {
150
170
validation .addEndState ();
151
171
}
152
172
153
- if (s instanceof OperationState ) {
154
- OperationState operationState = ( OperationState ) s ;
155
- if ( operationState . getActions () == null || operationState . getActions ().size () < 1 ) {
156
- addValidationError ("Operation State has no actions defined" ,
173
+ if (workflow . getRetries () != null ) {
174
+ List < RetryDefinition > retryDefs = workflow . getRetries (). getRetryDefs () ;
175
+ if ( s . getOnErrors () == null || s . getOnErrors ().isEmpty ()) {
176
+ addValidationError ("No onErrors found for state" + s . getName () + " but retries is defined" ,
157
177
ValidationError .WORKFLOW_VALIDATION );
178
+ }else {
179
+ for (Error e :s .getOnErrors ()){
180
+ if (e .getRetryRef () == null || e .getRetryRef ().isEmpty ()){
181
+ addValidationError ("No retryRef found for onErrors" + e .getError (),
182
+ ValidationError .WORKFLOW_VALIDATION );
183
+ }
184
+ else {
185
+ boolean validRetryDefinition = false ;
186
+ for (RetryDefinition rd :retryDefs ){
187
+ if (rd .getName ().equals (e .getRetryRef ())){
188
+ validRetryDefinition = true ;
189
+ break ;
190
+ }
191
+ }
192
+ if (!validRetryDefinition ) {
193
+ addValidationError (e .getRetryRef () +" is not a valid retryRef" ,
194
+ ValidationError .WORKFLOW_VALIDATION );
195
+ }
196
+ }
197
+ }
158
198
}
199
+ }
200
+
201
+
202
+ if (s instanceof OperationState ) {
203
+ OperationState operationState = (OperationState ) s ;
159
204
160
205
List <Action > actions = operationState .getActions ();
161
206
for (Action action : actions ) {
@@ -203,10 +248,6 @@ public List<ValidationError> validate() {
203
248
}
204
249
List <OnEvents > eventsActionsList = eventState .getOnEvents ();
205
250
for (OnEvents onEvents : eventsActionsList ) {
206
- if (onEvents .getActions () == null || onEvents .getActions ().size () < 1 ) {
207
- addValidationError ("Event State eventsActions has no actions" ,
208
- ValidationError .WORKFLOW_VALIDATION );
209
- }
210
251
211
252
List <String > eventRefs = onEvents .getEventRefs ();
212
253
if (eventRefs == null || eventRefs .size () < 1 ) {
@@ -243,6 +284,18 @@ public List<ValidationError> validate() {
243
284
addValidationError ("Switch state event condition eventRef does not reference a defined workflow event" ,
244
285
ValidationError .WORKFLOW_VALIDATION );
245
286
}
287
+ if (ec .getEnd ()!=null ){
288
+ validation .addEndState ();
289
+ }
290
+ }
291
+ }
292
+
293
+ if (switchState .getDataConditions () != null && switchState .getDataConditions ().size () > 0 ) {
294
+ List <DataCondition > dataConditions = switchState .getDataConditions ();
295
+ for (DataCondition dc : dataConditions ) {
296
+ if (dc .getEnd ()!=null ){
297
+ validation .addEndState ();
298
+ }
246
299
}
247
300
}
248
301
}
@@ -257,16 +310,17 @@ public List<ValidationError> validate() {
257
310
258
311
if (s instanceof ParallelState ) {
259
312
ParallelState parallelState = (ParallelState ) s ;
260
- if (parallelState .getBranches () == null || parallelState .getBranches ().size () < 1 ) {
261
- addValidationError ("Parallel state should have branches" ,
313
+
314
+ if (parallelState .getBranches () == null || parallelState .getBranches ().size () < 2 ) {
315
+ addValidationError ("Parallel state should have at lest two branches" ,
262
316
ValidationError .WORKFLOW_VALIDATION );
263
317
}
264
318
319
+
265
320
List <Branch > branches = parallelState .getBranches ();
266
321
for (Branch branch : branches ) {
267
- if ((branch .getActions () == null || branch .getActions ().size () < 1 )
268
- && (branch .getWorkflowId () == null || branch .getWorkflowId ().length () < 1 )) {
269
- addValidationError ("Parallel state should define either actions or workflow id" ,
322
+ if (branch .getWorkflowId () == null || branch .getWorkflowId ().length () < 1 ) {
323
+ addValidationError ("Parallel state should define workflow id" ,
270
324
ValidationError .WORKFLOW_VALIDATION );
271
325
}
272
326
}
@@ -282,7 +336,7 @@ public List<ValidationError> validate() {
282
336
283
337
if (s instanceof InjectState ) {
284
338
InjectState injectState = (InjectState ) s ;
285
- if (injectState .getData () == null ) {
339
+ if (injectState .getData () == null || injectState . getData (). isEmpty () ) {
286
340
addValidationError ("InjectState should have non-null data" ,
287
341
ValidationError .WORKFLOW_VALIDATION );
288
342
}
@@ -300,9 +354,8 @@ public List<ValidationError> validate() {
300
354
ValidationError .WORKFLOW_VALIDATION );
301
355
}
302
356
303
- if ((forEachState .getActions () == null || forEachState .getActions ().size () < 1 )
304
- && (forEachState .getWorkflowId () == null || forEachState .getWorkflowId ().length () < 1 )) {
305
- addValidationError ("ForEach state should define either actions or workflow id" ,
357
+ if (forEachState .getWorkflowId () == null || forEachState .getWorkflowId ().length () < 1 ) {
358
+ addValidationError ("ForEach state should define a workflow id" ,
306
359
ValidationError .WORKFLOW_VALIDATION );
307
360
}
308
361
}
0 commit comments