Skip to content

Commit b0638b5

Browse files
authored
Merge pull request #39 from API-Flows/validate-reusable-parameter
Validate reusable parameter
2 parents cd8b7fa + 39241bd commit b0638b5

File tree

5 files changed

+98
-93
lines changed

5 files changed

+98
-93
lines changed

src/main/java/com/apiflows/model/Parameter.java

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ public class Parameter {
77
private String name;
88
private String in;
99
private String value;
10-
private String target;
1110
private String style;
12-
private String $ref = null;
1311

1412
@JsonProperty("name")
1513
public String getName() {
@@ -38,15 +36,6 @@ public void setValue(String value) {
3836
this.value = value;
3937
}
4038

41-
@JsonProperty("target")
42-
public String getTarget() {
43-
return target;
44-
}
45-
46-
public void setTarget(String target) {
47-
this.target = target;
48-
}
49-
5039
public String getStyle() {
5140
return style;
5241
}
@@ -55,14 +44,6 @@ public void setStyle(String style) {
5544
this.style = style;
5645
}
5746

58-
public String get$ref() {
59-
return $ref;
60-
}
61-
62-
public void set$ref(String $ref) {
63-
this.$ref = $ref;
64-
}
65-
6647
public Parameter name(String name) {
6748
this.name = name;
6849
return this;
@@ -78,19 +59,9 @@ public Parameter value(String value) {
7859
return this;
7960
}
8061

81-
public Parameter target(String target) {
82-
this.target = target;
83-
return this;
84-
}
85-
8662
public Parameter style(String style) {
8763
this.style = style;
8864
return this;
8965
}
9066

91-
public Parameter $ref(String $ref) {
92-
this.$ref = $ref;
93-
return this;
94-
}
95-
9667
}

src/main/java/com/apiflows/parser/OpenAPIWorkflowValidator.java

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,14 @@ List<String> validateStep(Step step, String workflowId ) {
171171

172172
if(step.getParameters() != null) {
173173
for(Parameter parameter : step.getParameters()) {
174-
errors.addAll(validateParameter(parameter, workflowId, null));
175-
176-
if(step.getWorkflowId() != null) {
177-
// when the step in context specifies a workflowId the parameter IN must be defined
178-
if(parameter.getIn() == null) {
174+
if(isRuntimeExpression(parameter.getName())) {
175+
errors.addAll(validateReusableParameter(parameter, workflowId, null));
176+
} else {
177+
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) {
179182
errors.add("'Workflow[" + workflowId + "]' parameter IN must be defined");
180183
}
181184
}
@@ -208,12 +211,12 @@ List<String> validateStep(Step step, String workflowId ) {
208211
return errors;
209212
}
210213

211-
List<String> validateParameter(Parameter parameter, String workflowId, String componentName ) {
214+
List<String> validateParameter(Parameter parameter, String workflowId, String componentName) {
212215
List<String> SUPPORTED_VALUES = Arrays.asList("path", "query", "header", "cookie", "body", "workflow");
213216

214217
String source;
215218

216-
if(workflowId != null) {
219+
if (workflowId != null) {
217220
source = "Workflow[" + workflowId + "]";
218221
} else {
219222
source = "Component[" + componentName + "]";
@@ -222,37 +225,57 @@ List<String> validateParameter(Parameter parameter, String workflowId, String co
222225

223226
List<String> errors = new ArrayList<>();
224227

225-
if(parameter.get$ref() != null) {
226-
// Reference object
227-
// check is URI
228-
} else {
229-
// Parameter object
230-
String name = parameter.getName();
228+
// Parameter object
229+
String name = parameter.getName();
231230

232-
if(name == null) {
233-
errors.add(source + " parameter has no name");
234-
}
235-
if(parameter.getIn() != null) {
236-
if(!SUPPORTED_VALUES.contains(parameter.getIn())) {
237-
if(name != null) {
238-
errors.add(source + "parameter " + name + " type (" + parameter.getIn() + ") is invalid");
239-
} else {
240-
errors.add(source + " parameter type (" + parameter.getIn() + ") is invalid");
241-
}
242-
}
243-
}
244-
if(parameter.getValue() == null) {
245-
if(name != null) {
246-
errors.add(source + " parameter " + name + " has no value");
231+
if (name == null) {
232+
errors.add(source + " parameter has no name");
233+
}
234+
if (parameter.getIn() != null) {
235+
if (!SUPPORTED_VALUES.contains(parameter.getIn())) {
236+
if (name != null) {
237+
errors.add(source + "parameter " + name + " in (" + parameter.getIn() + ") is invalid");
247238
} else {
248-
errors.add(source + " parameter has no value");
239+
errors.add(source + " parameter in (" + parameter.getIn() + ") is invalid");
249240
}
250241
}
251-
if(parameter.getTarget() != null) {
252-
if(!isValidJsonPointer(parameter.getTarget())) {
253-
errors.add(source + " parameter " + name + " target is not a valid Json Pointer");
254-
}
242+
}
243+
if (parameter.getValue() == null) {
244+
if (name != null) {
245+
errors.add(source + " parameter " + name + " has no value");
246+
} else {
247+
errors.add(source + " parameter has no value");
248+
}
249+
}
250+
if(isRuntimeExpression(parameter.getName())) {
251+
errors.add(source + " parameter " + name + " is a Reusable Parameter object");
252+
}
253+
254+
return errors;
255+
}
256+
257+
List<String> validateReusableParameter(Parameter parameter, String workflowId, String componentName ) {
258+
259+
String source;
260+
261+
if(workflowId != null) {
262+
source = "Workflow[" + workflowId + "]";
263+
} else {
264+
source = "Component[" + componentName + "]";
265+
}
266+
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");
255275
}
276+
277+
// TODO: check reusable parameter exists in Components
278+
256279
}
257280
return errors;
258281
}
@@ -561,4 +584,8 @@ public boolean isValidJsonPointer(String jsonPointerString) {
561584
return ret;
562585
}
563586

587+
boolean isRuntimeExpression(String name) {
588+
return name.startsWith("$");
589+
}
590+
564591
}

src/main/java/com/apiflows/parser/source/OperationBinder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ List<Operation> getOperations(String openapi) {
5858

5959
ParseOptions options = new ParseOptions();
6060
options.setResolve(true);
61-
6261
SwaggerParseResult parseResult = null;
6362

6463
try {

src/test/java/com/apiflows/parser/OpenAPIWorkflowValidatorTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void validateStepWithoutInAttribute() {
188188
Step step = new Step()
189189
.stepId("step-one")
190190
.description("First step in the workflow")
191-
.workflowId("workflow-id-2");
191+
.operationId("op-id-2");
192192
step.addParameter(new Parameter()
193193
.name("param")
194194
.value("value"));
@@ -198,6 +198,27 @@ void validateStepWithoutInAttribute() {
198198
assertEquals(1, validator.validateStep(step, worklowId).size());
199199
}
200200

201+
@Test
202+
void validateReusableParameter() {
203+
Parameter parameter = new Parameter()
204+
.name("$components.parameters.page")
205+
.value("1");
206+
String worklowId = "q1";
207+
208+
assertEquals(0, validator.validateReusableParameter(parameter, worklowId, null).size());
209+
}
210+
211+
@Test
212+
void validateReusableParameterWithInAttribute() {
213+
Parameter parameter = new Parameter()
214+
.name("$components.parameters.page")
215+
.value("1")
216+
.in("query");
217+
String worklowId = "q1";
218+
219+
// error: must not define IN attribute
220+
assertEquals(1, validator.validateReusableParameter(parameter, worklowId, null).size());
221+
}
201222

202223
@Test
203224
void validateParameter() {

src/test/resources/1.0.0/pet-coupons.workflow.yaml

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@ workflows:
4747
workflowId: place-order
4848
parameters:
4949
- name: pet_id
50-
in: body
5150
value: $steps.find-pet.outputs.my_pet_id
5251
- name: coupon_code
53-
in: body
5452
value: $steps.find-coupons.outputs.my_coupon_code
5553
successCriteria:
5654
- condition: $statusCode == 200
@@ -72,9 +70,9 @@ workflows:
7270
- name: status
7371
in: query
7472
value: "available"
75-
- $ref: '#/components/parameters/page'
73+
- name: $components.parameters.page
7674
value: 1
77-
- $ref: '#/components/parameters/pageSize'
75+
- name: $components.parameters.pageSize
7876
value: 10
7977
successCriteria:
8078
- condition: $statusCode == 200
@@ -84,7 +82,6 @@ workflows:
8482
workflowId: place-order
8583
parameters:
8684
- name: pet_id
87-
in: body
8885
value: $steps.find-pet.outputs.my_pet_id
8986
successCriteria:
9087
- condition: $statusCode == 200
@@ -113,26 +110,14 @@ workflows:
113110
steps:
114111
- stepId: place-order
115112
operationId: placeOrder
116-
parameters:
117-
- name: pet_id
118-
in: body
119-
target: /petId
120-
value: $inputs.pet_id
121-
- name: coupon_code
122-
in: body
123-
target: /couponCode
124-
value: $inputs.coupon_code
125-
- name: quantity
126-
in: body
127-
value: $inputs.quantity
128-
- name: status
129-
in: body
130-
target: /status
131-
value: "placed"
132-
- name: complete
133-
in: body
134-
target: /complete
135-
value: false
113+
requestBody:
114+
contentType: application/json
115+
payload:
116+
petId: $inputs.pet_id
117+
quantity: $inputs.quantity
118+
couponCode: $inputs.coupon_code
119+
status: placed
120+
complete: false
136121
successCriteria:
137122
- condition: $statusCode == 200
138123
outputs:
@@ -161,8 +146,10 @@ components:
161146
description: Indicates the domain name of the store where the customer is browsing or buying pets, e.g. "pets.example.com" or "pets.example.co.uk".
162147
parameters:
163148
page:
164-
type: integer
165-
format: int32
149+
name: page
150+
in: query
151+
value: 1
166152
pageSize:
167-
type: integer
168-
format: int32
153+
name: pageSize
154+
in: query
155+
value: 100

0 commit comments

Comments
 (0)