Skip to content

Commit 4fe4669

Browse files
authored
Merge branch 'master' into issue1658
2 parents 2ec8ebb + 6a82e92 commit 4fe4669

File tree

6 files changed

+366
-29
lines changed

6 files changed

+366
-29
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ components:
653653
```
654654

655655
### Extensions
656-
This project has a core artifact--`swagger-parser`, which uses Java Service Provider Inteface (SPI) so additional extensions can be added.
656+
This project has a core artifact--`swagger-parser`, which uses Java Service Provider Interface (SPI) so additional extensions can be added.
657657

658658
To build your own extension, you simply need to create a `src/main/resources/META-INF/services/io.swagger.v3.parser.core.extensions.SwaggerParserExtension` file with the full classname of your implementation. Your class must also implement the `io.swagger.v3.parser.core.extensions.SwaggerParserExtension` interface. Then, including your library with the `swagger-parser` module will cause it to be triggered automatically.
659659

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,8 +1684,26 @@ public Parameter getParameter(ObjectNode obj, String location, ParseResult resul
16841684

16851685
ObjectNode contentNode = getObject("content", obj, false, location, result);
16861686
if (contentNode != null) {
1687-
parameter.setContent(getContent(contentNode, String.format("%s.%s", location, "content"), result));
1688-
}
1687+
Content content = getContent(contentNode, String.format("%s.%s", location, "content"), result);
1688+
if(content.size() == 0) {
1689+
result.unsupported(location,"content with no media type",contentNode);
1690+
result.invalid();
1691+
}
1692+
else if(content.size() > 1) {
1693+
result.unsupported(location,"content with multiple media types",contentNode);
1694+
result.invalid();
1695+
}
1696+
else if(parameter.getSchema() != null) {
1697+
result.unsupported(location,"content when schema defined",contentNode);
1698+
result.invalid();
1699+
}
1700+
else {
1701+
parameter.setContent(content);
1702+
}
1703+
}
1704+
else if(parameter.getSchema() == null) {
1705+
result.missing(location,"content");
1706+
}
16891707

16901708
Map<String, Object> extensions = getExtensions(obj);
16911709
if (extensions != null && extensions.size() > 0) {
@@ -3105,9 +3123,14 @@ public RequestBody getRequestBody(ObjectNode node, String location, ParseResult
31053123
}
31063124

31073125
final ObjectNode contentNode = getObject("content", node, true, location, result);
3108-
if (contentNode != null) {
3109-
body.setContent(getContent(contentNode, location + ".content", result));
3110-
}
3126+
Content content = getContent(contentNode, location + ".content", result);
3127+
if(content != null && content.isEmpty()) {
3128+
result.unsupported(location,"content with no media type",contentNode);
3129+
result.invalid();
3130+
}
3131+
else {
3132+
body.setContent(content);
3133+
}
31113134

31123135
Map<String, Object> extensions = getExtensions(node);
31133136
if (extensions != null && extensions.size() > 0) {

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java

Lines changed: 235 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,63 @@ public void testDeserializeByteString() {
12201220
"attribute components.schemas.ByteString.default=`W.T.F?` is not of type `byte`"));
12211221
}
12221222

1223+
@Test
1224+
public void testBodyContent() {
1225+
String json =
1226+
"{"
1227+
+ " \"openapi\": \"3.0.0\","
1228+
+ " \"info\": {"
1229+
+ " \"title\": \"Operations\","
1230+
+ " \"version\": \"0.0.0\""
1231+
+ " },"
1232+
+ " \"paths\": {"
1233+
+ " \"/operations\": {"
1234+
+ " \"post\": {"
1235+
+ " \"requestBody\": {"
1236+
+ " \"description\": \"Content empty\","
1237+
+ " \"content\": {"
1238+
+ " }"
1239+
+ " },"
1240+
+ " \"responses\": {"
1241+
+ " \"default\": {"
1242+
+ " \"description\": \"None\""
1243+
+ " }"
1244+
+ " }"
1245+
+ " },"
1246+
+ " \"put\": {"
1247+
+ " \"requestBody\": {"
1248+
+ " \"description\": \"Content undefined\""
1249+
+ " },"
1250+
+ " \"responses\": {"
1251+
+ " \"default\": {"
1252+
+ " \"description\": \"None\""
1253+
+ " }"
1254+
+ " }"
1255+
+ " }"
1256+
+ " }"
1257+
+ " }"
1258+
+ "}"
1259+
;
1260+
OpenAPIV3Parser parser = new OpenAPIV3Parser();
1261+
SwaggerParseResult result = parser.readContents(json, null, null);
1262+
1263+
Operation post = result.getOpenAPI().getPaths().get( "/operations").getPost();
1264+
assertEquals( post.getRequestBody().getContent(), null, "Empty content");
1265+
assertEquals
1266+
(result.getMessages().contains("attribute paths.'/operations'(post).requestBody.content with no media type is unsupported"),
1267+
true,
1268+
"Empty content error reported");
1269+
1270+
Operation put = result.getOpenAPI().getPaths().get( "/operations").getPut();
1271+
assertEquals( put.getRequestBody().getContent(), null, "Empty content");
1272+
assertEquals
1273+
(result.getMessages().contains("attribute paths.'/operations'(put).requestBody.content is missing"),
1274+
true,
1275+
"Missing content error reported");
1276+
1277+
assertEquals( result.getMessages().size(), 2, "Messages");
1278+
}
1279+
12231280
@Test
12241281
public void testStyleInvalid() {
12251282
String json =
@@ -1270,6 +1327,161 @@ public void testStyleInvalid() {
12701327
assertEquals(result.getMessages().get(0), "attribute paths.'/realize/{param}'(post).parameters.[param].style is not of type `StyleEnum`");
12711328
}
12721329

1330+
@Test
1331+
public void testParamContent() {
1332+
String json =
1333+
"{"
1334+
+ " \"openapi\": \"3.0.0\","
1335+
+ " \"info\": {"
1336+
+ " \"title\": \"Operations\","
1337+
+ " \"version\": \"0.0.0\""
1338+
+ " },"
1339+
+ " \"paths\": {"
1340+
+ " \"/operations\": {"
1341+
+ " \"post\": {"
1342+
+ " \"parameters\": ["
1343+
+ " {"
1344+
+ " \"name\": \"param0\","
1345+
+ " \"in\": \"query\","
1346+
+ " \"content\": {"
1347+
+ " }"
1348+
+ " },"
1349+
+ " {"
1350+
+ " \"name\": \"param1\","
1351+
+ " \"in\": \"query\","
1352+
+ " \"content\": {"
1353+
+ " \"text/plain\": {"
1354+
+ " }"
1355+
+ " }"
1356+
+ " },"
1357+
+ " {"
1358+
+ " \"name\": \"param2\","
1359+
+ " \"in\": \"query\","
1360+
+ " \"content\": {"
1361+
+ " \"text/plain\": {"
1362+
+ " },"
1363+
+ " \"application/json\": {"
1364+
+ " \"schema\": {"
1365+
+ " \"type\": \"object\""
1366+
+ " }"
1367+
+ " }"
1368+
+ " }"
1369+
+ " }"
1370+
+ " ],"
1371+
+ " \"responses\": {"
1372+
+ " \"default\": {"
1373+
+ " \"description\": \"None\""
1374+
+ " }"
1375+
+ " }"
1376+
+ " }"
1377+
+ " }"
1378+
+ " }"
1379+
+ "}"
1380+
;
1381+
OpenAPIV3Parser parser = new OpenAPIV3Parser();
1382+
SwaggerParseResult result = parser.readContents(json, null, null);
1383+
Operation post = result.getOpenAPI().getPaths().get( "/operations").getPost();
1384+
1385+
Parameter param0 =
1386+
post.getParameters().stream()
1387+
.filter( p -> "param0".equals( p.getName()))
1388+
.findFirst()
1389+
.orElseThrow( () -> new IllegalStateException( "Can't find parameter=param0"));
1390+
assertEquals
1391+
(result.getMessages().contains( "attribute paths.'/operations'(post).parameters.[param0].content with no media type is unsupported"),
1392+
true,
1393+
"No media types error reported");
1394+
assertEquals( param0.getContent(), null, "Empty content");
1395+
1396+
Parameter param1 =
1397+
post.getParameters().stream()
1398+
.filter( p -> "param1".equals( p.getName()))
1399+
.findFirst()
1400+
.orElseThrow( () -> new IllegalStateException( "Can't find parameter=param1"));
1401+
assertEquals( param1.getContent().size(), 1, "Valid content size");
1402+
1403+
Parameter param2 =
1404+
post.getParameters().stream()
1405+
.filter( p -> "param2".equals( p.getName()))
1406+
.findFirst()
1407+
.orElseThrow( () -> new IllegalStateException( "Can't find parameter=param2"));
1408+
assertEquals
1409+
(result.getMessages().contains( "attribute paths.'/operations'(post).parameters.[param2].content with multiple media types is unsupported"),
1410+
true,
1411+
"Multiple media types error reported");
1412+
assertEquals( param2.getContent(), null, "Content with multiple media types");
1413+
1414+
assertEquals( result.getMessages().size(), 2, "Messages");
1415+
}
1416+
1417+
@Test
1418+
public void testParamData() {
1419+
String json =
1420+
"{"
1421+
+ " \"openapi\": \"3.0.0\","
1422+
+ " \"info\": {"
1423+
+ " \"title\": \"Operations\","
1424+
+ " \"version\": \"0.0.0\""
1425+
+ " },"
1426+
+ " \"paths\": {"
1427+
+ " \"/operations\": {"
1428+
+ " \"post\": {"
1429+
+ " \"parameters\": ["
1430+
+ " {"
1431+
+ " \"name\": \"param0\","
1432+
+ " \"in\": \"query\""
1433+
+ " },"
1434+
+ " {"
1435+
+ " \"name\": \"param2\","
1436+
+ " \"in\": \"query\","
1437+
+ " \"content\": {"
1438+
+ " \"text/plain\": {"
1439+
+ " }"
1440+
+ " },"
1441+
+ " \"schema\": {"
1442+
+ " \"type\": \"object\""
1443+
+ " }"
1444+
+ " }"
1445+
+ " ],"
1446+
+ " \"responses\": {"
1447+
+ " \"default\": {"
1448+
+ " \"description\": \"None\""
1449+
+ " }"
1450+
+ " }"
1451+
+ " }"
1452+
+ " }"
1453+
+ " }"
1454+
+ "}"
1455+
;
1456+
OpenAPIV3Parser parser = new OpenAPIV3Parser();
1457+
SwaggerParseResult result = parser.readContents(json, null, null);
1458+
Operation post = result.getOpenAPI().getPaths().get( "/operations").getPost();
1459+
1460+
Parameter param0 =
1461+
post.getParameters().stream()
1462+
.filter( p -> "param0".equals( p.getName()))
1463+
.findFirst()
1464+
.orElseThrow( () -> new IllegalStateException( "Can't find parameter=param0"));
1465+
assertEquals
1466+
(result.getMessages().contains( "attribute paths.'/operations'(post).parameters.[param0].content is missing"),
1467+
true,
1468+
"No schema or content error reported");
1469+
assertEquals( param0.getContent(), null, "No schema or content");
1470+
1471+
Parameter param2 =
1472+
post.getParameters().stream()
1473+
.filter( p -> "param2".equals( p.getName()))
1474+
.findFirst()
1475+
.orElseThrow( () -> new IllegalStateException( "Can't find parameter=param2"));
1476+
assertEquals
1477+
(result.getMessages().contains( "attribute paths.'/operations'(post).parameters.[param2].content when schema defined is unsupported"),
1478+
true,
1479+
"Both schema and content error reported");
1480+
assertEquals( param2.getContent(), null, "Content when schema defined");
1481+
1482+
assertEquals( result.getMessages().size(), 2, "Messages");
1483+
}
1484+
12731485
@Test
12741486
public void testDeserializeWithMessages() {
12751487
String yaml = "openapi: '3.0.0'\n" +
@@ -2602,29 +2814,32 @@ public void readContentObject(JsonNode rootNode) throws Exception {
26022814
final Paths paths = openAPI.getPaths();
26032815
Assert.assertNotNull(paths);
26042816

2605-
PathItem petByStatusEndpoint = paths.get("/pet/findByStatus");
2817+
PathItem petByStatusEndpoint = paths.get("/pet/findByStatusContent");
26062818
Assert.assertNotNull(petByStatusEndpoint.getGet());
26072819
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters());
2608-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().size(), 1);
2820+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().size(), 3);
2821+
26092822
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters().get(0).getContent());
2610-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().size(),3);
2823+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().size(),1);
26112824
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/json").getSchema().getType(),"array");
26122825
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/json").getExample(),null);
26132826
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/json").getExamples().get("list").getSummary(),"List of Names");
26142827
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/json").getSchema().getType(),"array");
26152828

2616-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/xml").getExamples().get("list").getSummary(),"List of names");
2617-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/xml").getExamples().get("list").getValue(),"<Users><User name='Bob'/><User name='Diane'/><User name='Mary'/><User name='Bill'/></Users>");
2618-
2619-
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/xml").getExamples().get("empty").getSummary());
2620-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/xml").getExamples().get("empty").getSummary(),"Empty list");
2621-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("application/xml").getExamples().get("empty").getValue(),"<Users/>");
2622-
2623-
2624-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("text/plain").getExamples().get("list").getSummary(),"List of names");
2625-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("text/plain").getExamples().get("list").getValue(),"Bob,Diane,Mary,Bill");
2626-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("text/plain").getExamples().get("empty").getSummary(),"Empty");
2627-
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(0).getContent().get("text/plain").getExamples().get("empty").getValue(),"");
2829+
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters().get(1).getContent());
2830+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(1).getContent().size(),1);
2831+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(1).getContent().get("application/xml").getExamples().get("list").getSummary(),"List of names");
2832+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(1).getContent().get("application/xml").getExamples().get("list").getValue(),"<Users><User name='Bob'/><User name='Diane'/><User name='Mary'/><User name='Bill'/></Users>");
2833+
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters().get(1).getContent().get("application/xml").getExamples().get("empty").getSummary());
2834+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(1).getContent().get("application/xml").getExamples().get("empty").getSummary(),"Empty list");
2835+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(1).getContent().get("application/xml").getExamples().get("empty").getValue(),"<Users/>");
2836+
2837+
Assert.assertNotNull(petByStatusEndpoint.getGet().getParameters().get(2).getContent());
2838+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(2).getContent().size(),1);
2839+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(2).getContent().get("text/plain").getExamples().get("list").getSummary(),"List of names");
2840+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(2).getContent().get("text/plain").getExamples().get("list").getValue(),"Bob,Diane,Mary,Bill");
2841+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(2).getContent().get("text/plain").getExamples().get("empty").getSummary(),"Empty");
2842+
Assert.assertEquals(petByStatusEndpoint.getGet().getParameters().get(2).getContent().get("text/plain").getExamples().get("empty").getValue(),"");
26282843

26292844
PathItem petEndpoint = paths.get("/pet");
26302845
Assert.assertNotNull(petEndpoint.getPut());
@@ -2825,7 +3040,7 @@ public void readExamplesObject(JsonNode rootNode) throws Exception {
28253040

28263041
final Paths paths = openAPI.getPaths();
28273042
Assert.assertNotNull(paths);
2828-
Assert.assertEquals(paths.size(), 18);
3043+
Assert.assertEquals(paths.size(), 19);
28293044

28303045
//parameters operation get
28313046
PathItem petByStatusEndpoint = paths.get("/pet/findByStatus");
@@ -2849,7 +3064,7 @@ public void readSchemaObject(JsonNode rootNode) throws Exception {
28493064

28503065
final Paths paths = openAPI.getPaths();
28513066
Assert.assertNotNull(paths);
2852-
Assert.assertEquals(paths.size(), 18);
3067+
Assert.assertEquals(paths.size(), 19);
28533068

28543069
//parameters operation get
28553070
PathItem petByStatusEndpoint = paths.get("/pet/findByStatus");
@@ -2875,7 +3090,7 @@ public void readSchemaArray(JsonNode rootNode) throws Exception {
28753090

28763091
final Paths paths = openAPI.getPaths();
28773092
Assert.assertNotNull(paths);
2878-
Assert.assertEquals(paths.size(), 18);
3093+
Assert.assertEquals(paths.size(), 19);
28793094

28803095
//parameters operation get
28813096
PathItem petByStatusEndpoint = paths.get("/pet/findByTags");
@@ -2902,7 +3117,7 @@ public void readProducesTestEndpoint(JsonNode rootNode) throws Exception {
29023117

29033118
final Paths paths = openAPI.getPaths();
29043119
Assert.assertNotNull(paths);
2905-
Assert.assertEquals(paths.size(), 18);
3120+
Assert.assertEquals(paths.size(), 19);
29063121

29073122
//parameters operation get
29083123
PathItem producesTestEndpoint = paths.get("/producesTest");
@@ -2969,7 +3184,7 @@ public void readPathsObject(JsonNode rootNode) throws Exception {
29693184

29703185
final Paths paths = openAPI.getPaths();
29713186
Assert.assertNotNull(paths);
2972-
Assert.assertEquals(paths.size(), 18);
3187+
Assert.assertEquals(paths.size(), 19);
29733188

29743189

29753190
PathItem petRef = paths.get("/pathItemRef");

0 commit comments

Comments
 (0)