@@ -13,7 +13,8 @@ public class OpenAPIWorkflowValidator {
1313 Set <String > workflowIds = new HashSet <>();
1414 Map <String , Set <String >> stepIds = new HashMap <>();
1515 Set <String > operationIds = new HashSet <>();
16- Set <Schema > components = new HashSet <>();
16+ Set <String > componentIds = new HashSet <>();
17+ Components components = null ;
1718
1819 OpenAPIWorkflowValidator () {
1920 }
@@ -31,11 +32,12 @@ public OpenAPIWorkflowValidatorResult validate() {
3132 loadWorkflowIds (this .openAPIWorkflow );
3233 loadStepIds (this .openAPIWorkflow .getWorkflows ());
3334 loadOperationIds (this .openAPIWorkflow );
35+ loadComponents (this .openAPIWorkflow .getComponents ());
3436
3537 OpenAPIWorkflowValidatorResult result = new OpenAPIWorkflowValidatorResult ();
3638
3739 if (openAPIWorkflow .getArazzo () == null || openAPIWorkflow .getArazzo ().isEmpty ()) {
38- result .addError ("'workflowsSpec ' is undefined" );
40+ result .addError ("'arazzo ' is undefined" );
3941 }
4042
4143 // Info
@@ -85,7 +87,7 @@ List<String> validateInfo(Info info) {
8587 }
8688
8789 List <String > validateSourceDescriptions (List <SourceDescription > sourceDescriptions ) {
88- List <String > SUPPORTED_TYPES = Arrays .asList ("openapi" , "workflowsSpec " );
90+ List <String > SUPPORTED_TYPES = Arrays .asList ("openapi" , "arazzo " );
8991
9092 List <String > errors = new ArrayList <>();
9193
@@ -171,15 +173,18 @@ List<String> validateStep(Step step, String workflowId ) {
171173
172174 if (step .getParameters () != null ) {
173175 for (Parameter parameter : step .getParameters ()) {
174- if (isRuntimeExpression (parameter .getName ())) {
176+ if (isRuntimeExpression (parameter .getReference ())) {
177+ // reference a reusable object
175178 errors .addAll (validateReusableParameter (parameter , workflowId , null ));
176179 } else {
180+ // parameter
177181 errors .addAll (validateParameter (parameter , workflowId , null ));
178- }
179- if (step .getWorkflowId () == null ) {
180- // when the step in context is NOT a workflowId the parameter IN must be defined
181- if (!isRuntimeExpression (parameter .getName ()) && parameter .getIn () == null ) {
182- errors .add ("'Workflow[" + workflowId + "]' parameter IN must be defined" );
182+
183+ if (step .getWorkflowId () == null ) {
184+ // when the step in context is NOT a workflowId the parameter IN must be defined
185+ if (!isRuntimeExpression (parameter .getName ()) && parameter .getIn () == null ) {
186+ errors .add ("'Workflow[" + workflowId + "]' parameter IN must be defined" );
187+ }
183188 }
184189 }
185190 }
@@ -212,7 +217,7 @@ List<String> validateStep(Step step, String workflowId ) {
212217 }
213218
214219 List <String > validateParameter (Parameter parameter , String workflowId , String componentName ) {
215- List <String > SUPPORTED_VALUES = Arrays .asList ("path" , "query" , "header" , "cookie" , "body" , "workflow" );
220+ List <String > SUPPORTED_VALUES = Arrays .asList ("path" , "query" , "header" , "cookie" , "body" );
216221
217222 String source ;
218223
@@ -264,19 +269,18 @@ List<String> validateReusableParameter(Parameter parameter, String workflowId, S
264269 source = "Component[" + componentName + "]" ;
265270 }
266271
267- List <String > errors = new ArrayList <>();
268-
269- if (isRuntimeExpression (parameter .getName ())) {
270- // Reusable Parameter object
271- String name = parameter .getName ();
272-
273- if (parameter .getIn () != null ) {
274- errors .add (source + "parameter " + name + " in (" + parameter .getIn () + ") should not be provided for a Reusable Parameter Object" );
275- }
272+ // reference to reusable object
273+ String reference = parameter .getReference ();
274+ // normalize reference
275+ String key = reference .replace ("$components.parameters." , "" );
276276
277- // TODO: check reusable parameter exists in Components
277+ List < String > errors = new ArrayList <>();
278278
279+ // check reusable parameter exists in Components
280+ if (!this .components .getParameters ().containsKey (key )) {
281+ errors .add (source + " parameter '" + reference + "' not found" );
279282 }
283+
280284 return errors ;
281285 }
282286
@@ -447,14 +451,13 @@ String getOutputsKeyRegularExpression() {
447451 List <String > loadWorkflowIds (OpenAPIWorkflow openAPIWorkflow ) {
448452 List <String > errors = new ArrayList <>();
449453
450- boolean multipleWorkflowsSpec = getNumWorkflowsSpecSourceDescriptions (openAPIWorkflow .getSourceDescriptions ()) > 1 ? true : false ;
451-
454+ boolean multipleSpecs = getNumArazzoTypeSourceDescriptions (openAPIWorkflow .getSourceDescriptions ()) > 1 ? true : false ;
452455
453456 if (openAPIWorkflow .getWorkflows () != null ) {
454457 validateWorkflowIdsUniqueness (openAPIWorkflow .getWorkflows ());
455458
456459 for (Workflow workflow : openAPIWorkflow .getWorkflows ()) {
457- errors .addAll (validateStepsWorkflowIds (workflow .getSteps (), multipleWorkflowsSpec ));
460+ errors .addAll (validateStepsWorkflowIds (workflow .getSteps (), multipleSpecs ));
458461 }
459462
460463 for (Workflow workflow : openAPIWorkflow .getWorkflows ()) {
@@ -508,6 +511,10 @@ List<String> loadOperationIds(OpenAPIWorkflow openAPIWorkflow) {
508511 return errors ;
509512 }
510513
514+ void loadComponents (Components components ) {
515+ this .components = components ;
516+ }
517+
511518 public List <String > validateStepsOperationIds (List <Step > steps , boolean multipleOpenApiFiles ) {
512519 List <String > errors = new ArrayList <>();
513520
@@ -528,9 +535,9 @@ int getNumOpenApiSourceDescriptions(List<SourceDescription> sourceDescriptions)
528535 return (int ) sourceDescriptions .stream ().filter (p -> p .isOpenApi ()).count ();
529536 }
530537
531- // num of SourceDescriptions with type 'workflowsSpec '
532- int getNumWorkflowsSpecSourceDescriptions (List <SourceDescription > sourceDescriptions ) {
533- return (int ) sourceDescriptions .stream ().filter (p -> p .isWorkflowsSpec ()).count ();
538+ // num of SourceDescriptions with type 'arazzo '
539+ int getNumArazzoTypeSourceDescriptions (List <SourceDescription > sourceDescriptions ) {
540+ return (int ) sourceDescriptions .stream ().filter (p -> p .isArazzo ()).count ();
534541 }
535542
536543 boolean stepExists (String workflowId , String stepId ) {
@@ -554,11 +561,11 @@ List<String> validateWorkflowIdsUniqueness(List<Workflow> workflows) {
554561 return errors ;
555562 }
556563
557- List <String > validateStepsWorkflowIds (List <Step > steps , boolean multipleWorkflowsSpecFiles ) {
564+ List <String > validateStepsWorkflowIds (List <Step > steps , boolean multipleArazzoTypeFiles ) {
558565 List <String > errors = new ArrayList <>();
559566
560567 for (Step step : steps ) {
561- if (multipleWorkflowsSpecFiles ) {
568+ if (multipleArazzoTypeFiles ) {
562569 // must use runtime expression to map applicable SourceDescription
563570 if (step .getWorkflowId () != null && !step .getWorkflowId ().startsWith ("$sourceDescriptions." )) {
564571 errors .add ("Operation " + step .getWorkflowId () + " must be specified using a runtime expression (e.g., $sourceDescriptions.<name>.<workflowId>)" );
0 commit comments