Repository: swagger-api/swagger-parser
Pull request #919 (2018-11-09 06:55:25)

Fix for issue 918
Hi team,

This PR is to solve the issue #918 (Headers Internal Ref Not Resolved).

Please review the PR and merge the same.

Thanks,
Mohammed Rizwan


Patch:
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java
index 17523795..8502da69 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java
@@ -5,6 +5,7 @@ import io.swagger.v3.oas.models.Operation;
 import io.swagger.v3.oas.models.PathItem;
 import io.swagger.v3.oas.models.callbacks.Callback;
 import io.swagger.v3.oas.models.examples.Example;
+import io.swagger.v3.oas.models.headers.Header;
 import io.swagger.v3.oas.models.links.Link;
 import io.swagger.v3.oas.models.media.ArraySchema;
 import io.swagger.v3.oas.models.media.ComposedSchema;
@@ -50,6 +51,7 @@ public class ResolverFully {
     private Map<String, Example> examples;
     private Map<String, Parameter> parameters;
     private Map<String, RequestBody> requestBodies;
+    private Map<String, Header> headers;
     private Map<String, Link> links;
 
     public void resolveFully(OpenAPI openAPI) {
@@ -74,6 +76,12 @@ public class ResolverFully {
             }
         }
 
+        if (openAPI.getComponents() != null && openAPI.getComponents().getHeaders() != null) {
+            headers = openAPI.getComponents().getHeaders();
+            if (headers == null) {
+                headers = new HashMap<>();
+            }
+        }  
 
         if (openAPI.getComponents() != null && openAPI.getComponents().getParameters() != null) {
             parameters = openAPI.getComponents().getParameters();
@@ -85,7 +93,6 @@ public class ResolverFully {
             links = openAPI.getComponents().getLinks();
             if (links == null) {
                 links = new HashMap<>();
-
             }
         }
 
@@ -174,6 +181,21 @@ public class ResolverFully {
                             }
                         }
                     }
+
+                    Map<String, Header> headers = response.getHeaders();
+                    if (headers != null) {
+                        for (Map.Entry<String, Header> header : headers.entrySet()) {
+                            Header value = header.getValue();
+                            Header resolvedValue = value.get$ref() != null ? resolveHeader(value) : value;
+                            Map<String, Example> examples = resolvedValue.getExamples();
+                            if(examples != null) {
+                                Map<String,Example> resolved = resolveExample(examples);
+                                resolvedValue.setExamples(resolved);
+                            }
+                            header.setValue(resolvedValue);
+                        }
+                    }  
+
                     Map<String, Link> links = response.getLinks();
                     if (links != null) {
                         for (Map.Entry<String, Link> link : links.entrySet()) {
@@ -187,6 +209,18 @@ public class ResolverFully {
         }
     }
 
+    public Header resolveHeader(Header header){
+        RefFormat refFormat = computeRefFormat(header.get$ref());
+        String $ref = header.get$ref();
+        if (!isAnExternalRefFormat(refFormat)){
+            if (headers != null && !headers.isEmpty()) {
+                String referenceKey = computeDefinitionName($ref);
+                return headers.getOrDefault(referenceKey, header);
+            }
+        }
+        return header;
+    }
+  
     public Link resolveLink(Link link){
         RefFormat refFormat = computeRefFormat(link.get$ref());
         String $ref = link.get$ref();


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 8e3e2804..8e4754b9 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
@@ -12,6 +12,7 @@ import io.swagger.v3.oas.models.Components;
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.oas.models.Operation;
 import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.headers.Header;
 import io.swagger.v3.oas.models.links.Link;
 import io.swagger.v3.oas.models.media.*;
 import io.swagger.v3.oas.models.examples.Example;
@@ -1539,6 +1540,15 @@ public class OpenAPIV3ParserTest {
     }
 
     @Test
+    public void testIssue915() {
+        ParseOptions parseOptions = new ParseOptions();
+        parseOptions.setResolveFully(true);
+        OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/issue_918.yaml", null, parseOptions);
+        Map<String, Header> headers = openAPI.getPaths().get("/2.0/users/").getGet().getResponses().get("200").getHeaders();
+        String description = headers.get("X-Rate-Limit").getDescription();
+        assertEquals(description, "The number of allowed requests in the current period");
+    }
+
     public void shouldParseParameters() {
         ParseOptions parseOptions = new ParseOptions();
         parseOptions.setResolveFully(true);
diff --git a/modules/swagger-parser-v3/src/test/resources/issue_918.yaml b/modules/swagger-parser-v3/src/test/resources/issue_918.yaml
new file mode 100644
index 00000000..568cf9e4
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/issue_918.yaml
@@ -0,0 +1,20 @@
+openapi: 3.0.0
+info:
+  title: headers in components
+  version: 1.0.0
+paths:
+  /2.0/users/:
+    get:
+      operationId: getUserByName
+      responses:
+        '200':
+          description: The User
+          headers:
+            X-Rate-Limit:
+              $ref: "#/components/headers/X-Rate-Limit-Ref"
+components:
+  headers:
+    X-Rate-Limit-Ref:
+      description: The number of allowed requests in the current period
+      schema:
+        type: integer
\ No newline at end of file