Repository: swagger-api/swagger-parser
Pull request #1104 (2019-05-24 16:12:56)

Remote PathItem Resolving - issue #1103


Patch:
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
index 280ebc68..608e1325 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ComponentsProcessor.java
@@ -221,13 +221,13 @@ public class ComponentsProcessor {
 
             schemaProcessor.processSchema(model);
 
-            //if we process a RefModel here, in the #/definitions table, we want to overwrite it with the referenced value
+            //if we process a RefModel here, in the #/components/schemas table, we want to overwrite it with the referenced value
             if (model.get$ref() != null) {
                 final String renamedRef = cache.getRenamedRef(originalRef);
 
                 if (renamedRef != null) {
-                    //we definitely resolved the referenced and shoved it in the definitions map
-                    // because the referenced model may be in the definitions map, we need to remove old instances
+                    //we definitely resolved the referenced and shoved it in the components map
+                    // because the referenced model may be in the components map, we need to remove old instances
                     final Schema resolvedModel = schemas.get(renamedRef);
 
                     // ensure the reference isn't still in use
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
index 0c4c55a3..8c5ce7f0 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java
@@ -162,6 +162,11 @@ public class PathsProcessor {
     }
 
     protected void updateLocalRefs(ApiResponse response, String pathRef) {
+        if (response.get$ref() != null){
+            if(isLocalRef(response.get$ref())) {
+                response.set$ref(computeLocalRef(response.get$ref(), pathRef));
+            }
+        }
         if(response.getContent() != null) {
             Map<String, MediaType> content = response.getContent();
             for (String key: content.keySet()) {
@@ -188,6 +193,11 @@ public class PathsProcessor {
     }
 
     protected void updateLocalRefs(Parameter param, String pathRef) {
+        if (param.get$ref() != null){
+            if(isLocalRef(param.get$ref())) {
+                param.set$ref(computeLocalRef(param.get$ref(), pathRef));
+            }
+        }
         if(param.getSchema() != null) {
             updateLocalRefs(param.getSchema(), pathRef);
         }
@@ -204,6 +214,11 @@ public class PathsProcessor {
     }
 
     protected void updateLocalRefs(RequestBody body, String pathRef) {
+        if (body.get$ref() != null){
+            if(isLocalRef(body.get$ref())) {
+                body.set$ref(computeLocalRef(body.get$ref(), pathRef));
+            }
+        }
         if(body.getContent() != null) {
             Map<String, MediaType> content = body.getContent();
             for (String key: content.keySet()) {


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 c40a1105..c843d6f8 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
@@ -275,8 +275,6 @@ public class OpenAPIV3ParserTest {
 
         Assert.assertNotNull(openAPI);
         Assert.assertEquals(openAPI.getPaths().get("/").getGet().getResponses().get("200").getContent().get("application/json").getSchema().get$ref(),"#/components/schemas/schema-with-reference");
-
-
     }
 
     @Test
@@ -286,7 +284,6 @@ public class OpenAPIV3ParserTest {
         final OpenAPI openAPI = new OpenAPIV3Parser().readLocation("oapi-reference-test/index.yaml", null, options).getOpenAPI();
 
         Assert.assertNotNull(openAPI);
-
         Assert.assertEquals(openAPI.getPaths().get("/").getGet().getResponses().get("200").getContent().get("application/json").getSchema().get$ref(),"#/components/schemas/schema-with-reference");
 
     }
@@ -296,7 +293,6 @@ public class OpenAPIV3ParserTest {
         final OpenAPI openAPI = new OpenAPIV3Parser().readLocation("extensions-responses.yaml", null, new ParseOptions()).getOpenAPI();
 
         Assert.assertNotNull(openAPI);
-
         Assert.assertNotNull(openAPI.getPaths().getExtensions());
         Assert.assertNotNull(openAPI.getPaths().get("/something").getGet().getResponses().getExtensions());
 
@@ -483,8 +479,6 @@ public class OpenAPIV3ParserTest {
 
     @Test
     public void testResolveFully() throws Exception{
-
-
         String pathFile = FileUtils.readFileToString(new File("src/test/resources/oas3.yaml.template"));
         pathFile = pathFile.replace("${dynamicPort}", String.valueOf(this.serverPort));
         ParseOptions options = new ParseOptions();
@@ -498,6 +492,8 @@ public class OpenAPIV3ParserTest {
         assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object");
     }
 
+
+
     @Test
     public void testResolveEmpty(@Injectable final List<AuthorizationValue> auths) throws Exception{
         String pathFile = FileUtils.readFileToString(new File("src/test/resources/empty-oas.yaml"));
@@ -512,12 +508,9 @@ public class OpenAPIV3ParserTest {
 
     @Test
     public void testResolveFullyExample() throws Exception{
-
-
         String pathFile = FileUtils.readFileToString(new File("src/test/resources/oas3.yaml.template"));
         pathFile = pathFile.replace("${dynamicPort}", String.valueOf(this.serverPort));
         ParseOptions options = new ParseOptions();
-        //options.setResolve(true);
         options.setResolveFully(true);
 
         SwaggerParseResult result = new OpenAPIV3Parser().readContents(pathFile, new ArrayList<>(), options  );
@@ -558,8 +551,25 @@ public class OpenAPIV3ParserTest {
     }
 
     @Test
-    public void test30NoOptions(@Injectable final List<AuthorizationValue> auths) throws Exception{
+    public void testRemotePathItemIssue1103(@Injectable final List<AuthorizationValue> auths) throws Exception{
+        OpenAPI result = new OpenAPIV3Parser().read("issue-1103/remote-pathItem-swagger.yaml");
+        Assert.assertNotNull(result);
+        Assert.assertNotNull(result.getPaths().get("/Translation/{lang}"));
+        Assert.assertEquals(result.getPaths().get("/Translation/{lang}").getPut().getParameters().get(0).getName(), "lang");
+    }
+
 
+
+    @Test
+    public void testRemoteParameterIssue1103(@Injectable final List<AuthorizationValue> auths) throws Exception{
+        OpenAPI result = new OpenAPIV3Parser().read("issue-1103/remote-parameter-swagger.yaml");
+        Assert.assertNotNull(result);
+        Assert.assertEquals(result.getPaths().get("/Translation/{lang}").getPut().getParameters().get(0).getName(), "lang");
+
+    }
+
+    @Test
+    public void test30NoOptions(@Injectable final List<AuthorizationValue> auths) throws Exception{
         String pathFile = FileUtils.readFileToString(new File("src/test/resources/oas3.yaml.template"));
         pathFile = pathFile.replace("${dynamicPort}", String.valueOf(this.serverPort));
 
@@ -573,7 +583,6 @@ public class OpenAPIV3ParserTest {
 
     @Test
     public void testShellMethod(@Injectable final List<AuthorizationValue> auths){
-
         String url = "http://localhost:${dynamicPort}/remote/spec";
         url = url.replace("${dynamicPort}", String.valueOf(this.serverPort));
 
@@ -584,7 +593,6 @@ public class OpenAPIV3ParserTest {
 
     @Test
     public void testInlineModelResolverByUrl(){
-
         String url = "http://localhost:${dynamicPort}/remote/json";
         url = url.replace("${dynamicPort}", String.valueOf(this.serverPort));
 
@@ -665,7 +673,6 @@ public class OpenAPIV3ParserTest {
         OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/composedSchemaRef.yaml", auths, options);
 
         Assert.assertNotNull(openAPI);
-
         Assert.assertTrue(openAPI.getComponents().getSchemas().size() == 5);
         Schema schema = openAPI.getPaths().get("/path").getGet().getResponses().get("200").getContent().get("application/json").getSchema();
         Assert.assertTrue(schema instanceof ComposedSchema);
@@ -708,9 +715,7 @@ public class OpenAPIV3ParserTest {
                 "    $ref: '#/paths/~1foo'";
 
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
-
         OpenAPI openAPI = (parser.readContents(yaml,null,null)).getOpenAPI();
-
         assertEquals(openAPI.getPaths().get("foo"),openAPI.getPaths().get("foo2"));
 
 
@@ -738,7 +743,6 @@ public class OpenAPIV3ParserTest {
                 "          description: ok";
 
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
-
         OpenAPI openAPI = (parser.readContents(yaml,null,null)).getOpenAPI();
 
     }
@@ -886,7 +890,6 @@ public class OpenAPIV3ParserTest {
     @Test
     public void testLoadRelativeFileTree_Json() throws Exception {
         final OpenAPI openAPI = doRelativeFileTest("src/test/resources/relative-file-references/json/parent.json");
-        //Json.mapper().writerWithDefaultPrettyPrinter().writeValue(new File("resolved.json"), openAPI);
     }
 
     @Test
@@ -999,7 +1002,6 @@ public class OpenAPIV3ParserTest {
 
         assertNotNull(model);
         assertTrue(model instanceof ArraySchema);
-
         ArraySchema am = (ArraySchema) model;
         assertTrue(am.getItems() instanceof ByteArraySchema);
         assertEquals(am.getItems().getFormat(), "byte");
@@ -1009,7 +1011,6 @@ public class OpenAPIV3ParserTest {
     public void testIssue62() {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
         final OpenAPI openAPI = parser.read("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/fixtures/v2.0/json/resources/resourceWithLinkedDefinitions.json");
-
         assertNotNull(openAPI.getPaths().get("/pets/{petId}").getGet());
     }
 
@@ -1028,7 +1029,6 @@ public class OpenAPIV3ParserTest {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
         final OpenAPI openAPI = parser.read("src/test/resources/petstore.yaml");
         final List<Parameter> operationParams = openAPI.getPaths().get("/pet/{petId}").getPost().getParameters();
-
         final PathParameter pathParameter = (PathParameter) operationParams.get(0);
         Assert.assertTrue(pathParameter.getRequired());
     }
@@ -1037,7 +1037,6 @@ public class OpenAPIV3ParserTest {
     public void testIssue108() {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
         final OpenAPI openAPI = parser.read("src/test/resources/issue_108.yaml");
-
         assertNotNull(openAPI);
     }
 
@@ -1106,7 +1105,6 @@ public class OpenAPIV3ParserTest {
     @Test
     public void testIssue255() {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
-
         OpenAPI openAPI = parser.read("objectExample.yaml");
         assertEquals(openAPI.getComponents().getSchemas().get("SamplePayload").getExample().toString(), "[{\"op\":\"replace\",\"path\":\"/s\",\"v\":\"w\"}]");
     }
@@ -1114,7 +1112,6 @@ public class OpenAPIV3ParserTest {
     @Test
     public void testIssue286() {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
-
         OpenAPI openAPI = parser.read("issue_286.yaml");
         Schema response = openAPI.getPaths().get("/").getGet().getResponses().get("200").getContent().get("*/*").getSchema();
         assertTrue(response.get$ref() != null);
@@ -1160,15 +1157,10 @@ public class OpenAPIV3ParserTest {
 
         assertEquals(sbpModel.getType(), "string");
         assertEquals(sbpModel.getFormat(), "uuid");
-
         RequestBody bodyParameter = openAPI.getPaths().get("/evenMorePets").getPost().getRequestBody();
-
         assertTrue(bodyParameter.getRequired());
-
         Schema refModel = bodyParameter.getContent().get("application/json").getSchema();
         assertTrue(refModel.get$ref() != null);
-
-
         assertEquals(refModel.get$ref(), "#/components/schemas/Pet");
     }
 
@@ -1182,10 +1174,7 @@ public class OpenAPIV3ParserTest {
             Json.prettyPrint(readResult.getMessages());
         }
         final OpenAPI openAPI = readResult.getOpenAPI();
-
-
         final PathItem path = openAPI.getPaths().get("/health");
-
         assertEquals(path.getClass(), PathItem.class); //we successfully converted the RefPath to a Path
 
         final List<Parameter> parameters = path.getParameters();
@@ -1197,7 +1186,6 @@ public class OpenAPIV3ParserTest {
         assertParamDetails(operationParams, 0, PathParameter.class, "param3", "path");
         assertParamDetails(operationParams, 1, HeaderParameter.class, "param4", "header");
 
-
         final Map<String, ApiResponse> responsesMap = operation.getResponses();
 
         assertResponse(openAPI, responsesMap, "200","application/json", "Health information from the server", "#/components/schemas/health");
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java
index 101dba9f..5e5a10e1 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java
@@ -2304,8 +2304,6 @@ public class OpenAPIDeserializerTest {
         Assert.assertEquals(server.get(2).getExtensions().get("x-server").toString(),"server extension");
         Assert.assertEquals(server.get(2).getVariables().get("basePath").getDescription(),"testing overwriting");
         Assert.assertEquals(server.get(2).getVariables().get("basePath").getDefault(),"v2");
-
-
     }
 
     @Test
@@ -2321,6 +2319,7 @@ public class OpenAPIDeserializerTest {
         final OpenAPI openAPI = result.getOpenAPI();
         Assert.assertNotNull(openAPI);
 
+
         assertEquals(openAPI.getServers().get(0).getUrl(),"/");
     }
 
diff --git a/modules/swagger-parser-v3/src/test/resources/issue-1103/domain.yaml b/modules/swagger-parser-v3/src/test/resources/issue-1103/domain.yaml
new file mode 100644
index 00000000..92650a14
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/issue-1103/domain.yaml
@@ -0,0 +1,33 @@
+openapi: 3.0.0
+info:
+  version: 1.0.0
+  title: API Reuse Common Components
+  description: Definitions of API components to be referred across different API files
+components:
+  pathitems:
+    Translation:
+      put:
+        tags:
+          - Translation
+        summary: Set value of this parameter
+        description: Provide the lookup table for localized strings
+        parameters:
+          - $ref: '#/components/parameters/param_lang'
+  parameters:
+    param_lang:
+      name: lang
+      in: path
+      description: language - 2-letter abbreviation
+      required: true
+      schema:
+        type: string
+        enum:
+          - en
+          - se
+          - dk
+          - fi
+          - false
+          - de
+          - es
+          - et
+          - fr
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-parameter-swagger.yaml b/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-parameter-swagger.yaml
new file mode 100644
index 00000000..1a62d818
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-parameter-swagger.yaml
@@ -0,0 +1,14 @@
+openapi: 3.0.0
+info:
+  version: "1"
+  title: Admin Web App Services
+  description: 'Services'
+paths:
+  '/Translation/{lang}':
+    put:
+      tags:
+        - Translation_Settings
+      summary: Set value of this parameter
+      description: Provide the lookup table for localized strings
+      parameters:
+        - $ref: 'domain.yaml#/components/parameters/param_lang'
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-pathItem-swagger.yaml b/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-pathItem-swagger.yaml
new file mode 100644
index 00000000..0b392671
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/issue-1103/remote-pathItem-swagger.yaml
@@ -0,0 +1,8 @@
+openapi: 3.0.0
+info:
+  version: 2.0.0
+  title: Admin Web App Services
+  description: 'Services API'
+paths:
+  '/Translation/{lang}':
+    $ref: './domain.yaml#/components/pathitems/Translation'
\ No newline at end of file