Skip to content

Commit

Permalink
Merge pull request #50 from quen2404/improve-extension-support
Browse files Browse the repository at this point in the history
Improve extension support
  • Loading branch information
quen2404 authored Jul 12, 2018
2 parents 3e14c85 + 816f4e2 commit e0d18c4
Show file tree
Hide file tree
Showing 29 changed files with 276 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public Optional<ChangedApiResponse> diff(ApiResponses left, ApiResponses right,
.ifPresent(changedResponse -> resps.put(responseCode, changedResponse));
}
changedApiResponse.setChangedResponses(resps);
openApiDiff.getExtensionsDiff().diff(left.getExtensions(), right.getExtensions(), context)
.ifPresent(changedApiResponse::setChangedExtensions);
return isChanged(changedApiResponse);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.qdesrame.openapi.diff.compare;

import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.DiffContext;

Expand All @@ -11,5 +12,10 @@ public interface ExtensionDiff {

String getName();

Optional<Changed> diff(Object left, Object right, DiffContext context);
Optional<Changed> diff(Change extension, DiffContext context);

default boolean isParentApplicable(Change.Type type, Object object, Object extension, DiffContext context) {
return true;
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.qdesrame.openapi.diff.compare;

import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.Changed;
import com.qdesrame.openapi.diff.model.CompatibleChanged;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.schema.ChangedExtensions;

import java.util.*;
import java.util.function.Function;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;

Expand All @@ -21,23 +25,53 @@ public ExtensionsDiff(OpenApiDiff openApiDiff) {
}
}

public boolean isParentApplicable(Change.Type type, Object parent, Map<String, Object> extensions, DiffContext context) {
if (extensions.size() == 0) {
return true;
}
return extensions.entrySet().stream()
.map(entry -> executeExtension(entry.getKey(), extensionDiff -> extensionDiff.isParentApplicable(type, parent, entry.getValue(), context)))
.allMatch(aBoolean -> aBoolean.orElse(true));
}

public Optional<ExtensionDiff> getExtensionDiff(String name) {
return extensionsDiff.stream()
.filter(diff -> ("x-" + diff.getName()).equals(name))
.findFirst();
}

public <T> Optional<T> executeExtension(String name, Function<ExtensionDiff, T> predicate) {
return getExtensionDiff(name)
.map(extensionDiff -> extensionDiff.setOpenApiDiff(openApiDiff))
.map(predicate);
}

public Optional<ChangedExtensions> diff(Map<String, Object> left, Map<String, Object> right) {
return this.diff(left, right, null);
}

public Optional<ChangedExtensions> diff(Map<String, Object> left, Map<String, Object> right, DiffContext context) {
if (null == left) left = new LinkedHashMap<>();
if (null == right) right = new LinkedHashMap<>();
ChangedExtensions changedExtensions = new ChangedExtensions(left, new LinkedHashMap<>(right), context);
changedExtensions.getIncreased().putAll(right);
for (String key : left.keySet()) {
if (changedExtensions.getIncreased().containsKey(key)) {
Optional<ExtensionDiff> extensionDiff = extensionsDiff.stream()
.filter(diff -> ("x-" + diff.getName()).equals(key)).findFirst();
Object leftValue = left.get(key);
Object rightValue = changedExtensions.getIncreased().remove(key);
extensionDiff.ifPresent(diff -> diff.setOpenApiDiff(openApiDiff).diff(leftValue, rightValue, context)
.ifPresent(changed -> changedExtensions.getChanged().put(key, changed)));
Object leftValue = left.get(key);
if (right.containsKey(key)) {
Object rightValue = right.remove(key);
executeExtensionDiff(key, Change.changed(leftValue, rightValue), context)
.ifPresent(changed -> changedExtensions.getChanged().put(key, changed));
} else {
changedExtensions.getMissing().put(key, left.get(key));
executeExtensionDiff(key, Change.removed(leftValue), context)
.ifPresent(changed -> changedExtensions.getMissing().put(key, changed));
}
}
right.forEach((key, value) -> executeExtensionDiff(key, Change.added(value), context)
.ifPresent(changed -> changedExtensions.getIncreased().put(key, changed)));
return isChanged(changedExtensions);
}

private Optional<Changed> executeExtensionDiff(String name, Change change, DiffContext context) {
return executeExtension(name, diff -> diff.setOpenApiDiff(openApiDiff).diff(change, context))
.orElse(Optional.of(CompatibleChanged.compatible(change)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ protected Optional<ChangedHeader> computeDiff(HashSet<String> refSet, Header lef
changedHeader.setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode()));
openApiDiff.getSchemaDiff().diff(new HashSet<>(), left.getSchema(), right.getSchema(), context.copyWithRequired(true)).ifPresent(changedHeader::setChangedSchema);
openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context).ifPresent(changedHeader::setChangedContent);

openApiDiff.getExtensionsDiff().diff(left.getExtensions(), right.getExtensions(), context)
.ifPresent(changedHeader::setChangedExtensions);
return isChanged(changedHeader);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import com.qdesrame.openapi.diff.model.ChangedOAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlow;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

/**
* Created by adarsh.sharma on 12/01/18.
Expand All @@ -18,14 +20,20 @@ public OAuthFlowDiff(OpenApiDiff openApiDiff) {
this.openApiDiff = openApiDiff;
}

private static Map<String, Object> getExtensions(OAuthFlow oAuthFlow) {
return ofNullable(oAuthFlow).map(OAuthFlow::getExtensions).orElse(null);
}

public Optional<ChangedOAuthFlow> diff(OAuthFlow left, OAuthFlow right) {
ChangedOAuthFlow changedOAuthFlow = new ChangedOAuthFlow(left, right);
if (left != null && right != null) {
changedOAuthFlow.setChangedAuthorizationUrl(!Objects.equals(left.getAuthorizationUrl(), right.getAuthorizationUrl()));
changedOAuthFlow.setChangedTokenUrl(!Objects.equals(left.getTokenUrl(), right.getTokenUrl()));
changedOAuthFlow.setChangedRefreshUrl(!Objects.equals(left.getRefreshUrl(), right.getRefreshUrl()));
}

openApiDiff.getExtensionsDiff().diff(getExtensions(left), getExtensions(right))
.ifPresent(changedOAuthFlow::setChangedExtensions);
return isChanged(changedOAuthFlow);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.qdesrame.openapi.diff.model.ChangedOAuthFlows;
import io.swagger.v3.oas.models.security.OAuthFlows;

import java.util.Map;
import java.util.Optional;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

/**
* Created by adarsh.sharma on 12/01/18.
Expand All @@ -17,6 +19,10 @@ public OAuthFlowsDiff(OpenApiDiff openApiDiff) {
this.openApiDiff = openApiDiff;
}

private static Map<String, Object> getExtensions(OAuthFlows oAuthFlow) {
return ofNullable(oAuthFlow).map(OAuthFlows::getExtensions).orElse(null);
}

public Optional<ChangedOAuthFlows> diff(OAuthFlows left, OAuthFlows right) {
ChangedOAuthFlows changedOAuthFlows = new ChangedOAuthFlows(left, right);
if (left != null && right != null) {
Expand All @@ -25,6 +31,9 @@ public Optional<ChangedOAuthFlows> 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);
}
openApiDiff.getExtensionsDiff().diff(getExtensions(left), getExtensions(right))
.ifPresent(changedOAuthFlows::setChangedExtensions);
return isChanged(changedOAuthFlows);
}

}
10 changes: 10 additions & 0 deletions src/main/java/com/qdesrame/openapi/diff/compare/OpenApiDiff.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.qdesrame.openapi.diff.compare;

import com.qdesrame.openapi.diff.model.*;
import com.qdesrame.openapi.diff.model.schema.ChangedExtensions;
import com.qdesrame.openapi.diff.utils.EndpointUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
Expand Down Expand Up @@ -47,6 +48,8 @@ public class OpenApiDiff {
private List<Endpoint> newEndpoints;
private List<Endpoint> missingEndpoints;
private List<ChangedOperation> changedOperations;
private ChangedExtensions changedExtensions;


/*
* @param oldSpecOpenApi
Expand Down Expand Up @@ -105,9 +108,15 @@ private ChangedOpenApi compare() {
changedOperations.addAll(changedPath.getChanged());
});
});
getExtensionsDiff().diff(oldSpecOpenApi.getExtensions(), newSpecOpenApi.getExtensions())
.ifPresent(this::setChangedExtension);
return getChangedOpenApi();
}

private void setChangedExtension(ChangedExtensions changedExtension) {
this.changedExtensions = changedExtension;
}

private void preProcess(OpenAPI openApi) {
List<SecurityRequirement> securityRequirements = openApi.getSecurity();

Expand All @@ -132,6 +141,7 @@ private ChangedOpenApi getChangedOpenApi() {
changedOpenApi.setNewSpecOpenApi(newSpecOpenApi);
changedOpenApi.setOldSpecOpenApi(oldSpecOpenApi);
changedOpenApi.setChangedOperations(changedOperations);
changedOpenApi.setChangedExtensions(changedExtensions);
return changedOpenApi;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public Optional<ChangedOperation> diff(Operation oldOperation, Operation newOper
.ifPresent(changedOperation::setChangedSecurityRequirements);
}

openApiDiff.getExtensionsDiff().diff(oldOperation.getExtensions(), newOperation.getExtensions(), context)
.ifPresent(changedOperation::setChangedExtensions);

return isChanged(changedOperation);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ protected Optional<ChangedParameter> computeDiff(HashSet<String> refSet, Paramet
}
openApiDiff.getContentDiff().diff(left.getContent(), right.getContent(), context)
.ifPresent(changedParameter::setChangedContent);

openApiDiff.getExtensionsDiff().diff(left.getExtensions(), right.getExtensions(), context)
.ifPresent(changedParameter::setChangedExtensions);
return isChanged(changedParameter);
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/qdesrame/openapi/diff/compare/PathDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public Optional<ChangedPath> diff(PathItem left, PathItem right, DiffContext con
Operation newOperation = newOperationMap.get(method);
openApiDiff.getOperationDiff().diff(oldOperation, newOperation, context.copyWithMethod(method)).ifPresent(changedPath.getChanged()::add);
}
openApiDiff.getExtensionsDiff().diff(left.getExtensions(), right.getExtensions(), context)
.ifPresent(changedPath::setChangedExtensions);
return isChanged(changedPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import io.swagger.v3.oas.models.parameters.RequestBody;

import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

/**
* Created by adarsh.sharma on 28/12/17.
Expand All @@ -30,6 +32,10 @@ public Optional<ChangedRequestBody> diff(RequestBody left, RequestBody right, Di
return cachedDiff(new HashSet<>(), left, right, leftRef, rightRef, context);
}

private static Map<String, Object> getExtensions(RequestBody body) {
return ofNullable(body).map(RequestBody::getExtensions).orElse(null);
}

@Override
protected Optional<ChangedRequestBody> computeDiff(HashSet<String> refSet, RequestBody left, RequestBody right, DiffContext context) {
Content oldRequestContent = new Content();
Expand Down Expand Up @@ -59,6 +65,8 @@ protected Optional<ChangedRequestBody> computeDiff(HashSet<String> refSet, Reque
changedRequestBody.setChangeDescription(!Objects.equals(leftDescription, rightDescription));

openApiDiff.getContentDiff().diff(oldRequestContent, newRequestContent, context).ifPresent(changedRequestBody::setChangedContent);
openApiDiff.getExtensionsDiff().diff(getExtensions(left), getExtensions(right), context)
.ifPresent(changedRequestBody::setChangedExtensions);

return isChanged(changedRequestBody);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ protected Optional<ChangedResponse> computeDiff(HashSet<String> refSet, ApiRespo
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()));

openApiDiff.getExtensionsDiff().diff(left.getExtensions(), right.getExtensions(), context)
.ifPresent(changedResponse::setChangedExtensions);
return isChanged(changedResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ protected Optional<ChangedSecurityScheme> computeDiff(HashSet<String> refSet, Se
.getOpenIdConnectUrl()));
break;
}
openApiDiff.getExtensionsDiff().diff(leftSecurityScheme.getExtensions(), rightSecurityScheme.getExtensions(), context)
.ifPresent(changedSecurityScheme::setChangedExtensions);

return Optional.of(changedSecurityScheme);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.qdesrame.openapi.diff.compare.MapKeyDiff;
import com.qdesrame.openapi.diff.compare.OpenApiDiff;
import com.qdesrame.openapi.diff.model.Change;
import com.qdesrame.openapi.diff.model.ChangedSchema;
import com.qdesrame.openapi.diff.model.DiffContext;
import com.qdesrame.openapi.diff.model.ListDiff;
Expand All @@ -13,9 +14,9 @@
import lombok.Getter;

import java.util.*;
import java.util.stream.Collectors;

import static com.qdesrame.openapi.diff.utils.ChangedUtils.isChanged;
import static java.util.Optional.ofNullable;

@Getter
public class SchemaDiffResult {
Expand Down Expand Up @@ -60,8 +61,8 @@ public Optional<ChangedSchema> diff(HashSet<String> refSet, Components leftCompo

compareAdditionalProperties(refSet, left, right, context);

changedSchema.getIncreasedProperties().putAll(filterProperties(propertyDiff.getIncreased(), context));
changedSchema.getMissingProperties().putAll(filterProperties(propertyDiff.getMissing(), context));
changedSchema.getIncreasedProperties().putAll(filterProperties(Change.Type.ADDED, propertyDiff.getIncreased(), context));
changedSchema.getMissingProperties().putAll(filterProperties(Change.Type.REMOVED, propertyDiff.getMissing(), context));
return isApplicable(context);
}

Expand All @@ -73,10 +74,19 @@ protected Optional<ChangedSchema> isApplicable(DiffContext context) {
return isChanged(changedSchema);
}

private Map<String, Schema> filterProperties(Map<String, Schema> properties, DiffContext context) {
return properties.entrySet().stream()
.filter(entry -> isPropertyApplicable(entry.getValue(), context))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
private Map<String, Schema> filterProperties(Change.Type type, Map<String, Schema> properties, DiffContext context) {
Map<String, Schema> result = new LinkedHashMap<>();
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
if (isPropertyApplicable(entry.getValue(), context)
&& openApiDiff.getExtensionsDiff()
.isParentApplicable(
type,
entry.getValue(),
ofNullable(entry.getValue().getExtensions()).orElse(new LinkedHashMap()), context)) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}

private boolean isPropertyApplicable(Schema schema, DiffContext context) {
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/com/qdesrame/openapi/diff/model/Change.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.qdesrame.openapi.diff.model;

import lombok.Getter;

@Getter
public class Change<T> {
private final T oldValue;
private final T newValue;
private final Type type;

private Change(T oldValue, T newValue, Type type) {
this.oldValue = oldValue;
this.newValue = newValue;
this.type = type;
}

public static <T> Change<T> changed(T oldValue, T newValue) {
return new Change<>(oldValue, newValue, Type.CHANGED);
}

public static <T> Change<T> added(T newValue) {
return new Change<>(null, newValue, Type.ADDED);
}

public static <T> Change<T> removed(T oldValue) {
return new Change<>(oldValue, null, Type.REMOVED);
}

public enum Type {
ADDED,
CHANGED,
REMOVED
}
}
Loading

0 comments on commit e0d18c4

Please sign in to comment.