Skip to content
This repository was archived by the owner on Nov 24, 2022. It is now read-only.

Commit d674677

Browse files
authored
Merge branch 'master' into use-specialized-schema-subtypes-where-possible
2 parents 598e45c + 832e6a7 commit d674677

17 files changed

Lines changed: 757 additions & 201 deletions

File tree

modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ public class ParseOptions {
55
private boolean resolveCombinators = true;
66
private boolean resolveFully;
77
private boolean flatten;
8+
private boolean skipMatches;
89

910
public boolean isResolve() {
1011
return resolve;
@@ -33,4 +34,12 @@ public void setResolveFully(boolean resolveFully) {
3334
public boolean isFlatten() { return flatten; }
3435

3536
public void setFlatten(boolean flatten) { this.flatten = flatten; }
37+
38+
public boolean isSkipMatches() {
39+
return skipMatches;
40+
}
41+
42+
public void setSkipMatches(boolean skipMatches) {
43+
this.skipMatches = skipMatches;
44+
}
3645
}

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ public SwaggerParseResult readLocation(String url, List<AuthorizationValue> auth
6868
if (options.isResolveFully()) {
6969
result.setOpenAPI(resolver.resolve());
7070
new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
71-
}else if (options.isFlatten()){
72-
InlineModelResolver inlineResolver = new InlineModelResolver();
73-
inlineResolver.flatten(result.getOpenAPI());
71+
} else if (options.isFlatten()) {
72+
InlineModelResolver inlineModelResolver = new InlineModelResolver();
73+
inlineModelResolver.setSkipMatches(options.isSkipMatches());
74+
inlineModelResolver.flatten(result.getOpenAPI());
7475
}
7576
}
7677
}
@@ -194,7 +195,9 @@ public SwaggerParseResult readContents(String swaggerAsString, List<Authorizatio
194195
result.setOpenAPI(new OpenAPIResolver(result.getOpenAPI(), auth, null).resolve());
195196
new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
196197
} else if (options.isFlatten()) {
197-
new InlineModelResolver().flatten(result.getOpenAPI());
198+
InlineModelResolver inlineModelResolver = new InlineModelResolver();
199+
inlineModelResolver.setSkipMatches(options.isSkipMatches());
200+
inlineModelResolver.flatten(result.getOpenAPI());
198201
}
199202
}else{
200203
JsonNode rootNode = mapper.readTree(swaggerAsString.getBytes());

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,13 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) {
173173
}
174174

175175
}
176-
if (schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null && ((ArraySchema) schema).getItems().get$ref() != null
177-
&& StringUtils.isNotBlank(((ArraySchema) schema).getItems().get$ref())) {
178-
processRefSchema(((ArraySchema) schema).getItems(), file);
176+
if (schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null) {
177+
ArraySchema arraySchema = (ArraySchema) schema;
178+
if (StringUtils.isNotBlank(arraySchema.getItems().get$ref())) {
179+
processRefSchema(((ArraySchema) schema).getItems(), file);
180+
} else {
181+
processProperties(arraySchema.getItems().getProperties() ,file);
182+
}
179183
}
180184
}
181185

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ public Paths getPaths(ObjectNode obj, String location, ParseResult result) {
546546
}
547547
ObjectNode path = (ObjectNode) pathValue;
548548
PathItem pathObj = getPathItem(path,String.format("%s.'%s'", location,pathName), result);
549-
String[] eachPart = pathName.split("/");
549+
String[] eachPart = pathName.split("[-/.]+");
550550
Arrays.stream(eachPart)
551551
.filter(part -> part.startsWith("{") && part.endsWith("}") && part.length() > 2)
552552
.forEach(part -> {

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

Lines changed: 105 additions & 193 deletions
Large diffs are not rendered by default.

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import static com.github.tomakehurst.wiremock.client.WireMock.get;
6767
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
6868
import static org.testng.Assert.assertEquals;
69+
import static org.testng.Assert.assertFalse;
6970
import static org.testng.Assert.assertNotNull;
7071
import static org.testng.Assert.assertNull;
7172
import static org.testng.Assert.assertTrue;
@@ -490,6 +491,99 @@ public void testIssue85(@Injectable final List<AuthorizationValue> auths) {
490491
assertTrue(prop instanceof Schema);
491492
}
492493

494+
@Test
495+
public void testIssue1157(@Injectable final List<AuthorizationValue> auths) {
496+
ParseOptions options = new ParseOptions();
497+
options.setResolve(true);
498+
options.setResolveFully(true);
499+
500+
OpenAPI openAPIAnyOf = new OpenAPIV3Parser().readLocation("/issue-1157/anyOf-example.yaml", auths, options).getOpenAPI();
501+
Schema petSchemaAnyOf = openAPIAnyOf.getComponents().getSchemas().get("Pet");
502+
assertTrue(petSchemaAnyOf instanceof ComposedSchema);
503+
assertTrue(((ComposedSchema) petSchemaAnyOf).getAnyOf() != null);
504+
505+
OpenAPI openAPIOneOf = new OpenAPIV3Parser().readLocation("/issue-1157/oneOf-example.yaml", auths, options).getOpenAPI();
506+
Schema petSchemaOneOf = openAPIOneOf.getComponents().getSchemas().get("Pet");
507+
assertTrue(petSchemaOneOf instanceof ComposedSchema);
508+
assertTrue(((ComposedSchema) petSchemaOneOf).getOneOf() != null);
509+
510+
OpenAPI openAPIAllOf = new OpenAPIV3Parser().readLocation("/issue-1157/allOf-example.yaml", auths, options).getOpenAPI();
511+
Schema petSchemaAllOf = openAPIAllOf.getComponents().getSchemas().get("Pet");
512+
assertFalse(petSchemaAllOf instanceof ComposedSchema);
513+
assertTrue(petSchemaAllOf.getProperties() != null);
514+
515+
}
516+
517+
@Test
518+
public void testIssue1161(@Injectable final List<AuthorizationValue> auths) {
519+
String path = "/issue-1161/swagger.yaml";
520+
521+
ParseOptions options = new ParseOptions();
522+
options.setResolve(true);
523+
options.setResolveFully(true);
524+
525+
OpenAPI openAPI = new OpenAPIV3Parser().readLocation(path, auths, options).getOpenAPI();
526+
527+
Schema petsSchema = openAPI.getComponents().getSchemas().get("Pets");
528+
Schema colouringsSchema = openAPI.getComponents().getSchemas().get("Colouring");
529+
530+
assertNotNull(petsSchema);
531+
assertNotNull(colouringsSchema);
532+
533+
assertTrue(petsSchema instanceof ComposedSchema);
534+
assertTrue(petsSchema.getProperties() != null);
535+
assertTrue(((ComposedSchema) petsSchema).getOneOf() != null);
536+
537+
Schema petsColouringProperty = (Schema) petsSchema.getProperties().get("colouring");
538+
assertTrue(petsColouringProperty.get$ref() == null);
539+
assertTrue(petsColouringProperty == colouringsSchema);
540+
}
541+
542+
@Test
543+
public void testIssue1170(@Injectable final List<AuthorizationValue> auths) {
544+
String path = "/issue-1170/swagger.yaml";
545+
546+
ParseOptions options = new ParseOptions();
547+
options.setResolve(true);
548+
options.setResolveFully(true);
549+
550+
OpenAPI openAPI = new OpenAPIV3Parser().readLocation(path, auths, options).getOpenAPI();
551+
552+
// Array schema with items $ref
553+
Schema breedsListSchema = openAPI.getComponents().getSchemas().get("BreedsList");
554+
Schema breedSchema = openAPI.getComponents().getSchemas().get("Breed");
555+
556+
assertNotNull(breedsListSchema);
557+
assertNotNull(breedSchema);
558+
559+
assertTrue(breedsListSchema instanceof ArraySchema);
560+
Schema breedPropertySchema = ((ArraySchema) breedsListSchema).getItems().getProperties().get("breed");
561+
assertNotNull(breedPropertySchema);
562+
563+
// Verify items resolved fully
564+
assertTrue(breedPropertySchema.get$ref() == null);
565+
assertTrue(breedPropertySchema == breedSchema);
566+
567+
568+
// Array schema with inline items object with $ref properties
569+
Schema petsListSchema = openAPI.getComponents().getSchemas().get("PetsList");
570+
Schema colouringsSchema = openAPI.getComponents().getSchemas().get("Colouring");
571+
Schema colourSchema = openAPI.getComponents().getSchemas().get("Colour");
572+
573+
assertNotNull(petsListSchema);
574+
assertNotNull(colouringsSchema);
575+
assertNotNull(colourSchema);
576+
577+
assertTrue(petsListSchema instanceof ArraySchema);
578+
Schema colouringPropertySchema = ((ArraySchema) petsListSchema).getItems().getProperties().get("colouring");
579+
assertNotNull(colouringPropertySchema);
580+
581+
// Verify inline items resolved fully
582+
assertTrue(colouringPropertySchema.get$ref() == null);
583+
assertTrue(colouringPropertySchema == colouringsSchema);
584+
585+
}
586+
493587
@Test
494588
public void selfReferenceTest(@Injectable final List<AuthorizationValue> auths) {
495589
String yaml = "" +

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ public class OpenAPIV3ParserTest {
6767
protected WireMockServer wireMockServer;
6868

6969

70+
@Test
71+
public void testIssue1169() {
72+
ParseOptions options = new ParseOptions();
73+
options.setResolve(true);
74+
SwaggerParseResult parseResult = new OpenAPIV3Parser().readLocation("issue1169.yaml", null, options);
75+
assertTrue(parseResult.getMessages().size() == 0);
76+
OpenAPI apispec = parseResult.getOpenAPI();
77+
assertNotNull(apispec);
78+
}
79+
7080

7181
@Test
7282
public void testIssue339() throws Exception {
@@ -2051,6 +2061,48 @@ public void testResolveFullyMap() {
20512061
assertFalse(yaml.contains("$ref"));
20522062
}
20532063

2064+
@Test
2065+
public void testParseOptionsSkipMatchesFalse() {
2066+
final String location = "src/test/resources/skipMatches.yaml";
2067+
2068+
final ParseOptions options = new ParseOptions();
2069+
options.setResolve(true);
2070+
options.setFlatten(true);
2071+
options.setSkipMatches(false);
2072+
2073+
final OpenAPIV3Parser parserUnderTest = new OpenAPIV3Parser();
2074+
2075+
final SwaggerParseResult result = parserUnderTest.readLocation(location, null, options);
2076+
2077+
final OpenAPI openAPI = result.getOpenAPI();
2078+
2079+
assertNotNull(openAPI);
2080+
assertNotNull(openAPI.getComponents());
2081+
assertNotNull(openAPI.getComponents().getSchemas());
2082+
assertEquals(4, openAPI.getComponents().getSchemas().size());
2083+
}
2084+
2085+
@Test
2086+
public void testParseOptionsSkipMatchesTrue() {
2087+
final String location = "src/test/resources/skipMatches.yaml";
2088+
2089+
final ParseOptions options = new ParseOptions();
2090+
options.setResolve(true);
2091+
options.setFlatten(true);
2092+
options.setSkipMatches(true);
2093+
2094+
final OpenAPIV3Parser parserUnderTest = new OpenAPIV3Parser();
2095+
2096+
final SwaggerParseResult result = parserUnderTest.readLocation(location, null, options);
2097+
2098+
final OpenAPI openAPI = result.getOpenAPI();
2099+
2100+
assertNotNull(openAPI);
2101+
assertNotNull(openAPI.getComponents());
2102+
assertNotNull(openAPI.getComponents().getSchemas());
2103+
assertEquals(6, openAPI.getComponents().getSchemas().size());
2104+
}
2105+
20542106
private static int getDynamicPort() {
20552107
return new Random().ints(10000, 20000).findFirst().getAsInt();
20562108
}

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.swagger.v3.oas.models.PathItem;
1010
import io.swagger.v3.oas.models.media.ArraySchema;
1111
import io.swagger.v3.oas.models.media.Content;
12+
import io.swagger.v3.oas.models.media.IntegerSchema;
1213
import io.swagger.v3.oas.models.media.MediaType;
1314
import io.swagger.v3.oas.models.media.ObjectSchema;
1415
import io.swagger.v3.oas.models.media.Schema;
@@ -426,6 +427,111 @@ public void testInlineResponseModelWithTitle() throws Exception {
426427
assertTrue(model.getProperties().get("name") instanceof StringSchema);
427428
}
428429

430+
@Test
431+
public void testSkipInlineMatchesFalse() {
432+
final OpenAPI openAPI = new OpenAPI();
433+
434+
final InlineModelResolver inlineModelResolver = new InlineModelResolver();
435+
inlineModelResolver.setSkipMatches(false);
436+
437+
final Schema operationAlphaInAsset = new ObjectSchema();
438+
operationAlphaInAsset.setTitle("operationAlphaInAsset");
439+
operationAlphaInAsset.addProperties("id1", new IntegerSchema());
440+
operationAlphaInAsset.addProperties("id2", new IntegerSchema());
441+
442+
final Schema operationAlphaIn = new ObjectSchema();
443+
operationAlphaIn.setTitle("operationAlphaIn");
444+
operationAlphaIn.addProperties("asset", operationAlphaInAsset);
445+
446+
final Schema operationAlphaRequest = new ObjectSchema();
447+
operationAlphaRequest.setTitle("operationAlphaRequest");
448+
operationAlphaRequest.addProperties("in", operationAlphaIn);
449+
450+
final Schema operationBetaInAsset = new ObjectSchema();
451+
operationBetaInAsset.setTitle("operationBetaInAsset");
452+
operationBetaInAsset.addProperties("id1", new IntegerSchema());
453+
operationBetaInAsset.addProperties("id2", new IntegerSchema());
454+
455+
final Schema operationBetaIn = new ObjectSchema();
456+
operationBetaIn.setTitle("operationBetaIn");
457+
operationBetaIn.addProperties("asset", operationBetaInAsset);
458+
459+
final Schema operationBetaRequest = new ObjectSchema();
460+
operationBetaRequest.setTitle("operationBetaRequest");
461+
operationBetaRequest.addProperties("in", operationBetaIn);
462+
463+
openAPI.path("/operationAlpha", new PathItem()
464+
.get(new Operation()
465+
.requestBody(new RequestBody()
466+
.content(new Content().addMediaType("*/*", new MediaType()
467+
.schema(operationAlphaRequest))))));
468+
469+
openAPI.path("/operationBeta", new PathItem()
470+
.get(new Operation()
471+
.requestBody(new RequestBody()
472+
.content(new Content().addMediaType("*/*", new MediaType()
473+
.schema(operationBetaRequest))))));
474+
475+
inlineModelResolver.flatten(openAPI);
476+
477+
assertNotNull(openAPI);
478+
assertNotNull(openAPI.getComponents());
479+
assertNotNull(openAPI.getComponents().getSchemas());
480+
assertEquals(4, openAPI.getComponents().getSchemas().size());
481+
}
482+
483+
@Test
484+
public void testSkipInlineMatchesTrue() {
485+
final OpenAPI openAPI = new OpenAPI();
486+
487+
final InlineModelResolver inlineModelResolver = new InlineModelResolver();
488+
inlineModelResolver.setSkipMatches(true);
489+
490+
final Schema operationAlphaInAsset = new ObjectSchema();
491+
operationAlphaInAsset.setTitle("operationAlphaInAsset");
492+
operationAlphaInAsset.addProperties("id1", new IntegerSchema());
493+
operationAlphaInAsset.addProperties("id2", new IntegerSchema());
494+
495+
final Schema operationAlphaIn = new ObjectSchema();
496+
operationAlphaIn.setTitle("operationAlphaIn");
497+
operationAlphaIn.addProperties("asset", operationAlphaInAsset);
498+
499+
final Schema operationAlphaRequest = new ObjectSchema();
500+
operationAlphaRequest.setTitle("operationAlphaRequest");
501+
operationAlphaRequest.addProperties("in", operationAlphaIn);
502+
503+
final Schema operationBetaInAsset = new ObjectSchema();
504+
operationBetaInAsset.setTitle("operationBetaInAsset");
505+
operationBetaInAsset.addProperties("id1", new IntegerSchema());
506+
operationBetaInAsset.addProperties("id2", new IntegerSchema());
507+
508+
final Schema operationBetaIn = new ObjectSchema();
509+
operationBetaIn.setTitle("operationBetaIn");
510+
operationBetaIn.addProperties("asset", operationBetaInAsset);
511+
512+
final Schema operationBetaRequest = new ObjectSchema();
513+
operationBetaRequest.setTitle("operationBetaRequest");
514+
operationBetaRequest.addProperties("in", operationBetaIn);
515+
516+
openAPI.path("/operationAlpha", new PathItem()
517+
.get(new Operation()
518+
.requestBody(new RequestBody()
519+
.content(new Content().addMediaType("*/*", new MediaType()
520+
.schema(operationAlphaRequest))))));
521+
522+
openAPI.path("/operationBeta", new PathItem()
523+
.get(new Operation()
524+
.requestBody(new RequestBody()
525+
.content(new Content().addMediaType("*/*", new MediaType()
526+
.schema(operationBetaRequest))))));
527+
528+
inlineModelResolver.flatten(openAPI);
529+
530+
assertNotNull(openAPI);
531+
assertNotNull(openAPI.getComponents());
532+
assertNotNull(openAPI.getComponents().getSchemas());
533+
assertEquals(6, openAPI.getComponents().getSchemas().size());
534+
}
429535

430536
@Test
431537
public void resolveInlineArrayModelWithTitle() throws Exception {

0 commit comments

Comments
 (0)