diff --git a/pom.xml b/pom.xml index a7100782..ef131c53 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ com.qdesrame openapi-diff - 1.2.1-SNAPSHOT + 2.0.0-SNAPSHOT jar openapi-diff diff --git a/src/main/java/com/qdesrame/openapi/diff/Main.java b/src/main/java/com/qdesrame/openapi/diff/Main.java index 2dd52036..7dc6b353 100644 --- a/src/main/java/com/qdesrame/openapi/diff/Main.java +++ b/src/main/java/com/qdesrame/openapi/diff/Main.java @@ -131,10 +131,10 @@ public static void main(String... args) { } } if (line.hasOption("state")) { - System.out.println(result.isDiff() ? result.isDiffBackwardCompatible() ? "compatible" : "incompatible" : "no_changes"); + System.out.println(result.isChanged().getValue()); System.exit(0); } else { - System.exit(result.isDiff() ? 1 : 0); + System.exit(result.isUnchanged() ? 0 : 1); } } catch (ParseException e) { // oops, something went wrong diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java index ac2626d8..faf5867c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ApiResponseDiff.java @@ -2,6 +2,7 @@ import com.qdesrame.openapi.diff.model.ChangedApiResponse; import com.qdesrame.openapi.diff.model.ChangedResponse; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; @@ -10,6 +11,8 @@ import java.util.Map; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 04/01/18. */ @@ -20,19 +23,18 @@ public ApiResponseDiff(OpenApiDiff openApiDiff) { this.openApiDiff = openApiDiff; } - public Optional diff(ApiResponses left, ApiResponses right) { + public Optional diff(ApiResponses left, ApiResponses right, DiffContext context) { MapKeyDiff responseMapKeyDiff = MapKeyDiff.diff(left, right); - ChangedApiResponse changedApiResponse = new ChangedApiResponse(left, right); + ChangedApiResponse changedApiResponse = new ChangedApiResponse(left, right, context); changedApiResponse.setAddResponses(responseMapKeyDiff.getIncreased()); changedApiResponse.setMissingResponses(responseMapKeyDiff.getMissing()); List sharedResponseCodes = responseMapKeyDiff.getSharedKey(); - Map resps = new HashMap<>(); for (String responseCode : sharedResponseCodes) { - openApiDiff.getResponseDiff().diff(left.get(responseCode), right.get(responseCode)) + openApiDiff.getResponseDiff().diff(left.get(responseCode), right.get(responseCode), context) .ifPresent(changedResponse -> resps.put(responseCode, changedResponse)); } changedApiResponse.setChangedResponses(resps); - return changedApiResponse.isDiff() ? Optional.of(changedApiResponse) : Optional.empty(); + return isChanged(changedApiResponse); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java b/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java new file mode 100644 index 00000000..209a1113 --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/compare/CacheKey.java @@ -0,0 +1,43 @@ +package com.qdesrame.openapi.diff.compare; + +import com.qdesrame.openapi.diff.model.DiffContext; +import lombok.Getter; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +@Getter +public final class CacheKey { + private final String left; + private final String right; + private final DiffContext context; + + public CacheKey(final String left, final String right, final DiffContext context) { + this.left = left; + this.right = right; + this.context = context; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + CacheKey cacheKey = (CacheKey) o; + + return new EqualsBuilder() + .append(left, cacheKey.left) + .append(right, cacheKey.right) + .append(context, cacheKey.context) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(left) + .append(right) + .append(context) + .toHashCode(); + } +} diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java index a9754fdc..14511806 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ContentDiff.java @@ -2,11 +2,15 @@ import com.qdesrame.openapi.diff.model.ChangedContent; import com.qdesrame.openapi.diff.model.ChangedMediaType; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; import java.util.*; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isUnchanged; + public class ContentDiff implements Comparable { private OpenApiDiff openApiDiff; @@ -20,8 +24,8 @@ public boolean compare(Content left, Content right) { return false; } - public Optional diff(Content left, Content right) { - ChangedContent changedContent = new ChangedContent(left, right); + public Optional diff(Content left, Content right, DiffContext context) { + ChangedContent changedContent = new ChangedContent(left, right, context); MapKeyDiff mediaTypeDiff = MapKeyDiff.diff(left, right); changedContent.setIncreased(mediaTypeDiff.getIncreased()); @@ -31,13 +35,13 @@ public Optional diff(Content left, Content right) { for (String mediaTypeKey : sharedMediaTypes) { MediaType oldMediaType = left.get(mediaTypeKey); MediaType newMediaType = right.get(mediaTypeKey); - ChangedMediaType changedMediaType = new ChangedMediaType(oldMediaType.getSchema(), newMediaType.getSchema()); - openApiDiff.getSchemaDiff().diff(new HashSet<>(), oldMediaType.getSchema(), newMediaType.getSchema()).ifPresent(changedMediaType::setChangedSchema); - if (changedMediaType.isDiff()) { + ChangedMediaType changedMediaType = new ChangedMediaType(oldMediaType.getSchema(), newMediaType.getSchema(), context); + openApiDiff.getSchemaDiff().diff(new HashSet<>(), oldMediaType.getSchema(), newMediaType.getSchema(), context).ifPresent(changedMediaType::setChangedSchema); + if (!isUnchanged(changedMediaType)) { changedMediaTypes.put(mediaTypeKey, changedMediaType); } } changedContent.setChanged(changedMediaTypes); - return changedContent.isDiff() ? Optional.of(changedContent) : Optional.empty(); + return isChanged(changedContent); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java index f15badf4..b2a6c6db 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/HeaderDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedHeader; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -10,6 +11,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 28/12/17. */ @@ -25,26 +28,26 @@ public HeaderDiff(OpenApiDiff openApiDiff) { this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null; } - public Optional diff(Header left, Header right) { - return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref()); + public Optional diff(Header left, Header right, DiffContext context) { + return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context); } @Override - protected Optional computeDiff(HashSet refSet, Header left, Header right) { + protected Optional computeDiff(HashSet refSet, Header left, Header right, DiffContext context) { left = refPointer.resolveRef(leftComponents, left, left.get$ref()); right = refPointer.resolveRef(rightComponents, right, right.get$ref()); - ChangedHeader changedHeader = new ChangedHeader(left, right); + ChangedHeader changedHeader = new ChangedHeader(left, right, context); changedHeader.setChangeDescription(!Objects.equals(left.getDescription(), right.getDescription())); changedHeader.setChangeRequired(getBooleanDiff(left.getRequired(), right.getRequired())); changedHeader.setChangeDeprecated(!Boolean.TRUE.equals(left.getDeprecated()) && Boolean.TRUE.equals(right.getDeprecated())); changedHeader.setChangeStyle(!Objects.equals(left.getStyle(), right.getStyle())); changedHeader.setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode())); - openApiDiff.getSchemaDiff().diff(new HashSet<>(), left.getSchema(), right.getSchema()).ifPresent(changedHeader::setChangedSchema); - openApiDiff.getContentDiff().diff(left.getContent(), right.getContent()).ifPresent(changedHeader::setChangedContent); + openApiDiff.getSchemaDiff().diff(new HashSet<>(), left.getSchema(), right.getSchema(), context).ifPresent(changedHeader::setChangedSchema); + openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context).ifPresent(changedHeader::setChangedContent); - return changedHeader.isDiff() ? Optional.of(changedHeader) : Optional.empty(); + return isChanged(changedHeader); } private boolean getBooleanDiff(Boolean left, Boolean right) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java index 58c990dc..9e39a030 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/HeadersDiff.java @@ -2,6 +2,7 @@ import com.qdesrame.openapi.diff.model.ChangedHeader; import com.qdesrame.openapi.diff.model.ChangedHeaders; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.headers.Header; import java.util.HashMap; @@ -9,6 +10,8 @@ import java.util.Map; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 28/12/17. */ @@ -19,8 +22,8 @@ public HeadersDiff(OpenApiDiff openApiDiff) { this.openApiDiff = openApiDiff; } - public Optional diff(Map left, Map right) { - ChangedHeaders changedHeaders = new ChangedHeaders(left, right); + public Optional diff(Map left, Map right, DiffContext context) { + ChangedHeaders changedHeaders = new ChangedHeaders(left, right, context); MapKeyDiff headerMapDiff = MapKeyDiff.diff(left, right); changedHeaders.setIncreased(headerMapDiff.getIncreased()); changedHeaders.setMissing(headerMapDiff.getMissing()); @@ -30,11 +33,11 @@ public Optional diff(Map left, Map changed.put(headerKey, changedHeader)); } changedHeaders.setChanged(changed); - return changedHeaders.isDiff() ? Optional.of(changedHeaders) : Optional.empty(); + return isChanged(changedHeaders); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java index 52a07326..68d5d2cc 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowDiff.java @@ -6,6 +6,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 12/01/18. */ @@ -24,6 +26,6 @@ public Optional diff(OAuthFlow left, OAuthFlow right) { changedOAuthFlow.setChangedRefreshUrl(!Objects.equals(left.getRefreshUrl(), right.getRefreshUrl())); } - return changedOAuthFlow.isDiff() ? Optional.of(changedOAuthFlow) : Optional.empty(); + return isChanged(changedOAuthFlow); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java index 5a83b714..ae3235a1 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/OAuthFlowsDiff.java @@ -5,6 +5,8 @@ import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 12/01/18. */ @@ -23,6 +25,6 @@ public Optional diff(OAuthFlows left, OAuthFlows right) { openApiDiff.getoAuthFlowDiff().diff(left.getClientCredentials(), right.getClientCredentials()).ifPresent(changedOAuthFlows::setChangedClientCredentialOAuthFlow); openApiDiff.getoAuthFlowDiff().diff(left.getAuthorizationCode(), right.getAuthorizationCode()).ifPresent(changedOAuthFlows::setChangedAuthorizationCodeOAuthFlow); } - return changedOAuthFlows.isDiff() ? Optional.of(changedOAuthFlows) : Optional.empty(); + return isChanged(changedOAuthFlows); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java index 8f1c3087..5e17ecc0 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/OperationDiff.java @@ -2,14 +2,16 @@ import com.qdesrame.openapi.diff.model.ChangedOperation; import com.qdesrame.openapi.diff.model.ChangedParameters; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.parameters.Parameter; import java.util.List; import java.util.Map; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 04/01/18. */ @@ -20,34 +22,34 @@ public OperationDiff(OpenApiDiff openApiDiff) { this.openApiDiff = openApiDiff; } - public Optional diff(String pathUrl, PathItem.HttpMethod method, Map pathParameters, Operation oldOperation, Operation newOperation) { - ChangedOperation changedOperation = new ChangedOperation(pathUrl, method, oldOperation, newOperation); + public Optional diff(Operation oldOperation, Operation newOperation, DiffContext context) { + ChangedOperation changedOperation = new ChangedOperation(context.getUrl(), context.getMethod(), oldOperation, newOperation); changedOperation.setSummary(newOperation.getSummary()); changedOperation.setDeprecated(!Boolean.TRUE.equals(oldOperation.getDeprecated()) && Boolean.TRUE.equals(newOperation.getDeprecated())); if (oldOperation.getRequestBody() != null || newOperation.getRequestBody() != null) { - openApiDiff.getRequestBodyDiff().diff(oldOperation.getRequestBody(), newOperation.getRequestBody()) + openApiDiff.getRequestBodyDiff().diff(oldOperation.getRequestBody(), newOperation.getRequestBody(), context.copyAsRequest()) .ifPresent(changedOperation::setChangedRequestBody); } - openApiDiff.getParametersDiff().diff(oldOperation.getParameters(), newOperation.getParameters()) + openApiDiff.getParametersDiff().diff(oldOperation.getParameters(), newOperation.getParameters(), context) .ifPresent(params -> { - removePathParameters(pathParameters, params); + removePathParameters(context.getParameters(), params); changedOperation.setChangedParameters(params); }); if (oldOperation.getResponses() != null || newOperation.getResponses() != null) { - openApiDiff.getApiResponseDiff().diff(oldOperation.getResponses(), newOperation.getResponses()) + openApiDiff.getApiResponseDiff().diff(oldOperation.getResponses(), newOperation.getResponses(), context.copyAsResponse()) .ifPresent(changedOperation::setChangedApiResponse); } if (oldOperation.getSecurity() != null || newOperation.getSecurity() != null) { - openApiDiff.getSecurityRequirementsDiff().diff(oldOperation.getSecurity(), newOperation.getSecurity()) + openApiDiff.getSecurityRequirementsDiff().diff(oldOperation.getSecurity(), newOperation.getSecurity(), context) .ifPresent(changedOperation::setChangedSecurityRequirements); } - return changedOperation.isDiff() ? Optional.of(changedOperation) : Optional.empty(); + return isChanged(changedOperation); } public void removePathParameters(Map pathParameters, ChangedParameters params) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java index 7cea0df6..25bdedb6 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ParameterDiff.java @@ -2,6 +2,7 @@ import com.qdesrame.openapi.diff.model.ChangedParameter; import com.qdesrame.openapi.diff.model.ChangedSchema; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -11,6 +12,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + public class ParameterDiff extends ReferenceDiffCache { private Components leftComponents; @@ -24,13 +27,13 @@ public ParameterDiff(OpenApiDiff openApiDiff) { this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null; } - public Optional diff(Parameter left, Parameter right) { - return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref()); + public Optional diff(Parameter left, Parameter right, DiffContext context) { + return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context); } @Override - protected Optional computeDiff(HashSet refSet, Parameter left, Parameter right) { - ChangedParameter changedParameter = new ChangedParameter(right.getName(), right.getIn()); + protected Optional computeDiff(HashSet refSet, Parameter left, Parameter right, DiffContext context) { + ChangedParameter changedParameter = new ChangedParameter(right.getName(), right.getIn(), context); left = refPointer.resolveRef(this.leftComponents, left, left.get$ref()); right = refPointer.resolveRef(this.rightComponents, right, right.get$ref()); @@ -43,14 +46,14 @@ protected Optional computeDiff(HashSet refSet, Paramet changedParameter.setChangeAllowEmptyValue(getBooleanDiff(left.getAllowEmptyValue(), right.getAllowEmptyValue())); changedParameter.setChangeStyle(!Objects.equals(left.getStyle(), right.getStyle())); changedParameter.setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode())); - Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, left.getSchema(), right.getSchema()); + Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, left.getSchema(), right.getSchema(), context); if (changedSchema.isPresent()) { changedParameter.setChangedSchema(changedSchema.get()); } - openApiDiff.getContentDiff().diff(left.getContent(), right.getContent()) + openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context) .ifPresent(changedParameter::setChangedContent); - return changedParameter.isDiff() ? Optional.of(changedParameter) : Optional.empty(); + return isChanged(changedParameter); } private boolean getBooleanDiff(Boolean left, Boolean right) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java index 12009be1..f2c50c7c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ParametersDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedParameters; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -11,6 +12,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * compare two parameter * @@ -37,8 +40,8 @@ public static boolean same(Parameter left, Parameter right) { return Objects.equals(left.getName(), right.getName()) && Objects.equals(left.getIn(), right.getIn()); } - public Optional diff(List left, List right) { - ChangedParameters changedParameters = new ChangedParameters(left, right != null ? new ArrayList<>(right) : null); + public Optional diff(List left, List right, DiffContext context) { + ChangedParameters changedParameters = new ChangedParameters(left, right != null ? new ArrayList<>(right) : null, context); if (null == left) left = new ArrayList<>(); if (null == right) right = new ArrayList<>(); @@ -51,11 +54,11 @@ public Optional diff(List left, List ri } else { Parameter rightPara = rightParam.get(); right.remove(rightPara); - openApiDiff.getParameterDiff().diff(leftPara, rightPara).ifPresent(changedParameters.getChanged()::add); + openApiDiff.getParameterDiff().diff(leftPara, rightPara, context).ifPresent(changedParameters.getChanged()::add); } } changedParameters.getIncreased().addAll(right); - return changedParameters.isDiff() ? Optional.of(changedParameters) : Optional.empty(); + return isChanged(changedParameters); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java index 73a9d59a..883a4361 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedPath; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; @@ -8,6 +9,8 @@ import java.util.Map; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + public class PathDiff { private OpenApiDiff openApiDiff; @@ -15,8 +18,8 @@ public PathDiff(OpenApiDiff openApiDiff) { this.openApiDiff = openApiDiff; } - public Optional diff(String pathUrl, Map pathParameters, PathItem left, PathItem right) { - ChangedPath changedPath = new ChangedPath(pathUrl, left, right); + public Optional diff(PathItem left, PathItem right, DiffContext context) { + ChangedPath changedPath = new ChangedPath(context.getUrl(), left, right, context); Map oldOperationMap = left.readOperationsMap(); Map newOperationMap = right.readOperationsMap(); @@ -28,8 +31,8 @@ public Optional diff(String pathUrl, Map pathParame for (PathItem.HttpMethod method : sharedMethods) { Operation oldOperation = oldOperationMap.get(method); Operation newOperation = newOperationMap.get(method); - openApiDiff.getOperationDiff().diff(pathUrl, method, pathParameters, oldOperation, newOperation).ifPresent(changedPath.getChanged()::add); + openApiDiff.getOperationDiff().diff(oldOperation, newOperation, context.copyWithMethod(method)).ifPresent(changedPath.getChanged()::add); } - return changedPath.isDiff() ? Optional.of(changedPath) : Optional.empty(); + return isChanged(changedPath); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java index 724b83c0..731d3f11 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/PathsDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedPaths; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.Paths; @@ -8,6 +9,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + public class PathsDiff { private static final String REGEX_PATH = "\\{([^/]+)\\}"; private OpenApiDiff openApiDiff; @@ -50,12 +53,15 @@ public Optional diff(final Map left, final Map changedPaths.getChanged().put(result.get(), path)); + DiffContext context = new DiffContext(); + context.setUrl(url); + context.setParameters(params); + openApiDiff.getPathDiff().diff(leftPath, rightPath, context).ifPresent(path -> changedPaths.getChanged().put(result.get(), path)); } else { changedPaths.getMissing().put(url, leftPath); } }); - return changedPaths.isDiff() ? Optional.of(changedPaths) : Optional.empty(); + return isChanged(changedPaths); } public static Paths valOrEmpty(Paths path) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java b/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java index 53a61a22..7458e93f 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ReferenceDiffCache.java @@ -1,5 +1,7 @@ package com.qdesrame.openapi.diff.compare; +import com.qdesrame.openapi.diff.model.DiffContext; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -9,49 +11,41 @@ * Created by adarsh.sharma on 07/01/18. */ public abstract class ReferenceDiffCache { - private Map> refDiffMap; + private Map refDiffMap; public ReferenceDiffCache() { this.refDiffMap = new HashMap<>(); } - private Optional getFromCache(String leftRef, String rightRef) { - Optional> changedSchemaMap = Optional.ofNullable(refDiffMap.get(leftRef)); - if (changedSchemaMap.isPresent()) { - return Optional.ofNullable(changedSchemaMap.get().get(rightRef)); - } - return Optional.empty(); + private Optional getFromCache(CacheKey cacheKey) { + return Optional.ofNullable(refDiffMap.get(cacheKey)); } - private void addToCache(String leftRef, String rightRef, D changed) { - Map changedSchemaMap = refDiffMap.computeIfAbsent(leftRef, k -> new HashMap<>()); - changedSchemaMap.put(rightRef, changed); + private void addToCache(CacheKey cacheKey, D changed) { + refDiffMap.put(cacheKey, changed); } - public Optional cachedDiff(HashSet refSet, C left, C right, String leftRef, String rightRef) { + public Optional cachedDiff(HashSet refSet, C left, C right, String leftRef, String rightRef, DiffContext context) { boolean areBothRefParameters = leftRef != null && rightRef != null; if (areBothRefParameters) { - Optional changedFromRef = getFromCache(leftRef, rightRef); + CacheKey key = new CacheKey(leftRef, rightRef, context); + Optional changedFromRef = getFromCache(key); if (changedFromRef.isPresent()) { return changedFromRef; } else { String refKey = getRefKey(leftRef, rightRef); - if(refSet.contains(refKey)) { + if (refSet.contains(refKey)) { return Optional.empty(); } else { refSet.add(refKey); - Optional changed = computeDiff(refSet, left, right); - - if(areBothRefParameters) { - addToCache(leftRef, rightRef, changed.isPresent()? changed.get(): null); - } + Optional changed = computeDiff(refSet, left, right, context); + addToCache(key, changed.orElse(null)); refSet.remove(refKey); - return changed; } } } else { - return computeDiff(refSet, left, right); + return computeDiff(refSet, left, right, context); } } @@ -59,6 +53,6 @@ protected String getRefKey(String leftRef, String rightRef) { return leftRef + ":" + rightRef; } - protected abstract Optional computeDiff(HashSet refSet, C left, C right); + protected abstract Optional computeDiff(HashSet refSet, C left, C right, DiffContext context); } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/RequestBodyDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/RequestBodyDiff.java index 532408d9..adadc4b6 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/RequestBodyDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/RequestBodyDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedRequestBody; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.media.Content; @@ -10,6 +11,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 28/12/17. */ @@ -21,12 +24,12 @@ public RequestBodyDiff(OpenApiDiff openApiDiff) { this.openApiDiff = openApiDiff; } - public Optional diff(RequestBody left, RequestBody right) { - return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref()); + public Optional diff(RequestBody left, RequestBody right, DiffContext context) { + return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context); } @Override - protected Optional computeDiff(HashSet refSet, RequestBody left, RequestBody right) { + protected Optional computeDiff(HashSet refSet, RequestBody left, RequestBody right, DiffContext context) { Content oldRequestContent = new Content(); Content newRequestContent = new Content(); RequestBody oldRequestBody = null; @@ -43,8 +46,7 @@ protected Optional computeDiff(HashSet refSet, Reque newRequestContent = newRequestBody.getContent(); } } - - ChangedRequestBody changedRequestBody = new ChangedRequestBody(oldRequestBody, newRequestBody); + ChangedRequestBody changedRequestBody = new ChangedRequestBody(oldRequestBody, newRequestBody, context); boolean leftRequired = oldRequestBody != null && Boolean.TRUE.equals(oldRequestBody.getRequired()); boolean rightRequired = newRequestBody != null && Boolean.TRUE.equals(newRequestBody.getRequired()); @@ -54,8 +56,8 @@ protected Optional computeDiff(HashSet refSet, Reque String rightDescription = newRequestBody != null ? newRequestBody.getDescription() : null; changedRequestBody.setChangeDescription(!Objects.equals(leftDescription, rightDescription)); - openApiDiff.getContentDiff().diff(oldRequestContent, newRequestContent).ifPresent(changedRequestBody::setChangedContent); + openApiDiff.getContentDiff().diff(oldRequestContent, newRequestContent, context).ifPresent(changedRequestBody::setChangedContent); - return changedRequestBody.isDiff() ? Optional.of(changedRequestBody) : Optional.empty(); + return isChanged(changedRequestBody); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/ResponseDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/ResponseDiff.java index 7ee3995a..eec3520c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/ResponseDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/ResponseDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedResponse; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -10,6 +11,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 28/12/17. */ @@ -25,21 +28,21 @@ public ResponseDiff(OpenApiDiff openApiDiff) { this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null; } - public Optional diff(ApiResponse left, ApiResponse right) { - return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref()); + public Optional diff(ApiResponse left, ApiResponse right, DiffContext context) { + return cachedDiff(new HashSet<>(), left, right, left.get$ref(), right.get$ref(), context); } @Override - protected Optional computeDiff(HashSet refSet, ApiResponse left, ApiResponse right) { + protected Optional computeDiff(HashSet refSet, ApiResponse left, ApiResponse right, DiffContext context) { left = refPointer.resolveRef(leftComponents, left, left.get$ref()); right = refPointer.resolveRef(rightComponents, right, right.get$ref()); - ChangedResponse changedResponse = new ChangedResponse(left, right); + ChangedResponse changedResponse = new ChangedResponse(left, right, context); - openApiDiff.getContentDiff().diff(left.getContent(), right.getContent()).ifPresent(changedResponse::setChangedContent); - openApiDiff.getHeadersDiff().diff(left.getHeaders(), right.getHeaders()).ifPresent(changedResponse::setChangedHeaders); + openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context).ifPresent(changedResponse::setChangedContent); + openApiDiff.getHeadersDiff().diff(left.getHeaders(), right.getHeaders(), context).ifPresent(changedResponse::setChangedHeaders); changedResponse.setChangeDescription(!Objects.equals(left.getDescription(), right.getDescription())); - return changedResponse.isDiff() ? Optional.of(changedResponse) : Optional.empty(); + return isChanged(changedResponse); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/SchemaDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/SchemaDiff.java index 512dc69b..209d05a0 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/SchemaDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/SchemaDiff.java @@ -4,6 +4,7 @@ import com.qdesrame.openapi.diff.compare.schemadiffresult.ComposedSchemaDiffResult; import com.qdesrame.openapi.diff.compare.schemadiffresult.SchemaDiffResult; import com.qdesrame.openapi.diff.model.ChangedSchema; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -58,20 +59,21 @@ public SchemaDiff(OpenApiDiff openApiDiff) { this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null; } - public Optional diff(HashSet refSet, Schema left, Schema right) { - return cachedDiff(refSet, left, right, left.get$ref(), right.get$ref()); + public Optional diff(HashSet refSet, Schema left, Schema right, DiffContext context) { + return cachedDiff(refSet, left, right, left.get$ref(), right.get$ref(), context); } - public Optional getTypeChangedSchema(Schema left, Schema right) { + public Optional getTypeChangedSchema(Schema left, Schema right, DiffContext context) { ChangedSchema changedSchema = SchemaDiff.getSchemaDiffResult(openApiDiff).getChangedSchema(); changedSchema.setOldSchema(left); changedSchema.setNewSchema(right); changedSchema.setChangedType(true); + changedSchema.setContext(context); return Optional.of(changedSchema); } @Override - protected Optional computeDiff(HashSet refSet, Schema left, Schema right) { + protected Optional computeDiff(HashSet refSet, Schema left, Schema right, DiffContext context) { left = refPointer.resolveRef(this.leftComponents, left, left.get$ref()); right = refPointer.resolveRef(this.rightComponents, right, right.get$ref()); @@ -82,12 +84,12 @@ protected Optional computeDiff(HashSet refSet, Schema lef // return the object if (!Objects.equals(left.getType(), right.getType()) || !Objects.equals(left.getFormat(), right.getFormat())) { - return getTypeChangedSchema(left, right); + return getTypeChangedSchema(left, right, context); } //If schema type is same then get specific SchemaDiffResult and compare the properties SchemaDiffResult result = SchemaDiff.getSchemaDiffResult(right.getClass(), openApiDiff); - return result.diff(refSet, leftComponents, rightComponents, left, right); + return result.diff(refSet, leftComponents, rightComponents, left, right, context); } protected static Schema resolveComposedSchema(Components components, Schema schema) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementDiff.java index 6d93bbaa..b25471c3 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementDiff.java @@ -2,12 +2,15 @@ import com.qdesrame.openapi.diff.model.ChangedSecurityRequirement; import com.qdesrame.openapi.diff.model.ChangedSecurityScheme; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import java.util.*; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 07/01/18. */ @@ -49,7 +52,7 @@ private LinkedHashMap> contains(SecurityRequirement right, return found; } - public Optional diff(SecurityRequirement left, SecurityRequirement right) { + public Optional diff(SecurityRequirement left, SecurityRequirement right, DiffContext context) { ChangedSecurityRequirement changedSecurityRequirement = new ChangedSecurityRequirement(left, right != null ? getCopy(right) : null); @@ -64,13 +67,13 @@ public Optional diff(SecurityRequirement left, Secur String rightSchemeRef = rightSec.keySet().stream().findFirst().get(); right.remove(rightSchemeRef); Optional diff = openApiDiff.getSecuritySchemeDiff() - .diff(leftSchemeRef, left.get(leftSchemeRef), rightSchemeRef, rightSec.get(rightSchemeRef)); + .diff(leftSchemeRef, left.get(leftSchemeRef), rightSchemeRef, rightSec.get(rightSchemeRef), context); diff.ifPresent(changedSecurityRequirement::addChanged); } } right.entrySet().stream().forEach(x -> changedSecurityRequirement.addIncreased(x.getKey(), x.getValue())); - return changedSecurityRequirement.isDiff() ? Optional.of(changedSecurityRequirement) : Optional.empty(); + return isChanged(changedSecurityRequirement); } public static SecurityRequirement getCopy(LinkedHashMap> right) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementsDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementsDiff.java index edbd920d..42dc5e6b 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementsDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/SecurityRequirementsDiff.java @@ -2,6 +2,7 @@ import com.qdesrame.openapi.diff.model.ChangedSecurityRequirement; import com.qdesrame.openapi.diff.model.ChangedSecurityRequirements; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -16,6 +17,8 @@ import java.util.Optional; import java.util.stream.Collectors; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 07/01/18. */ @@ -72,7 +75,7 @@ private Pair getPair(SecurityScheme secu return new ImmutablePair<>(securityScheme.getType(), securityScheme.getIn()); } - protected Optional diff(List left, List right) { + protected Optional diff(List left, List right, DiffContext context) { left = left == null ? new ArrayList<>() : left; right = right == null ? new ArrayList<>() : getCopy(right); @@ -86,13 +89,13 @@ protected Optional diff(List l } else { SecurityRequirement rightSec = rightSecOpt.get(); right.remove(rightSec); - Optional diff = openApiDiff.getSecurityRequirementDiff().diff(leftSecurity, rightSec); + Optional diff = openApiDiff.getSecurityRequirementDiff().diff(leftSecurity, rightSec, context); diff.ifPresent(changedSecurityRequirements::addChanged); } } right.forEach(changedSecurityRequirements::addIncreased); - return changedSecurityRequirements.isDiff() ? Optional.of(changedSecurityRequirements) : Optional.empty(); + return isChanged(changedSecurityRequirements); } private List getCopy(List right) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/SecuritySchemeDiff.java b/src/main/java/com/qdesrame/openapi/diff/compare/SecuritySchemeDiff.java index de752a97..57b09a33 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/SecuritySchemeDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/SecuritySchemeDiff.java @@ -1,6 +1,7 @@ package com.qdesrame.openapi.diff.compare; import com.qdesrame.openapi.diff.model.ChangedSecurityScheme; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.model.ListDiff; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.security.SecurityScheme; @@ -10,6 +11,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + /** * Created by adarsh.sharma on 11/01/18. */ @@ -24,10 +27,10 @@ public SecuritySchemeDiff(OpenApiDiff openApiDiff) { this.rightComponents = openApiDiff.getNewSpecOpenApi() != null ? openApiDiff.getNewSpecOpenApi().getComponents() : null; } - public Optional diff(String leftSchemeRef, List leftScopes, String rightSchemeRef, List rightScopes) { + public Optional diff(String leftSchemeRef, List leftScopes, String rightSchemeRef, List rightScopes, DiffContext context) { SecurityScheme leftSecurityScheme = leftComponents.getSecuritySchemes().get(leftSchemeRef); SecurityScheme rightSecurityScheme = rightComponents.getSecuritySchemes().get(rightSchemeRef); - Optional changedSecuritySchemeOpt = cachedDiff(new HashSet<>(), leftSecurityScheme, rightSecurityScheme, leftSchemeRef, rightSchemeRef); + Optional changedSecuritySchemeOpt = cachedDiff(new HashSet<>(), leftSecurityScheme, rightSecurityScheme, leftSchemeRef, rightSchemeRef, context); ChangedSecurityScheme changedSecurityScheme = changedSecuritySchemeOpt.orElse(new ChangedSecurityScheme(leftSecurityScheme, rightSecurityScheme)); changedSecurityScheme = getCopyWithoutScopes(changedSecurityScheme); @@ -38,11 +41,11 @@ public Optional diff(String leftSchemeRef, List l } } - return changedSecurityScheme.isDiff() ? Optional.of(changedSecurityScheme) : Optional.empty(); + return isChanged(changedSecurityScheme); } @Override - protected Optional computeDiff(HashSet refSet, SecurityScheme leftSecurityScheme, SecurityScheme rightSecurityScheme) { + protected Optional computeDiff(HashSet refSet, SecurityScheme leftSecurityScheme, SecurityScheme rightSecurityScheme, DiffContext context) { ChangedSecurityScheme changedSecurityScheme = new ChangedSecurityScheme(leftSecurityScheme, rightSecurityScheme); changedSecurityScheme.setChangedDescription(!Objects.equals(leftSecurityScheme.getDescription(), rightSecurityScheme.getDescription())); diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ArraySchemaDiffResult.java b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ArraySchemaDiffResult.java index 222aa0a0..02a7deec 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ArraySchemaDiffResult.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ArraySchemaDiffResult.java @@ -2,6 +2,7 @@ import com.qdesrame.openapi.diff.compare.OpenApiDiff; import com.qdesrame.openapi.diff.model.ChangedSchema; +import com.qdesrame.openapi.diff.model.DiffContext; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.Schema; @@ -18,9 +19,9 @@ public ArraySchemaDiffResult(OpenApiDiff openApiDiff) { } @Override - public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right) { + public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right, DiffContext context) { ArraySchema leftArraySchema = (ArraySchema) left; ArraySchema rightArraySchema = (ArraySchema) right; - return openApiDiff.getSchemaDiff().diff(refSet, leftArraySchema.getItems(), rightArraySchema.getItems()); + return openApiDiff.getSchemaDiff().diff(refSet, leftArraySchema.getItems(), rightArraySchema.getItems(), context); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ComposedSchemaDiffResult.java b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ComposedSchemaDiffResult.java index 14e8e9ba..929ef15d 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ComposedSchemaDiffResult.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/ComposedSchemaDiffResult.java @@ -4,6 +4,7 @@ import com.qdesrame.openapi.diff.compare.OpenApiDiff; import com.qdesrame.openapi.diff.model.ChangedOneOfSchema; import com.qdesrame.openapi.diff.model.ChangedSchema; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.utils.RefPointer; import com.qdesrame.openapi.diff.utils.RefType; import io.swagger.v3.oas.models.Components; @@ -29,8 +30,8 @@ public ComposedSchemaDiffResult(OpenApiDiff openApiDiff) { } @Override - public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right) { - if(left instanceof ComposedSchema) { + public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right, DiffContext context) { + if (left instanceof ComposedSchema) { ComposedSchema leftComposedSchema = (ComposedSchema) left; ComposedSchema rightComposedSchema = (ComposedSchema) right; if (CollectionUtils.isNotEmpty(leftComposedSchema.getOneOf()) @@ -51,8 +52,9 @@ public Optional diff(HashSet refSet, Components leftCompo Map leftMapping = getMapping(leftComposedSchema); Map rightMapping = getMapping(rightComposedSchema); - ChangedOneOfSchema changedOneOfSchema = new ChangedOneOfSchema(leftMapping, rightMapping); - MapKeyDiff mappingDiff = MapKeyDiff.diff(leftMapping, rightMapping); + ChangedOneOfSchema changedOneOfSchema = new ChangedOneOfSchema(leftMapping, rightMapping, context); + MapKeyDiff mappingDiff = MapKeyDiff.diff(getSchema(leftComponents, leftMapping), + getSchema(rightComponents, rightMapping)); changedOneOfSchema.setIncreasedMapping(mappingDiff.getIncreased()); changedOneOfSchema.setMissingMapping(mappingDiff.getMissing()); @@ -64,19 +66,23 @@ public Optional diff(HashSet refSet, Components leftCompo leftSchema.set$ref(leftMapping.get(key)); Schema rightSchema = new Schema(); rightSchema.set$ref(rightMapping.get(key)); - Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, leftSchema, rightSchema); - if (changedSchema.isPresent() && changedSchema.get().isDiff()) { - changedMapping.put(key, changedSchema.get()); - } + Optional changedSchema = openApiDiff.getSchemaDiff().diff(refSet, leftSchema, rightSchema, context); + changedSchema.ifPresent(schema -> changedMapping.put(key, schema)); } changedSchema.setChangedOneOfSchema(changedOneOfSchema); } - return super.diff(refSet, leftComponents, rightComponents, left, right); + return super.diff(refSet, leftComponents, rightComponents, left, right, context); } else { - return openApiDiff.getSchemaDiff().getTypeChangedSchema(left, right); + return openApiDiff.getSchemaDiff().getTypeChangedSchema(left, right, context); } } + private Map getSchema(Components components, Map mapping) { + Map result = new HashMap<>(); + mapping.forEach((key, value) -> result.put(key, refPointer.resolveRef(components, new Schema(), value))); + return result; + } + private Map getMapping(ComposedSchema composedSchema) { Map reverseMapping = new HashMap<>(); for (Schema schema : composedSchema.getOneOf()) { diff --git a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/SchemaDiffResult.java b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/SchemaDiffResult.java index d447e52c..3d6e3acc 100644 --- a/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/SchemaDiffResult.java +++ b/src/main/java/com/qdesrame/openapi/diff/compare/schemadiffresult/SchemaDiffResult.java @@ -3,7 +3,10 @@ import com.qdesrame.openapi.diff.compare.MapKeyDiff; import com.qdesrame.openapi.diff.compare.OpenApiDiff; import com.qdesrame.openapi.diff.model.ChangedSchema; +import com.qdesrame.openapi.diff.model.DiffContext; import com.qdesrame.openapi.diff.model.ListDiff; +import com.qdesrame.openapi.diff.model.schema.ChangedReadOnly; +import com.qdesrame.openapi.diff.model.schema.ChangedWriteOnly; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.media.Schema; import lombok.Getter; @@ -13,6 +16,8 @@ import java.util.Objects; import java.util.Optional; +import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged; + @Getter public class SchemaDiffResult { protected ChangedSchema changedSchema; @@ -28,7 +33,8 @@ public SchemaDiffResult(String type, OpenApiDiff openApiDiff) { this.changedSchema.setType(type); } - public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right) { + public Optional diff(HashSet refSet, Components leftComponents, Components rightComponents, Schema left, Schema right, DiffContext context) { + changedSchema.setContext(context); changedSchema.setOldSchema(left); changedSchema.setNewSchema(right); changedSchema.setChangeDeprecated(!Boolean.TRUE.equals(left.getDeprecated()) && Boolean.TRUE.equals(right.getDeprecated())); @@ -38,8 +44,8 @@ public Optional diff(HashSet refSet, Components leftCompo changedSchema.setChangeDefault(!Objects.equals(left.getDefault(), right.getDefault())); changedSchema.setChangeEnum(ListDiff.diff(left.getEnum(), right.getEnum())); changedSchema.setChangeFormat(!Objects.equals(left.getFormat(), right.getFormat())); - changedSchema.setChangeReadOnly(!Boolean.TRUE.equals(left.getReadOnly()) && Boolean.TRUE.equals(right.getReadOnly())); - changedSchema.setChangeWriteOnly(!Boolean.TRUE.equals(left.getWriteOnly()) && Boolean.TRUE.equals(right.getWriteOnly())); + changedSchema.setChangedReadOnly(new ChangedReadOnly(context, left.getReadOnly(), right.getReadOnly())); + changedSchema.setChangedWriteOnly(new ChangedWriteOnly(context, left.getWriteOnly(), right.getWriteOnly())); changedSchema.setChangedMaxLength(!Objects.equals(left.getMaxLength(), right.getMaxLength())); Map leftProperties = null == left ? null : left.getProperties(); @@ -49,36 +55,33 @@ public Optional diff(HashSet refSet, Components leftCompo Map missingProp = propertyDiff.getMissing(); for (String key : propertyDiff.getSharedKey()) { - Optional resultSchema = openApiDiff.getSchemaDiff().diff(refSet, leftProperties.get(key), rightProperties.get(key)); - if (resultSchema.isPresent() && resultSchema.get().isDiff()) { - changedSchema.getChangedProperties().put(key, resultSchema.get()); - } + Optional resultSchema = openApiDiff.getSchemaDiff().diff(refSet, leftProperties.get(key), rightProperties.get(key), context); + resultSchema.ifPresent(changedSchema1 -> changedSchema.getChangedProperties().put(key, changedSchema1)); } - compareAdditionalProperties(refSet, left, right); + compareAdditionalProperties(refSet, left, right, context); changedSchema.getIncreasedProperties().putAll(increasedProp); changedSchema.getMissingProperties().putAll(missingProp); - return changedSchema.isDiff() ? Optional.of(changedSchema) : Optional.empty(); + return isChanged(changedSchema); } - private void compareAdditionalProperties(HashSet refSet, Schema leftSchema, Schema rightSchema) { + private void compareAdditionalProperties(HashSet refSet, Schema leftSchema, Schema rightSchema, DiffContext context) { Object left = leftSchema.getAdditionalProperties(); Object right = rightSchema.getAdditionalProperties(); if ((left != null && left instanceof Schema) || (right != null && right instanceof Schema)) { Schema leftAdditionalSchema = (Schema) left; Schema rightAdditionalSchema = (Schema) right; ChangedSchema apChangedSchema = new ChangedSchema(); + apChangedSchema.setContext(context); apChangedSchema.setOldSchema(leftAdditionalSchema); apChangedSchema.setNewSchema(rightAdditionalSchema); if (left != null && right != null) { Optional addPropChangedSchemaOP - = openApiDiff.getSchemaDiff().diff(refSet, leftAdditionalSchema, rightAdditionalSchema); + = openApiDiff.getSchemaDiff().diff(refSet, leftAdditionalSchema, rightAdditionalSchema, context); apChangedSchema = addPropChangedSchemaOP.orElse(apChangedSchema); } - if (apChangedSchema.isDiff()) { - changedSchema.setAddPropChangedSchema(apChangedSchema); - } + isChanged(apChangedSchema).ifPresent(changedSchema::setAddPropChangedSchema); } } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/Changed.java b/src/main/java/com/qdesrame/openapi/diff/model/Changed.java index 8922201e..70aa8b9c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/Changed.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/Changed.java @@ -1,7 +1,21 @@ package com.qdesrame.openapi.diff.model; public interface Changed { - boolean isDiff(); + DiffResult isChanged(); - boolean isDiffBackwardCompatible(); + default boolean isCompatible() { + return isChanged().isCompatible(); + } + + default boolean isIncompatible() { + return isChanged().isIncompatible(); + } + + default boolean isUnchanged() { + return isChanged().isUnchanged(); + } + + default boolean isDifferent() { + return isChanged().isDifferent(); + } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedApiResponse.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedApiResponse.java index 5d2b2e93..1d98d358 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedApiResponse.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedApiResponse.java @@ -14,28 +14,30 @@ @Getter @Setter public class ChangedApiResponse implements Changed { - private ApiResponses oldApiResponses; - private ApiResponses newApiResponses; + private final ApiResponses oldApiResponses; + private final ApiResponses newApiResponses; + private final DiffContext context; private Map missingResponses; private Map addResponses; private Map changedResponses; - public ChangedApiResponse(ApiResponses oldApiResponses, ApiResponses newApiResponses) { + public ChangedApiResponse(ApiResponses oldApiResponses, ApiResponses newApiResponses, DiffContext context) { this.oldApiResponses = oldApiResponses; this.newApiResponses = newApiResponses; + this.context = context; this.missingResponses = new HashMap<>(); this.addResponses = new HashMap<>(); this.changedResponses = new HashMap<>(); } @Override - public boolean isDiff() { - return !addResponses.isEmpty() || !missingResponses.isEmpty() || !changedResponses.isEmpty(); - } - - @Override - public boolean isDiffBackwardCompatible() { - return addResponses.size() == 0 - && changedResponses.values().stream().allMatch(c -> c.isDiffBackwardCompatible()); + public DiffResult isChanged() { + if (addResponses.size() == 0 && missingResponses.size() == 0 && changedResponses.size() == 0) { + return DiffResult.NO_CHANGES; + } + if (missingResponses.size() == 0 && changedResponses.values().stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedContent.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedContent.java index 2228fe42..fcdb1a9e 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedContent.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedContent.java @@ -13,31 +13,34 @@ */ @Getter @Setter -public class ChangedContent implements RequestResponseChanged { - private Content oldContent; - private Content newContent; +public class ChangedContent implements Changed { + private final Content oldContent; + private final Content newContent; + private final DiffContext context; private Map increased; private Map missing; private Map changed; - public ChangedContent(Content oldContent, Content newContent) { + public ChangedContent(Content oldContent, Content newContent, DiffContext context) { this.oldContent = oldContent; this.newContent = newContent; + this.context = context; this.increased = new HashMap<>(); this.missing = new HashMap<>(); this.changed = new HashMap<>(); } @Override - public boolean isDiff() { - return !increased.isEmpty() || !missing.isEmpty() || !changed.isEmpty(); - } - - @Override - public boolean isDiffBackwardCompatible(boolean isRequest) { - return ((isRequest && missing.isEmpty()) || (!isRequest && increased.isEmpty())) - && changed.values().stream().allMatch(c -> c.isDiffBackwardCompatible(isRequest)); + public DiffResult isChanged() { + if (increased.isEmpty() && missing.isEmpty() && changed.isEmpty()) { + return DiffResult.NO_CHANGES; + } + if (((context.isRequest() && missing.isEmpty()) || (context.isResponse() && increased.isEmpty())) + && changed.values().stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeader.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeader.java index a8d1124d..09ebf99d 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeader.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeader.java @@ -10,8 +10,9 @@ @Getter @Setter public class ChangedHeader implements Changed { - private Header oldHeader; - private Header newHeader; + private final Header oldHeader; + private final Header newHeader; + private final DiffContext context; private boolean changeDescription; private boolean changeRequired; @@ -21,28 +22,25 @@ public class ChangedHeader implements Changed { private ChangedSchema changedSchema; private ChangedContent changedContent; - public ChangedHeader(Header oldHeader, Header newHeader) { + public ChangedHeader(Header oldHeader, Header newHeader, DiffContext context) { this.oldHeader = oldHeader; this.newHeader = newHeader; + this.context = context; } @Override - public boolean isDiff() { - return changeDescription - || changeRequired - || changeDeprecated - || changeStyle - || changeExplode - || (changedSchema != null && changedSchema.isDiff()) - || (changedContent != null && changedContent.isDiff()); + public DiffResult isChanged() { + if (!changeDescription && !changeRequired && !changeDeprecated && !changeStyle && !changeExplode + && (changedSchema == null || changedSchema.isUnchanged()) + && (changedContent == null || changedContent.isUnchanged())) { + return DiffResult.NO_CHANGES; + } + if (!changeRequired && !changeStyle && !changeExplode + && (changedSchema == null || changedSchema.isCompatible()) + && (changedContent == null || changedContent.isCompatible())) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } - @Override - public boolean isDiffBackwardCompatible() { - return changeRequired - && changeStyle - && changeExplode - && (changedSchema == null || changedSchema.isDiffBackwardCompatible(false)) - && (changedContent == null || changedContent.isDiffBackwardCompatible(false)); - } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeaders.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeaders.java index 60eb461f..7824e9d1 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeaders.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedHeaders.java @@ -12,28 +12,28 @@ @Getter @Setter public class ChangedHeaders implements Changed { - private Map oldHeaders; - private Map newHeaders; + private final Map oldHeaders; + private final Map newHeaders; + private final DiffContext context; private Map increased; private Map missing; private Map changed; - public ChangedHeaders(Map oldHeaders, Map newHeaders) { + public ChangedHeaders(Map oldHeaders, Map newHeaders, DiffContext context) { this.oldHeaders = oldHeaders; this.newHeaders = newHeaders; + this.context = context; } @Override - public boolean isDiff() { - return !increased.isEmpty() - || !missing.isEmpty() - || (changed != null && !changed.isEmpty()); - } - - @Override - public boolean isDiffBackwardCompatible() { - return missing.isEmpty() - && (changed == null || changed.values().stream().allMatch(c -> c.isDiffBackwardCompatible())); + public DiffResult isChanged() { + if (increased.isEmpty() && missing.isEmpty() && (changed == null || changed.isEmpty())) { + return DiffResult.NO_CHANGES; + } + if (missing.isEmpty() && (changed == null || changed.values().stream().allMatch(Changed::isCompatible))) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedMediaType.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedMediaType.java index d06f7e0a..3182182b 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedMediaType.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedMediaType.java @@ -6,24 +6,27 @@ @Getter @Setter -public class ChangedMediaType implements RequestResponseChanged { - private Schema oldSchema; - private Schema newSchema; +public class ChangedMediaType implements Changed { + private final Schema oldSchema; + private final Schema newSchema; + private final DiffContext context; private ChangedSchema changedSchema; - public ChangedMediaType(Schema oldSchema, Schema newSchema) { + public ChangedMediaType(Schema oldSchema, Schema newSchema, DiffContext context) { this.oldSchema = oldSchema; this.newSchema = newSchema; + this.context = context; } @Override - public boolean isDiff() { - return (changedSchema != null && changedSchema.isDiff()); - } - - @Override - public boolean isDiffBackwardCompatible(boolean isRequest) { - return (changedSchema == null || changedSchema.isDiffBackwardCompatible(isRequest)); + public DiffResult isChanged() { + if (this.changedSchema == null || this.changedSchema.isUnchanged()) { + return DiffResult.NO_CHANGES; + } + if (this.changedSchema.isCompatible()) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlow.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlow.java index 5469d9f4..9c8c15ac 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlow.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlow.java @@ -23,16 +23,11 @@ public ChangedOAuthFlow(OAuthFlow oldOAuthFlow, OAuthFlow newOAuthFlow) { } @Override - public boolean isDiff() { - return changedAuthorizationUrl || - changedTokenUrl || - changedRefreshUrl; - } - - @Override - public boolean isDiffBackwardCompatible() { - return !changedAuthorizationUrl && - !changedTokenUrl && - !changedRefreshUrl; + public DiffResult isChanged() { + if (!changedAuthorizationUrl && !changedTokenUrl && !changedRefreshUrl) { + return DiffResult.NO_CHANGES; + } else { + return DiffResult.INCOMPATIBLE; + } } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlows.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlows.java index 39f48a42..2c6a8a2b 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlows.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOAuthFlows.java @@ -10,8 +10,8 @@ @Getter @Setter public class ChangedOAuthFlows implements Changed { - private OAuthFlows oldOAuthFlows; - private OAuthFlows newOAuthFlows; + private final OAuthFlows oldOAuthFlows; + private final OAuthFlows newOAuthFlows; private ChangedOAuthFlow changedImplicitOAuthFlow; private ChangedOAuthFlow changedPasswordOAuthFlow; @@ -24,18 +24,20 @@ public ChangedOAuthFlows(OAuthFlows oldOAuthFlows, OAuthFlows newOAuthFlows) { } @Override - public boolean isDiff() { - return (changedImplicitOAuthFlow != null && changedImplicitOAuthFlow.isDiff()) || - (changedPasswordOAuthFlow != null && changedPasswordOAuthFlow.isDiff()) || - (changedClientCredentialOAuthFlow != null && changedClientCredentialOAuthFlow.isDiff()) || - (changedAuthorizationCodeOAuthFlow != null && changedAuthorizationCodeOAuthFlow.isDiff()); + public DiffResult isChanged() { + if ((changedImplicitOAuthFlow == null || changedImplicitOAuthFlow.isUnchanged()) + && (changedPasswordOAuthFlow == null || changedPasswordOAuthFlow.isUnchanged()) + && (changedClientCredentialOAuthFlow == null || changedClientCredentialOAuthFlow.isUnchanged()) + && (changedAuthorizationCodeOAuthFlow == null || changedAuthorizationCodeOAuthFlow.isUnchanged())) { + return DiffResult.NO_CHANGES; + } + if ((changedImplicitOAuthFlow == null || changedImplicitOAuthFlow.isCompatible()) + && (changedPasswordOAuthFlow == null || changedPasswordOAuthFlow.isCompatible()) + && (changedClientCredentialOAuthFlow == null || changedClientCredentialOAuthFlow.isCompatible()) + && (changedAuthorizationCodeOAuthFlow == null || changedAuthorizationCodeOAuthFlow.isCompatible())) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } - @Override - public boolean isDiffBackwardCompatible() { - return (changedImplicitOAuthFlow == null || changedImplicitOAuthFlow.isDiffBackwardCompatible()) && - (changedPasswordOAuthFlow == null || changedPasswordOAuthFlow.isDiffBackwardCompatible()) && - (changedClientCredentialOAuthFlow == null || changedClientCredentialOAuthFlow.isDiffBackwardCompatible()) && - (changedAuthorizationCodeOAuthFlow == null || changedAuthorizationCodeOAuthFlow.isDiffBackwardCompatible()); - } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOneOfSchema.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOneOfSchema.java index 7136cdaf..a9ecbea6 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOneOfSchema.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOneOfSchema.java @@ -1,5 +1,6 @@ package com.qdesrame.openapi.diff.model; +import io.swagger.v3.oas.models.media.Schema; import lombok.Getter; import lombok.Setter; @@ -10,27 +11,30 @@ */ @Getter @Setter -public class ChangedOneOfSchema implements RequestResponseChanged { - private Map oldMapping; - private Map newMapping; +public class ChangedOneOfSchema implements Changed { + private final Map oldMapping; + private final Map newMapping; + private final DiffContext context; - private Map increasedMapping; - private Map missingMapping; + private Map increasedMapping; + private Map missingMapping; private Map changedMapping; - public ChangedOneOfSchema(Map oldMapping, Map newMapping) { + public ChangedOneOfSchema(Map oldMapping, Map newMapping, DiffContext context) { this.oldMapping = oldMapping; this.newMapping = newMapping; + this.context = context; } @Override - public boolean isDiff() { - return increasedMapping.size() > 0 || missingMapping.size() > 0 || changedMapping.size() > 0; - } - - @Override - public boolean isDiffBackwardCompatible(boolean isRequest) { - return ((isRequest && missingMapping.isEmpty()) || (!isRequest && increasedMapping.isEmpty())) - && changedMapping.values().stream().allMatch(m -> m.isDiffBackwardCompatible(isRequest)); + public DiffResult isChanged() { + if (increasedMapping.size() == 0 && missingMapping.size() == 0 && changedMapping.size() == 0) { + return DiffResult.NO_CHANGES; + } + if (((context.isRequest() && missingMapping.isEmpty()) || (context.isResponse() && increasedMapping.isEmpty())) + && changedMapping.values().stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOpenApi.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOpenApi.java index b2625bc0..14f00d9c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOpenApi.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOpenApi.java @@ -23,21 +23,20 @@ public class ChangedOpenApi implements Changed { public List getDeprecatedEndpoints() { return changedOperations.stream() - .filter(c -> c.isDeprecated()) + .filter(ChangedOperation::isDeprecated) .map(c -> EndpointUtils.convert2Endpoint(c.getPathUrl(), c.getHttpMethod(), c.getNewOperation())) .collect(Collectors.toList()); } @Override - public boolean isDiff() { - return newEndpoints.size() > 0 - || missingEndpoints.size() > 0 - || changedOperations.size() > 0; - } - - public boolean isDiffBackwardCompatible() { - return missingEndpoints.size() == 0 - && changedOperations.stream().allMatch(c -> c.isDiffBackwardCompatible()); + public DiffResult isChanged() { + if (newEndpoints.size() == 0 && missingEndpoints.size() == 0 && changedOperations.size() == 0) { + return DiffResult.NO_CHANGES; + } + if (missingEndpoints.size() == 0 && changedOperations.stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOperation.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOperation.java index 96bb345a..a5d7d4fd 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedOperation.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedOperation.java @@ -27,31 +27,32 @@ public ChangedOperation(String pathUrl, PathItem.HttpMethod httpMethod, Operatio } @Override - public boolean isDiff() { - return deprecated || isDiffParam() || isDiffRequest() || isDiffResponse() || isDiffSecurity(); + public DiffResult isChanged() { + //TODO BETTER HANDLING FOR DEPRECIATION + if (!deprecated && isChangedParam().isUnchanged() && isChangedRequest().isUnchanged() + && isChangedResponse().isUnchanged() && isChangedSecurity().isUnchanged()) { + return DiffResult.NO_CHANGES; + } + if (isChangedParam().isCompatible() && isChangedRequest().isCompatible() + && isChangedResponse().isCompatible() && isChangedSecurity().isCompatible()) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } - @Override - public boolean isDiffBackwardCompatible() { - return (changedParameters == null || changedParameters.isDiffBackwardCompatible()) - && (changedRequestBody == null || changedRequestBody.isDiffBackwardCompatible()) - && (changedApiResponse == null || changedApiResponse.isDiffBackwardCompatible()) - && (changedSecurityRequirements == null || changedSecurityRequirements.isDiffBackwardCompatible()); - } - - public boolean isDiffParam() { - return changedParameters != null && changedParameters.isDiff(); + public DiffResult isChangedParam() { + return changedParameters == null ? DiffResult.NO_CHANGES : changedParameters.isChanged(); } - public boolean isDiffResponse() { - return changedApiResponse != null && changedApiResponse.isDiff(); + public DiffResult isChangedResponse() { + return changedApiResponse == null ? DiffResult.NO_CHANGES : changedApiResponse.isChanged(); } - public boolean isDiffRequest() { - return changedRequestBody != null && changedRequestBody.isDiff(); + public DiffResult isChangedRequest() { + return changedRequestBody == null ? DiffResult.NO_CHANGES : changedRequestBody.isChanged(); } - public boolean isDiffSecurity() { - return changedSecurityRequirements != null && changedSecurityRequirements.isDiff(); + public DiffResult isChangedSecurity() { + return changedSecurityRequirements == null ? DiffResult.NO_CHANGES : changedSecurityRequirements.isChanged(); } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameter.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameter.java index 29972fc6..72303d1e 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameter.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameter.java @@ -12,6 +12,7 @@ public class ChangedParameter implements Changed { private String name; private String in; + private final DiffContext context; private boolean changeDescription; private boolean changeRequired; @@ -22,30 +23,32 @@ public class ChangedParameter implements Changed { private ChangedSchema changedSchema; private ChangedContent changedContent; - public ChangedParameter(String name, String in) { + public ChangedParameter(String name, String in, DiffContext context) { this.name = name; this.in = in; + this.context = context; } @Override - public boolean isDiff() { - return changeDescription - || changeRequired - || deprecated - || changeAllowEmptyValue - || changeStyle - || changeExplode - || (changedSchema != null && changedSchema.isDiff()) - || (changedContent != null && changedContent.isDiff()); - } - - @Override - public boolean isDiffBackwardCompatible() { - return (!changeRequired || Boolean.TRUE.equals(oldParameter.getRequired())) + public DiffResult isChanged() { + if (!changeDescription + && !changeRequired + && !deprecated + && !changeAllowEmptyValue + && !changeStyle + && !changeExplode + && (changedSchema == null || changedSchema.isUnchanged()) + && (changedContent == null || changedContent.isUnchanged())) { + return DiffResult.NO_CHANGES; + } + if ((!changeRequired || Boolean.TRUE.equals(oldParameter.getRequired())) && (!changeAllowEmptyValue || Boolean.TRUE.equals(newParameter.getAllowEmptyValue())) && !changeStyle && !changeExplode - && (changedSchema == null || changedSchema.isDiffBackwardCompatible(true)) - && (changedContent == null || changedContent.isDiffBackwardCompatible(true)); + && (changedSchema == null || changedSchema.isCompatible()) + && (changedContent == null || changedContent.isCompatible())) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameters.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameters.java index e4054a58..bc8d1076 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameters.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedParameters.java @@ -10,29 +10,32 @@ @Getter @Setter public class ChangedParameters implements Changed { - private List oldParameterList; - private List newParameterList; + private final List oldParameterList; + private final List newParameterList; + private final DiffContext context; private List increased; private List missing; private List changed; - public ChangedParameters(List oldParameterList, List newParameterList) { + public ChangedParameters(List oldParameterList, List newParameterList, DiffContext context) { this.oldParameterList = oldParameterList; this.newParameterList = newParameterList; + this.context = context; this.increased = new ArrayList<>(); this.missing = new ArrayList<>(); this.changed = new ArrayList<>(); } @Override - public boolean isDiff() { - return !increased.isEmpty() || !missing.isEmpty() || !changed.isEmpty(); - } - - @Override - public boolean isDiffBackwardCompatible() { - return increased.stream().noneMatch(Parameter::getRequired) && missing.isEmpty() - && changed.stream().allMatch(ChangedParameter::isDiffBackwardCompatible); + public DiffResult isChanged() { + if (increased.isEmpty() && missing.isEmpty() && changed.isEmpty()) { + return DiffResult.NO_CHANGES; + } + if (increased.stream().noneMatch(Parameter::getRequired) && missing.isEmpty() + && changed.stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedPath.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedPath.java index 7b44c0b1..fd1fc0c8 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedPath.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedPath.java @@ -13,29 +13,33 @@ @Getter @Setter public class ChangedPath implements Changed { + private final String pathUrl; + private final PathItem oldPath; + private final PathItem newPath; + private final DiffContext context; + Map increased; Map missing; List changed; - private String pathUrl; - private PathItem oldPath; - private PathItem newPath; - public ChangedPath(String pathUrl, PathItem oldPath, PathItem newPath) { + public ChangedPath(String pathUrl, PathItem oldPath, PathItem newPath, DiffContext context) { this.pathUrl = pathUrl; this.oldPath = oldPath; this.newPath = newPath; + this.context = context; this.increased = new LinkedHashMap<>(); this.missing = new LinkedHashMap<>(); this.changed = new ArrayList<>(); } @Override - public boolean isDiff() { - return !increased.isEmpty() || !missing.isEmpty() || !changed.isEmpty(); - } - - @Override - public boolean isDiffBackwardCompatible() { - return missing.isEmpty() && changed.stream().allMatch(ChangedOperation::isDiffBackwardCompatible); + public DiffResult isChanged() { + if (increased.isEmpty() && missing.isEmpty() && changed.isEmpty()) { + return DiffResult.NO_CHANGES; + } + if (missing.isEmpty() && changed.stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedPaths.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedPaths.java index 6ee8357d..4fa4a83c 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedPaths.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedPaths.java @@ -10,8 +10,8 @@ @Getter @Setter public class ChangedPaths implements Changed { - private Map oldPathMap; - private Map newPathMap; + private final Map oldPathMap; + private final Map newPathMap; private Map increased; private Map missing; @@ -26,12 +26,13 @@ public ChangedPaths(Map oldPathMap, Map newP } @Override - public boolean isDiff() { - return !increased.isEmpty() || !missing.isEmpty() || !changed.isEmpty(); - } - - @Override - public boolean isDiffBackwardCompatible() { - return missing.isEmpty() && changed.values().stream().allMatch(ChangedPath::isDiffBackwardCompatible); + public DiffResult isChanged() { + if (increased.isEmpty() && missing.isEmpty() && changed.isEmpty()) { + return DiffResult.NO_CHANGES; + } + if (missing.isEmpty() && changed.values().stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedRequestBody.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedRequestBody.java index 2e7618eb..cf481cd7 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedRequestBody.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedRequestBody.java @@ -10,24 +10,28 @@ @Getter @Setter public class ChangedRequestBody implements Changed { - private RequestBody oldRequestBody; - private RequestBody newRequestBody; + private final RequestBody oldRequestBody; + private final RequestBody newRequestBody; + private final DiffContext context; + private boolean changeDescription; private boolean changeRequired; private ChangedContent changedContent; - public ChangedRequestBody(RequestBody oldRequestBody, RequestBody newRequestBody) { + public ChangedRequestBody(RequestBody oldRequestBody, RequestBody newRequestBody, DiffContext context) { this.oldRequestBody = oldRequestBody; this.newRequestBody = newRequestBody; + this.context = context; } @Override - public boolean isDiff() { - return changeDescription || changeRequired || (changedContent != null && changedContent.isDiff()); - } - - @Override - public boolean isDiffBackwardCompatible() { - return !changeRequired && (changedContent == null || changedContent.isDiffBackwardCompatible(true)); + public DiffResult isChanged() { + if (!changeDescription && !changeRequired && (changedContent == null || changedContent.isUnchanged())) { + return DiffResult.NO_CHANGES; + } + if (!changeRequired && (changedContent == null || changedContent.isCompatible())) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedResponse.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedResponse.java index 762e9fb8..f4805d1b 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedResponse.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedResponse.java @@ -1,5 +1,6 @@ package com.qdesrame.openapi.diff.model; +import com.qdesrame.openapi.diff.utils.ChangedUtils; import io.swagger.v3.oas.models.responses.ApiResponse; import lombok.Getter; import lombok.Setter; @@ -7,28 +8,28 @@ @Getter @Setter public class ChangedResponse implements Changed { - private ApiResponse oldApiResponse; - private ApiResponse newApiResponse; + private final ApiResponse oldApiResponse; + private final ApiResponse newApiResponse; + private final DiffContext context; private boolean changeDescription; private ChangedHeaders changedHeaders; private ChangedContent changedContent; - public ChangedResponse(ApiResponse oldApiResponse, ApiResponse newApiResponse) { + public ChangedResponse(ApiResponse oldApiResponse, ApiResponse newApiResponse, DiffContext context) { this.oldApiResponse = oldApiResponse; this.newApiResponse = newApiResponse; + this.context = context; } @Override - public boolean isDiff() { - return changeDescription - ||(changedContent != null && changedContent.isDiff()) - || (changedHeaders != null && changedHeaders.isDiff()); - } - - @Override - public boolean isDiffBackwardCompatible() { - return (changedContent == null || changedContent.isDiffBackwardCompatible(false)) - && (changedHeaders == null || changedHeaders.isDiffBackwardCompatible()); + public DiffResult isChanged() { + if (!changeDescription && ChangedUtils.isUnchanged(changedContent) && ChangedUtils.isUnchanged(changedHeaders)) { + return DiffResult.NO_CHANGES; + } + if (ChangedUtils.isCompatible(changedContent) && ChangedUtils.isCompatible(changedHeaders)) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSchema.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSchema.java index 2c74f05e..b7c07956 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSchema.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSchema.java @@ -1,5 +1,8 @@ package com.qdesrame.openapi.diff.model; +import com.qdesrame.openapi.diff.model.schema.ChangedReadOnly; +import com.qdesrame.openapi.diff.model.schema.ChangedWriteOnly; +import com.qdesrame.openapi.diff.utils.ChangedUtils; import io.swagger.v3.oas.models.media.Schema; import lombok.Getter; import lombok.Setter; @@ -13,7 +16,8 @@ */ @Getter @Setter -public class ChangedSchema implements RequestResponseChanged { +public class ChangedSchema implements Changed { + protected DiffContext context; protected Schema oldSchema; protected Schema newSchema; protected String type; @@ -27,8 +31,8 @@ public class ChangedSchema implements RequestResponseChanged { protected boolean changeDefault; protected ListDiff changeEnum; protected boolean changeFormat; - protected boolean changeReadOnly; - protected boolean changeWriteOnly; + protected ChangedReadOnly changedReadOnly; + protected ChangedWriteOnly changedWriteOnly; protected boolean changedType; protected boolean changedMaxLength; protected boolean discriminatorPropertyChanged; @@ -42,33 +46,21 @@ public ChangedSchema() { } @Override - public boolean isDiff() { - return Boolean.TRUE.equals(changedType) - || (oldSchema != null && newSchema == null) - || (oldSchema == null && newSchema != null) - || changeWriteOnly - || changedMaxLength - || changeReadOnly - || (changeEnum != null && (changeEnum.getIncreased().size() > 0 || changeEnum.getMissing().size() > 0)) - || changeFormat - || increasedProperties.size() > 0 - || missingProperties.size() > 0 - || changedProperties.size() > 0 - || changeDeprecated - || (changeRequired != null && changeRequired.getIncreased().size() > 0) - || (changeRequired != null && changeRequired.getMissing().size() > 0) - || discriminatorPropertyChanged - || (addPropChangedSchema != null) - || (changedOneOfSchema != null && changedOneOfSchema.isDiff()); - } - - @Override - public boolean isDiffBackwardCompatible(boolean isRequest) { + public DiffResult isChanged() { + if (!changedType && (oldSchema == null && newSchema == null || oldSchema != null && newSchema != null) + && ChangedUtils.isUnchanged(changedWriteOnly) && ChangedUtils.isUnchanged(changedReadOnly) + && !changedMaxLength && (changeEnum == null || changeEnum.isUnchanged()) + && !changeFormat && increasedProperties.size() == 0 && missingProperties.size() == 0 + && changedProperties.values().size() == 0 && !changeDeprecated + && (changeRequired == null || changeRequired.isUnchanged()) && !discriminatorPropertyChanged + && ChangedUtils.isUnchanged(addPropChangedSchema) && ChangedUtils.isUnchanged(changedOneOfSchema)) { + return DiffResult.NO_CHANGES; + } boolean backwardCompatibleForRequest = (changeEnum == null || changeEnum.getMissing().isEmpty()) && (changeRequired == null || CollectionUtils.isEmpty(changeRequired.getIncreased())) && (oldSchema != null || newSchema == null) && (!changedMaxLength || newSchema.getMaxLength() == null || - (oldSchema.getMaxLength() != null && oldSchema.getMaxLength()<= newSchema.getMaxLength())); + (oldSchema.getMaxLength() != null && oldSchema.getMaxLength() <= newSchema.getMaxLength())); boolean backwardCompatibleForResponse = (changeEnum == null || changeEnum.getIncreased().isEmpty()) && missingProperties.isEmpty() && @@ -76,11 +68,13 @@ public boolean isDiffBackwardCompatible(boolean isRequest) { (!changedMaxLength || oldSchema.getMaxLength() == null || (newSchema.getMaxLength() != null && newSchema.getMaxLength() <= oldSchema.getMaxLength())); - return (isRequest && backwardCompatibleForRequest || !isRequest && backwardCompatibleForResponse ) - && !changedType - && !discriminatorPropertyChanged - && (changedOneOfSchema == null || changedOneOfSchema.isDiffBackwardCompatible(isRequest)) - && (addPropChangedSchema == null || addPropChangedSchema.isDiffBackwardCompatible(isRequest)) - && changedProperties.values().stream().allMatch(p -> p.isDiffBackwardCompatible(isRequest)); + if ((context.isRequest() && backwardCompatibleForRequest || context.isResponse() && backwardCompatibleForResponse) + && !changedType && !discriminatorPropertyChanged && ChangedUtils.isCompatible(changedOneOfSchema) + && ChangedUtils.isCompatible(addPropChangedSchema) + && changedProperties.values().stream().allMatch(Changed::isCompatible)) { + return DiffResult.COMPATIBLE; + } + + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirement.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirement.java index d14defa2..71773808 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirement.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirement.java @@ -27,32 +27,32 @@ public ChangedSecurityRequirement(SecurityRequirement oldSecurityRequirement, Se } @Override - public boolean isDiff() { - return missing != null || increased != null || CollectionUtils.isNotEmpty(changed); - } - - @Override - public boolean isDiffBackwardCompatible() { - return increased == null && - (changed == null || changed.stream().allMatch(x -> x.isDiffBackwardCompatible())); + public DiffResult isChanged() { + if (missing == null && increased == null && CollectionUtils.isEmpty(changed)) { + return DiffResult.NO_CHANGES; + } + if (increased == null && (changed == null || changed.stream().allMatch(Changed::isCompatible))) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } public void addMissing(String key, List scopes) { - if(missing == null) { + if (missing == null) { missing = new SecurityRequirement(); } missing.put(key, scopes); } public void addIncreased(String key, List scopes) { - if(increased == null) { + if (increased == null) { increased = new SecurityRequirement(); } increased.put(key, scopes); } public void addChanged(ChangedSecurityScheme changedSecurityScheme) { - if(changed == null) { + if (changed == null) { changed = new ArrayList<>(); } changed.add(changedSecurityScheme); diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirements.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirements.java index b1353291..d18f22e2 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirements.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityRequirements.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import lombok.Getter; import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; import java.util.ArrayList; import java.util.List; @@ -27,16 +28,14 @@ public ChangedSecurityRequirements(List oldSecurityRequirem } @Override - public boolean isDiff() { - return (missing != null && !missing.isEmpty()) || - (increased != null && !increased.isEmpty()) || - (changed != null && changed.stream().anyMatch(x -> x.isDiff())); - } - - @Override - public boolean isDiffBackwardCompatible() { - return (missing == null || missing.isEmpty()) && - (changed == null || changed.stream().allMatch(x -> x.isDiffBackwardCompatible())); + public DiffResult isChanged() { + if (CollectionUtils.isEmpty(missing) && CollectionUtils.isEmpty(increased) && CollectionUtils.isEmpty(changed)) { + return DiffResult.NO_CHANGES; + } + if (CollectionUtils.isEmpty(missing) && (changed == null || changed.stream().allMatch(Changed::isCompatible))) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } public void addMissing(SecurityRequirement securityRequirement) { diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityScheme.java b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityScheme.java index 75387afc..06843086 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityScheme.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ChangedSecurityScheme.java @@ -1,5 +1,6 @@ package com.qdesrame.openapi.diff.model; +import com.qdesrame.openapi.diff.utils.ChangedUtils; import io.swagger.v3.oas.models.security.SecurityScheme; import lombok.Getter; import lombok.Setter; @@ -27,25 +28,17 @@ public ChangedSecurityScheme(SecurityScheme oldSecurityScheme, SecurityScheme ne } @Override - public boolean isDiff() { - return changedType || - changedDescription || - changedIn || - changedScheme || - changedBearerFormat || - (changedOAuthFlows != null && changedOAuthFlows.isDiff()) || - changedOpenIdConnectUrl || - changedScopes != null; - } - - @Override - public boolean isDiffBackwardCompatible() { - return !changedType && - !changedIn && - !changedScheme && - !changedBearerFormat && - (changedOAuthFlows == null || changedOAuthFlows.isDiffBackwardCompatible()) && - !changedOpenIdConnectUrl && - (changedScopes == null || changedScopes.getIncreased().isEmpty()); + public DiffResult isChanged() { + if (!changedType && !changedDescription && !changedIn && !changedScheme && !changedBearerFormat + && ChangedUtils.isUnchanged(changedOAuthFlows) && !changedOpenIdConnectUrl + && (changedScopes == null || changedScopes.isUnchanged())) { + return DiffResult.NO_CHANGES; + } + if (!changedType && !changedIn && !changedScheme && !changedBearerFormat + && ChangedUtils.isCompatible(changedOAuthFlows) && !changedOpenIdConnectUrl + && (changedScopes == null || changedScopes.getIncreased().isEmpty())) { + return DiffResult.COMPATIBLE; + } + return DiffResult.INCOMPATIBLE; } } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/DiffContext.java b/src/main/java/com/qdesrame/openapi/diff/model/DiffContext.java new file mode 100644 index 00000000..12392a6e --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/model/DiffContext.java @@ -0,0 +1,123 @@ +package com.qdesrame.openapi.diff.model; + +import io.swagger.v3.oas.models.PathItem; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Quentin Desramé on 04/04/17. + */ +public class DiffContext { + + private String url; + private Map parameters; + private PathItem.HttpMethod method; + private boolean response; + private boolean request; + + public DiffContext() { + parameters = new HashMap<>(); + response = false; + request = true; + } + + public DiffContext copyWithMethod(PathItem.HttpMethod method) { + return copy().setMethod(method); + } + + public DiffContext copyAsRequest() { + return copy().setRequest(); + } + + public DiffContext copyAsResponse() { + return copy().setResponse(); + } + + private DiffContext setRequest() { + this.request = true; + this.response = false; + return this; + } + + private DiffContext setResponse() { + this.response = true; + this.request = false; + return this; + } + + public boolean isResponse() { + return this.response; + } + + public boolean isRequest() { + return this.request; + } + + public String getUrl() { + return url; + } + + public DiffContext setUrl(String url) { + this.url = url; + return this; + } + + public PathItem.HttpMethod getMethod() { + return method; + } + + private DiffContext setMethod(PathItem.HttpMethod method) { + this.method = method; + return this; + } + + private DiffContext copy() { + DiffContext context = new DiffContext(); + context.url = this.url; + context.parameters = this.parameters; + context.method = this.method; + context.response = this.response; + context.request = this.request; + return context; + } + + public Map getParameters() { + return parameters; + } + + public DiffContext setParameters(Map parameters) { + this.parameters = parameters; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + DiffContext that = (DiffContext) o; + + return new EqualsBuilder() + .append(response, that.response) + .append(request, that.request) + .append(url, that.url) + .append(parameters, that.parameters) + .append(method, that.method) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(url) + .append(parameters) + .append(method) + .append(response) + .append(request) + .toHashCode(); + } +} diff --git a/src/main/java/com/qdesrame/openapi/diff/model/DiffResult.java b/src/main/java/com/qdesrame/openapi/diff/model/DiffResult.java new file mode 100644 index 00000000..f9ece275 --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/model/DiffResult.java @@ -0,0 +1,34 @@ +package com.qdesrame.openapi.diff.model; + +public enum DiffResult { + NO_CHANGES("no_changes"), + COMPATIBLE("compatible"), + INCOMPATIBLE("incompatible"), + UNKNOWN("unknown"); + + private final String value; + + DiffResult(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public boolean isUnchanged() { + return this.equals(NO_CHANGES); + } + + public boolean isDifferent() { + return !this.equals(NO_CHANGES); + } + + public boolean isIncompatible() { + return !this.equals(NO_CHANGES) && !this.equals(COMPATIBLE); + } + + public boolean isCompatible() { + return this.equals(NO_CHANGES) || this.equals(COMPATIBLE); + } +} diff --git a/src/main/java/com/qdesrame/openapi/diff/model/ListDiff.java b/src/main/java/com/qdesrame/openapi/diff/model/ListDiff.java index 701944f0..d6faab83 100644 --- a/src/main/java/com/qdesrame/openapi/diff/model/ListDiff.java +++ b/src/main/java/com/qdesrame/openapi/diff/model/ListDiff.java @@ -44,4 +44,8 @@ public static ListDiff diff(List left, List right) { return instance; } + public boolean isUnchanged() { + return missing.size() == 0 && increased.size() == 0; + } + } diff --git a/src/main/java/com/qdesrame/openapi/diff/model/RequestResponseChanged.java b/src/main/java/com/qdesrame/openapi/diff/model/RequestResponseChanged.java deleted file mode 100644 index b6b0786a..00000000 --- a/src/main/java/com/qdesrame/openapi/diff/model/RequestResponseChanged.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.qdesrame.openapi.diff.model; - -/** - * Created by adarsh.sharma on 24/12/17. - */ -public interface RequestResponseChanged { - boolean isDiff(); - boolean isDiffBackwardCompatible(boolean isRequest); -} diff --git a/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedReadOnly.java b/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedReadOnly.java new file mode 100644 index 00000000..e01c1f6d --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedReadOnly.java @@ -0,0 +1,40 @@ +package com.qdesrame.openapi.diff.model.schema; + +import com.qdesrame.openapi.diff.model.Changed; +import com.qdesrame.openapi.diff.model.DiffContext; +import com.qdesrame.openapi.diff.model.DiffResult; + +import java.util.Objects; +import java.util.Optional; + +public class ChangedReadOnly implements Changed { + private final DiffContext context; + private final boolean oldValue; + private final boolean newValue; +// private final boolean required; + + public ChangedReadOnly(DiffContext context, Boolean oldValue, Boolean newValue) { + this.context = context; + this.oldValue = Optional.ofNullable(oldValue).orElse(false); + this.newValue = Optional.ofNullable(newValue).orElse(false); +// this.required = required; + } + + @Override + public DiffResult isChanged() { + if (Objects.equals(oldValue, newValue)) { + return DiffResult.NO_CHANGES; + } + if (context.isResponse()) { + return DiffResult.COMPATIBLE; + } + if (context.isRequest()) { + if (Boolean.TRUE.equals(newValue)) { + return DiffResult.COMPATIBLE; + } else { + return DiffResult.INCOMPATIBLE; + } + } + return DiffResult.UNKNOWN; + } +} diff --git a/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedWriteOnly.java b/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedWriteOnly.java new file mode 100644 index 00000000..148b8485 --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/model/schema/ChangedWriteOnly.java @@ -0,0 +1,40 @@ +package com.qdesrame.openapi.diff.model.schema; + +import com.qdesrame.openapi.diff.model.Changed; +import com.qdesrame.openapi.diff.model.DiffContext; +import com.qdesrame.openapi.diff.model.DiffResult; + +import java.util.Objects; +import java.util.Optional; + +public class ChangedWriteOnly implements Changed { + private final DiffContext context; + private final boolean oldValue; + private final boolean newValue; +// private final boolean required; + + public ChangedWriteOnly(DiffContext context, Boolean oldValue, Boolean newValue) { + this.context = context; + this.oldValue = Optional.ofNullable(oldValue).orElse(false); + this.newValue = Optional.ofNullable(newValue).orElse(false); +// this.required = required; + } + + @Override + public DiffResult isChanged() { + if (Objects.equals(oldValue, newValue)) { + return DiffResult.NO_CHANGES; + } + if (context.isRequest()) { + return DiffResult.COMPATIBLE; + } + if (context.isResponse()) { + if (Boolean.TRUE.equals(newValue)) { + return DiffResult.INCOMPATIBLE; + } else { + return DiffResult.COMPATIBLE; + } + } + return DiffResult.UNKNOWN; + } +} diff --git a/src/main/java/com/qdesrame/openapi/diff/output/ConsoleRender.java b/src/main/java/com/qdesrame/openapi/diff/output/ConsoleRender.java index 45c391a5..2abcb5ff 100644 --- a/src/main/java/com/qdesrame/openapi/diff/output/ConsoleRender.java +++ b/src/main/java/com/qdesrame/openapi/diff/output/ConsoleRender.java @@ -17,7 +17,7 @@ public class ConsoleRender implements Render { @Override public String render(ChangedOpenApi diff) { output = new StringBuilder(); - if (!diff.isDiff()) { + if (diff.isUnchanged()) { output.append("No differences. Specifications are equivalents"); } else { output.append(bigTitle("Api Change Log")) @@ -39,7 +39,7 @@ public String render(ChangedOpenApi diff) { output .append(renderBody(ol_newEndpoint, ol_missingEndpoint, ol_deprecatedEndpoint, ol_changed)) .append(title("Result")) - .append(StringUtils.center(diff.isDiffBackwardCompatible() ? + .append(StringUtils.center(diff.isCompatible() ? "API changes are backward compatible" : "API changes broke backward compatibility", LINE_LENGTH)) .append(System.lineSeparator()) .append(separator('-')); @@ -57,17 +57,17 @@ private String ol_changed(List operations) { String desc = operation.getSummary(); StringBuilder ul_detail = new StringBuilder(); - if (operation.isDiffParam()) { + if (operation.isChangedParam().isDifferent()) { ul_detail.append(StringUtils.repeat(' ', 2)).append("Parameter:") .append(System.lineSeparator()) .append(ul_param(operation.getChangedParameters())); } - if (operation.isDiffRequest()) { + if (operation.isChangedRequest().isDifferent()) { ul_detail.append(StringUtils.repeat(' ', 2)).append("Request:") .append(System.lineSeparator()) .append(ul_content(operation.getChangedRequestBody().getChangedContent(), true)); } - if (operation.isDiffResponse()) { + if (operation.isChangedResponse().isDifferent()) { ul_detail.append(StringUtils.repeat(' ', 2)).append("Return Type:") .append(System.lineSeparator()) .append(ul_response(operation.getChangedApiResponse())); @@ -142,8 +142,7 @@ private String itemContent(String title, String contentType, ChangedMediaType ch sb.append(itemContent(title, contentType)) .append(StringUtils.repeat(' ', 10)) .append("Schema: ") - .append(changedMediaType.isDiffBackwardCompatible(isRequest) ? - "Backward compatible" : "Broken compatibility") + .append(changedMediaType.isCompatible() ? "Backward compatible" : "Broken compatibility") .append(System.lineSeparator()); return sb.toString(); } diff --git a/src/main/java/com/qdesrame/openapi/diff/output/HtmlRender.java b/src/main/java/com/qdesrame/openapi/diff/output/HtmlRender.java index c6c30c49..007033df 100644 --- a/src/main/java/com/qdesrame/openapi/diff/output/HtmlRender.java +++ b/src/main/java/com/qdesrame/openapi/diff/output/HtmlRender.java @@ -121,14 +121,14 @@ private ContainerTag ol_changed(List changedOperations) { String desc = changedOperation.getSummary(); ContainerTag ul_detail = ul().withClass("detail"); - if (changedOperation.isDiffParam()) { + if (changedOperation.isChangedParam().isDifferent()) { ul_detail.with(li().with(h3("Parameters")).with(ul_param(changedOperation.getChangedParameters()))); } - if (changedOperation.isDiffRequest()) { + if (changedOperation.isChangedRequest().isDifferent()) { ul_detail.with(li().with(h3("Request")).with(ul_request(changedOperation.getChangedRequestBody().getChangedContent()))); } else { } - if (changedOperation.isDiffResponse()) { + if (changedOperation.isChangedResponse().isDifferent()) { ul_detail.with(li().with(h3("Response")).with(ul_response(changedOperation.getChangedApiResponse()))); } ol.with(li().with(span(method).withClass(method)).withText(pathUrl + " ").with(span(desc)) diff --git a/src/main/java/com/qdesrame/openapi/diff/output/MarkdownRender.java b/src/main/java/com/qdesrame/openapi/diff/output/MarkdownRender.java index ac805e23..fc4584c4 100644 --- a/src/main/java/com/qdesrame/openapi/diff/output/MarkdownRender.java +++ b/src/main/java/com/qdesrame/openapi/diff/output/MarkdownRender.java @@ -81,13 +81,13 @@ private String listEndpoints(List changedOperations) { changedOperations.stream().map(operation -> { StringBuilder details = new StringBuilder() .append(itemEndpoint(operation.getHttpMethod().toString(), operation.getPathUrl(), operation.getSummary())); - if (operation.isDiffParam()) { + if (operation.isChangedParam().isDifferent()) { details.append(titleH5("Parameters:")).append(parameters(operation.getChangedParameters())); } - if (operation.isDiffRequest()) { + if (operation.isChangedRequest().isDifferent()) { details.append(titleH5("Request:")).append(bodyContent(operation.getChangedRequestBody().getChangedContent())); } - if (operation.isDiffResponse()) { + if (operation.isChangedResponse().isDifferent()) { details.append(titleH5("Return Type:")).append(responses(operation.getChangedApiResponse())); } return details.toString(); @@ -216,13 +216,28 @@ private String schema(ChangedSchema schema) { return schema(1, schema); } + private String oneOfSchema(int deepness, ChangedOneOfSchema schema, String discriminator) { + StringBuilder sb = new StringBuilder(""); + sb.append(format("%sSwitch `%s`:\n", indent(deepness), discriminator)); + schema.getMissingMapping().keySet() + .forEach(key -> sb.append(format("%s- Removed '%s'\n", indent(deepness), key))); + schema.getIncreasedMapping().forEach((key, sub) -> + sb.append(format("%s- Added '%s':\n", indent(deepness), key)).append(schema(deepness + 1, sub))); + schema.getChangedMapping().forEach((key, sub) -> + sb.append(format("%s- Updated `%s`:\n", indent(deepness), key)) + .append(schema(deepness + 1, sub))); + return sb.toString(); + } + private String schema(int deepness, ChangedSchema schema) { StringBuilder sb = new StringBuilder(""); if (schema.isDiscriminatorPropertyChanged()) { LOGGER.debug("Discriminator property changed"); } if (schema.getChangedOneOfSchema() != null) { - LOGGER.debug("One of schema changed"); + String discriminator = schema.getNewSchema().getDiscriminator() != null ? + schema.getNewSchema().getDiscriminator().getPropertyName() : ""; + sb.append(oneOfSchema(deepness, schema.getChangedOneOfSchema(), discriminator)); } sb.append(listDiff(deepness, "enum", schema.getChangeEnum())); sb.append(properties(deepness, "Added property", schema.getIncreasedProperties(), true)); @@ -239,6 +254,13 @@ private String schema(int deepness, ComposedSchema schema) { .map(this::resolve) .forEach(composedChild -> sb.append(schema(deepness, composedChild))); } + if (schema.getOneOf() != null && schema.getOneOf() != null) { + LOGGER.debug("One of schema"); + sb.append(format("%sOne of:\n\n", indent(deepness))); + schema.getOneOf().stream() + .map(this::resolve) + .forEach(composedChild -> sb.append(schema(deepness + 1, composedChild))); + } return sb.toString(); } diff --git a/src/main/java/com/qdesrame/openapi/diff/utils/ChangedUtils.java b/src/main/java/com/qdesrame/openapi/diff/utils/ChangedUtils.java new file mode 100644 index 00000000..36e8c0c9 --- /dev/null +++ b/src/main/java/com/qdesrame/openapi/diff/utils/ChangedUtils.java @@ -0,0 +1,23 @@ +package com.qdesrame.openapi.diff.utils; + +import com.qdesrame.openapi.diff.model.Changed; + +import java.util.Optional; + +public class ChangedUtils { + + public static boolean isUnchanged(Changed changed) { + return changed == null || changed.isUnchanged(); + } + + public static boolean isCompatible(Changed changed) { + return changed == null || changed.isCompatible(); + } + + public static Optional isChanged(T changed) { + if (isUnchanged(changed)) { + return Optional.empty(); + } + return Optional.of(changed); + } +} diff --git a/src/test/java/com/qdesrame/openapi/test/BackwardCompatibilityTest.java b/src/test/java/com/qdesrame/openapi/test/BackwardCompatibilityTest.java index 7a40eefc..b0dca557 100644 --- a/src/test/java/com/qdesrame/openapi/test/BackwardCompatibilityTest.java +++ b/src/test/java/com/qdesrame/openapi/test/BackwardCompatibilityTest.java @@ -13,6 +13,7 @@ public class BackwardCompatibilityTest { private final String OPENAPI_DOC2 = "backwardCompatibility/bc_2.yaml"; private final String OPENAPI_DOC3 = "backwardCompatibility/bc_3.yaml"; private final String OPENAPI_DOC4 = "backwardCompatibility/bc_4.yaml"; + private final String OPENAPI_DOC5 = "backwardCompatibility/bc_5.yaml"; @Test public void testNoChange() { @@ -43,4 +44,9 @@ public void testApiChangedOperationMissing() { public void testApiOperationChanged() { assertOpenApiBackwardCompatible(OPENAPI_DOC2, OPENAPI_DOC4, true); } + + @Test + public void testApiReadWriteOnlyPropertiesChanged() { + assertOpenApiBackwardCompatible(OPENAPI_DOC1, OPENAPI_DOC5, true); + } } diff --git a/src/test/java/com/qdesrame/openapi/test/ResponseHeaderDiffTest.java b/src/test/java/com/qdesrame/openapi/test/ResponseHeaderDiffTest.java index dd0c66d6..3d172ec6 100644 --- a/src/test/java/com/qdesrame/openapi/test/ResponseHeaderDiffTest.java +++ b/src/test/java/com/qdesrame/openapi/test/ResponseHeaderDiffTest.java @@ -29,7 +29,7 @@ public void testDiffDifferent() { Assert.assertTrue(changedResponses.size() > 0); Assert.assertTrue(changedResponses.containsKey("200")); ChangedHeaders changedHeaders = changedResponses.get("200").getChangedHeaders(); - Assert.assertTrue(changedHeaders.isDiff()); + Assert.assertTrue(changedHeaders.isDifferent()); Assert.assertTrue(changedHeaders.getChanged().size() == 1); Assert.assertTrue(changedHeaders.getIncreased().size() == 1); Assert.assertTrue(changedHeaders.getMissing().size() == 1); diff --git a/src/test/java/com/qdesrame/openapi/test/SecurityDiffTest.java b/src/test/java/com/qdesrame/openapi/test/SecurityDiffTest.java index ae348999..4c97b087 100644 --- a/src/test/java/com/qdesrame/openapi/test/SecurityDiffTest.java +++ b/src/test/java/com/qdesrame/openapi/test/SecurityDiffTest.java @@ -24,10 +24,10 @@ public void testDiffDifferent() { ChangedOperation changedOperation1 = changedOpenApi.getChangedOperations().stream().filter(x -> x.getPathUrl().equals("/pet/{petId}")).findFirst().get(); assertNotNull(changedOperation1); - assertFalse(changedOperation1.isDiffBackwardCompatible()); + assertFalse(changedOperation1.isCompatible()); ChangedSecurityRequirements changedSecurityRequirements1 = changedOperation1.getChangedSecurityRequirements(); assertNotNull(changedSecurityRequirements1); - assertFalse(changedSecurityRequirements1.isDiffBackwardCompatible()); + assertFalse(changedSecurityRequirements1.isCompatible()); assertTrue(changedSecurityRequirements1.getIncreased().size() == 1); assertTrue(changedSecurityRequirements1.getChanged().size() == 1); ChangedSecurityRequirement changedSecurityRequirement1 = changedSecurityRequirements1.getChanged().get(0); @@ -39,10 +39,10 @@ public void testDiffDifferent() { ChangedOperation changedOperation2 = changedOpenApi.getChangedOperations().stream().filter(x -> x.getPathUrl().equals("/pet3")).findFirst().get(); assertNotNull(changedOperation2); - assertFalse(changedOperation2.isDiffBackwardCompatible()); + assertFalse(changedOperation2.isCompatible()); ChangedSecurityRequirements changedSecurityRequirements2 = changedOperation2.getChangedSecurityRequirements(); assertNotNull(changedSecurityRequirements2); - assertFalse(changedSecurityRequirements2.isDiffBackwardCompatible()); + assertFalse(changedSecurityRequirements2.isCompatible()); assertTrue(changedSecurityRequirements2.getChanged().size() == 1); ChangedSecurityRequirement changedSecurityRequirement2 = changedSecurityRequirements2.getChanged().get(0); assertTrue(changedSecurityRequirement2.getChanged().size() == 1); @@ -52,7 +52,7 @@ public void testDiffDifferent() { ChangedOperation changedOperation3 = changedOpenApi.getChangedOperations().stream().filter(x -> x.getPathUrl().equals("/pet/findByStatus2")).findFirst().get(); assertNotNull(changedOperation3); - assertTrue(changedOperation3.isDiffBackwardCompatible()); + assertTrue(changedOperation3.isCompatible()); ChangedSecurityRequirements changedSecurityRequirements3 = changedOperation3.getChangedSecurityRequirements(); assertNotNull(changedSecurityRequirements3); assertTrue(changedSecurityRequirements3.getIncreased().size() == 1); diff --git a/src/test/java/com/qdesrame/openapi/test/TestUtils.java b/src/test/java/com/qdesrame/openapi/test/TestUtils.java index 7286b742..f6b4bcfc 100644 --- a/src/test/java/com/qdesrame/openapi/test/TestUtils.java +++ b/src/test/java/com/qdesrame/openapi/test/TestUtils.java @@ -3,12 +3,16 @@ import com.qdesrame.openapi.diff.OpenApiCompare; import com.qdesrame.openapi.diff.model.ChangedOpenApi; import org.junit.Assert; +import org.slf4j.Logger; + +import static org.slf4j.LoggerFactory.getLogger; public class TestUtils { + public static final Logger LOG = getLogger(TestUtils.class); public static void assertOpenApiAreEquals(String oldSpec, String newSpec) { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(oldSpec, newSpec); - + LOG.info("Result: {}", changedOpenApi.isChanged().getValue()); Assert.assertTrue(changedOpenApi.getNewEndpoints().isEmpty()); Assert.assertTrue(changedOpenApi.getMissingEndpoints().isEmpty()); Assert.assertTrue(changedOpenApi.getChangedOperations().isEmpty()); @@ -16,7 +20,7 @@ public static void assertOpenApiAreEquals(String oldSpec, String newSpec) { public static void assertOpenApiChangedEndpoints(String oldSpec, String newSpec) { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(oldSpec, newSpec); - + LOG.info("Result: {}", changedOpenApi.isChanged().getValue()); Assert.assertTrue(changedOpenApi.getNewEndpoints().isEmpty()); Assert.assertTrue(changedOpenApi.getMissingEndpoints().isEmpty()); Assert.assertTrue(changedOpenApi.getChangedOperations().size() > 0); @@ -24,13 +28,13 @@ public static void assertOpenApiChangedEndpoints(String oldSpec, String newSpec) public static void assertOpenApiBackwardCompatible(String oldSpec, String newSpec, boolean isDiff) { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(oldSpec, newSpec); - Assert.assertTrue(changedOpenApi.isDiff() == isDiff); - Assert.assertTrue(changedOpenApi.isDiffBackwardCompatible()); + LOG.info("Result: {}", changedOpenApi.isChanged().getValue()); + Assert.assertTrue(changedOpenApi.isCompatible()); } public static void assertOpenApiBackwardIncompatible(String oldSpec, String newSpec) { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(oldSpec, newSpec); - Assert.assertTrue(changedOpenApi.isDiff()); - Assert.assertTrue(!changedOpenApi.isDiffBackwardCompatible()); + LOG.info("Result: {}", changedOpenApi.isChanged().getValue()); + Assert.assertTrue(changedOpenApi.isIncompatible()); } } diff --git a/src/test/resources/backwardCompatibility/bc_1.yaml b/src/test/resources/backwardCompatibility/bc_1.yaml index 32a970a3..8247d2fc 100644 --- a/src/test/resources/backwardCompatibility/bc_1.yaml +++ b/src/test/resources/backwardCompatibility/bc_1.yaml @@ -112,6 +112,9 @@ components: properties: bark: type: string + test: + writeOnly: true + type: string Lizard: type: object properties: diff --git a/src/test/resources/backwardCompatibility/bc_2.yaml b/src/test/resources/backwardCompatibility/bc_2.yaml index 86c97816..f8c6d7dc 100644 --- a/src/test/resources/backwardCompatibility/bc_2.yaml +++ b/src/test/resources/backwardCompatibility/bc_2.yaml @@ -131,6 +131,9 @@ components: properties: bark: type: string + test: + writeOnly: true + type: string Lizard: type: object properties: diff --git a/src/test/resources/backwardCompatibility/bc_3.yaml b/src/test/resources/backwardCompatibility/bc_3.yaml index 45fa7ce5..456fc055 100644 --- a/src/test/resources/backwardCompatibility/bc_3.yaml +++ b/src/test/resources/backwardCompatibility/bc_3.yaml @@ -144,6 +144,9 @@ components: properties: bark: type: string + test: + writeOnly: true + type: string Lizard: type: object properties: diff --git a/src/test/resources/backwardCompatibility/bc_4.yaml b/src/test/resources/backwardCompatibility/bc_4.yaml index 27100d04..5de739f8 100644 --- a/src/test/resources/backwardCompatibility/bc_4.yaml +++ b/src/test/resources/backwardCompatibility/bc_4.yaml @@ -136,6 +136,9 @@ components: properties: bark: type: string + test: + writeOnly: true + type: string Lizard: type: object properties: diff --git a/src/test/resources/backwardCompatibility/bc_5.yaml b/src/test/resources/backwardCompatibility/bc_5.yaml new file mode 100644 index 00000000..6b282ba4 --- /dev/null +++ b/src/test/resources/backwardCompatibility/bc_5.yaml @@ -0,0 +1,131 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. You can find out more about + Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, + #swagger](http://swagger.io/irc/). For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: Swagger Petstore + termsOfService: 'http://swagger.io/terms/' + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user + externalDocs: + description: Find out more about our store + url: 'http://swagger.io' +paths: + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + explode: true + schema: + type: array + items: + type: string + maxLength: 16 + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + pets: + type: array + items: + $ref: '#/components/schemas/Dog' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Pet: + type: object + required: + - pet_type + properties: + pet_type: + type: string + discriminator: + propertyName: pet_type + mapping: + cachorro: Dog + Cat: + type: object + properties: + name: + type: string + Dog: + type: object + properties: + bark: + type: string + test: + type: string + Lizard: + type: object + properties: + lovesRocks: + type: boolean + + MyResponseType: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + - $ref: '#/components/schemas/Lizard' + discriminator: + propertyName: pet_type + mapping: + dog: '#/components/schemas/Dog' \ No newline at end of file