Skip to content
This repository has been archived by the owner on Aug 8, 2018. It is now read-only.

Commit

Permalink
Use external model references instead of inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre Rabold authored and Frank Schmid committed Jan 26, 2016
1 parent 43ad8e7 commit 8365dce
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
Expand All @@ -39,15 +40,15 @@ public class SchemaTransformer {

/**
* Get a schema schema in "flattened" form whereby all dependent references are resolved
* and included as inline schema definitions
* and included as external schema definitions
*
* @return the json-schema string in flattened form
*/
public String flatten(String model, String models) {
return getFlattened(deserialize(model), deserialize(models));
public String flatten(String apiId, String model, String models) {
return getFlattened(apiId, deserialize(model), deserialize(models));
}

private void buildSchemaReferenceMap(JsonNode model, JsonNode models, Map<String, String> modelMap) {
private void buildSchemaReferenceMap(String apiId, JsonNode model, JsonNode models, Map<String, String> modelMap) {
Map<JsonNode, JsonNode> refs = new HashMap<>();
findReferences(model, refs);

Expand All @@ -58,10 +59,10 @@ private void buildSchemaReferenceMap(JsonNode model, JsonNode models, Map<String

JsonNode subSchema = getSchema(schemaName, models);

// replace reference values with inline definitions
replaceRef((ObjectNode) refs.get(ref), schemaName);
// replace reference values with external definitions
replaceRef(apiId, (ObjectNode) refs.get(ref), schemaName);

buildSchemaReferenceMap(subSchema, models, modelMap);
buildSchemaReferenceMap(apiId, subSchema, models, modelMap);

modelMap.put(schemaName, serializeExisting(subSchema));
}
Expand All @@ -71,12 +72,10 @@ private JsonNode getSchema(String schemaName, JsonNode models) {
return models.findPath(schemaName);
}

private String getFlattened(JsonNode model, JsonNode models) {
private String getFlattened(String apiId, JsonNode model, JsonNode models) {
HashMap<String, String> schemaMap = new HashMap<>();

buildSchemaReferenceMap(model, models, schemaMap);

replaceRefs(model, schemaMap);
buildSchemaReferenceMap(apiId, model, models, schemaMap);

if (LOG.isTraceEnabled()) {
try {
Expand Down Expand Up @@ -108,26 +107,12 @@ private void validate(JsonNode rootNode) {
}
}

/*
* Add schema references as inline definitions to the root schema
*/
private void replaceRefs(JsonNode root, HashMap<String, String> schemaMap) {

ObjectNode definitionsNode = new ObjectNode(JsonNodeFactory.instance);

for (Map.Entry<String, String> entry : schemaMap.entrySet()) {
JsonNode schemaNode = deserialize(entry.getValue());
definitionsNode.set(entry.getKey(), schemaNode);
}

((ObjectNode)root).set("definitions", definitionsNode);
}

/*
* Replace a reference node with an inline reference
*/
private void replaceRef(ObjectNode parent, String schemaName) {
parent.set("$ref", new TextNode("#/definitions/" + schemaName));
private void replaceRef(String apiId, ObjectNode parent, String schemaName) {
// parent.set("$ref", new TextNode("#/definitions/" + schemaName));
parent.set("$ref", new TextNode("https://apigateway.amazonaws.com/restapis/" + apiId + "/models/" + schemaName));
}

/*
Expand Down Expand Up @@ -163,7 +148,7 @@ JsonNode deserialize(String schemaText) {
*/
private String serializeExisting(JsonNode root) {
try {
return new ObjectMapper().writeValueAsString(root);
return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(root);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Could not serialize generated schema json", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ private void createModels(RestApi api, Map<String, com.wordnik.swagger.models.Mo
private void createModel(RestApi api, String modelName, com.wordnik.swagger.models.Model model, Map<String, com.wordnik.swagger.models.Model> definitions, String modelContentType) {
LOG.info(format("Creating model for api id %s with name %s", api.getId(), modelName));

createModel(api, modelName, model.getDescription(), generateSchema(model, modelName, definitions), modelContentType);
createModel(api, modelName, model.getDescription(), generateSchema(api, model, modelName, definitions), modelContentType);
}

private void createModel(RestApi api, String modelName, Property model, String modelContentType) {
LOG.info(format("Creating model for api id %s with name %s", api.getId(), modelName));

createModel(api, modelName, model.getDescription(), generateSchema(model, modelName, swagger.getDefinitions()), modelContentType);
createModel(api, modelName, model.getDescription(), generateSchema(api, model, modelName, swagger.getDefinitions()), modelContentType);
}

private void updateMethods(RestApi api, String basePath, Map<String, Path> paths, List<String> apiProduces) {
Expand Down Expand Up @@ -320,17 +320,17 @@ private Boolean isApiKeyRequired(Operation op) {
return false;
}

private String generateSchema(Property model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
return generateSchemaString(model, modelName, definitions);
private String generateSchema(RestApi api, Property model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
return generateSchemaString(api, model, modelName, definitions);
}

private String generateSchemaString(Object model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
private String generateSchemaString(RestApi api, Object model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
try {
String modelSchema = Json.mapper().writeValueAsString(model);
String models = Json.mapper().writeValueAsString(definitions);

// inline all references
String schema = new SchemaTransformer().flatten(modelSchema, models);
String schema = new SchemaTransformer().flatten(api.getId(), modelSchema, models);

LOG.info("Generated json-schema for model " + modelName + ": " + schema);

Expand All @@ -340,8 +340,8 @@ private String generateSchemaString(Object model, String modelName, Map<String,
}
}

private String generateSchema(com.wordnik.swagger.models.Model model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
return generateSchemaString(model, modelName, definitions);
private String generateSchema(RestApi api, com.wordnik.swagger.models.Model model, String modelName, Map<String, com.wordnik.swagger.models.Model> definitions) {
return generateSchemaString(api, model, modelName, definitions);
}

private Optional<String> getInputModel(BodyParameter p) {
Expand Down Expand Up @@ -400,7 +400,7 @@ private void updateModels(RestApi api, Map<String, com.wordnik.swagger.models.Mo

private void updateModel(RestApi api, String modelName, com.wordnik.swagger.models.Model model) {
LOG.info(format("Updating model for api id %s and model name %s", api.getId(), modelName));
updateModel(api, modelName, generateSchema(model, modelName, swagger.getDefinitions()));
updateModel(api, modelName, generateSchema(api, model, modelName, swagger.getDefinitions()));
}

private void updateMethod(RestApi api, Resource resource, String httpMethod, Operation op, String modelContentType) {
Expand Down

0 comments on commit 8365dce

Please sign in to comment.