Repository: swagger-api/swagger-parser
Pull request #1564 (2021-05-14 12:39:52)

Bug/1562 path body
sorry to raise your attention on bug #1562 again. But I found that my initial contribution still has some shortcomings if used with OData services, that have '.' separated path names. And also with the caml-case writing option.

here's a sample of such path separators in action https://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/TripPin.openapi3.json
`/People('{UserName}')/Microsoft.OData.SampleService.Models.TripPin.ShareTrip`


Patch:
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
index cd97f892..941bb687 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
@@ -398,12 +398,20 @@ public class InlineModelResolver {
       StringBuilder body = new StringBuilder();
       if (parts.length > 2)
       {
-        body.append(parts[parts.length-2]);
+        body.append(normalize(parts[parts.length-2])).append('_');
       }
-      body.append(parts[parts.length-1]);
-      body.append("Body");
+      if (parts.length > 1)
+      {
+        body.append(normalize(parts[parts.length-1])).append('_');
+      }
+      body.append("body");
       return body.toString();
     }
+    
+    private static String normalize(String pathPart)
+    {
+      return pathPart.replace(".", "_");
+    }
 
     private String resolveModelName(String title, String key) {
         if (title == null) {


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 bebf6c26..c54cbb7f 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
@@ -1,6 +1,22 @@
 package io.swagger.v3.parser.test;
 
 
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
 import java.io.File;
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -14,11 +30,20 @@ import java.util.Map;
 import java.util.Random;
 import java.util.Set;
 
+import org.apache.commons.io.FileUtils;
+import org.hamcrest.CoreMatchers;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.reporters.Files;
+
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.client.WireMock;
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+
 import io.swagger.v3.core.util.Json;
 import io.swagger.v3.core.util.Yaml;
 import io.swagger.v3.oas.models.Components;
@@ -52,32 +77,6 @@ import io.swagger.v3.parser.core.models.AuthorizationValue;
 import io.swagger.v3.parser.core.models.ParseOptions;
 import io.swagger.v3.parser.core.models.SwaggerParseResult;
 import mockit.Injectable;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.hamcrest.CoreMatchers;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-import org.testng.reporters.Files;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
 
 
 public class OpenAPIV3ParserTest {
@@ -416,9 +415,9 @@ public class OpenAPIV3ParserTest {
 
         OpenAPI openAPI = parseResult.getOpenAPI();
         assertNotNull(openAPI.getComponents().getSchemas().get("status"));
-        assertNotNull(openAPI.getComponents().getSchemas().get("testBody"));
+        assertNotNull(openAPI.getComponents().getSchemas().get("test_body"));
         assertNotNull(openAPI.getComponents().getSchemas().get("inline_response_200"));
-        assertNotNull(openAPI.getComponents().getSchemas().get("testBody_1"));
+        assertNotNull(openAPI.getComponents().getSchemas().get("test_body_1"));
         assertNotNull(openAPI.getComponents().getSchemas().get("Test1"));
         assertNotNull(openAPI.getComponents().getSchemas().get("Test2"));
     }
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java
index fa96f8a8..5b4a60c7 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java
@@ -637,7 +637,7 @@ public class InlineModelResolverTest {
         RequestBody body = getOperation.getRequestBody();
         assertTrue(body.getContent().get("*/*").getSchema().get$ref() != null);
 
-        Schema bodySchema = openAPI.getComponents().getSchemas().get("helloBody");
+        Schema bodySchema = openAPI.getComponents().getSchemas().get("hello_body");
         assertTrue(bodySchema instanceof Schema);
 
         assertNotNull(bodySchema.getProperties().get("address"));
@@ -676,7 +676,48 @@ public class InlineModelResolverTest {
         RequestBody body = getOperation.getRequestBody();
         assertTrue(body.getContent().get("*/*").getSchema().get$ref() != null);
 
-        Schema bodySchema = openAPI.getComponents().getSchemas().get("greethelloBody");
+        Schema bodySchema = openAPI.getComponents().getSchemas().get("greet_hello_body");
+        assertTrue(bodySchema instanceof Schema);
+
+        assertNotNull(bodySchema.getProperties().get("address"));
+    }
+    
+    @Test
+    public void resolveInlineRequestBody_stripsDotsFromPath() throws Exception {
+        OpenAPI openAPI = new OpenAPI();
+
+        ObjectSchema objectSchema = new ObjectSchema();
+        objectSchema.addProperties("street", new StringSchema());
+
+        Schema schema = new Schema();
+        schema.addProperties("address", objectSchema);
+        schema.addProperties("name", new StringSchema());
+
+        MediaType mediaType = new MediaType();
+        mediaType.setSchema(schema);
+
+        Content content = new Content();
+        content.addMediaType("*/*", mediaType );
+
+        RequestBody requestBody = new RequestBody();
+        requestBody.setContent(content);
+
+        Operation operation = new Operation();
+        operation.setRequestBody(requestBody);
+
+        PathItem pathItem = new PathItem();
+        pathItem.setGet(operation);
+        openAPI.path("/api/Cloud.Greet.Hello",pathItem);
+
+        new InlineModelResolver(true, true).flatten(openAPI);
+
+        Operation getOperation = openAPI.getPaths().get("/api/Cloud.Greet.Hello").getGet();
+        RequestBody body = getOperation.getRequestBody();
+        assertEquals("use dot as common word separator: as it occurs frequently on OData services", 
+            "#/components/schemas/ApiCloudGreetHelloBody", 
+            body.getContent().get("*/*").getSchema().get$ref());
+
+        Schema bodySchema = openAPI.getComponents().getSchemas().get("ApiCloudGreetHelloBody");
         assertTrue(bodySchema instanceof Schema);
 
         assertNotNull(bodySchema.getProperties().get("address"));
@@ -805,9 +846,9 @@ public class InlineModelResolverTest {
         Schema inner = am.getItems();
         assertTrue(inner.get$ref() != null);
 
-        assertEquals( "#/components/schemas/helloBody",inner.get$ref());
+        assertEquals( "#/components/schemas/hello_body",inner.get$ref());
 
-        Schema inline = openAPI.getComponents().getSchemas().get("helloBody");
+        Schema inline = openAPI.getComponents().getSchemas().get("hello_body");
         assertNotNull(inline);
         assertTrue(inline instanceof Schema);
 
@@ -1091,7 +1132,7 @@ public class InlineModelResolverTest {
         RequestBody requestBody = operation.getRequestBody();
         assertTrue(requestBody.getContent().get("*/*").getSchema().get$ref() != null);
 
-        Schema body = swagger.getComponents().getSchemas().get("helloBody");
+        Schema body = swagger.getComponents().getSchemas().get("hello_body");
         assertTrue(body instanceof Schema);
 
 
@@ -1153,9 +1194,9 @@ public class InlineModelResolverTest {
         assertTrue(inner.get$ref() != null);
 
 
-        assertEquals(inner.get$ref(), "#/components/schemas/helloBody");
+        assertEquals(inner.get$ref(), "#/components/schemas/hello_body");
 
-        Schema inline = openAPI.getComponents().getSchemas().get("helloBody");
+        Schema inline = openAPI.getComponents().getSchemas().get("hello_body");
         assertNotNull(inline);
 
         Schema p = (Schema)inline.getProperties().get("arbitrary");