Skip to content

Commit 78b948c

Browse files
authored
Merge pull request #932 from ymohdriz/branch_issue_911_v1
Fix for issue 911 in swagger parser v1
2 parents ccdb9eb + 7f6ed2b commit 78b948c

File tree

4 files changed

+118
-3
lines changed

4 files changed

+118
-3
lines changed

modules/swagger-parser/src/main/java/io/swagger/parser/util/SwaggerDeserializer.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,63 @@ public Map<String,Path> paths(ObjectNode obj, String location, ParseResult resul
188188
} else {
189189
ObjectNode path = (ObjectNode) pathValue;
190190
Path pathObj = path(path, location + ".'" + pathName + "'", result);
191+
String[] eachPart = pathName.split("/");
192+
for (String part : eachPart) {
193+
if (part.startsWith("{") && part.endsWith("}") && part.length() > 2) {
194+
String pathParam = part.substring(1, part.length() - 1);
195+
boolean definedInPathLevel = isPathParamDefined(pathParam, pathObj.getParameters());
196+
if (definedInPathLevel) {
197+
continue;
198+
}
199+
List<Operation> operationsInAPath = getAllOperationsInAPath(pathObj);
200+
for (Operation operation : operationsInAPath) {
201+
if (!isPathParamDefined(pathParam, operation.getParameters())) {
202+
result.warning(location + ".'" + pathName + "'"," Declared path parameter " + pathParam + " needs to be defined as a path parameter in path or operation level");
203+
break;
204+
}
205+
}
206+
}
207+
}
191208
output.put(pathName, pathObj);
192209
}
193210
}
194211
}
195212
return output;
196213
}
197214

215+
private boolean isPathParamDefined(String pathParam, List<Parameter> parameters) {
216+
if (parameters == null || parameters.isEmpty()) {
217+
return false;
218+
} else {
219+
for (Parameter parameter : parameters) {
220+
if (pathParam.equals(parameter.getName()) && "path".equals(parameter.getIn())) {
221+
return true;
222+
}
223+
}
224+
}
225+
return false;
226+
}
227+
228+
private void addToOperationsList(List<Operation> operationsList, Operation operation) {
229+
if (operation == null) {
230+
return;
231+
}
232+
operationsList.add(operation);
233+
}
234+
235+
private List<Operation> getAllOperationsInAPath(Path pathObj) {
236+
List<Operation> operations = new ArrayList<>();
237+
addToOperationsList(operations, pathObj.getGet());
238+
addToOperationsList(operations, pathObj.getPut());
239+
addToOperationsList(operations, pathObj.getPost());
240+
addToOperationsList(operations, pathObj.getPatch());
241+
addToOperationsList(operations, pathObj.getDelete());
242+
addToOperationsList(operations, pathObj.getOptions());
243+
addToOperationsList(operations, pathObj.getHead());
244+
return operations;
245+
}
246+
198247
public Path path(ObjectNode obj, String location, ParseResult result) {
199-
boolean hasRef = false;
200-
Path output = null;
201248
if(obj.get("$ref") != null) {
202249
JsonNode ref = obj.get("$ref");
203250
if(ref.getNodeType().equals(JsonNodeType.STRING)) {
@@ -1606,6 +1653,7 @@ protected static class ParseResult {
16061653
private Map<Location, JsonNode> extra = new LinkedHashMap<Location, JsonNode>();
16071654
private Map<Location, JsonNode> unsupported = new LinkedHashMap<Location, JsonNode>();
16081655
private Map<Location, String> invalidType = new LinkedHashMap<Location, String>();
1656+
private List<Location> warnings = new ArrayList<>();
16091657
private List<Location> missing = new ArrayList<Location>();
16101658
private List<Location> unique = new ArrayList<>();
16111659

@@ -1628,6 +1676,10 @@ public void missing(String location, String key) {
16281676
missing.add(new Location(location, key));
16291677
}
16301678

1679+
public void warning(String location, String key) {
1680+
warnings.add(new Location(location, key));
1681+
}
1682+
16311683
public void invalidType(String location, String key, String expectedType, JsonNode value){
16321684
invalidType.put(new Location(location, key), expectedType);
16331685
}
@@ -1693,6 +1745,11 @@ public List<String> getMessages() {
16931745
String message = "attribute " + location + l.key + " is missing";
16941746
messages.add(message);
16951747
}
1748+
for (Location l : warnings) {
1749+
String location = l.location.equals("") ? "" : l.location + ".";
1750+
String message = "attribute " + location +l.key;
1751+
messages.add(message);
1752+
}
16961753
for (Location l : unique) {
16971754
String location = l.location.equals("") ? "" : l.location + ".";
16981755
String message = "attribute " + location + l.key + " is repeated";

modules/swagger-parser/src/test/java/io/swagger/parser/util/SwaggerDeserializerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,14 @@ public void testUntypedAdditionalProperties() {
15571557
assertEquals(additionalProperties.getType(), null);
15581558
}
15591559

1560+
@Test
1561+
public void testIssue911() {
1562+
SwaggerDeserializationResult result = new SwaggerParser().readWithInfo("issue_911.yaml", null, true);
1563+
System.out.println(result.getMessages());
1564+
assertEquals(result.getMessages().size(),1);
1565+
assertNotNull(result.getSwagger());
1566+
}
1567+
15601568
@Test
15611569
public void testArrayParameterDefaultValue() {
15621570
String swaggerSpec = "swagger: '2.0'\n" +
@@ -1647,5 +1655,4 @@ public void testArrayParameterDefaultValue() {
16471655
assertNotNull(parameter4.getDefault());
16481656
assertNotNull(parameter4.getDefaultValue());
16491657
}
1650-
16511658
}

modules/swagger-parser/src/test/resources/duplicateOperationId.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
},
77
"paths": {
88
"/pets/{id}": {
9+
"parameters" : [
10+
{
11+
"in": "path",
12+
"name": "id",
13+
"type": "string"
14+
}
15+
],
916
"get": {
1017
"operationId": "getPetsById",
1118
"responses": {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
swagger: 2.0
2+
info:
3+
description: >-
4+
This is a sample server Petstore server. You can find out more about
5+
Swagger at http://swagger.io or on
6+
irc.freenode.net, #swagger. For this sample, you can use the api key
7+
"special-key" to test the authorization filters
8+
version: 1.0.0
9+
title: Swagger Petstore
10+
termsOfService: 'http://swagger.io/terms/'
11+
contact:
12+
13+
license:
14+
name: Apache 2.0
15+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
16+
externalDocs:
17+
description: Find more info here
18+
url: 'https://swagger.io'
19+
tags:
20+
- name: pet
21+
description: Pet Operations
22+
externalDocs:
23+
url: 'http://swagger.io'
24+
- name: user
25+
description: All about the Users
26+
paths:
27+
'/pet/{petId}/{pathParamNotDefined}':
28+
get:
29+
tags:
30+
- pet
31+
summary: Find pet by ID
32+
description: >-
33+
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API
34+
error conditions
35+
operationId: getPetById
36+
responses:
37+
200:
38+
description: 200 ok
39+
parameters:
40+
- name: petId
41+
in: path
42+
description: ID of pet that needs to be fetched
43+
required: true
44+
type: integer

0 commit comments

Comments
 (0)