Repository: swagger-api/swagger-parser
Pull request #1482 (2020-11-05 22:14:01)

fixed bug related to nested definitions within subfolder
In this pull request we have fix for nested references for external references within subfolder.


Patch:
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
index 0dd95535..520abaa5 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java
@@ -1,7 +1,9 @@
 package io.swagger.v3.parser.processors;
 
 
+import java.io.File;
 import java.net.URI;
+import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -111,7 +113,12 @@ public final class ExternalRefProcessor {
             if (schema.get$ref() != null) {
                 RefFormat ref = computeRefFormat(schema.get$ref());
                 if (isAnExternalRefFormat(ref)) {
-                    schema.set$ref(processRefToExternalSchema(schema.get$ref(), ref));
+                    String schemaFullRef = schema.get$ref();
+                    String parent = file.substring(0, file.lastIndexOf(File.separatorChar));
+                    if (!parent.isEmpty()) {
+                        schemaFullRef = Paths.get(parent, schemaFullRef).normalize().toString();
+                    }
+                    schema.set$ref(processRefToExternalSchema(schemaFullRef, ref));
                 } else {
                     processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE);
                 }


Test patch:
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
index a560af9e..5df69f71 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
@@ -1296,6 +1296,69 @@ public class OpenAPIV3ParserTest {
         assertEquals( definitions.get("k").getTitle(), "k-definition");
     }
 
+    @Test
+    public void testLoadExternalNestedDefinitionsWithReferenceWithinSubfolder() throws Exception {
+        OpenAPIV3Parser parser = new OpenAPIV3Parser();
+        final OpenAPI openAPI = parser.read("src/test/resources/nested-references-2/main.yaml");
+
+        Map<String, Schema> definitions = openAPI.getComponents().getSchemas();
+        assertTrue(definitions.containsKey("GreetingResponse"));
+        assertTrue(definitions.containsKey("GreetingMessage"));
+        assertTrue(definitions.containsKey("greeting-message"));
+
+        String greetingMessageRef = ((Schema) definitions.get("GreetingResponse")
+                .getProperties().get("GreetingMessage")).get$ref();
+
+        assertEquals(greetingMessageRef,"#/components/schemas/GreetingMessage");
+        assertEquals(definitions.get("GreetingMessage").get$ref(),"#/components/schemas/greeting-message");
+
+        String description = ((Schema)definitions.get("greeting-message")
+                .getProperties().get("Text")).getDescription();
+        assertEquals(description,"Text message");
+    }
+
+    @Test
+    public void testLoadExternalNestedDefinitionsWithReferenceWithinSameFolder() throws Exception {
+        OpenAPIV3Parser parser = new OpenAPIV3Parser();
+        final OpenAPI openAPI = parser.read("src/test/resources/nested-references-3/main.yaml");
+
+        Map<String, Schema> definitions = openAPI.getComponents().getSchemas();
+        assertTrue(definitions.containsKey("GreetingResponse"));
+        assertTrue(definitions.containsKey("GreetingMessage"));
+        assertTrue(definitions.containsKey("greeting-message"));
+
+        String greetingMessageRef = ((Schema) definitions.get("GreetingResponse")
+                .getProperties().get("GreetingMessage")).get$ref();
+
+        assertEquals(greetingMessageRef,"#/components/schemas/GreetingMessage");
+        assertEquals(definitions.get("GreetingMessage").get$ref(),"#/components/schemas/greeting-message");
+
+        String description = ((Schema)definitions.get("greeting-message")
+                .getProperties().get("Text")).getDescription();
+        assertEquals(description,"Text message");
+    }
+
+    @Test
+    public void testLoadExternalNestedDefinitionsWithReferenceOnDifferentFolderLevels() throws Exception {
+        OpenAPIV3Parser parser = new OpenAPIV3Parser();
+        final OpenAPI openAPI = parser.read("src/test/resources/nested-references-4/main.yaml");
+
+        Map<String, Schema> definitions = openAPI.getComponents().getSchemas();
+        assertTrue(definitions.containsKey("GreetingResponse"));
+        assertTrue(definitions.containsKey("GreetingMessage"));
+        assertTrue(definitions.containsKey("greeting-message"));
+
+        String greetingMessageRef = ((Schema) definitions.get("GreetingResponse")
+                .getProperties().get("GreetingMessage")).get$ref();
+
+        assertEquals(greetingMessageRef,"#/components/schemas/GreetingMessage");
+        assertEquals(definitions.get("GreetingMessage").get$ref(),"#/components/schemas/greeting-message");
+
+        String description = ((Schema)definitions.get("greeting-message")
+                .getProperties().get("Text")).getDescription();
+        assertEquals(description,"Text message");
+    }
+
     @Test
     public void testPetstore() throws Exception {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-2/main.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-2/main.yaml
new file mode 100644
index 00000000..298e87d0
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-2/main.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: test
+  version: '0.0.0'
+paths: {}
+components:
+  schemas:
+    GreetingResponse:
+      $ref: "./schemas/greeting-response.yaml"
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-message.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-message.yaml
new file mode 100644
index 00000000..b538ef7f
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-message.yaml
@@ -0,0 +1,5 @@
+type: object
+properties:
+  Text:
+    description: Text message
+    type: string
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-response.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-response.yaml
new file mode 100644
index 00000000..e9a18bec
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/greeting-response.yaml
@@ -0,0 +1,4 @@
+type: object
+properties:
+  GreetingMessage:
+    $ref: ./shared-defs.yaml#/components/schemas/GreetingMessage
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/shared-defs.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/shared-defs.yaml
new file mode 100644
index 00000000..c75f566d
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-2/schemas/shared-defs.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: shared test
+  version: '0.0.0'
+paths: { }
+components:
+  schemas:
+    GreetingMessage:
+      $ref: ./greeting-message.yaml
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-message.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-message.yaml
new file mode 100644
index 00000000..b538ef7f
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-message.yaml
@@ -0,0 +1,5 @@
+type: object
+properties:
+  Text:
+    description: Text message
+    type: string
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-response.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-response.yaml
new file mode 100644
index 00000000..e9a18bec
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-3/greeting-response.yaml
@@ -0,0 +1,4 @@
+type: object
+properties:
+  GreetingMessage:
+    $ref: ./shared-defs.yaml#/components/schemas/GreetingMessage
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-3/main.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-3/main.yaml
new file mode 100644
index 00000000..a3fd1e89
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-3/main.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: test
+  version: '0.0.0'
+paths: {}
+components:
+  schemas:
+    GreetingResponse:
+      $ref: "./greeting-response.yaml"
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-3/shared-defs.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-3/shared-defs.yaml
new file mode 100644
index 00000000..c75f566d
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-3/shared-defs.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: shared test
+  version: '0.0.0'
+paths: { }
+components:
+  schemas:
+    GreetingMessage:
+      $ref: ./greeting-message.yaml
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-4/main.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-4/main.yaml
new file mode 100644
index 00000000..8f9b58f9
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-4/main.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: test
+  version: '0.0.0'
+paths: {}
+components:
+  schemas:
+    GreetingResponse:
+      $ref: "./schemas/sub/greeting-response.yaml"
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/shared-defs.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/shared-defs.yaml
new file mode 100644
index 00000000..9817ea1e
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/shared-defs.yaml
@@ -0,0 +1,10 @@
+---
+openapi: "3.0.0"
+info:
+  title: shared test
+  version: '0.0.0'
+paths: { }
+components:
+  schemas:
+    GreetingMessage:
+      $ref: ./sub/greeting-message.yaml
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-message.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-message.yaml
new file mode 100644
index 00000000..b538ef7f
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-message.yaml
@@ -0,0 +1,5 @@
+type: object
+properties:
+  Text:
+    description: Text message
+    type: string
diff --git a/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-response.yaml b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-response.yaml
new file mode 100644
index 00000000..a93ba08a
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/nested-references-4/schemas/sub/greeting-response.yaml
@@ -0,0 +1,4 @@
+type: object
+properties:
+  GreetingMessage:
+    $ref: ../shared-defs.yaml#/components/schemas/GreetingMessage