Repository: swagger-api/swagger-parser
Pull request #836 (2018-09-12 02:35:19)

Fix for issue 835
Hi team,

This PR is to solve the issue #835 (OAS Conversion of formData reference parameters to request body is incorrect (OAS 2 to 3 conversion))

Please review the PR and merge the same.

Thanks,
Mohammed


Patch:
diff --git a/README.md b/README.md
index b7bbe3a9..d34d5ae5 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,7 @@ You can include this library from Sonatype OSS for SNAPSHOTS, or Maven central f
 <dependency>
   <groupId>io.swagger.parser.v3</groupId>
   <artifactId>swagger-parser</artifactId>
-  <version>2.0.5-SNAPSHOT</version>
+  <version>2.0.4</version>
 </dependency>
 
 ```
@@ -108,7 +108,7 @@ or
 <dependency>
   <groupId>io.swagger.parser.v3</groupId>
   <artifactId>swagger-parser</artifactId>
-  <version>2.0.5-SNAPSHOT</version>
+  <version>2.0.4</version>
 </dependency>
 
 ```
diff --git a/modules/swagger-parser-core/pom.xml b/modules/swagger-parser-core/pom.xml
index 51afca3f..cf0f0c64 100644
--- a/modules/swagger-parser-core/pom.xml
+++ b/modules/swagger-parser-core/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <groupId>io.swagger.parser.v3</groupId>
         <artifactId>swagger-parser-project</artifactId>
-        <version>2.0.5-SNAPSHOT</version>
+        <version>2.0.4</version>
         <relativePath>../..</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/modules/swagger-parser-v2-converter/pom.xml b/modules/swagger-parser-v2-converter/pom.xml
index bcd7459b..f5471d44 100644
--- a/modules/swagger-parser-v2-converter/pom.xml
+++ b/modules/swagger-parser-v2-converter/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <groupId>io.swagger.parser.v3</groupId>
         <artifactId>swagger-parser-project</artifactId>
-        <version>2.0.5-SNAPSHOT</version>
+        <version>2.0.4</version>
         <relativePath>../..</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
index 371ea850..0a47ca63 100644
--- a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
+++ b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
@@ -194,7 +194,8 @@ public class SwaggerConverter implements SwaggerParserExtension {
                 if ("body".equals(v.getIn())) {
                     components.addRequestBodies(k, convertParameterToRequestBody(v));
                 } else if ("formData".equals(v.getIn())) {
-                    components.addRequestBodies(k, convertFormDataToRequestBody(v));
+                    // formData_ is added not to overwrite existing schemas
+                    components.addSchemas("formData_" + k, convertFormDataToSchema(v));
                 } else {
                     components.addParameters(k, convert(v));
                 }
@@ -529,6 +530,16 @@ public class SwaggerConverter implements SwaggerParserExtension {
         return false;
     }
 
+    private boolean isRefAFormParam(io.swagger.models.parameters.Parameter param) {
+        if (param instanceof RefParameter) {
+            RefParameter refParameter = (RefParameter) param;
+            String simpleRef = refParameter.getSimpleRef();
+            io.swagger.models.parameters.Parameter parameter = globalV2Parameters.get(simpleRef);
+            return "formData".equals(parameter.getIn());
+        }
+        return false;
+    }
+
     public Operation convert(io.swagger.models.Operation v2Operation) {
         Operation operation = new Operation();
         if (StringUtils.isNotBlank(v2Operation.getDescription())) {
@@ -555,10 +566,11 @@ public class SwaggerConverter implements SwaggerParserExtension {
                     String $ref = convert.get$ref();
                     if ($ref != null && $ref.startsWith("#/components/requestBodies/") && isRefABodyParam(param)) {
                         operation.setRequestBody(new RequestBody().$ref($ref));
+                    } else if ($ref != null && $ref.startsWith("#/components/schemas/") && isRefAFormParam(param)) {
+                        formParams.add(param);
                     } else {
                         operation.addParametersItem(convert);
                     }
-                    //operation.addParametersItem(convert(param));
                 }
             }
 
@@ -611,8 +623,9 @@ public class SwaggerConverter implements SwaggerParserExtension {
         return vendorExtensions;
     }
 
-    private RequestBody convertFormDataToRequestBody(io.swagger.models.parameters.Parameter formParam) {
-        return convertFormDataToRequestBody(Arrays.asList(formParam), null);
+    private Schema convertFormDataToSchema(io.swagger.models.parameters.Parameter formParam) {
+        SerializableParameter sp = (SerializableParameter) formParam;
+        return convert(sp);
     }
 
     private RequestBody convertFormDataToRequestBody(List<io.swagger.models.parameters.Parameter> formParams, List<String> consumes) {
@@ -621,73 +634,27 @@ public class SwaggerConverter implements SwaggerParserExtension {
         Schema formSchema = new Schema();
 
         for (io.swagger.models.parameters.Parameter param : formParams) {
-            SerializableParameter sp = (SerializableParameter) param;
+            SerializableParameter sp;
 
             Schema schema;
-            if ("file".equals(sp.getType())) {
-                schema = new FileSchema();
-            } else if ("array".equals(sp.getType())) {
-                ArraySchema as = new ArraySchema();
-                if (sp.getItems() != null) {
-                    as.setItems(convert(sp.getItems()));
-                }
-                schema = as;
+            String name;
+            if (param instanceof RefParameter) {
+                RefParameter refParameter = (RefParameter) param;
+                String simpleRef = refParameter.getSimpleRef();
+                sp = (SerializableParameter) globalV2Parameters.get(simpleRef);
+                name = components.getSchemas().get("formData_" + simpleRef).getName();
+                schema = new Schema().$ref("#/components/schemas/formData_" + simpleRef);
             } else {
-                schema = new Schema();
-                schema.setType(sp.getType());
-                schema.setFormat(sp.getFormat());
-            }
-
-            schema.setDescription(sp.getDescription());
-            schema.setReadOnly(sp.isReadOnly());
-            schema.setEnum(sp.getEnum());
-
-            if (sp.getMaxItems() != null) {
-                schema.setMaxItems(sp.getMaxItems());
-            }
-            if (sp.getMinItems() != null) {
-                schema.setMinItems(sp.getMinItems());
-            }
-            if (sp.isUniqueItems() != null) {
-                schema.setUniqueItems(sp.isUniqueItems());
-            }
-
-            schema.setMaximum(sp.getMaximum());
-            schema.setExclusiveMaximum(sp.isExclusiveMaximum());
-            schema.setMinimum(sp.getMinimum());
-            schema.setExclusiveMinimum(sp.isExclusiveMinimum());
-            schema.setMinLength(sp.getMinLength());
-            schema.setMaxLength(sp.getMaxLength());
-
-            if (sp.getVendorExtensions() != null) {
-                Object exampleExtension = sp.getVendorExtensions().get("x-example");
-                if (exampleExtension != null) {
-                    schema.setExample(exampleExtension);
-                }
-                Object nullableExtension = sp.getVendorExtensions().get("x-nullable");
-                if (nullableExtension != null) {
-                    schema.setNullable((Boolean) nullableExtension);
-                }
-                schema.setExtensions(convert(sp.getVendorExtensions()));
-            }
-
-            if (sp.getMultipleOf() != null) {
-                schema.setMultipleOf(new BigDecimal(sp.getMultipleOf().toString()));
-            }
-
-            schema.setPattern(sp.getPattern());
-            schema.setExtensions(convert(sp.getVendorExtensions()));
-
-            if (sp instanceof AbstractSerializableParameter) {
-                AbstractSerializableParameter ap = (AbstractSerializableParameter) sp;
-                schema.setDefault(ap.getDefault());
+                sp = (SerializableParameter) param;
+                schema = convert(sp);
+                name = schema.getName();
             }
 
             if (sp.getRequired()) {
                 formSchema.addRequiredItem(sp.getName());
             }
 
-            formSchema.addProperties(param.getName(), schema);
+            formSchema.addProperties(name, schema);
         }
 
         List<String> mediaTypes = new ArrayList<>(globalConsumes);
@@ -709,6 +676,69 @@ public class SwaggerConverter implements SwaggerParserExtension {
         return body;
     }
 
+    private Schema convert(SerializableParameter sp) {
+        Schema schema;
+        if ("file".equals(sp.getType())) {
+            schema = new FileSchema();
+        } else if ("array".equals(sp.getType())) {
+            ArraySchema as = new ArraySchema();
+            if (sp.getItems() != null) {
+                as.setItems(convert(sp.getItems()));
+            }
+            schema = as;
+        } else {
+            schema = new Schema();
+            schema.setType(sp.getType());
+            schema.setFormat(sp.getFormat());
+        }
+
+        schema.setDescription(sp.getDescription());
+        schema.setReadOnly(sp.isReadOnly());
+        schema.setEnum(sp.getEnum());
+
+        if (sp.getMaxItems() != null) {
+            schema.setMaxItems(sp.getMaxItems());
+        }
+        if (sp.getMinItems() != null) {
+            schema.setMinItems(sp.getMinItems());
+        }
+        if (sp.isUniqueItems() != null) {
+            schema.setUniqueItems(sp.isUniqueItems());
+        }
+
+        schema.setMaximum(sp.getMaximum());
+        schema.setExclusiveMaximum(sp.isExclusiveMaximum());
+        schema.setMinimum(sp.getMinimum());
+        schema.setExclusiveMinimum(sp.isExclusiveMinimum());
+        schema.setMinLength(sp.getMinLength());
+        schema.setMaxLength(sp.getMaxLength());
+        schema.setName(sp.getName());
+
+        if (sp.getVendorExtensions() != null) {
+            Object exampleExtension = sp.getVendorExtensions().get("x-example");
+            if (exampleExtension != null) {
+                schema.setExample(exampleExtension);
+            }
+            Object nullableExtension = sp.getVendorExtensions().get("x-nullable");
+            if (nullableExtension != null) {
+                schema.setNullable((Boolean) nullableExtension);
+            }
+            schema.setExtensions(convert(sp.getVendorExtensions()));
+        }
+
+        if (sp.getMultipleOf() != null) {
+            schema.setMultipleOf(new BigDecimal(sp.getMultipleOf().toString()));
+        }
+
+        schema.setPattern(sp.getPattern());
+
+        if (sp instanceof AbstractSerializableParameter) {
+            AbstractSerializableParameter ap = (AbstractSerializableParameter) sp;
+            schema.setDefault(ap.getDefault());
+        }
+        return schema;
+    }
+
     private RequestBody convertParameterToRequestBody(io.swagger.models.parameters.Parameter param) {
         return convertParameterToRequestBody(param, null);
     }
@@ -957,6 +987,8 @@ public class SwaggerConverter implements SwaggerParserExtension {
                 if (components.getRequestBodies() != null &&
                         components.getRequestBodies().get(ref.getSimpleRef()) != null) {
                     updatedRef += "requestBodies";
+                } else if (components.getSchemas() != null && components.getSchemas().get("formData_" + ref.getSimpleRef()) != null) {
+                    updatedRef += "schemas";
                 } else {
                     updatedRef += "parameters";
                 }
diff --git a/modules/swagger-parser-v3/pom.xml b/modules/swagger-parser-v3/pom.xml
index 041014b2..c71f09c1 100644
--- a/modules/swagger-parser-v3/pom.xml
+++ b/modules/swagger-parser-v3/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <groupId>io.swagger.parser.v3</groupId>
         <artifactId>swagger-parser-project</artifactId>
-        <version>2.0.5-SNAPSHOT</version>
+        <version>2.0.4</version>
         <relativePath>../..</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
@@ -80,6 +80,6 @@
         </dependency>
     </dependencies>
     <properties>
-        <swagger-core-module-version>2.0.5-SNAPSHOT</swagger-core-module-version>
+        <swagger-core-module-version>2.0.4</swagger-core-module-version>
     </properties>
 </project>
diff --git a/modules/swagger-parser/pom.xml b/modules/swagger-parser/pom.xml
index 26e0e332..f9a57012 100644
--- a/modules/swagger-parser/pom.xml
+++ b/modules/swagger-parser/pom.xml
@@ -3,7 +3,7 @@
     <parent>
         <groupId>io.swagger.parser.v3</groupId>
         <artifactId>swagger-parser-project</artifactId>
-        <version>2.0.5-SNAPSHOT</version>
+        <version>2.0.4</version>
         <relativePath>../..</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index c5100cc4..ebd4fb3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>io.swagger.parser.v3</groupId>
     <artifactId>swagger-parser-project</artifactId>
-    <version>2.0.5-SNAPSHOT</version>
+    <version>2.0.4</version>
     <packaging>pom</packaging>
     <name>swagger-parser-project</name>
     <developers>
@@ -250,7 +250,7 @@
         </repository>
     </repositories>
     <properties>
-        <swagger-parser-v2-version>1.0.39-SNAPSHOT</swagger-parser-v2-version>
+        <swagger-parser-v2-version>1.0.38</swagger-parser-v2-version>
         <commons-io-version>2.4</commons-io-version>
         <slf4j-version>1.6.3</slf4j-version>
         <swagger-core-version>2.0.4</swagger-core-version>


Test patch:
diff --git a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
index bd0a75d5..ea36a55c 100644
--- a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
+++ b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
@@ -325,11 +325,12 @@ public class V2ConverterTest {
     public void testIssue17() throws Exception {
         OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_17_JSON);
         Map<String, RequestBody> requestBodies = oas.getComponents().getRequestBodies();
-        assertNotNull(requestBodies.get("formEmail").getContent().get("multipart/form-data"));
-        assertNotNull(requestBodies.get("formPassword").getContent().get("multipart/form-data"));
+        Map<String, Schema> schemas = oas.getComponents().getSchemas();
+        assertNotNull(schemas.get("formData_formEmail"));
+        assertNotNull(schemas.get("formData_formPassword"));
         assertNotNull(requestBodies.get("bodyParam").getContent().get("*/*"));
-        assertEquals(oas.getPaths().get("/formPost").getPost().getParameters().get(0).get$ref(),
-                REQUEST_BODY_FORMEMAIL);
+        assertNull(oas.getPaths().get("/formPost").getPost().getParameters());
+        assertNotNull(oas.getPaths().get("/formPost").getPost().getRequestBody());
         assertNotNull(oas.getPaths().get("/report/{userId}").getGet().getRequestBody().
                 getContent().get("multipart/form-data").getSchema().getProperties().get("limitForm"));
     }