Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix model array change detect and detect produces/consumes changes #30

Merged
merged 2 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 73 additions & 10 deletions src/main/java/com/deepoove/swagger/diff/compare/ModelDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

import com.deepoove.swagger.diff.model.ElProperty;

import io.swagger.models.ArrayModel;
import io.swagger.models.Model;
import io.swagger.models.RefModel;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;

/**
* compare two model
Expand Down Expand Up @@ -51,12 +55,18 @@ public ModelDiff diff(Model leftModel, Model rightModel, String parentEl) {
return this.diff(leftModel, rightModel, parentEl, new HashSet<Model>());
}

private ModelDiff diff(Model leftModel, Model rightModel, String parentEl, Set<Model> visited) {
public ModelDiff diff(Property leftProperty, Property rightProperty) {
return this.diff(findModel(leftProperty, oldDedinitions), findModel(rightProperty, newDedinitions));
}

private ModelDiff diff(Model leftInputModel, Model rightInputModel, String parentEl, Set<Model> visited) {
// Stop recursing if both models are null
// OR either model is already contained in the visiting history
if ((null == leftModel && null == rightModel) || visited.contains(leftModel) || visited.contains(rightModel)) {
if ((null == leftInputModel && null == rightInputModel) || visited.contains(leftInputModel) || visited.contains(rightInputModel)) {
return this;
}
Model leftModel = isModelReference(leftInputModel) ? findReferenceModel(leftInputModel, oldDedinitions) : leftInputModel;
Model rightModel = isModelReference(rightInputModel) ? findReferenceModel(rightInputModel, newDedinitions) : rightInputModel;
Map<String, Property> leftProperties = null == leftModel ? null : leftModel.getProperties();
Map<String, Property> rightProperties = null == rightModel ? null : rightModel.getProperties();

Expand All @@ -71,19 +81,16 @@ private ModelDiff diff(Model leftModel, Model rightModel, String parentEl, Set<M
sharedKey.stream().forEach((key) -> {
Property left = leftProperties.get(key);
Property right = rightProperties.get(key);

if ((left instanceof RefProperty) && (right instanceof RefProperty)) {
String leftRef = ((RefProperty) left).getSimpleRef();
String rightRef = ((RefProperty) right).getSimpleRef();

diff(oldDedinitions.get(leftRef), newDedinitions.get(rightRef),
Model leftSubModel = findModel(left, oldDedinitions);
Model rightSubModel = findModel(left, newDedinitions);
if (leftSubModel != null || rightSubModel != null) {
diff(leftSubModel, rightSubModel,
buildElString(parentEl, key),
copyAndAdd(visited, leftModel, rightModel));

} else if (left != null && right != null && !left.equals(right)) {
// Add a changed ElProperty if not a Reference
// Useless
changed.add(convert2ElProperty(key, parentEl, left));
changed.add(addChangeMetadata(convert2ElProperty(key, parentEl, left), left, right));
}
});
return this;
Expand Down Expand Up @@ -113,13 +120,69 @@ private ElProperty convert2ElProperty(String propName, String parentEl, Property
return pWithPath;
}

private ElProperty addChangeMetadata(ElProperty diffProperty, Property left, Property right) {
diffProperty.setTypeChange(!left.getType().equalsIgnoreCase(right.getType()));
List<String> leftEnums = enumValues(left);
List<String> rightEnums = enumValues(right);
if (!leftEnums.isEmpty() && !rightEnums.isEmpty()) {
ListDiff<String> enumDiff = ListDiff.diff(leftEnums, rightEnums, (t, enumVal) -> {
for (String value : t) {
if (enumVal.equalsIgnoreCase(value)) { return value; }
}
return null;
});
diffProperty.setNewEnums(enumDiff.getIncreased() != null && ! enumDiff.getIncreased().isEmpty());
diffProperty.setRemovedEnums(enumDiff.getMissing() != null && ! enumDiff.getMissing().isEmpty());
}
return diffProperty;
}

@SuppressWarnings("unchecked")
private <T> Set<T> copyAndAdd(Set<T> set, T... add) {
Set<T> newSet = new HashSet<T>(set);
newSet.addAll(Arrays.asList(add));
return newSet;
}

private List<String> enumValues(Property prop) {
if (prop instanceof StringProperty && ((StringProperty) prop).getEnum() != null) {
return ((StringProperty) prop).getEnum();
} else {
return new ArrayList<>();
}
}

private Model findModel(Property property, Map<String, Model> modelMap) {
String modelName = null;
if (property instanceof RefProperty){
modelName = ((RefProperty) property).getSimpleRef();
} else if (property instanceof ArrayProperty) {
Property arrayType = ((ArrayProperty) property).getItems();
if (arrayType instanceof RefProperty) {
modelName = ((RefProperty) arrayType).getSimpleRef();
}
}
return modelName == null ? null : modelMap.get(modelName);
}

private boolean isModelReference(Model model) {
return model instanceof RefModel || model instanceof ArrayModel;
}

private Model findReferenceModel(Model model, Map<String, Model> modelMap) {
String modelName = null;
if (model instanceof RefModel){
modelName = ((RefModel) model).getSimpleRef();
} else if (model instanceof ArrayModel) {
Property arrayType = ((ArrayModel) model).getItems();
if (arrayType instanceof RefProperty) {
modelName = ((RefProperty) arrayType).getSimpleRef();
}
}
return modelName == null ? null : modelMap.get(modelName);
}


public List<ElProperty> getIncreased() {
return increased;
}
Expand Down
20 changes: 6 additions & 14 deletions src/main/java/com/deepoove/swagger/diff/compare/ParameterDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.deepoove.swagger.diff.model.ChangedParameter;

import io.swagger.models.Model;
import io.swagger.models.RefModel;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;

Expand Down Expand Up @@ -65,19 +64,12 @@ public ParameterDiff diff(List<Parameter> left, List<Parameter> right) {
BodyParameter leftBodyPara = (BodyParameter) leftPara;
Model leftSchema = leftBodyPara.getSchema();
BodyParameter rightBodyPara = (BodyParameter) rightPara;
Model rightSchema = rightBodyPara.getSchema();
if (leftSchema instanceof RefModel && rightSchema instanceof RefModel) {
String leftRef = ((RefModel) leftSchema).getSimpleRef();
String rightRef = ((RefModel) rightSchema).getSimpleRef();
Model leftModel = oldDedinitions.get(leftRef);
Model rightModel = newDedinitions.get(rightRef);

ModelDiff diff = ModelDiff.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftModel, rightModel, leftPara.getName());
changedParameter.setIncreased(diff.getIncreased());
changedParameter.setMissing(diff.getMissing());
changedParameter.setChanged(diff.getChanged());
}
Model rightSchema = rightBodyPara.getSchema();
ModelDiff diff = ModelDiff.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftSchema, rightSchema, leftPara.getName());
changedParameter.setIncreased(diff.getIncreased());
changedParameter.setMissing(diff.getMissing());
changedParameter.setChanged(diff.getChanged());
}

// is requried
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/com/deepoove/swagger/diff/compare/PropertyDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import io.swagger.models.Model;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;

public class PropertyDiff {

Expand All @@ -34,16 +33,12 @@ public static PropertyDiff buildWithDefinition(Map<String, Model> left,
}

public PropertyDiff diff(Property left, Property right) {
if ((null == left || left instanceof RefProperty) && (null == right || right instanceof RefProperty)) {
Model leftModel = null == left ? null : oldDedinitions.get(((RefProperty) left).getSimpleRef());
Model rightModel = null == right ? null : newDedinitions.get(((RefProperty) right).getSimpleRef());
ModelDiff diff = ModelDiff
.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftModel, rightModel);
increased.addAll(diff.getIncreased());
missing.addAll(diff.getMissing());
changed.addAll(diff.getChanged());
}
ModelDiff diff = ModelDiff
.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(left, right);
increased.addAll(diff.getIncreased());
missing.addAll(diff.getMissing());
changed.addAll(diff.getChanged());
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public static SpecificationDiff diff(Swagger oldSpec, Swagger newSpec) {
changedOperation.setMissingProps(propertyDiff.getMissing());
changedOperation.setChangedProps(propertyDiff.getChanged());

// Diff Consumes
ListDiff<String> consumeDiff = getMediaTypeDiff(oldOperation.getConsumes(), newOperation.getConsumes());
changedOperation.setAddConsumes(consumeDiff.getIncreased());
changedOperation.setMissingConsumes(consumeDiff.getMissing());

// Diff Produces
ListDiff<String> producesDiff = getMediaTypeDiff(oldOperation.getProduces(), newOperation.getProduces());
changedOperation.setAddProduces(producesDiff.getIncreased());
changedOperation.setMissingProduces(producesDiff.getMissing());

if (changedOperation.isDiff()) {
operas.put(method, changedOperation);
}
Expand Down Expand Up @@ -151,6 +161,15 @@ private static Collection<? extends Endpoint> convert2EndpointList(String pathUr
return endpoints;
}

private static ListDiff<String> getMediaTypeDiff(List<String> oldTypes, List<String> newTypes) {
return ListDiff.diff(oldTypes, newTypes, (t, sample) -> {
for (String mediaType : t) {
if (sample.equalsIgnoreCase(mediaType)) { return mediaType; }
}
return null;
});
}

public List<Endpoint> getNewEndpoints() {
return newEndpoints;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class ChangedOperation implements Changed {
private List<ElProperty> addProps = new ArrayList<ElProperty>();
private List<ElProperty> missingProps = new ArrayList<ElProperty>();
private List<ElProperty> changedProps = new ArrayList<ElProperty>();
private List<String> addConsumes = new ArrayList<>();
private List<String> missingConsumes = new ArrayList<>();
private List<String> addProduces = new ArrayList<>();
private List<String> missingProduces = new ArrayList<>();

public List<Parameter> getAddParameters() {
return addParameters;
Expand Down Expand Up @@ -76,7 +80,7 @@ public void setSummary(String summary) {

public boolean isDiff() {
return !addParameters.isEmpty() || !missingParameters.isEmpty()
|| !changedParameter.isEmpty() || isDiffProp();
|| !changedParameter.isEmpty() || isDiffProp() || isDiffConsumes() || isDiffProduces();
}
public boolean isDiffProp(){
return !addProps.isEmpty()
Expand All @@ -87,4 +91,44 @@ public boolean isDiffParam(){
return !addParameters.isEmpty() || !missingParameters.isEmpty()
|| !changedParameter.isEmpty();
}

public boolean isDiffConsumes(){
return !addConsumes.isEmpty() || !missingConsumes.isEmpty();
}

public boolean isDiffProduces(){
return !addProduces.isEmpty() || !missingProduces.isEmpty();
}

public List<String> getAddConsumes() {
return this.addConsumes;
}

public void setAddConsumes(List<String> increased) {
this.addConsumes = increased == null ? new ArrayList<>() : increased;
}

public List<String> getMissingConsumes() {
return this.missingConsumes;
}

public void setMissingConsumes(List<String> missing) {
this.missingConsumes = missing == null ? new ArrayList<>() : missing;
}

public List<String> getAddProduces() {
return this.addProduces;
}

public void setAddProduces(List<String> increased) {
this.addProduces = increased == null ? new ArrayList<>() : increased;
}

public List<String> getMissingProduces() {
return this.missingProduces;
}

public void setMissingProduces(List<String> missing) {
this.missingProduces = missing == null ? new ArrayList<>() : missing;
}
}
28 changes: 28 additions & 0 deletions src/main/java/com/deepoove/swagger/diff/model/ElProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class ElProperty {

private Property property;

// optional change metadata
private boolean isTypeChange;
private boolean newEnums;
private boolean removedEnums;

public Property getProperty() {
return property;
}
Expand All @@ -29,4 +34,27 @@ public void setEl(String el) {
this.el = el;
}

public boolean isTypeChange() {
return isTypeChange;
}

public void setTypeChange(boolean typeChange) {
isTypeChange = typeChange;
}

public boolean isNewEnums() {
return newEnums;
}

public void setNewEnums(boolean newEnums) {
this.newEnums = newEnums;
}

public boolean isRemovedEnums() {
return removedEnums;
}

public void setRemovedEnums(boolean removedEnums) {
this.removedEnums = removedEnums;
}
}
Loading