From d0e9198ea45c680ad7e7881651d981e1d8361de3 Mon Sep 17 00:00:00 2001 From: Gokul Raj S <56819171+GORA-SAG@users.noreply.github.com> Date: Fri, 31 Jan 2020 12:13:06 +0530 Subject: [PATCH 1/2] Fix for issue #1249 Swagger 2 validation allows path params to be non-required --- .../parser/util/SwaggerDeserializer.java | 665 ++++++++---------- .../io/swagger/parser/SwaggerParserTest.java | 127 ++-- .../src/test/resources/issue-1249.json | 35 + 3 files changed, 411 insertions(+), 416 deletions(-) create mode 100644 modules/swagger-parser/src/test/resources/issue-1249.json diff --git a/modules/swagger-parser/src/main/java/io/swagger/parser/util/SwaggerDeserializer.java b/modules/swagger-parser/src/main/java/io/swagger/parser/util/SwaggerDeserializer.java index a5999a33c8..4bf713ddaa 100644 --- a/modules/swagger-parser/src/main/java/io/swagger/parser/util/SwaggerDeserializer.java +++ b/modules/swagger-parser/src/main/java/io/swagger/parser/util/SwaggerDeserializer.java @@ -30,7 +30,7 @@ public class SwaggerDeserializer { protected static Set OPERATION_KEYS = new LinkedHashSet(Arrays.asList("scheme", "tags", "summary", "description", "externalDocs", "operationId", "consumes", "produces", "parameters", "responses", "schemes", "deprecated", "security")); protected static Set PARAMETER_KEYS = new LinkedHashSet(Arrays.asList("name", "in", "description", "required", "type", "format", "allowEmptyValue", "items", "collectionFormat", "default", "maximum", "exclusiveMaximum", "minimum", "exclusiveMinimum", "maxLength", "minLength", "pattern", "maxItems", "minItems", "uniqueItems", "enum", "multipleOf", "readOnly", "allowEmptyValue")); protected static Set BODY_PARAMETER_KEYS = new LinkedHashSet(Arrays.asList("name", "in", "description", "required", "schema")); - protected static Set SECURITY_SCHEME_KEYS = new LinkedHashSet(Arrays.asList("type", "name", "in", "description", "flow", "authorizationUrl", "tokenUrl" , "scopes")); + protected static Set SECURITY_SCHEME_KEYS = new LinkedHashSet(Arrays.asList("type", "name", "in", "description", "flow", "authorizationUrl", "tokenUrl", "scopes")); private final Set operationIDs = new HashSet<>(); @@ -48,7 +48,7 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { String location = ""; Swagger swagger = new Swagger(); if (node.getNodeType().equals(JsonNodeType.OBJECT)) { - ObjectNode on = (ObjectNode)node; + ObjectNode on = (ObjectNode) node; Iterator it = null; // required @@ -56,7 +56,7 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { swagger.setSwagger(value); ObjectNode obj = getObject("info", on, true, "", result); - if(obj != null) { + if (obj != null) { Info info = info(obj, "info", result); swagger.info(info); } @@ -69,7 +69,7 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { swagger.setBasePath(value); ArrayNode array = getArray("schemes", on, false, location, result); - if(array != null) { + if (array != null) { it = array.iterator(); while (it.hasNext()) { JsonNode n = it.next(); @@ -84,7 +84,7 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { } array = getArray("consumes", on, false, location, result); - if(array != null) { + if (array != null) { it = array.iterator(); while (it.hasNext()) { JsonNode n = it.next(); @@ -96,7 +96,7 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { } array = getArray("produces", on, false, location, result); - if(array != null) { + if (array != null) { it = array.iterator(); while (it.hasNext()) { JsonNode n = it.next(); @@ -118,13 +118,13 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { obj = getObject("parameters", on, false, location, result); // TODO: parse - if(obj != null) { + if (obj != null) { Map parameters = new LinkedHashMap<>(); Set keys = getKeys(obj); - for(String key : keys) { + for (String key : keys) { JsonNode paramNode = obj.get(key); - if(paramNode instanceof ObjectNode) { - Parameter parameter = this.parameter((ObjectNode)paramNode, location, result); + if (paramNode instanceof ObjectNode) { + Parameter parameter = this.parameter((ObjectNode) paramNode, location, result); parameters.put(key, parameter); } } @@ -153,16 +153,14 @@ public Swagger parseRoot(JsonNode node, ParseResult result) { // extra keys Set keys = getKeys(on); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { swagger.vendorExtension(key, extension(on.get(key))); - } - else if(!ROOT_KEYS.contains(key)) { + } else if (!ROOT_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } - } - else { + } else { result.invalidType("", "", "object", node); result.invalid(); return null; @@ -170,25 +168,32 @@ else if(!ROOT_KEYS.contains(key)) { return swagger; } - public Map paths(ObjectNode obj, String location, ParseResult result) { + public Map paths(ObjectNode obj, String location, ParseResult result) { Map output = new LinkedHashMap<>(); - if(obj == null) { + if (obj == null) { return null; } Set pathKeys = getKeys(obj); - for(String pathName : pathKeys) { + for (String pathName : pathKeys) { JsonNode pathValue = obj.get(pathName); - if(pathName.startsWith("x-")) { + if (pathName.startsWith("x-")) { result.unsupported(location, pathName, pathValue); - } - else { + } else { if (!pathValue.getNodeType().equals(JsonNodeType.OBJECT)) { result.invalidType(location, pathName, "object", pathValue); } else { ObjectNode path = (ObjectNode) pathValue; Path pathObj = path(path, location + ".'" + pathName + "'", result); String[] eachPart = pathName.split("[-/.]+"); + List operationsInAPath = getAllOperationsInAPath(pathObj); + for (Operation operation : operationsInAPath) { + for (Parameter parameter : operation.getParameters()) { + if ("path".equalsIgnoreCase(parameter.getIn()) && !parameter.getRequired()) { + result.warning(location + ".'" + parameter.getName() + "'", " For path parameter '" + parameter.getName() + "' the required value should be true"); + } + } + } for (String part : eachPart) { if (part.startsWith("{") && part.endsWith("}") && part.length() > 2) { String pathParam = part.substring(1, part.length() - 1); @@ -196,10 +201,9 @@ public Map paths(ObjectNode obj, String location, ParseResult resul if (definedInPathLevel) { continue; } - List operationsInAPath = getAllOperationsInAPath(pathObj); for (Operation operation : operationsInAPath) { if (!isPathParamDefined(pathParam, operation.getParameters())) { - result.warning(location + ".'" + pathName + "'"," Declared path parameter " + pathParam + " needs to be defined as a path parameter in path or operation level"); + result.warning(location + ".'" + pathName + "'", " Declared path parameter " + pathParam + " needs to be defined as a path parameter in path or operation level"); break; } } @@ -218,6 +222,9 @@ private boolean isPathParamDefined(String pathParam, List parameters) } else { for (Parameter parameter : parameters) { if (parameter instanceof RefParameter || (pathParam.equals(parameter.getName()) && "path".equals(parameter.getIn()))) { + if (!parameter.getRequired()) { + + } return true; } } @@ -245,19 +252,17 @@ private List getAllOperationsInAPath(Path pathObj) { } public Path path(ObjectNode obj, String location, ParseResult result) { - if(obj.get("$ref") != null) { + if (obj.get("$ref") != null) { JsonNode ref = obj.get("$ref"); - if(ref.getNodeType().equals(JsonNodeType.STRING)) { - - return pathRef((TextNode)ref, location, result); - } + if (ref.getNodeType().equals(JsonNodeType.STRING)) { - else if(ref.getNodeType().equals(JsonNodeType.OBJECT)){ + return pathRef((TextNode) ref, location, result); + } else if (ref.getNodeType().equals(JsonNodeType.OBJECT)) { ObjectNode on = (ObjectNode) ref; // extra keys Set keys = getKeys(on); - for(String key : keys) { + for (String key : keys) { result.extra(location, key, on.get(key)); } } @@ -269,62 +274,61 @@ else if(ref.getNodeType().equals(JsonNodeType.OBJECT)){ path.setParameters(parameters(parameters, location, result)); ObjectNode on = getObject("get", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(get)", result); - if(op != null) { + if (op != null) { path.setGet(op); } } on = getObject("put", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(put)", result); - if(op != null) { + if (op != null) { path.setPut(op); } } on = getObject("post", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(post)", result); - if(op != null) { + if (op != null) { path.setPost(op); } } on = getObject("head", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(head)", result); - if(op != null) { + if (op != null) { path.setHead(op); } } on = getObject("delete", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(delete)", result); - if(op != null) { + if (op != null) { path.setDelete(op); } } on = getObject("patch", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(patch)", result); - if(op != null) { + if (op != null) { path.setPatch(op); } } on = getObject("options", obj, false, location, result); - if(on != null) { + if (on != null) { Operation op = operation(on, location + "(options)", result); - if(op != null) { + if (op != null) { path.setOptions(op); } } // extra keys Set keys = getKeys(obj); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { path.setVendorExtension(key, extension(obj.get(key))); - } - else if(!PATH_KEYS.contains(key)) { + } else if (!PATH_KEYS.contains(key)) { result.extra(location, key, obj.get(key)); } } @@ -332,13 +336,13 @@ else if(!PATH_KEYS.contains(key)) { } public Operation operation(ObjectNode obj, String location, ParseResult result) { - if(obj == null) { + if (obj == null) { return null; } Operation output = new Operation(); ArrayNode array = getArray("tags", obj, false, location, result); List tags = tagStrings(array, location, result); - if(tags != null) { + if (tags != null) { output.tags(tags); } String value = getString("summary", obj, false, location, result); @@ -355,47 +359,47 @@ public Operation operation(ObjectNode obj, String location, ParseResult result) output.operationId(value); array = getArray("consumes", obj, false, location, result); - if(array != null) { - if (array.size() == 0) { - output.consumes(Collections. emptyList()); - } else { - Iterator it = array.iterator(); - while (it.hasNext()) { - JsonNode n = it.next(); - String s = getString(n, location + ".consumes", result); - if (s != null) { - output.consumes(s); - } - } - } + if (array != null) { + if (array.size() == 0) { + output.consumes(Collections.emptyList()); + } else { + Iterator it = array.iterator(); + while (it.hasNext()) { + JsonNode n = it.next(); + String s = getString(n, location + ".consumes", result); + if (s != null) { + output.consumes(s); + } + } + } } array = getArray("produces", obj, false, location, result); if (array != null) { - if (array.size() == 0) { - output.produces(Collections. emptyList()); - } else { - Iterator it = array.iterator(); - while (it.hasNext()) { - JsonNode n = it.next(); - String s = getString(n, location + ".produces", result); - if (s != null) { - output.produces(s); - } - } - } + if (array.size() == 0) { + output.produces(Collections.emptyList()); + } else { + Iterator it = array.iterator(); + while (it.hasNext()) { + JsonNode n = it.next(); + String s = getString(n, location + ".produces", result); + if (s != null) { + output.produces(s); + } + } + } } ArrayNode parameters = getArray("parameters", obj, false, location, result); output.setParameters(parameters(parameters, location, result)); ObjectNode responses = getObject("responses", obj, true, location, result); Map responsesObject = responses(responses, location, result); - if(responsesObject != null && responsesObject.size() == 0) { + if (responsesObject != null && responsesObject.size() == 0) { result.missing(location, "responses"); } output.setResponses(responsesObject); array = getArray("schemes", obj, false, location, result); - if(array != null) { + if (array != null) { Iterator it = array.iterator(); while (it.hasNext()) { JsonNode n = it.next(); @@ -409,15 +413,15 @@ public Operation operation(ObjectNode obj, String location, ParseResult result) } } Boolean deprecated = getBoolean("deprecated", obj, false, location, result); - if(deprecated != null) { + if (deprecated != null) { output.setDeprecated(deprecated); } array = getArray("security", obj, false, location, result); List security = securityRequirements(array, location, result); - if(security != null) { + if (security != null) { List>> ss = new ArrayList<>(); - for(SecurityRequirement s : security) { - if(s.getRequirements() != null && s.getRequirements().size() > 0) { + for (SecurityRequirement s : security) { + if (s.getRequirements() != null && s.getRequirements().size() > 0) { ss.add(s.getRequirements()); } } @@ -426,11 +430,10 @@ public Operation operation(ObjectNode obj, String location, ParseResult result) // extra keys Set keys = getKeys(obj); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { output.setVendorExtension(key, extension(obj.get(key))); - } - else if(!OPERATION_KEYS.contains(key)) { + } else if (!OPERATION_KEYS.contains(key)) { result.extra(location, key, obj.get(key)); } } @@ -446,12 +449,10 @@ public Boolean getBoolean(String key, ObjectNode node, boolean required, String result.missing(location, key); result.invalid(); } - } - else { - if(v.getNodeType().equals(JsonNodeType.BOOLEAN)) { + } else { + if (v.getNodeType().equals(JsonNodeType.BOOLEAN)) { value = v.asBoolean(); - } - else if(v.getNodeType().equals(JsonNodeType.STRING)) { + } else if (v.getNodeType().equals(JsonNodeType.STRING)) { String stringValue = v.textValue(); return Boolean.parseBoolean(stringValue); } @@ -461,13 +462,13 @@ else if(v.getNodeType().equals(JsonNodeType.STRING)) { public List parameters(ArrayNode obj, String location, ParseResult result) { List output = new ArrayList(); - if(obj == null) { + if (obj == null) { return output; } - for(JsonNode item : obj) { - if(item.getNodeType().equals(JsonNodeType.OBJECT)) { + for (JsonNode item : obj) { + if (item.getNodeType().equals(JsonNodeType.OBJECT)) { Parameter param = parameter((ObjectNode) item, location, result); - if(param != null) { + if (param != null) { output.add(param); } } @@ -477,17 +478,16 @@ public List parameters(ArrayNode obj, String location, ParseResult re public Parameter parameter(ObjectNode obj, String location, ParseResult result) { - if(obj == null) { + if (obj == null) { return null; } Parameter output = null; JsonNode ref = obj.get("$ref"); - if(ref != null) { - if(ref.getNodeType().equals(JsonNodeType.STRING)) { + if (ref != null) { + if (ref.getNodeType().equals(JsonNodeType.STRING)) { return refParameter((TextNode) ref, location, result); - } - else { + } else { result.invalidType(location, "$ref", "string", obj); return null; } @@ -495,34 +495,30 @@ public Parameter parameter(ObjectNode obj, String location, ParseResult result) String l = null; JsonNode ln = obj.get("name"); - if(ln != null) { + if (ln != null) { l = ln.asText(); - } - else { + } else { l = "['unknown']"; } location += ".[" + l + "]"; String value = getString("in", obj, true, location, result); - if(value != null) { + if (value != null) { String type = getString("type", obj, false, location, result); String format = getString("format", obj, false, location, result); AbstractSerializableParameter sp = null; - if("query".equals(value)) { + if ("query".equals(value)) { sp = new QueryParameter(); - } - else if ("header".equals(value)) { + } else if ("header".equals(value)) { sp = new HeaderParameter(); - } - else if ("path".equals(value)) { + } else if ("path".equals(value)) { sp = new PathParameter(); - } - else if ("formData".equals(value)) { + } else if ("formData".equals(value)) { sp = new FormParameter(); } - if(sp != null) { + if (sp != null) { // type is mandatory when sp != null String paramType = getString("type", obj, true, location, result); Map map = new LinkedHashMap(); @@ -534,25 +530,25 @@ else if ("formData".equals(value)) { sp.setDefault(defaultValue); BigDecimal bd = getBigDecimal("maximum", obj, false, location, result); - if(bd != null) { + if (bd != null) { map.put(MAXIMUM, bd); sp.setMaximum(bd); } Boolean bl = getBoolean("exclusiveMaximum", obj, false, location, result); - if(bl != null) { + if (bl != null) { map.put(EXCLUSIVE_MAXIMUM, bl); sp.setExclusiveMaximum(bl); } bd = getBigDecimal("minimum", obj, false, location, result); - if(bd != null) { + if (bd != null) { map.put(MINIMUM, bd); sp.setMinimum(bd); } bl = getBoolean("exclusiveMinimum", obj, false, location, result); - if(bl != null) { + if (bl != null) { map.put(EXCLUSIVE_MINIMUM, bl); sp.setExclusiveMinimum(bl); } @@ -586,7 +582,7 @@ else if ("formData".equals(value)) { sp.setMaxLength(iv); bd = getBigDecimal("multipleOf", obj, false, location, result); - if(bd != null) { + if (bd != null) { map.put(MULTIPLE_OF, bd); sp.setMultipleOf(bd.doubleValue()); } @@ -596,13 +592,12 @@ else if ("formData".equals(value)) { sp.setUniqueItems(uniqueItems); ArrayNode an = getArray("enum", obj, false, location, result); - if(an != null) { + if (an != null) { List _enum = new ArrayList(); - for(JsonNode n : an) { - if(n.isValueNode()) { + for (JsonNode n : an) { + if (n.isValueNode()) { _enum.add(n.asText()); - } - else { + } else { result.invalidType(location, "enum", "value", n); } } @@ -611,34 +606,33 @@ else if ("formData".equals(value)) { } bl = getBoolean("readOnly", obj, false, location, result); - if(bl != null) { + if (bl != null) { map.put(READ_ONLY, bl); sp.setReadOnly(bl); } bl = getBoolean("allowEmptyValue", obj, false, location, result); - if(bl != null) { + if (bl != null) { map.put(ALLOW_EMPTY_VALUE, bl); sp.setAllowEmptyValue(bl); } Property prop = PropertyBuilder.build(type, format, map); - if(prop != null) { + if (prop != null) { sp.setProperty(prop); ObjectNode items = getObject("items", obj, false, location, result); - if(items != null) { + if (items != null) { Property inner = schema(null, items, location, result); sp.setItems(inner); } } Set keys = getKeys(obj); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { sp.setVendorExtension(key, extension(obj.get(key))); - } - else if(!PARAMETER_KEYS.contains(key)) { + } else if (!PARAMETER_KEYS.contains(key)) { result.extra(location, key, obj.get(key)); } } @@ -647,41 +641,39 @@ else if(!PARAMETER_KEYS.contains(key)) { sp.setCollectionFormat(collectionFormat); output = sp; - } - else if ("body".equals(value)) { + } else if ("body".equals(value)) { BodyParameter bp = new BodyParameter(); JsonNode node = obj.get("schema"); - if(node != null && node instanceof ObjectNode) { - bp.setSchema(this.definition((ObjectNode)node, location, result)); + if (node != null && node instanceof ObjectNode) { + bp.setSchema(this.definition((ObjectNode) node, location, result)); } // examples ObjectNode examplesNode = getObject("examples", obj, false, location, result); - if(examplesNode != null) { + if (examplesNode != null) { Map examples = Json.mapper().convertValue(examplesNode, Json.mapper().getTypeFactory().constructMapType(Map.class, String.class, Object.class)); bp.setExamples(examples); } // pattern String pat = getString("pattern", obj, false, location, result); - if(pat != null) { + if (pat != null) { bp.setPattern(pat); } // readOnly Boolean bl = getBoolean("readOnly", obj, false, location, result); - if(bl != null) { + if (bl != null) { bp.setReadOnly(bl); } // vendor extensions Set keys = getKeys(obj); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { bp.setVendorExtension(key, extension(obj.get(key))); - } - else if(!BODY_PARAMETER_KEYS.contains(key)) { + } else if (!BODY_PARAMETER_KEYS.contains(key)) { result.extra(location, key, obj.get(key)); } } @@ -689,7 +681,7 @@ else if(!BODY_PARAMETER_KEYS.contains(key)) { // output = Json.mapper().convertValue(obj, Parameter.class); } - if(output != null) { + if (output != null) { value = getString("name", obj, true, location, result); output.setName(value); @@ -697,7 +689,7 @@ else if(!BODY_PARAMETER_KEYS.contains(key)) { output.setDescription(value); Boolean required = getBoolean("required", obj, false, location, result); - if(required != null) { + if (required != null) { output.setRequired(required); } } @@ -722,7 +714,7 @@ private Property schema(Map schemaItems, JsonNode obj, String lo public RefParameter refParameter(TextNode obj, String location, ParseResult result) { return new RefParameter(obj.asText()); } - + public RefResponse refResponse(TextNode obj, String location, ParseResult result) { return new RefResponse(obj.asText()); } @@ -734,21 +726,20 @@ public Path pathRef(TextNode ref, String location, ParseResult result) { return output; } - public Map definitions (ObjectNode node, String location, ParseResult result) { - if(node == null) + public Map definitions(ObjectNode node, String location, ParseResult result) { + if (node == null) return null; Set schemas = getKeys(node); Map output = new LinkedHashMap(); - for(String schemaName : schemas) { + for (String schemaName : schemas) { JsonNode schema = node.get(schemaName); - if(schema.getNodeType().equals(JsonNodeType.OBJECT)) { + if (schema.getNodeType().equals(JsonNodeType.OBJECT)) { Model model = definition((ObjectNode) schema, location + "." + schemaName, result); - if(model != null) { + if (model != null) { output.put(schemaName, model); } - } - else { + } else { result.invalidType(location, schemaName, "object", schema); } } @@ -756,18 +747,18 @@ public Map definitions (ObjectNode node, String location, ParseRe } public Model definition(ObjectNode node, String location, ParseResult result) { - if(result == null) { + if (result == null) { // TODO, this shouldn't happen, but the `ResolverCache#loadRef` method is passing null result = new ParseResult(); } - if(node == null) { + if (node == null) { result.missing(location, "empty schema"); return null; } - if(node.get("$ref") != null) { + if (node.get("$ref") != null) { return refModel(node, location, result); } - if(node.get("allOf") != null) { + if (node.get("allOf") != null) { return allOfModel(node, location, result); } Model model = null; @@ -775,7 +766,7 @@ public Model definition(ObjectNode node, String location, ParseResult result) { String type = getString("type", node, false, location, result); Model m = new ModelImpl(); - if("array".equals(type)) { + if ("array".equals(type)) { ArrayModel am = new ArrayModel(); ObjectNode propertyNode = getObject("properties", node, false, location, result); Map properties = properties(propertyNode, location, result); @@ -784,7 +775,7 @@ public Model definition(ObjectNode node, String location, ParseResult result) { ObjectNode itemsNode = getObject("items", node, false, location, result); Property items = property(itemsNode, location, result); - if(items != null) { + if (items != null) { am.items(items); } @@ -795,32 +786,31 @@ public Model definition(ObjectNode node, String location, ParseResult result) { am.setMinItems(minItems); Boolean uniqueItems = getBoolean("uniqueItems", node, false, location, result); - if(uniqueItems != null) { + if (uniqueItems != null) { am.setUniqueItems(uniqueItems); } // add xml specific information if available JsonNode xml = node.get("xml"); - if(xml != null) { + if (xml != null) { am.setXml(Json.mapper().convertValue(xml, Xml.class)); } - + // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { am.setVendorExtension(key, extension(node.get(key))); } } model = am; - } - else { + } else { ModelImpl impl = new ModelImpl(); impl.setType(type); JsonNode ap = node.get("additionalProperties"); - if(ap != null && ap.getNodeType().equals(JsonNodeType.OBJECT)) { + if (ap != null && ap.getNodeType().equals(JsonNodeType.OBJECT)) { impl.setAdditionalProperties(Json.mapper().convertValue(ap, Property.class)); } @@ -834,7 +824,7 @@ public Model definition(ObjectNode node, String location, ParseResult result) { impl.setDiscriminator(value); Boolean bp = getBoolean("uniqueItems", node, false, location, result); - if(bp != null) { + if (bp != null) { impl.setUniqueItems(bp); } @@ -846,12 +836,12 @@ public Model definition(ObjectNode node, String location, ParseResult result) { impl.setMaximum(bd); bp = getBoolean("exclusiveMaximum", node, false, location, result); - if(bp != null) { + if (bp != null) { impl.setExclusiveMaximum(bp); } bp = getBoolean("exclusiveMinimum", node, false, location, result); - if(bp != null) { + if (bp != null) { impl.setExclusiveMinimum(bp); } @@ -859,40 +849,39 @@ public Model definition(ObjectNode node, String location, ParseResult result) { impl.setPattern(value); BigDecimal maximum = getBigDecimal("maximum", node, false, location, result); - if(maximum != null) { + if (maximum != null) { impl.maximum(maximum); } BigDecimal minimum = getBigDecimal("minimum", node, false, location, result); - if(minimum != null) { + if (minimum != null) { impl.minimum(minimum); } Integer minLength = getInteger("minLength", node, false, location, result); - if(minLength != null) { + if (minLength != null) { impl.setMinLength(minLength); } Integer maxLength = getInteger("maxLength", node, false, location, result); - if(maxLength != null) { + if (maxLength != null) { impl.setMaxLength(maxLength); } BigDecimal multipleOf = getBigDecimal("multipleOf", node, false, location, result); - if(multipleOf != null) { + if (multipleOf != null) { impl.setMultipleOf(multipleOf); } ap = node.get("enum"); - if(ap != null) { + if (ap != null) { ArrayNode arrayNode = getArray("enum", node, false, location, result); - if(arrayNode != null) { - for(JsonNode n : arrayNode) { - if(n.isValueNode()) { + if (arrayNode != null) { + for (JsonNode n : arrayNode) { + if (n.isValueNode()) { impl._enum(n.asText()); - } - else { + } else { result.invalidType(location, "enum", "value", n); } } @@ -900,7 +889,7 @@ public Model definition(ObjectNode node, String location, ParseResult result) { } JsonNode xml = node.get("xml"); - if(xml != null) { + if (xml != null) { impl.setXml(Json.mapper().convertValue(xml, Xml.class)); } @@ -908,44 +897,42 @@ public Model definition(ObjectNode node, String location, ParseResult result) { ExternalDocs docs = externalDocs(externalDocs, location, result); impl.setExternalDocs(docs); - addProperties(location,node,result,impl); + addProperties(location, node, result, impl); // need to set properties first ArrayNode required = getArray("required", node, false, location, result); - if(required != null) { + if (required != null) { List requiredProperties = new ArrayList(); for (JsonNode n : required) { - if(n.getNodeType().equals(JsonNodeType.STRING)) { + if (n.getNodeType().equals(JsonNodeType.STRING)) { requiredProperties.add(((TextNode) n).textValue()); - } - else { + } else { result.invalidType(location, "required", "string", n); } } - if(requiredProperties.size() > 0) { + if (requiredProperties.size() > 0) { impl.setRequired(requiredProperties); } } // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { impl.setVendorExtension(key, extension(node.get(key))); - } - else if(!SCHEMA_KEYS.contains(key)) { + } else if (!SCHEMA_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } model = impl; } JsonNode exampleNode = node.get("example"); - if(exampleNode != null) { + if (exampleNode != null) { Object example = Json.mapper().convertValue(exampleNode, Object.class); model.setExample(example); } - if(model != null) { + if (model != null) { value = getString("description", node, false, location, result); model.setDescription(value); @@ -965,27 +952,25 @@ public Model allOfModel(ObjectNode node, String location, ParseResult result) { JsonNode allOf = node.get("allOf"); if (sub != null) { - if(sub.getNodeType().equals(JsonNodeType.OBJECT)) { - return refModel((ObjectNode)sub, location, result); - } - else { + if (sub.getNodeType().equals(JsonNodeType.OBJECT)) { + return refModel((ObjectNode) sub, location, result); + } else { result.invalidType(location, "$ref", "object", sub); return null; } } else if (allOf != null) { ComposedModel model = null; - if(allOf.getNodeType().equals(JsonNodeType.ARRAY)) { + if (allOf.getNodeType().equals(JsonNodeType.ARRAY)) { model = new ComposedModel(); int pos = 0; - for(JsonNode part : allOf) { - if(part.getNodeType().equals(JsonNodeType.OBJECT)) { + for (JsonNode part : allOf) { + if (part.getNodeType().equals(JsonNodeType.OBJECT)) { Model segment = definition((ObjectNode) part, location, result); - if(segment != null) { + if (segment != null) { model.getAllOf().add(segment); } - } - else { + } else { result.invalidType(location, "allOf[" + pos + "]", "object", part); } pos++; @@ -1003,25 +988,22 @@ public Model allOfModel(ObjectNode node, String location, ParseResult result) { } model.setInterfaces(interfaces); - if(child != null) { + if (child != null) { model.setChild(child); } - } - else { + } else { result.invalidType(location, "allOf", "array", allOf); } // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { model.setVendorExtension(key, extension(node.get(key))); - } - else if(!SCHEMA_KEYS.contains(key)) { + } else if (!SCHEMA_KEYS.contains(key)) { result.extra(location, key, node.get(key)); - } - else { + } else { String value = getString("title", node, false, location, result); model.setTitle(value); @@ -1030,7 +1012,7 @@ else if(!SCHEMA_KEYS.contains(key)) { } } - addProperties(location,node,result,model); + addProperties(location, node, result, model); return model; } @@ -1039,21 +1021,20 @@ else if(!SCHEMA_KEYS.contains(key)) { private void addProperties(String location, ObjectNode node, ParseResult result, AbstractModel model) { ObjectNode properties = getObject("properties", node, false, location, result); - if(properties != null) { + if (properties != null) { Set propertyNames = getKeys(properties); - for(String propertyName : propertyNames) { + for (String propertyName : propertyNames) { JsonNode propertyNode = properties.get(propertyName); - if(propertyNode.getNodeType().equals(JsonNodeType.OBJECT)) { + if (propertyNode.getNodeType().equals(JsonNodeType.OBJECT)) { ObjectNode on = (ObjectNode) propertyNode; Property property = property(on, location, result); - if(property != null) { + if (property != null) { if ("array".equals(property.getType()) && !(property instanceof ArrayProperty && ((ArrayProperty) property).getItems() != null)) { result.missing(location, "items"); } } model.addProperty(propertyName, property); - } - else { + } else { result.invalidType(location, "properties", "object", propertyNode); } } @@ -1061,19 +1042,18 @@ private void addProperties(String location, ObjectNode node, ParseResult result, } public Map properties(ObjectNode node, String location, ParseResult result) { - if(node == null) { + if (node == null) { return null; } Map output = new LinkedHashMap(); Set keys = getKeys(node); - for(String propertyName : keys) { + for (String propertyName : keys) { JsonNode propertyNode = node.get(propertyName); - if(propertyNode.getNodeType().equals(JsonNodeType.OBJECT)) { - Property property = property((ObjectNode)propertyNode, location, result); + if (propertyNode.getNodeType().equals(JsonNodeType.OBJECT)) { + Property property = property((ObjectNode) propertyNode, location, result); output.put(propertyName, property); - } - else { + } else { result.invalidType(location, propertyName, "object", propertyNode); } } @@ -1081,11 +1061,11 @@ public Map properties(ObjectNode node, String location, ParseR } public Property property(ObjectNode node, String location, ParseResult result) { - if(node != null) { - if(node.get("type") == null) { + if (node != null) { + if (node.get("type") == null) { // may have an enum where type can be inferred JsonNode enumNode = node.get("enum"); - if(enumNode != null && enumNode.isArray()) { + if (enumNode != null && enumNode.isArray()) { String type = inferTypeFromArray((ArrayNode) enumNode); node.put("type", type); } @@ -1096,29 +1076,25 @@ public Property property(ObjectNode node, String location, ParseResult result) { } public String inferTypeFromArray(ArrayNode an) { - if(an.size() == 0) { + if (an.size() == 0) { return "string"; } String type = null; - for(int i = 0; i < an.size(); i++) { + for (int i = 0; i < an.size(); i++) { JsonNode element = an.get(0); - if(element.isBoolean()) { - if(type == null) { + if (element.isBoolean()) { + if (type == null) { type = "boolean"; - } - else if(!"boolean".equals(type)) { + } else if (!"boolean".equals(type)) { type = "string"; } - } - else if(element.isNumber()) { - if(type == null) { + } else if (element.isNumber()) { + if (type == null) { type = "number"; - } - else if(!"number".equals(type)) { + } else if (!"number".equals(type)) { type = "string"; } - } - else { + } else { type = "string"; } } @@ -1129,19 +1105,18 @@ else if(!"number".equals(type)) { public RefModel refModel(ObjectNode node, String location, ParseResult result) { RefModel output = new RefModel(); - if(node.getNodeType().equals(JsonNodeType.OBJECT)) { - String refValue = ((TextNode)node.get("$ref")).textValue(); + if (node.getNodeType().equals(JsonNodeType.OBJECT)) { + String refValue = ((TextNode) node.get("$ref")).textValue(); output.set$ref(refValue); - } - else { + } else { result.invalidType(location, "$ref", "object", node); return null; } // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(!REF_MODEL_KEYS.contains(key)) { + for (String key : keys) { + if (!REF_MODEL_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } @@ -1150,18 +1125,17 @@ public RefModel refModel(ObjectNode node, String location, ParseResult result) { } public Map responses(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; Map output = new TreeMap(); Set keys = getKeys(node); - for(String key : keys) { + for (String key : keys) { if (key.startsWith("x-")) { - } - else { + } else { ObjectNode obj = getObject(key, node, false, location + ".responses", result); Response response = response(obj, location + "." + key, result); output.put(key, response); @@ -1172,17 +1146,16 @@ public Map responses(ObjectNode node, String location, ParseRe } public Response response(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; Response output = new Response(); JsonNode ref = node.get("$ref"); - if(ref != null) { - if(ref.getNodeType().equals(JsonNodeType.STRING)) { + if (ref != null) { + if (ref.getNodeType().equals(JsonNodeType.STRING)) { return refResponse((TextNode) ref, location, result); - } - else { + } else { result.invalidType(location, "$ref", "string", node); return null; } @@ -1192,7 +1165,7 @@ public Response response(ObjectNode node, String location, ParseResult result) { output.description(value); ObjectNode schema = getObject("schema", node, false, location, result); - if(schema != null) { + if (schema != null) { JsonNode schemaRef = schema.get("$ref"); if (schemaRef != null) { if (schemaRef.getNodeType().equals(JsonNodeType.STRING)) { @@ -1207,7 +1180,7 @@ public Response response(ObjectNode node, String location, ParseResult result) { } ObjectNode headersNode = getObject("headers", node, false, location, result); - if(headersNode != null) { + if (headersNode != null) { // TODO Map headers = Json.mapper().convertValue(headersNode, Json.mapper().getTypeFactory().constructMapType(Map.class, String.class, Property.class)); @@ -1215,18 +1188,17 @@ public Response response(ObjectNode node, String location, ParseResult result) { } ObjectNode examplesNode = getObject("examples", node, false, location, result); - if(examplesNode != null) { + if (examplesNode != null) { Map examples = Json.mapper().convertValue(examplesNode, Json.mapper().getTypeFactory().constructMapType(Map.class, String.class, Object.class)); output.setExamples(examples); } // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { output.setVendorExtension(key, extension(node.get(key))); - } - else if(!RESPONSE_KEYS.contains(key)) { + } else if (!RESPONSE_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } @@ -1234,7 +1206,7 @@ else if(!RESPONSE_KEYS.contains(key)) { } public Info info(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; Info info = new Info(); @@ -1260,11 +1232,10 @@ public Info info(ObjectNode node, String location, ParseResult result) { // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { info.setVendorExtension(key, extension(node.get(key))); - } - else if(!INFO_KEYS.contains(key)) { + } else if (!INFO_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } @@ -1273,7 +1244,7 @@ else if(!INFO_KEYS.contains(key)) { } public License license(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; License license = new License(); @@ -1286,11 +1257,10 @@ public License license(ObjectNode node, String location, ParseResult result) { // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { license.setVendorExtension(key, extension(node.get(key))); - } - else if(!LICENSE_KEYS.contains(key)) { + } else if (!LICENSE_KEYS.contains(key)) { result.extra(location + ".license", key, node.get(key)); } } @@ -1299,7 +1269,7 @@ else if(!LICENSE_KEYS.contains(key)) { } public Contact contact(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; Contact contact = new Contact(); @@ -1315,11 +1285,10 @@ public Contact contact(ObjectNode node, String location, ParseResult result) { // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { contact.setVendorExtension(key, extension(node.get(key))); - } - else if(!CONTACT_KEYS.contains(key)) { + } else if (!CONTACT_KEYS.contains(key)) { result.extra(location + ".contact", key, node.get(key)); } } @@ -1328,17 +1297,17 @@ else if(!CONTACT_KEYS.contains(key)) { } public Map securityDefinitions(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; Map output = new LinkedHashMap<>(); Set keys = getKeys(node); - for(String key : keys) { + for (String key : keys) { ObjectNode obj = getObject(key, node, false, location, result); SecuritySchemeDefinition def = securityDefinition(obj, location + "." + key, result); - if(def != null) { + if (def != null) { output.put(key, def); } } @@ -1347,24 +1316,23 @@ public Map securityDefinitions(ObjectNode node } public SecuritySchemeDefinition securityDefinition(ObjectNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; SecuritySchemeDefinition output = null; String type = getString("type", node, true, location, result); - if(type != null) { - if(type.equals("basic")) { + if (type != null) { + if (type.equals("basic")) { // TODO: parse manually for better feedback output = Json.mapper().convertValue(node, BasicAuthDefinition.class); - } - else if (type.equals("apiKey")) { + } else if (type.equals("apiKey")) { String position = getString("in", node, true, location, result); String name = getString("name", node, true, location, result); - if(name != null && ("header".equals(position) || "query".equals(position))) { + if (name != null && ("header".equals(position) || "query".equals(position))) { In in = In.forValue(position); - if(in != null) { + if (in != null) { output = new ApiKeyAuthDefinition() .name(name) .in(in); @@ -1373,29 +1341,26 @@ else if (type.equals("apiKey")) { } } JsonNode desc = node.get("description"); - if(desc != null) { + if (desc != null) { output.setDescription(desc.textValue()); } - } - else if (type.equals("oauth2")) { + } else if (type.equals("oauth2")) { // TODO: parse manually for better feedback output = Json.mapper().convertValue(node, OAuth2Definition.class); JsonNode desc = node.get("description"); - if(desc != null) { + if (desc != null) { output.setDescription(desc.textValue()); } - } - else { + } else { result.invalidType(location + ".type", "type", "basic|apiKey|oauth2", node); } - + // extra keys Set keys = getKeys(node); - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { output.setVendorExtension(key, extension(node.get(key))); - } - else if(!SECURITY_SCHEME_KEYS.contains(key)) { + } else if (!SECURITY_SCHEME_KEYS.contains(key)) { result.extra(location, key, node.get(key)); } } @@ -1406,14 +1371,14 @@ else if(!SECURITY_SCHEME_KEYS.contains(key)) { } public List securityRequirements(ArrayNode node, String location, ParseResult result) { - if(node == null) + if (node == null) return null; List output = new ArrayList(); - for(JsonNode item : node) { + for (JsonNode item : node) { SecurityRequirement security = new SecurityRequirement(); - if(item.getNodeType().equals(JsonNodeType.OBJECT)) { + if (item.getNodeType().equals(JsonNodeType.OBJECT)) { ObjectNode on = (ObjectNode) item; Set keys = getKeys(on); @@ -1440,13 +1405,13 @@ public List securityRequirements(ArrayNode node, String loc public List tagStrings(ArrayNode nodes, String location, ParseResult result) { - if(nodes == null) + if (nodes == null) return null; List output = new ArrayList(); - for(JsonNode node : nodes) { - if(node.getNodeType().equals(JsonNodeType.STRING)) { + for (JsonNode node : nodes) { + if (node.getNodeType().equals(JsonNodeType.STRING)) { output.add(node.textValue()); } } @@ -1454,15 +1419,15 @@ public List tagStrings(ArrayNode nodes, String location, ParseResult res } public List tags(ArrayNode nodes, String location, ParseResult result) { - if(nodes == null) + if (nodes == null) return null; List output = new ArrayList(); - for(JsonNode node : nodes) { - if(node.getNodeType().equals(JsonNodeType.OBJECT)) { + for (JsonNode node : nodes) { + if (node.getNodeType().equals(JsonNodeType.OBJECT)) { Tag tag = tag((ObjectNode) node, location + ".tags", result); - if(tag != null) { + if (tag != null) { output.add(tag); } } @@ -1474,7 +1439,7 @@ public List tags(ArrayNode nodes, String location, ParseResult result) { public Tag tag(ObjectNode node, String location, ParseResult result) { Tag tag = null; - if(node != null) { + if (node != null) { tag = new Tag(); Set keys = getKeys(node); @@ -1489,11 +1454,10 @@ public Tag tag(ObjectNode node, String location, ParseResult result) { tag.externalDocs(docs); // extra keys - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { tag.setVendorExtension(key, extension(node.get(key))); - } - else if(!TAG_KEYS.contains(key)) { + } else if (!TAG_KEYS.contains(key)) { result.extra(location + ".externalDocs", key, node.get(key)); } } @@ -1505,7 +1469,7 @@ else if(!TAG_KEYS.contains(key)) { public ExternalDocs externalDocs(ObjectNode node, String location, ParseResult result) { ExternalDocs output = null; - if(node != null) { + if (node != null) { output = new ExternalDocs(); Set keys = getKeys(node); @@ -1516,11 +1480,10 @@ public ExternalDocs externalDocs(ObjectNode node, String location, ParseResult r output.url(value); // extra keys - for(String key : keys) { - if(key.startsWith("x-")) { + for (String key : keys) { + if (key.startsWith("x-")) { output.setVendorExtension(key, extension(node.get(key))); - } - else if(!EXTERNAL_DOCS_KEYS.contains(key)) { + } else if (!EXTERNAL_DOCS_KEYS.contains(key)) { result.extra(location + ".externalDocs", key, node.get(key)); } } @@ -1531,10 +1494,9 @@ else if(!EXTERNAL_DOCS_KEYS.contains(key)) { public String getString(JsonNode node, String location, ParseResult result) { String output = null; - if(!node.getNodeType().equals(JsonNodeType.STRING)) { + if (!node.getNodeType().equals(JsonNodeType.STRING)) { result.invalidType(location, "", "string", node); - } - else { + } else { output = ((TextNode) node).asText(); } return output; @@ -1543,16 +1505,14 @@ public String getString(JsonNode node, String location, ParseResult result) { public ArrayNode getArray(String key, ObjectNode node, boolean required, String location, ParseResult result) { JsonNode value = node.get(key); ArrayNode an = null; - if(value == null) { - if(required) { + if (value == null) { + if (required) { result.missing(location, key); result.invalid(); } - } - else if(!value.getNodeType().equals(JsonNodeType.ARRAY)) { + } else if (!value.getNodeType().equals(JsonNodeType.ARRAY)) { result.invalidType(location, key, "array", value); - } - else { + } else { an = (ArrayNode) value; } return an; @@ -1561,19 +1521,17 @@ else if(!value.getNodeType().equals(JsonNodeType.ARRAY)) { public ObjectNode getObject(String key, ObjectNode node, boolean required, String location, ParseResult result) { JsonNode value = node.get(key); ObjectNode on = null; - if(value == null) { - if(required) { + if (value == null) { + if (required) { result.missing(location, key); result.invalid(); } - } - else if(!value.getNodeType().equals(JsonNodeType.OBJECT)) { + } else if (!value.getNodeType().equals(JsonNodeType.OBJECT)) { result.invalidType(location, key, "object", value); - if(required) { + if (required) { result.invalid(); } - } - else { + } else { on = (ObjectNode) value; } return on; @@ -1587,11 +1545,9 @@ public BigDecimal getBigDecimal(String key, ObjectNode node, boolean required, S result.missing(location, key); result.invalid(); } - } - else if(v.getNodeType().equals(JsonNodeType.NUMBER)) { + } else if (v.getNodeType().equals(JsonNodeType.NUMBER)) { value = new BigDecimal(v.asText()); - } - else if(!v.isValueNode()) { + } else if (!v.isValueNode()) { result.invalidType(location, key, "double", node); } return value; @@ -1605,11 +1561,9 @@ public Number getNumber(String key, ObjectNode node, boolean required, String lo result.missing(location, key); result.invalid(); } - } - else if(v.getNodeType().equals(JsonNodeType.NUMBER)) { + } else if (v.getNodeType().equals(JsonNodeType.NUMBER)) { value = v.numberValue(); - } - else if(!v.isValueNode()) { + } else if (!v.isValueNode()) { result.invalidType(location, key, "number", node); } return value; @@ -1623,11 +1577,9 @@ public Integer getInteger(String key, ObjectNode node, boolean required, String result.missing(location, key); result.invalid(); } - } - else if(v.getNodeType().equals(JsonNodeType.NUMBER)) { + } else if (v.getNodeType().equals(JsonNodeType.NUMBER)) { value = v.intValue(); - } - else if(!v.isValueNode()) { + } else if (!v.isValueNode()) { result.invalidType(location, key, "integer", node); } return value; @@ -1645,11 +1597,9 @@ public String getString(String key, ObjectNode node, boolean required, String lo result.missing(location, key); result.invalid(); } - } - else if(!v.isValueNode()) { + } else if (!v.isValueNode()) { result.invalidType(location, key, "string", node); - } - else { + } else { value = v.asText(); if (uniqueValues != null && !uniqueValues.add(value)) { result.unique(location, "operationId"); @@ -1661,7 +1611,7 @@ else if(!v.isValueNode()) { public Set getKeys(ObjectNode node) { Set keys = new LinkedHashSet<>(); - if(node == null) { + if (node == null) { return keys; } @@ -1705,7 +1655,7 @@ public void warning(String location, String key) { warnings.add(new Location(location, key)); } - public void invalidType(String location, String key, String expectedType, JsonNode value){ + public void invalidType(String location, String key, String expectedType, JsonNode value) { invalidType.put(new Location(location, key), expectedType); } @@ -1755,24 +1705,24 @@ public void setMissing(List missing) { public List getMessages() { List messages = new ArrayList(); - for(Location l : extra.keySet()) { + for (Location l : extra.keySet()) { String location = l.location.equals("") ? "" : l.location + "."; String message = "attribute " + location + l.key + " is unexpected"; messages.add(message); } - for(Location l : invalidType.keySet()) { + for (Location l : invalidType.keySet()) { String location = l.location.equals("") ? "" : l.location + "."; String message = "attribute " + location + l.key + " is not of type `" + invalidType.get(l) + "`"; messages.add(message); } - for(Location l : missing) { + for (Location l : missing) { String location = l.location.equals("") ? "" : l.location + "."; String message = "attribute " + location + l.key + " is missing"; messages.add(message); } for (Location l : warnings) { String location = l.location.equals("") ? "" : l.location + "."; - String message = "attribute " + location +l.key; + String message = "attribute " + location + l.key; messages.add(message); } for (Location l : unique) { @@ -1780,7 +1730,7 @@ public List getMessages() { String message = "attribute " + location + l.key + " is repeated"; messages.add(message); } - for(Location l : unsupported.keySet()) { + for (Location l : unsupported.keySet()) { String location = l.location.equals("") ? "" : l.location + "."; String message = "attribute " + location + l.key + " is unsupported"; messages.add(message); @@ -1812,6 +1762,7 @@ public int hashCode() { } private String key; + public Location(String location, String key) { this.location = location; this.key = key; diff --git a/modules/swagger-parser/src/test/java/io/swagger/parser/SwaggerParserTest.java b/modules/swagger-parser/src/test/java/io/swagger/parser/SwaggerParserTest.java index 3e06daef06..82ab91e891 100644 --- a/modules/swagger-parser/src/test/java/io/swagger/parser/SwaggerParserTest.java +++ b/modules/swagger-parser/src/test/java/io/swagger/parser/SwaggerParserTest.java @@ -57,7 +57,7 @@ public class SwaggerParserTest { @Test - public void testIssue1143(){ + public void testIssue1143() { SwaggerDeserializationResult result = new SwaggerParser().readWithInfo("issue1143.json", null, true); assertNotNull(result.getSwagger().getDefinitions().get("RedisResource")); assertNotNull(result.getSwagger().getDefinitions().get("identificacion_usuario_aplicacion")); @@ -79,9 +79,17 @@ public void testIssue1169() { assertNotNull(result.getSwagger()); } + @Test + public void testIssue1249() { + SwaggerDeserializationResult result = new SwaggerParser().readWithInfo("issue-1249.json", null, true); + Assert.assertEquals(result.getMessages().size(), 1); + assertEquals("attribute paths.'user'. For path parameter 'user' the required value should be true", result.getMessages().get(0)); + assertNotNull(result.getSwagger()); + } + @Test - public void testIssueRelativeRefs2(){ + public void testIssueRelativeRefs2() { String location = "exampleSpecs/specs/my-domain/test-api/v1/test-api-swagger_v1.json"; Swagger swagger = new SwaggerParser().read(location, null, true); assertNotNull(swagger); @@ -90,7 +98,7 @@ public void testIssueRelativeRefs2(){ ArrayProperty arraySchema = (ArrayProperty) definitions.get("confirmMessageType_v01").getProperties().get("resources"); ObjectProperty prop = (ObjectProperty) arraySchema.getItems(); RefProperty refProperty = (RefProperty) prop.getProperties().get("resourceID"); - assertEquals(refProperty.get$ref(),"#/definitions/simpleIDType_v01"); + assertEquals(refProperty.get$ref(), "#/definitions/simpleIDType_v01"); } @Test @@ -145,15 +153,15 @@ public void testIssue901_2() { assertNotNull(swagger.getDefinitions()); ArrayProperty arraySchema = (ArrayProperty) swagger.getDefinitions().get("Test.Definition").getProperties().get("stuff"); String internalRef = ((RefProperty) arraySchema.getItems()).get$ref(); - assertEquals(internalRef,"#/definitions/TEST.THING.OUT.Stuff"); + assertEquals(internalRef, "#/definitions/TEST.THING.OUT.Stuff"); } @Test public void testIssue901() { Swagger swagger = new SwaggerParser().read("issue-901/spec.yaml"); assertNotNull(swagger); - String internalRef = ((RefModel)swagger.getPaths().get("/test").getPut().getResponses().get("200").getResponseSchema()).get$ref(); - assertEquals(internalRef,"#/definitions/Test.Definition"); + String internalRef = ((RefModel) swagger.getPaths().get("/test").getPut().getResponses().get("200").getResponseSchema()).get$ref(); + assertEquals(internalRef, "#/definitions/Test.Definition"); assertNotNull(swagger.getDefinitions()); } @@ -171,13 +179,13 @@ public void testIssue845() { SwaggerDeserializationResult swaggerDeserializationResult = new SwaggerParser().readWithInfo(""); assertEquals(swaggerDeserializationResult.getMessages().get(0), "empty or null swagger supplied"); } - + @Test public void testIssue834() { Swagger swagger = new SwaggerParser().read("issue-834/index.yaml", null, true); assertNotNull(swagger); - Response foo200 =swagger.getPaths().get("/foo").getGet().getResponses().get("200"); + Response foo200 = swagger.getPaths().get("/foo").getGet().getResponses().get("200"); assertNotNull(foo200); RefModel model200 = (RefModel) foo200.getResponseSchema(); String foo200SchemaRef = model200.get$ref(); @@ -201,7 +209,7 @@ public void testIssue811_RefSchema_ToRefSchema() { final Swagger swagger = new SwaggerParser().read("oapi-reference-test2/index.yaml", null, true); Assert.assertNotNull(swagger); RefModel model = (RefModel) swagger.getPaths().get("/").getGet().getResponses().get("200").getResponseSchema(); - Assert.assertEquals(model.get$ref() ,"#/definitions/schema-with-reference"); + Assert.assertEquals(model.get$ref(), "#/definitions/schema-with-reference"); } @Test @@ -211,7 +219,7 @@ public void testIssue811() throws Exception { Assert.assertNotNull(swagger); assertTrue(swagger.getPaths().get("/").getGet().getResponses().get("200").getResponseSchema() instanceof RefModel); RefModel model = (RefModel) swagger.getPaths().get("/").getGet().getResponses().get("200").getResponseSchema(); - Assert.assertEquals(model.get$ref(),"#/definitions/schema-with-reference"); + Assert.assertEquals(model.get$ref(), "#/definitions/schema-with-reference"); } @@ -297,10 +305,11 @@ public void testRefPaths() throws Exception { Swagger swagger = parser.parse(yaml); - assertEquals(swagger.getPaths().get("foo"),swagger.getPaths().get("foo2")); - + assertEquals(swagger.getPaths().get("foo"), swagger.getPaths().get("foo2")); + } + @Test public void testModelParameters() throws Exception { String yaml = "swagger: '2.0'\n" + @@ -463,7 +472,6 @@ public void testLoadRelativeFileTree_Json() throws Exception { } - @Test public void testPetstore() throws Exception { SwaggerParser parser = new SwaggerParser(); @@ -531,7 +539,7 @@ public void testLoadnestedExternalResponseReferencesFile_Yaml() throws Exception final Swagger swagger = doRelativeResponseFileTest("src/test/resources/nested-external-response-references/swagger-root.yaml"); assertNotNull(Yaml.mapper().writeValueAsString(swagger)); } - + @Test public void testLoadRecursiveExternalDef() throws Exception { SwaggerParser parser = new SwaggerParser(); @@ -721,7 +729,7 @@ public void testIssue292WithCSVCollectionFormat() { QueryParameter qp = (QueryParameter) param; assertEquals(qp.getCollectionFormat(), "csv"); } - + @Test public void testIssue286() { SwaggerParser parser = new SwaggerParser(); @@ -740,7 +748,7 @@ public void testIssue286WithModel() { Swagger swagger = parser.read("issue_286.yaml"); Model response = swagger.getPath("/").getGet().getResponses().get("200").getResponseSchema(); assertTrue(response instanceof RefModel); - assertEquals( "issue_286_PetList", ((RefModel) response).getSimpleRef()); + assertEquals("issue_286_PetList", ((RefModel) response).getSimpleRef()); assertNotNull(swagger.getDefinitions().get("issue_286_Allergy")); } @@ -870,14 +878,14 @@ private Swagger doRelativeFileTest(String location) { private Swagger doRelativeResponseFileTest(String location) { SwaggerParser parser = new SwaggerParser(); SwaggerDeserializationResult readResult = parser.readWithInfo(location, null, true); - + if (readResult.getMessages().size() > 0) { Json.prettyPrint(readResult.getMessages()); } final Swagger swagger = readResult.getSwagger(); - + Json.prettyPrint(swagger); - + final Path path = swagger.getPath("/users"); assertEquals(path.getClass(), Path.class); //we successfully converted the RefPath to a Path @@ -901,12 +909,12 @@ private Swagger doRelativeResponseFileTest(String location) { expectedPropertiesInModel(refInDefinitionsAddress_2, "postal", "country"); final ModelImpl refInDefinitionsCountry_2 = (ModelImpl) definitions.get("Country_2"); - expectedPropertiesInModel(refInDefinitionsCountry_2, "name"); - + expectedPropertiesInModel(refInDefinitionsCountry_2, "name"); + return swagger; } - - + + private void expectedPropertiesInModel(ModelImpl model, String... expectedProperties) { assertEquals(model.getProperties().size(), expectedProperties.length); for (String expectedProperty : expectedProperties) { @@ -941,7 +949,7 @@ public void testNestedReferences() { assertTrue(swagger.getDefinitions().containsKey("externalObject")); assertTrue(swagger.getDefinitions().containsKey("referencedByLocalElement")); assertTrue(swagger.getDefinitions().containsKey("referencedBy")); - assertEquals(((RefProperty)swagger.getDefinitions().get("externalObject").getProperties().get("hello1")).get$ref(), + assertEquals(((RefProperty) swagger.getDefinitions().get("externalObject").getProperties().get("hello1")).get$ref(), "#/definitions/referencedByLocalElement"); //issue #434 } @@ -1048,12 +1056,12 @@ public void testConverterIssue17() throws Exception { " collectionFormat: csv\n" + " responses:\n" + " 200:\n" + - " description: Successful response\n"+ + " description: Successful response\n" + " schema:\n" + " $ref: '#/definitions/Content'\n" + "definitions:\n" + - " Content:\n" + - " type: object"; + " Content:\n" + + " type: object"; SwaggerDeserializationResult result = new SwaggerParser().readWithInfo(yaml, Boolean.FALSE); assertNotNull(result.getSwagger()); @@ -1132,12 +1140,13 @@ public void testBadFormat() throws Exception { assertEquals(queryParameter.getCollectionFormat(), "multi"); assertEquals(queryParameter.isUniqueItems(), true); } + @Test public void testNumberAttributes() throws Exception { SwaggerParser parser = new SwaggerParser(); Swagger swagger = parser.read(TestUtils.getResourceAbsolutePath("/number_attributes.yaml")); - ModelImpl numberType = (ModelImpl)swagger.getDefinitions().get("NumberType"); + ModelImpl numberType = (ModelImpl) swagger.getDefinitions().get("NumberType"); assertNotNull(numberType); assertNotNull(numberType.getEnum()); assertEquals(numberType.getEnum().size(), 2); @@ -1148,7 +1157,7 @@ public void testNumberAttributes() throws Exception { assertEquals(numberType.getMinimum(), new BigDecimal("1.0")); assertEquals(numberType.getMaximum(), new BigDecimal("2.0")); - ModelImpl numberDoubleType = (ModelImpl)swagger.getDefinitions().get("NumberDoubleType"); + ModelImpl numberDoubleType = (ModelImpl) swagger.getDefinitions().get("NumberDoubleType"); assertNotNull(numberDoubleType); assertNotNull(numberDoubleType.getEnum()); assertEquals(numberDoubleType.getEnum().size(), 2); @@ -1159,7 +1168,7 @@ public void testNumberAttributes() throws Exception { assertEquals(numberDoubleType.getMinimum(), new BigDecimal("1.0")); assertEquals(numberDoubleType.getMaximum(), new BigDecimal("2.0")); - ModelImpl integerType = (ModelImpl)swagger.getDefinitions().get("IntegerType"); + ModelImpl integerType = (ModelImpl) swagger.getDefinitions().get("IntegerType"); assertNotNull(integerType); assertNotNull(integerType.getEnum()); assertEquals(integerType.getEnum().size(), 2); @@ -1170,7 +1179,7 @@ public void testNumberAttributes() throws Exception { assertEquals(integerType.getMinimum(), new BigDecimal("1")); assertEquals(integerType.getMaximum(), new BigDecimal("2")); - ModelImpl integerInt32Type = (ModelImpl)swagger.getDefinitions().get("IntegerInt32Type"); + ModelImpl integerInt32Type = (ModelImpl) swagger.getDefinitions().get("IntegerInt32Type"); assertNotNull(integerInt32Type); assertNotNull(integerInt32Type.getEnum()); assertEquals(integerInt32Type.getEnum().size(), 2); @@ -1192,43 +1201,43 @@ public void testDefinitionExample() throws Exception { ModelImpl model; ArrayModel arrayModel; - model = (ModelImpl)swagger.getDefinitions().get("NumberType"); - assertEquals((Double)model.getExample(), 2.0d, 0d); + model = (ModelImpl) swagger.getDefinitions().get("NumberType"); + assertEquals((Double) model.getExample(), 2.0d, 0d); - model = (ModelImpl)swagger.getDefinitions().get("IntegerType"); - assertEquals((int)model.getExample(), 2); + model = (ModelImpl) swagger.getDefinitions().get("IntegerType"); + assertEquals((int) model.getExample(), 2); - model = (ModelImpl)swagger.getDefinitions().get("StringType"); - assertEquals((String)model.getExample(), "2"); + model = (ModelImpl) swagger.getDefinitions().get("StringType"); + assertEquals((String) model.getExample(), "2"); - model = (ModelImpl)swagger.getDefinitions().get("ObjectType"); + model = (ModelImpl) swagger.getDefinitions().get("ObjectType"); assertTrue(model.getExample() instanceof Map); Map objectExample = (Map) model.getExample(); - assertEquals((String)objectExample.get("propertyA"), "valueA"); - assertEquals((Integer)objectExample.get("propertyB"), new Integer(123)); + assertEquals((String) objectExample.get("propertyA"), "valueA"); + assertEquals((Integer) objectExample.get("propertyB"), new Integer(123)); - arrayModel = (ArrayModel)swagger.getDefinitions().get("ArrayType"); + arrayModel = (ArrayModel) swagger.getDefinitions().get("ArrayType"); assertTrue(arrayModel.getExample() instanceof List); List arrayExample = (List) arrayModel.getExample(); - assertEquals((String)arrayExample.get(0).get("propertyA"), "valueA1"); - assertEquals((Integer)arrayExample.get(0).get("propertyB"), new Integer(123)); - assertEquals((String)arrayExample.get(1).get("propertyA"), "valueA2"); - assertEquals((Integer)arrayExample.get(1).get("propertyB"), new Integer(456)); + assertEquals((String) arrayExample.get(0).get("propertyA"), "valueA1"); + assertEquals((Integer) arrayExample.get(0).get("propertyB"), new Integer(123)); + assertEquals((String) arrayExample.get(1).get("propertyA"), "valueA2"); + assertEquals((Integer) arrayExample.get(1).get("propertyB"), new Integer(456)); - model = (ModelImpl)swagger.getDefinitions().get("NumberTypeStringExample"); - assertEquals((String)model.getExample(), "2.0"); + model = (ModelImpl) swagger.getDefinitions().get("NumberTypeStringExample"); + assertEquals((String) model.getExample(), "2.0"); - model = (ModelImpl)swagger.getDefinitions().get("IntegerTypeStringExample"); - assertEquals((String)model.getExample(), "2"); + model = (ModelImpl) swagger.getDefinitions().get("IntegerTypeStringExample"); + assertEquals((String) model.getExample(), "2"); - model = (ModelImpl)swagger.getDefinitions().get("StringTypeStringExample"); - assertEquals((String)model.getExample(), "2"); + model = (ModelImpl) swagger.getDefinitions().get("StringTypeStringExample"); + assertEquals((String) model.getExample(), "2"); - model = (ModelImpl)swagger.getDefinitions().get("ObjectTypeStringExample"); - assertEquals((String)model.getExample(), "{\"propertyA\": \"valueA\", \"propertyB\": 123}"); + model = (ModelImpl) swagger.getDefinitions().get("ObjectTypeStringExample"); + assertEquals((String) model.getExample(), "{\"propertyA\": \"valueA\", \"propertyB\": 123}"); arrayModel = (ArrayModel) swagger.getDefinitions().get("ArrayTypeStringExample"); - assertEquals((String)arrayModel.getExample(), "[{\"propertyA\": \"valueA1\", \"propertyB\": 123}, {\"propertyA\": \"valueA2\", \"propertyB\": 456}]"); + assertEquals((String) arrayModel.getExample(), "[{\"propertyA\": \"valueA1\", \"propertyB\": 123}, {\"propertyA\": \"valueA2\", \"propertyB\": 456}]"); } @Test @@ -1339,8 +1348,8 @@ public void testIssue594() { " description: 'OK'\n"; SwaggerDeserializationResult result = new SwaggerParser().readWithInfo(yaml); assertNotNull(result.getSwagger()); - ArrayModel schema = (ArrayModel)((BodyParameter)result.getSwagger().getPaths().get("/test").getPost().getParameters().get(0)).getSchema(); - assertEquals(((RefProperty)schema.getItems()).get$ref(),"#/definitions/Pet"); + ArrayModel schema = (ArrayModel) ((BodyParameter) result.getSwagger().getPaths().get("/test").getPost().getParameters().get(0)).getSchema(); + assertEquals(((RefProperty) schema.getItems()).get$ref(), "#/definitions/Pet"); assertNotNull(schema.getMaxItems()); assertNotNull(schema.getMinItems()); @@ -1454,7 +1463,7 @@ public void readingSpecNodeShouldNotOverQuotingStringExample() throws Exception String yaml = Files.readFile(new File("src/test/resources/over-quoted-example.yaml")); JsonNode rootNode = Yaml.mapper().readValue(yaml, JsonNode.class); SwaggerParser parser = new SwaggerParser(); - Swagger swagger = parser.read(rootNode,true); + Swagger swagger = parser.read(rootNode, true); Map definitions = swagger.getDefinitions(); assertEquals("NoQuotePlease", definitions.get("CustomerType").getExample()); @@ -1480,7 +1489,7 @@ public void testRefAdditionalProperties() throws Exception { Assert.assertNotNull(swagger); Assert.assertTrue(swagger.getDefinitions().size() == 3); - + Assert.assertNotNull(swagger.getDefinitions().get("link-object")); Assert.assertNotNull(swagger.getDefinitions().get("rel-data")); Assert.assertNotNull(swagger.getDefinitions().get("result")); @@ -1562,6 +1571,6 @@ public void testIssue913() { final Swagger swagger = parser.read("src/test/resources/issue-913/BS/ApiSpecification.yaml"); Assert.assertNotNull(swagger); Assert.assertNotNull(swagger.getDefinitions().get("indicatorType")); - Assert.assertEquals(swagger.getDefinitions().get("indicatorType").getProperties().size(),1); + Assert.assertEquals(swagger.getDefinitions().get("indicatorType").getProperties().size(), 1); } } diff --git a/modules/swagger-parser/src/test/resources/issue-1249.json b/modules/swagger-parser/src/test/resources/issue-1249.json new file mode 100644 index 0000000000..77d4c122df --- /dev/null +++ b/modules/swagger-parser/src/test/resources/issue-1249.json @@ -0,0 +1,35 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Example API" + }, + "host": "example.com", + "basePath": "/", + "paths": { + "/api/admin/{account}/users/{user}": { + "post": { + "operationId": "addUser", + "parameters": [ + { + "name": "account", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "user", + "in": "path", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + } + } +} \ No newline at end of file From fa73c86d05f78fa42e14a3c3d5aaede58708dce2 Mon Sep 17 00:00:00 2001 From: Gokul Raj S <56819171+GORA-SAG@users.noreply.github.com> Date: Fri, 31 Jan 2020 12:31:44 +0530 Subject: [PATCH 2/2] Fix for issue #1249 adopted test testArrayParameterDefaultValue in SwaggerDeserializerTest --- .../java/io/swagger/parser/util/SwaggerDeserializerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-parser/src/test/java/io/swagger/parser/util/SwaggerDeserializerTest.java b/modules/swagger-parser/src/test/java/io/swagger/parser/util/SwaggerDeserializerTest.java index 5b2dae71a0..7f7fae1c8b 100644 --- a/modules/swagger-parser/src/test/java/io/swagger/parser/util/SwaggerDeserializerTest.java +++ b/modules/swagger-parser/src/test/java/io/swagger/parser/util/SwaggerDeserializerTest.java @@ -1672,7 +1672,7 @@ public void testArrayParameterDefaultValue() { SwaggerDeserializationResult result = parser.readWithInfo(swaggerSpec); List messageList = result.getMessages(); Set messages = new HashSet(messageList); - assertEquals(0, messages.size()); + assertEquals(1, messages.size()); Swagger swagger = result.getSwagger(); List parameters = swagger.getPaths().get("/test").getGet().getParameters();