From 41583139290706b3977f61aea7a71e2ffaf25653 Mon Sep 17 00:00:00 2001 From: Mohammed Rizwan Date: Fri, 12 Oct 2018 16:07:55 +0530 Subject: [PATCH] Fix for issue 258 (Code roll-in to Swagger 2.0) --- .../parser/util/SwaggerDeserializer.java | 22 ++++++++++++++- .../io/swagger/parser/SwaggerParserTest.java | 8 ++++++ .../test/resources/duplicateOperationId.json | 27 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 modules/swagger-parser/src/test/resources/duplicateOperationId.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 03d656bdc3..4227f734fb 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 @@ -32,6 +32,8 @@ public class SwaggerDeserializer { 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")); + private final Set operationIDs = new HashSet<>(); + public SwaggerDeserializationResult deserialize(JsonNode rootNode) { SwaggerDeserializationResult result = new SwaggerDeserializationResult(); ParseResult rootParse = new ParseResult(); @@ -301,7 +303,7 @@ public Operation operation(ObjectNode obj, String location, ParseResult result) ExternalDocs docs = externalDocs(externalDocs, location, result); output.setExternalDocs(docs); - value = getString("operationId", obj, false, location, result); + value = getString("operationId", obj, false, location, result, operationIDs); output.operationId(value); array = getArray("consumes", obj, false, location, result); @@ -1577,6 +1579,10 @@ else if(!v.isValueNode()) { } public String getString(String key, ObjectNode node, boolean required, String location, ParseResult result) { + return getString(key, node, required, location, result, null); + } + + public String getString(String key, ObjectNode node, boolean required, String location, ParseResult result, Set uniqueValues) { String value = null; JsonNode v = node.get(key); if (node == null || v == null) { @@ -1590,6 +1596,10 @@ else if(!v.isValueNode()) { } else { value = v.asText(); + if (uniqueValues != null && !uniqueValues.add(value)) { + result.unique(location, "operationId"); + result.invalid(); + } } return value; } @@ -1614,6 +1624,7 @@ protected static class ParseResult { private Map unsupported = new LinkedHashMap(); private Map invalidType = new LinkedHashMap(); private List missing = new ArrayList(); + private List unique = new ArrayList<>(); public ParseResult() { } @@ -1626,6 +1637,10 @@ public void extra(String location, String key, JsonNode value) { extra.put(new Location(location, key), value); } + public void unique(String location, String key) { + unique.add(new Location(location, key)); + } + public void missing(String location, String key) { missing.add(new Location(location, key)); } @@ -1695,6 +1710,11 @@ public List getMessages() { String message = "attribute " + location + l.key + " is missing"; messages.add(message); } + for (Location l : unique) { + String location = l.location.equals("") ? "" : l.location + "."; + String message = "attribute " + location + l.key + " is repeated"; + messages.add(message); + } for(Location l : unsupported.keySet()) { String location = l.location.equals("") ? "" : l.location + "."; String message = "attribute " + location + l.key + " is unsupported"; 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 17bfd1d08d..37e9150d1f 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 @@ -1248,4 +1248,12 @@ public void testIssue844() { assertEquals(swagger.getSwagger().getPath("/pets/{id}").getGet().getParameters().get(0).getIn(), "header"); } + @Test + public void testIssue258() { + SwaggerDeserializationResult result = new SwaggerParser().readWithInfo("duplicateOperationId.json", null, true); + assertNotNull(result); + assertNotNull(result.getSwagger()); + assertEquals(result.getMessages().get(0), "attribute paths.'/pets/{id}'(post).operationId is repeated"); + } + } \ No newline at end of file diff --git a/modules/swagger-parser/src/test/resources/duplicateOperationId.json b/modules/swagger-parser/src/test/resources/duplicateOperationId.json new file mode 100644 index 0000000000..dbf40cb429 --- /dev/null +++ b/modules/swagger-parser/src/test/resources/duplicateOperationId.json @@ -0,0 +1,27 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.9-abcd", + "title": "Duplicate operationID" + }, + "paths": { + "/pets/{id}": { + "get": { + "operationId": "getPetsById", + "responses": { + "default": { + "description": "error payload" + } + } + }, + "post": { + "operationId": "getPetsById", + "responses": { + "default": { + "description": "error payload" + } + } + } + } + } +} \ No newline at end of file