Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAS 3.1 Support #1730

Merged
merged 34 commits into from
May 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
679090a
oas3.1 initial support
frantuma Aug 25, 2021
fd2f858
oas3.1 initial support - fix oas3.1 code branch
frantuma Sep 23, 2021
8202a51
oas3.1 initial support - tests and param resolution fix
frantuma Sep 28, 2021
7b67f42
oas3.1 initial support - response resolution fix
frantuma Sep 28, 2021
b745034
oas 3.1 - info.summary - components.pathItem - discriminator.extension
gracekarina Sep 29, 2021
60fa222
oas3.1 initial support - temp fix/ignore tests
frantuma Sep 28, 2021
b63375d
oas 3.1 - parse/validate OAS 3.1 fields
gracekarina Oct 6, 2021
cfa76c2
oas 3.1 - added sibling to ref in PathItem
gracekarina Oct 6, 2021
7f4e4a0
oas 3.1 - addressed comments in PR
gracekarina Oct 7, 2021
3d88fcd
oas 3.1 - adding sibling for pathItem,response,parameter,example,requ…
gracekarina Oct 7, 2021
20d3970
oas 3.1 - test for siblings ref ticket
gracekarina Oct 8, 2021
fe6017e
oas 3.1 - minor fix
gracekarina Oct 8, 2021
fdad858
oas 3.1 - bad URI test
gracekarina Oct 11, 2021
73fdbb0
oas 3.1 - test for siblings ref and other field JsonSchema
gracekarina Dec 11, 2021
ae424f7
oas 3.1 - test for exclusiveMaximum and ExclusiveMinimun
gracekarina Dec 14, 2021
4d69f7c
oas 3.1 - test ref siblings: const, contentEncoding, contentMediaType
gracekarina Dec 15, 2021
90d7591
oas 3.1 - deserialize Json Schema
gracekarina Dec 31, 2021
0e7bcfa
oas 3.1 - implementation of Examples, unevaluatedProperties, and othe…
gracekarina Jan 6, 2022
45f2496
oas 3.1 - more Json Schema parsing
gracekarina Jan 17, 2022
663f5b0
oas 3.1 - basic oas31 yaml file for testing
gracekarina Jan 17, 2022
79eb20b
oas 3.1 - test for oas31 support implementation review
gracekarina Jan 18, 2022
b7fcacb
oas 3.1 - minor oas 3.1 test update
frantuma Jan 18, 2022
042b4cd
oas 3.1 - includes support for #1603
gracekarina Jan 27, 2022
704bb6d
oas 3.1 - adding tests for unevaluatedItems deprecated
gracekarina Feb 1, 2022
676a852
oas 3.1 - add test demostrating 3.0 behavior and 3.1
gracekarina Feb 3, 2022
bd3cc23
oas 3.1 - fix rebase issues
frantuma Mar 2, 2022
23353bb
added keys to set in oas3.1
gracekarina Mar 9, 2022
d0b5039
test for new keys in schema 202012
gracekarina Mar 17, 2022
cd4b447
updating new JsonSchema in deserializer
gracekarina Mar 28, 2022
6d4693c
update new JsonSchema
gracekarina Mar 28, 2022
4332f25
remove print lines
gracekarina Mar 28, 2022
870b7ae
de-duplicate getJsonSchema and getSchema method for 3.1
gracekarina Apr 5, 2022
a0b774a
oas 3.1 - dereference support
frantuma May 20, 2022
6eb30c0
bump version to 2.1.0-SNAPSHOT (oas 3.1 support)
frantuma May 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ charset = utf-8

[modules/swagger-parser-v3/src/test/resources/**/*.json]
trim_trailing_whitespace = false

insert_final_newline = false
[modules/swagger-parser-v3/src/test/resources/**/*.yaml]
trim_trailing_whitespace = false
insert_final_newline = false
2 changes: 1 addition & 1 deletion modules/swagger-parser-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.0.34-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ public class ParseOptions {
private boolean validateInternalRefs = true;
private boolean legacyYamlDeserialization = false;
private boolean resolveRequestBody = false;


private boolean oaiAuthor;
private boolean defaultSchemaTypeObject = true;

public boolean isResolve() {
return resolve;
}
Expand All @@ -37,7 +40,7 @@ public boolean isResolveFully() {
public void setResolveFully(boolean resolveFully) {
this.resolveFully = resolveFully;
}

public boolean isResolveRequestBody() {
return resolveRequestBody;
}
Expand Down Expand Up @@ -105,11 +108,27 @@ public void setLegacyYamlDeserialization(boolean legacyYamlDeserialization) {
this.legacyYamlDeserialization = legacyYamlDeserialization;
}

public void setOaiAuthor(boolean oaiAuthor) {
this.oaiAuthor = oaiAuthor;
}

public boolean isOaiAuthor() {
return oaiAuthor;
}

public void setValidateInternalRefs(boolean validateInternalRefs) {
this.validateInternalRefs = validateInternalRefs;
}

public boolean isValidateInternalRefs() {
return validateInternalRefs;
}

public boolean isDefaultSchemaTypeObject() {
return defaultSchemaTypeObject;
}

public void setDefaultSchemaTypeObject(boolean defaultSchemaTypeObject) {
this.defaultSchemaTypeObject = defaultSchemaTypeObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public class SwaggerParseResult {
private List<String> messages = null;
private OpenAPI openAPI;
private boolean openapi31;

public SwaggerParseResult messages(List<String> messages) {
this.messages = messages;
Expand Down Expand Up @@ -52,4 +53,17 @@ public static SwaggerParseResult ofError(String message){
result.setMessages(Collections.singletonList(message));
return result;
}

public void setOpenapi31(boolean openapi31) {
this.openapi31 = openapi31;
}

public SwaggerParseResult openapi31(boolean openapi31) {
this.openapi31 = openapi31;
return this;
}

public boolean isOpenapi31() {
return this.openapi31;
}
}
2 changes: 1 addition & 1 deletion modules/swagger-parser-v2-converter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.0.34-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
3 changes: 1 addition & 2 deletions modules/swagger-parser-v3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.parser.v3</groupId>
<artifactId>swagger-parser-project</artifactId>
<version>2.0.34-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down Expand Up @@ -64,7 +64,6 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import io.swagger.v3.parser.exception.EncodingNotSupportedException;
import io.swagger.v3.parser.exception.ReadContentException;
import io.swagger.v3.parser.reference.DereferencerContext;
import io.swagger.v3.parser.reference.DereferencersFactory;
import io.swagger.v3.parser.reference.OpenAPIDereferencer;
import io.swagger.v3.parser.util.ClasspathHelper;
import io.swagger.v3.parser.util.DeserializationUtils;
import io.swagger.v3.parser.util.InlineModelResolver;
Expand Down Expand Up @@ -136,7 +139,7 @@ public SwaggerParseResult parseJsonNode(String path, JsonNode node) {
return new OpenAPIDeserializer().deserialize(node, path,new ParseOptions());
}
public SwaggerParseResult parseJsonNode(String path, JsonNode node, ParseOptions options) {
return new OpenAPIDeserializer().deserialize(node, path, options);
return new OpenAPIDeserializer().deserialize(node, path, options, options.isOaiAuthor());
}

public SwaggerParseResult readContents(String yaml) {
Expand All @@ -145,7 +148,7 @@ public SwaggerParseResult readContents(String yaml) {
return readContents(yaml, null, options);
}

private SwaggerParseResult readContents(String swaggerAsString, List<AuthorizationValue> auth, ParseOptions options,
public SwaggerParseResult readContents(String swaggerAsString, List<AuthorizationValue> auth, ParseOptions options,
String location) {
if (swaggerAsString == null || swaggerAsString.trim().isEmpty()) {
return SwaggerParseResult.ofError("Null or empty definition");
Expand Down Expand Up @@ -180,6 +183,7 @@ private SwaggerParseResult readContents(String swaggerAsString, List<Authorizati
}
}
return result;

} catch (JsonProcessingException e) {
LOGGER.warn("Exception while parsing:", e);
final String message = getParseErrorMessage(e.getOriginalMessage(), location);
Expand All @@ -201,9 +205,26 @@ private SwaggerParseResult resolve(SwaggerParseResult result, List<Authorization
try {
if (options != null) {
if (options.isResolve() || options.isResolveFully()) {
OpenAPIResolver resolver = new OpenAPIResolver(result.getOpenAPI(), emptyListIfNull(auth),
location, null, options);
resolver.resolve(result);
if (result.getOpenAPI().getOpenapi() != null && result.getOpenAPI().getOpenapi().startsWith("3.1")) {
DereferencerContext dereferencerContext = new DereferencerContext(
result,
auth,
location,
options,
null,
null,
true
);
List<OpenAPIDereferencer> dereferencers = DereferencersFactory.getInstance().getDereferencers();
if (dereferencers.iterator().hasNext()) {
OpenAPIDereferencer dereferencer = dereferencers.iterator().next();
dereferencer.dereference(dereferencerContext, dereferencers.iterator());
}
} else {
OpenAPIResolver resolver = new OpenAPIResolver(result.getOpenAPI(), emptyListIfNull(auth),
location, null, options);
resolver.resolve(result);
}
if (options.isResolveFully()) {
new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class ResolverCache {
private List<String> referencedModelKeys = new ArrayList<>();
private Set<String> resolveValidationMessages;
private final ParseOptions parseOptions;

protected boolean openapi31;

/*
* a map that stores original external references, and their associated renamed
Expand All @@ -86,6 +86,7 @@ public ResolverCache(OpenAPI openApi, List<AuthorizationValue> auths, String par
}

public ResolverCache(OpenAPI openApi, List<AuthorizationValue> auths, String parentFileLocation, Set<String> resolveValidationMessages, ParseOptions parseOptions) {
this.openapi31 = openApi != null && openApi.getOpenapi() != null && openApi.getOpenapi().startsWith("3.1");
this.openApi = openApi;
this.auths = auths;
this.rootPath = parentFileLocation;
Expand Down Expand Up @@ -165,7 +166,7 @@ else if (rootPath != null) {
if (parseOptions.isValidateExternalRefs()) {
result = deserializeFragment(tree, expectedType, file, "/");
} else {
result = DeserializationUtils.deserialize(contents, file, expectedType);
result = DeserializationUtils.deserialize(contents, file, expectedType, openapi31);
}
resolutionCache.put(ref, result);
if (deserializationUtilResult.getMessages() != null) {
Expand All @@ -191,9 +192,9 @@ else if (rootPath != null) {
} else {
if (expectedType.equals(Schema.class)) {
OpenAPIDeserializer deserializer = new OpenAPIDeserializer();
result = (T) deserializer.getSchema((ObjectNode) tree, definitionPath.replace("/", "."), null);
result = (T) deserializer.getSchema((ObjectNode) tree, definitionPath.replace("/", "."), new OpenAPIDeserializer.ParseResult().openapi31(openapi31));
} else {
result = DeserializationUtils.deserialize(tree, file, expectedType);
result = DeserializationUtils.deserialize(tree, file, expectedType, openapi31);
}
}
updateLocalRefs(file, result);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.swagger.v3.parser.extensions;

import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.ResolverCache;
import io.swagger.v3.parser.util.OpenAPIDeserializer;

import java.util.Map;

public interface JsonSchemaParserExtension {

Schema getSchema(ObjectNode node, String location, OpenAPIDeserializer.ParseResult result, Map<String, Object> rootMap, String basePath);


boolean resolveSchema(Schema schema, ResolverCache cache, OpenAPI openAPI, boolean openapi31);

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ public class CallbackProcessor {
private final ExternalRefProcessor externalRefProcessor;

public CallbackProcessor(ResolverCache cache, OpenAPI openAPI) {
this(cache, openAPI, false);
}
public CallbackProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
this.cache = cache;
this.operationProcessor = new OperationProcessor(cache, openAPI);
this.parameterProcessor = new ParameterProcessor(cache,openAPI);
this.operationProcessor = new OperationProcessor(cache, openAPI, openapi31);
this.parameterProcessor = new ParameterProcessor(cache,openAPI, openapi31);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
this.openAPI = openAPI;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,26 @@ public class ComponentsProcessor {
private final SecuritySchemeProcessor securitySchemeProcessor;

public ComponentsProcessor(OpenAPI openApi,ResolverCache cache){
this(openApi, cache, false);

}
public ComponentsProcessor(OpenAPI openApi,ResolverCache cache, boolean openapi31){
this.cache = cache;
this.openApi = openApi;
this.schemaProcessor = new SchemaProcessor(cache,openApi);
this.responseProcessor = new ResponseProcessor(cache, openApi);
this.requestBodyProcessor = new RequestBodyProcessor(cache, openApi);
this.parameterProcessor = new ParameterProcessor(cache, openApi);
this.headerProcessor = new HeaderProcessor(cache, openApi);
this.schemaProcessor = new SchemaProcessor(cache,openApi, openapi31);
this.responseProcessor = new ResponseProcessor(cache, openApi, openapi31);
this.requestBodyProcessor = new RequestBodyProcessor(cache, openApi, openapi31);
this.parameterProcessor = new ParameterProcessor(cache, openApi, openapi31);
this.headerProcessor = new HeaderProcessor(cache, openApi, openapi31);
this.exampleProcessor = new ExampleProcessor(cache,openApi);
this.linkProcessor = new LinkProcessor(cache,openApi);
this.callbackProcessor = new CallbackProcessor(cache,openApi);
this.linkProcessor = new LinkProcessor(cache,openApi, openapi31);
this.callbackProcessor = new CallbackProcessor(cache,openApi, openapi31);
this.securitySchemeProcessor = new SecuritySchemeProcessor(cache,openApi);

}



public void processComponents() {
if (openApi.getComponents() == null){
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.swagger.v3.parser.processors;


import java.io.File;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Collection;
Expand Down Expand Up @@ -391,9 +390,39 @@ public String processRefToExternalResponse(String $ref, RefFormat refFormat) {
}
}
newRef = possiblyConflictingDefinitionName;
openAPI.getComponents().addResponses(newRef, response);
cache.putRenamedRef($ref, newRef);

if(existingResponse == null) {
// don't overwrite existing model reference
openAPI.getComponents().addResponses(newRef, response);
cache.addReferencedKey(newRef);

String file = $ref.split("#/")[0];
if (response.get$ref() != null) {
RefFormat format = computeRefFormat(response.get$ref());
if (isAnExternalRefFormat(format)) {
String fullRef = response.get$ref();
if (!format.equals(RefFormat.URL)) {
String parent = file.substring(0, file.lastIndexOf('/'));
if (!parent.isEmpty()) {
if (fullRef.contains("#/")) {
String[] parts = fullRef.split("#/");
String fullRefFilePart = parts[0];
String fullRefInternalRefPart = parts[1];
fullRef = Paths.get(parent, fullRefFilePart).normalize().toString() + "#/" + fullRefInternalRefPart;
} else {
fullRef = Paths.get(parent, fullRef).normalize().toString();
}
}

}
response.set$ref(processRefToExternalResponse(fullRef, format));
} else {
processRefToExternalResponse(file + response.get$ref(), RefFormat.RELATIVE);
}
}
}

if(response != null) {
if(response.getContent() != null){
processRefContent(response.getContent(), $ref);
Expand Down Expand Up @@ -759,7 +788,22 @@ public String processRefToExternalParameter(String $ref, RefFormat refFormat) {
if (parameter.get$ref() != null) {
RefFormat format = computeRefFormat(parameter.get$ref());
if (isAnExternalRefFormat(format)) {
parameter.set$ref(processRefToExternalParameter(parameter.get$ref(), format));
String fullRef = parameter.get$ref();
if (!format.equals(RefFormat.URL)) {
String parent = file.substring(0, file.lastIndexOf('/'));
if (!parent.isEmpty()) {
if (fullRef.contains("#/")) {
String[] parts = fullRef.split("#/");
String fullRefFilePart = parts[0];
String fullRefInternalRefPart = parts[1];
fullRef = Paths.get(parent, fullRefFilePart).normalize().toString() + "#/" + fullRefInternalRefPart;
} else {
fullRef = Paths.get(parent, fullRef).normalize().toString();
}
}

}
parameter.set$ref(processRefToExternalParameter(fullRef, format));
} else {
processRefToExternalParameter(file + parameter.get$ref(), RefFormat.RELATIVE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ public class HeaderProcessor {


public HeaderProcessor(ResolverCache cache, OpenAPI openAPI) {
this(cache, openAPI, false);
}
public HeaderProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) {
this.cache = cache;
this.openAPI = openAPI;
this.schemaProcessor = new SchemaProcessor(cache,openAPI);
this.schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31);
this.exampleProcessor = new ExampleProcessor(cache,openAPI);
this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI);
}


public void processHeader(Header header) {

if(header.get$ref() != null){
Expand Down Expand Up @@ -72,4 +76,4 @@ public void processHeader(Header header) {
}
}
}
}
}
Loading