From 194c389a06853a67525c4e00d1c92f07ce27c16b Mon Sep 17 00:00:00 2001 From: cbornet Date: Wed, 24 Aug 2016 17:11:45 +0200 Subject: [PATCH 1/7] fix some inheritance/composition issues and add allOf unit tests Fix #3629 #3544 #3474 #3636 --- .../io/swagger/codegen/DefaultCodegen.java | 36 ++++- .../languages/JavascriptClientCodegen.java | 6 +- .../java/io/swagger/codegen/CodegenTest.java | 124 ++++++++++++++++++ .../src/test/resources/2_0/allOfTest.yaml | 104 +++++++++++++++ 4 files changed, 264 insertions(+), 6 deletions(-) create mode 100644 modules/swagger-codegen/src/test/resources/2_0/allOfTest.yaml diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 3ddba67f0d8..fd8e28d8a9a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -100,6 +100,7 @@ public class DefaultCodegen { protected List cliOptions = new ArrayList(); protected boolean skipOverwrite; protected boolean supportsInheritance; + protected boolean supportsMixins; protected Map supportedLibraries = new LinkedHashMap(); protected String library; protected Boolean sortParamsByRequiredFlag = true; @@ -1233,7 +1234,7 @@ public class DefaultCodegen { List required = new ArrayList(); Map allProperties; List allRequired; - if (supportsInheritance) { + if (supportsInheritance || supportsMixins) { allProperties = new LinkedHashMap(); allRequired = new ArrayList(); m.allVars = new ArrayList(); @@ -1254,17 +1255,20 @@ public class DefaultCodegen { interfaceModel = allDefinitions.get(_interface.getSimpleRef()); } // set first interface with discriminator found as parent - if (parent == null && interfaceModel instanceof ModelImpl && ((ModelImpl) interfaceModel).getDiscriminator() != null) { + if (parent == null + && ((interfaceModel instanceof ModelImpl && ((ModelImpl) interfaceModel).getDiscriminator() != null) + || (interfaceModel instanceof ComposedModel && isDiscriminatorInInterfaceTree((ComposedModel) interfaceModel, allDefinitions)))) { parent = _interface; } else { final String interfaceRef = toModelName(_interface.getSimpleRef()); m.interfaces.add(interfaceRef); addImport(m, interfaceRef); if (allDefinitions != null) { + if (!supportsMixins) { + addProperties(properties, required, interfaceModel, allDefinitions); + } if (supportsInheritance) { addProperties(allProperties, allRequired, interfaceModel, allDefinitions); - } else { - addProperties(properties, required, interfaceModel, allDefinitions); } } } @@ -1323,6 +1327,30 @@ public class DefaultCodegen { return m; } + /** + * Recursively look for a discriminator in the interface tree + */ + private boolean isDiscriminatorInInterfaceTree(ComposedModel model, Map allDefinitions) { + if (model == null || allDefinitions == null) + return false; + + Model child = ((ComposedModel) model).getChild(); + if (child instanceof ModelImpl && ((ModelImpl) child).getDiscriminator() != null) { + return true; + } + for (RefModel _interface : model.getInterfaces()) { + Model interfaceModel = allDefinitions.get(_interface.getSimpleRef()); + if (interfaceModel instanceof ModelImpl && ((ModelImpl) interfaceModel).getDiscriminator() != null) { + return true; + } + if (interfaceModel instanceof ComposedModel) { + + return isDiscriminatorInInterfaceTree((ComposedModel) interfaceModel, allDefinitions); + } + } + return false; + } + protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, ModelImpl swaggerModel) { MapProperty mapProperty = new MapProperty(swaggerModel.getAdditionalProperties()); addParentContainer(codegenModel, codegenModel.name, mapProperty); diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavascriptClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavascriptClientCodegen.java index 950212197b7..549c1988dfb 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavascriptClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavascriptClientCodegen.java @@ -223,6 +223,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo setUseInheritance(Boolean.parseBoolean((String)additionalProperties.get(USE_INHERITANCE))); } else { supportsInheritance = true; + supportsMixins = true; } if (additionalProperties.containsKey(EMIT_MODEL_METHODS)) { setEmitModelMethods(Boolean.parseBoolean((String)additionalProperties.get(EMIT_MODEL_METHODS))); @@ -386,6 +387,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo public void setUseInheritance(boolean useInheritance) { this.supportsInheritance = useInheritance; + this.supportsMixins = useInheritance; } public void setEmitModelMethods(boolean emitModelMethods) { @@ -889,7 +891,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo // NOTE: can't use 'mandatory' as it is built from ModelImpl.getRequired(), which sorts names // alphabetically and in any case the document order of 'required' and 'properties' can differ. List required = new ArrayList<>(); - List allRequired = supportsInheritance ? new ArrayList() : required; + List allRequired = supportsInheritance || supportsMixins ? new ArrayList() : required; cm.vendorExtensions.put("x-required", required); cm.vendorExtensions.put("x-all-required", allRequired); @@ -903,7 +905,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo } } - if (supportsInheritance) { + if (supportsInheritance || supportsMixins) { for (CodegenProperty var : cm.allVars) { if (Boolean.TRUE.equals(var.required)) { allRequired.add(var); diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java index 9842258fb92..e96ad452806 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java @@ -1,5 +1,6 @@ package io.swagger.codegen; +import io.swagger.models.Model; import io.swagger.models.Operation; import io.swagger.models.Swagger; import io.swagger.models.properties.Property; @@ -187,6 +188,129 @@ public class CodegenTest { Assert.assertEquals(op.discriminator, "className"); } + @Test(description = "handle simple composition") + public void simpleCompositionTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("SimpleComposition"); + CodegenModel composed = codegen.fromModel("SimpleComposition", model, swagger.getDefinitions()); + + Assert.assertEquals(composed.vars.size(), 3); + Assert.assertEquals(composed.vars.get(0).baseName, "modelOneProp"); + Assert.assertEquals(composed.vars.get(1).baseName, "modelTwoProp"); + Assert.assertEquals(composed.vars.get(2).baseName, "simpleCompositionProp"); + Assert.assertNull(composed.parent); + } + + @Test(description = "handle multi level composition") + public void multiCompositionTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("CompositionOfSimpleComposition"); + CodegenModel composed = codegen.fromModel("CompositionOfSimpleComposition", model, swagger.getDefinitions()); + + Assert.assertEquals(composed.vars.size(), 5); + Assert.assertEquals(composed.vars.get(0).baseName, "modelOneProp"); + Assert.assertEquals(composed.vars.get(1).baseName, "modelTwoProp"); + Assert.assertEquals(composed.vars.get(2).baseName, "simpleCompositionProp"); + Assert.assertEquals(composed.vars.get(3).baseName, "modelThreeProp"); + Assert.assertEquals(composed.vars.get(4).baseName, "compositionOfSimpleCompositionProp"); + Assert.assertNull(composed.parent); + } + + @Test(description = "handle simple inheritance") + public void simpleInheritanceTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("ChildOfSimpleParent"); + CodegenModel child = codegen.fromModel("ChildOfSimpleParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 2); + Assert.assertEquals(child.vars.get(0).baseName, "modelOneProp"); + Assert.assertEquals(child.vars.get(1).baseName, "childOfSimpleParentProp"); + Assert.assertEquals(child.parent, "SimpleParent"); + } + + @Test(description = "handle multi level inheritance") + public void multiInheritanceTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("ChildOfChildOfSimpleParent"); + CodegenModel child = codegen.fromModel("ChildOfChildOfSimpleParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 1); + Assert.assertEquals(child.vars.get(0).baseName, "childOfChildOfSimpleParentProp"); + Assert.assertEquals(child.parent, "ChildOfSimpleParent"); + } + + @Test(description = "copy properties in multi level inheritance if supportsInheritance is false") + public void noSupportsInheritanceTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + final Model model = swagger.getDefinitions().get("ChildOfChildOfSimpleParent"); + CodegenModel child = codegen.fromModel("ChildOfChildOfSimpleParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 5); + Assert.assertEquals(child.vars.get(0).baseName, "modelOneProp"); + Assert.assertEquals(child.vars.get(1).baseName, "disc"); + Assert.assertEquals(child.vars.get(2).baseName, "simpleParentProp"); + Assert.assertEquals(child.vars.get(3).baseName, "childOfSimpleParentProp"); + Assert.assertEquals(child.vars.get(4).baseName, "childOfChildOfSimpleParentProp"); + Assert.assertEquals(child.parent, "ChildOfSimpleParent"); + } + + @Test(description = "don't copy interfaces properties if supportsMixins is true") + public void supportsMixinsTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + codegen.supportsMixins = true; + final Model model = swagger.getDefinitions().get("ChildOfChildOfSimpleParent"); + CodegenModel child = codegen.fromModel("ChildOfChildOfSimpleParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 1); + Assert.assertEquals(child.vars.get(0).baseName, "childOfChildOfSimpleParentProp"); + Assert.assertEquals(child.allVars.size(), 5); + Assert.assertEquals(child.allVars.get(0).baseName, "modelOneProp"); + Assert.assertEquals(child.allVars.get(1).baseName, "disc"); + Assert.assertEquals(child.allVars.get(2).baseName, "simpleParentProp"); + Assert.assertEquals(child.allVars.get(3).baseName, "childOfSimpleParentProp"); + Assert.assertEquals(child.allVars.get(4).baseName, "childOfChildOfSimpleParentProp"); + + Assert.assertEquals(child.parent, "ChildOfSimpleParent"); + } + + @Test(description = "handle inheritance from composed model") + public void inheritanceOfComposedModelTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("ChildOfComposedParent"); + CodegenModel child = codegen.fromModel("ChildOfComposedParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 1); + Assert.assertEquals(child.vars.get(0).baseName, "childOfComposedParentProp"); + Assert.assertEquals(child.parent, "ComposedParent"); + } + + @Test(description = "handle multi level inheritance from composed model") + public void multiInheritanceOfComposedModelTest() { + final Swagger swagger = parseAndPrepareSwagger("src/test/resources/2_0/allOfTest.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.supportsInheritance = true; + final Model model = swagger.getDefinitions().get("ChildOfChildOfComposedParent"); + CodegenModel child = codegen.fromModel("ChildOfChildOfComposedParent", model, swagger.getDefinitions()); + + Assert.assertEquals(child.vars.size(), 1); + Assert.assertEquals(child.vars.get(0).baseName, "childOfChildOfComposedParentProp"); + Assert.assertEquals(child.parent, "ChildOfComposedParent"); + } + + @Test(description = "use operation consumes and produces") public void localConsumesAndProducesTest() { final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/globalConsumesAndProduces.json"); diff --git a/modules/swagger-codegen/src/test/resources/2_0/allOfTest.yaml b/modules/swagger-codegen/src/test/resources/2_0/allOfTest.yaml new file mode 100644 index 00000000000..2636d4e7aa9 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/2_0/allOfTest.yaml @@ -0,0 +1,104 @@ +swagger: '2.0' +info: + version: 0.0.0 + title: Simple API +paths: + /: + get: + responses: + 200: + description: OK + +definitions: + + ModelOne: + type: object + properties: + modelOneProp: + type: string + + ModelTwo: + type: object + properties: + modelTwoProp: + type: string + + ModelThree: + type: object + properties: + modelThreeProp: + type: string + + SimpleComposition: + allOf: + - $ref: '#/definitions/ModelOne' + - $ref: '#/definitions/ModelTwo' + - type: object + properties: + simpleCompositionProp: + type: string + + CompositionOfSimpleComposition: + allOf: + - $ref: '#/definitions/SimpleComposition' + - $ref: '#/definitions/ModelThree' + - type: object + properties: + compositionOfSimpleCompositionProp: + type: string + + SimpleParent: + type: object + discriminator: disc + properties: + disc: + type: string + simpleParentProp: + type: string + required: [disc] + + ChildOfSimpleParent: + allOf: + - $ref: '#/definitions/ModelOne' + - $ref: '#/definitions/SimpleParent' + - type: object + properties: + childOfSimpleParentProp: + type: string + + ChildOfChildOfSimpleParent: + allOf: + - $ref: '#/definitions/ChildOfSimpleParent' + - type: object + properties: + childOfChildOfSimpleParentProp: + type: string + + ComposedParent: + allOf: + - $ref: '#/definitions/ModelOne' + - $ref: '#/definitions/ModelTwo' + - type: object + discriminator: disc + properties: + disc: + type: string + composedParentProp: + type: string + required: [disc] + + ChildOfComposedParent: + allOf: + - $ref: '#/definitions/ComposedParent' + - type: object + properties: + childOfComposedParentProp: + type: string + + ChildOfChildOfComposedParent: + allOf: + - $ref: '#/definitions/ChildOfComposedParent' + - type: object + properties: + childOfChildOfComposedParentProp: + type: string \ No newline at end of file From b7708a44bf828c266135d0679ab907407e936942 Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Sun, 2 Oct 2016 09:56:19 -0400 Subject: [PATCH 2/7] [aspnet5] Fix basePath application to operations (#3911) * [aspnet5] Fix basePath application to operations * [aspnet5] Regenerate sample --- .../main/resources/aspnet5/controller.mustache | 7 +++---- .../aspnet5/src/IO.Swagger/Controllers/PetApi.cs | 16 ++++++++-------- .../src/IO.Swagger/Controllers/StoreApi.cs | 8 ++++---- .../src/IO.Swagger/Controllers/UserApi.cs | 16 ++++++++-------- .../aspnet5/src/IO.Swagger/Models/ApiResponse.cs | 2 +- .../aspnet5/src/IO.Swagger/Models/Category.cs | 2 +- .../aspnet5/src/IO.Swagger/Models/Order.cs | 2 +- .../aspnet5/src/IO.Swagger/Models/Pet.cs | 2 +- .../aspnet5/src/IO.Swagger/Models/Tag.cs | 2 +- .../aspnet5/src/IO.Swagger/Models/User.cs | 2 +- 10 files changed, 29 insertions(+), 30 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/aspnet5/controller.mustache b/modules/swagger-codegen/src/main/resources/aspnet5/controller.mustache index bfeb2307ff8..72c5480ad0d 100644 --- a/modules/swagger-codegen/src/main/resources/aspnet5/controller.mustache +++ b/modules/swagger-codegen/src/main/resources/aspnet5/controller.mustache @@ -16,9 +16,8 @@ namespace {{packageName}}.Controllers { {{#operations}} /// /// {{description}} - /// {{#description}}{{#basePath}} - [Route("{{{basePath}}}")] - {{/basePath}}[Description("{{description}}")]{{/description}} + /// {{#description}} + [Description("{{description}}")]{{/description}} public class {{classname}}Controller : Controller { {{#operation}} @@ -29,7 +28,7 @@ namespace {{packageName}}.Controllers /// {{description}}{{/allParams}}{{#responses}} /// {{message}}{{/responses}} [{{httpMethod}}] - [Route("{{path}}")] + [Route("{{basePathWithoutHost}}{{path}}")] [SwaggerOperation("{{operationId}}")]{{#returnType}} [SwaggerResponse(200, type: typeof({{&returnType}}))]{{/returnType}} public virtual {{#returnType}}IActionResult{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/PetApi.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/PetApi.cs index 8b6c8f3e09f..abac9871dc7 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/PetApi.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/PetApi.cs @@ -48,7 +48,7 @@ namespace IO.Swagger.Controllers /// Pet object that needs to be added to the store /// Invalid input [HttpPost] - [Route("/pet")] + [Route("/v2/pet")] [SwaggerOperation("AddPet")] public virtual void AddPet([FromBody]Pet body) { @@ -64,7 +64,7 @@ namespace IO.Swagger.Controllers /// /// Invalid pet value [HttpDelete] - [Route("/pet/{petId}")] + [Route("/v2/pet/{petId}")] [SwaggerOperation("DeletePet")] public virtual void DeletePet([FromRoute]long? petId, [FromHeader]string apiKey) { @@ -80,7 +80,7 @@ namespace IO.Swagger.Controllers /// successful operation /// Invalid status value [HttpGet] - [Route("/pet/findByStatus")] + [Route("/v2/pet/findByStatus")] [SwaggerOperation("FindPetsByStatus")] [SwaggerResponse(200, type: typeof(List))] public virtual IActionResult FindPetsByStatus([FromQuery]List status) @@ -102,7 +102,7 @@ namespace IO.Swagger.Controllers /// successful operation /// Invalid tag value [HttpGet] - [Route("/pet/findByTags")] + [Route("/v2/pet/findByTags")] [SwaggerOperation("FindPetsByTags")] [SwaggerResponse(200, type: typeof(List))] public virtual IActionResult FindPetsByTags([FromQuery]List tags) @@ -125,7 +125,7 @@ namespace IO.Swagger.Controllers /// Invalid ID supplied /// Pet not found [HttpGet] - [Route("/pet/{petId}")] + [Route("/v2/pet/{petId}")] [SwaggerOperation("GetPetById")] [SwaggerResponse(200, type: typeof(Pet))] public virtual IActionResult GetPetById([FromRoute]long? petId) @@ -148,7 +148,7 @@ namespace IO.Swagger.Controllers /// Pet not found /// Validation exception [HttpPut] - [Route("/pet")] + [Route("/v2/pet")] [SwaggerOperation("UpdatePet")] public virtual void UpdatePet([FromBody]Pet body) { @@ -165,7 +165,7 @@ namespace IO.Swagger.Controllers /// Updated status of the pet /// Invalid input [HttpPost] - [Route("/pet/{petId}")] + [Route("/v2/pet/{petId}")] [SwaggerOperation("UpdatePetWithForm")] public virtual void UpdatePetWithForm([FromRoute]long? petId, [FromForm]string name, [FromForm]string status) { @@ -182,7 +182,7 @@ namespace IO.Swagger.Controllers /// file to upload /// successful operation [HttpPost] - [Route("/pet/{petId}/uploadImage")] + [Route("/v2/pet/{petId}/uploadImage")] [SwaggerOperation("UploadFile")] [SwaggerResponse(200, type: typeof(ApiResponse))] public virtual IActionResult UploadFile([FromRoute]long? petId, [FromForm]string additionalMetadata, [FromForm]System.IO.Stream file) diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/StoreApi.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/StoreApi.cs index 26784668ba6..da0b7b0d67a 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/StoreApi.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/StoreApi.cs @@ -49,7 +49,7 @@ namespace IO.Swagger.Controllers /// Invalid ID supplied /// Order not found [HttpDelete] - [Route("/store/order/{orderId}")] + [Route("/v2/store/order/{orderId}")] [SwaggerOperation("DeleteOrder")] public virtual void DeleteOrder([FromRoute]string orderId) { @@ -63,7 +63,7 @@ namespace IO.Swagger.Controllers /// Returns a map of status codes to quantities /// successful operation [HttpGet] - [Route("/store/inventory")] + [Route("/v2/store/inventory")] [SwaggerOperation("GetInventory")] [SwaggerResponse(200, type: typeof(Dictionary))] public virtual IActionResult GetInventory() @@ -86,7 +86,7 @@ namespace IO.Swagger.Controllers /// Invalid ID supplied /// Order not found [HttpGet] - [Route("/store/order/{orderId}")] + [Route("/v2/store/order/{orderId}")] [SwaggerOperation("GetOrderById")] [SwaggerResponse(200, type: typeof(Order))] public virtual IActionResult GetOrderById([FromRoute]long? orderId) @@ -108,7 +108,7 @@ namespace IO.Swagger.Controllers /// successful operation /// Invalid Order [HttpPost] - [Route("/store/order")] + [Route("/v2/store/order")] [SwaggerOperation("PlaceOrder")] [SwaggerResponse(200, type: typeof(Order))] public virtual IActionResult PlaceOrder([FromBody]Order body) diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/UserApi.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/UserApi.cs index 1cfacdd09a7..023fc4366bc 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/UserApi.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Controllers/UserApi.cs @@ -48,7 +48,7 @@ namespace IO.Swagger.Controllers /// Created user object /// successful operation [HttpPost] - [Route("/user")] + [Route("/v2/user")] [SwaggerOperation("CreateUser")] public virtual void CreateUser([FromBody]User body) { @@ -63,7 +63,7 @@ namespace IO.Swagger.Controllers /// List of user object /// successful operation [HttpPost] - [Route("/user/createWithArray")] + [Route("/v2/user/createWithArray")] [SwaggerOperation("CreateUsersWithArrayInput")] public virtual void CreateUsersWithArrayInput([FromBody]List body) { @@ -78,7 +78,7 @@ namespace IO.Swagger.Controllers /// List of user object /// successful operation [HttpPost] - [Route("/user/createWithList")] + [Route("/v2/user/createWithList")] [SwaggerOperation("CreateUsersWithListInput")] public virtual void CreateUsersWithListInput([FromBody]List body) { @@ -94,7 +94,7 @@ namespace IO.Swagger.Controllers /// Invalid username supplied /// User not found [HttpDelete] - [Route("/user/{username}")] + [Route("/v2/user/{username}")] [SwaggerOperation("DeleteUser")] public virtual void DeleteUser([FromRoute]string username) { @@ -111,7 +111,7 @@ namespace IO.Swagger.Controllers /// Invalid username supplied /// User not found [HttpGet] - [Route("/user/{username}")] + [Route("/v2/user/{username}")] [SwaggerOperation("GetUserByName")] [SwaggerResponse(200, type: typeof(User))] public virtual IActionResult GetUserByName([FromRoute]string username) @@ -134,7 +134,7 @@ namespace IO.Swagger.Controllers /// successful operation /// Invalid username/password supplied [HttpGet] - [Route("/user/login")] + [Route("/v2/user/login")] [SwaggerOperation("LoginUser")] [SwaggerResponse(200, type: typeof(string))] public virtual IActionResult LoginUser([FromQuery]string username, [FromQuery]string password) @@ -154,7 +154,7 @@ namespace IO.Swagger.Controllers /// /// successful operation [HttpGet] - [Route("/user/logout")] + [Route("/v2/user/logout")] [SwaggerOperation("LogoutUser")] public virtual void LogoutUser() { @@ -171,7 +171,7 @@ namespace IO.Swagger.Controllers /// Invalid user supplied /// User not found [HttpPut] - [Route("/user/{username}")] + [Route("/v2/user/{username}")] [SwaggerOperation("UpdateUser")] public virtual void UpdateUser([FromRoute]string username, [FromBody]User body) { diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/ApiResponse.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/ApiResponse.cs index e34c3edf374..ab83518032c 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/ApiResponse.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/ApiResponse.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// Describes the result of uploading an image resource /// [DataContract] public partial class ApiResponse : IEquatable diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Category.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Category.cs index 15f10eb9aa7..8e1404c7338 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Category.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Category.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// A category for a pet /// [DataContract] public partial class Category : IEquatable diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Order.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Order.cs index a49276583c6..b20143353cc 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Order.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Order.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// An order for a pets from the pet store /// [DataContract] public partial class Order : IEquatable diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Pet.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Pet.cs index 6c4afd3b95e..9a6f87a2945 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Pet.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Pet.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// A pet for sale in the pet store /// [DataContract] public partial class Pet : IEquatable diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Tag.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Tag.cs index 4f2cc3e5cef..55269f40675 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Tag.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/Tag.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// A tag for a pet /// [DataContract] public partial class Tag : IEquatable diff --git a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/User.cs b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/User.cs index 8933e370956..1dbde78cb0b 100644 --- a/samples/server/petstore/aspnet5/src/IO.Swagger/Models/User.cs +++ b/samples/server/petstore/aspnet5/src/IO.Swagger/Models/User.cs @@ -33,7 +33,7 @@ using Newtonsoft.Json; namespace IO.Swagger.Models { /// - /// + /// A User who is purchasing from the pet store /// [DataContract] public partial class User : IEquatable From 4a74e788ec0256c48a5944f851dcce7fa0abd29c Mon Sep 17 00:00:00 2001 From: wing328 Date: Mon, 3 Oct 2016 09:32:20 +0800 Subject: [PATCH 3/7] fix python flask controller without tag (default_controller) --- .../codegen/languages/FlaskConnexionCodegen.java | 6 +----- .../petstore/flaskConnexion/swagger/swagger.yaml | 12 ++++++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java index 919435f747a..2ac51c7e9e1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/FlaskConnexionCodegen.java @@ -145,10 +145,6 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf } if(!new java.io.File(controllerPackage + File.separator + defaultController + ".py").exists()) { - //supportingFiles.add(new SupportingFile("controller.mustache", - // controllerPackage, - // defaultController + ".py") - //); supportingFiles.add(new SupportingFile("__init__.mustache", controllerPackage, "__init__.py") @@ -269,7 +265,7 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf } else { // no tag found, use "default_controller" as the default - String tag = "default_controller"; + String tag = "default"; operation.setTags(Arrays.asList(tag)); controllerName = tag + "_controller"; } diff --git a/samples/server/petstore/flaskConnexion/swagger/swagger.yaml b/samples/server/petstore/flaskConnexion/swagger/swagger.yaml index af17161ec2a..7b412611171 100644 --- a/samples/server/petstore/flaskConnexion/swagger/swagger.yaml +++ b/samples/server/petstore/flaskConnexion/swagger/swagger.yaml @@ -644,6 +644,8 @@ definitions: complete: type: "boolean" default: false + title: "Pet Order" + description: "An order for a pets from the pet store" xml: name: "Order" Category: @@ -654,6 +656,8 @@ definitions: format: "int64" name: type: "string" + title: "Pet catehgry" + description: "A category for a pet" xml: name: "Category" User: @@ -678,6 +682,8 @@ definitions: type: "integer" format: "int32" description: "User Status" + title: "a User" + description: "A User who is purchasing from the pet store" xml: name: "User" Tag: @@ -688,6 +694,8 @@ definitions: format: "int64" name: type: "string" + title: "Pet Tag" + description: "A tag for a pet" xml: name: "Tag" Pet: @@ -725,6 +733,8 @@ definitions: - "available" - "pending" - "sold" + title: "a Pet" + description: "A pet for sale in the pet store" xml: name: "Pet" ApiResponse: @@ -737,6 +747,8 @@ definitions: type: "string" message: type: "string" + title: "An uploaded response" + description: "Describes the result of uploading an image resource" externalDocs: description: "Find out more about Swagger" url: "http://swagger.io" From e633073082ecb575627c3ba0b7b757b19c86e326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Garc=C3=ADa?= Date: Mon, 3 Oct 2016 11:14:54 +0200 Subject: [PATCH 4/7] Add a new cli command to output version information (2nd attempt) #3892 (#3899) * Properly git-ignore all nbactions.xml files. * Add a command line action to print the program version (#3892). I am using maven resource filtering capabilities so that an existing version.properties resource file gets filtered upon build and populated with the project version tag. This resource is then read at runtime as required. * Using a different version tag when unreadable. --- .gitignore | 3 +- modules/swagger-codegen-cli/pom.xml | 1 + .../io/swagger/codegen/SwaggerCodegen.java | 9 +++- .../java/io/swagger/codegen/cmd/Meta.java | 8 +--- .../java/io/swagger/codegen/cmd/Version.java | 45 +++++++++++++++++++ .../src/main/resources/version.properties | 1 + 6 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Version.java create mode 100644 modules/swagger-codegen-cli/src/main/resources/version.properties diff --git a/.gitignore b/.gitignore index 18fc2b3035b..6433492c0f3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ out/ *.iws classpath.txt version.properties +!modules/swagger-codegen-cli/src/main/resources/version.properties .project .classpath lib/* @@ -33,7 +34,7 @@ packages/ /target /generated-files -/nbactions.xml +nbactions.xml # scalatra samples/server-generator/scalatra/output diff --git a/modules/swagger-codegen-cli/pom.xml b/modules/swagger-codegen-cli/pom.xml index e484393bb14..6b56d5a6f56 100644 --- a/modules/swagger-codegen-cli/pom.xml +++ b/modules/swagger-codegen-cli/pom.xml @@ -18,6 +18,7 @@ src/main/resources + true logback.xml diff --git a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/SwaggerCodegen.java b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/SwaggerCodegen.java index 98c0b8c05b5..94b64be8d02 100644 --- a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/SwaggerCodegen.java +++ b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/SwaggerCodegen.java @@ -6,6 +6,7 @@ import io.swagger.codegen.cmd.ConfigHelp; import io.swagger.codegen.cmd.Generate; import io.swagger.codegen.cmd.Langs; import io.swagger.codegen.cmd.Meta; +import io.swagger.codegen.cmd.Version; /** * User: lanwen @@ -21,16 +22,20 @@ public class SwaggerCodegen { public static void main(String[] args) { + String version = Version.readVersionFromResources(); @SuppressWarnings("unchecked") Cli.CliBuilder builder = Cli.builder("swagger-codegen-cli") - .withDescription("Swagger code generator CLI. More info on swagger.io") + .withDescription(String.format( + "Swagger code generator CLI (version %s). More info on swagger.io", + version)) .withDefaultCommand(Langs.class) .withCommands( Generate.class, Meta.class, Langs.class, Help.class, - ConfigHelp.class + ConfigHelp.class, + Version.class ); builder.build().parse(args).run(); diff --git a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Meta.java b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Meta.java index c2dffbe6200..3b5d71eec9f 100644 --- a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Meta.java +++ b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Meta.java @@ -68,12 +68,8 @@ public class Meta implements Runnable { "src/main/resources/META-INF/services", "io.swagger.codegen.CodegenConfig") ); - String swaggerVersion = this.getClass().getPackage().getImplementationVersion(); - // if the code is running outside of the jar (i.e. from the IDE), it will not have the version available. - // let's default it with something. - if (swaggerVersion==null) { - swaggerVersion = "2.1.3"; - } + String swaggerVersion = Version.readVersionFromResources(); + Map data = new ImmutableMap.Builder() .put("generatorPackage", targetPackage) .put("generatorClass", mainClass) diff --git a/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Version.java b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Version.java new file mode 100644 index 00000000000..c39b54a30a3 --- /dev/null +++ b/modules/swagger-codegen-cli/src/main/java/io/swagger/codegen/cmd/Version.java @@ -0,0 +1,45 @@ +package io.swagger.codegen.cmd; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import io.airlift.airline.Command; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Command(name = "version", description = "Show version information") +public class Version implements Runnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(Meta.class); + + private static final String VERSION_PLACEHOLDER = "${project.version}"; + + private static final String UNREADABLE_VERSION = "unreadable"; + private static final String UNSET_VERSION = "unset"; + private static final String UNKNOWN_VERSION = "unknown"; + + public static String readVersionFromResources() { + Properties versionProperties = new Properties(); + try (InputStream is = Version.class.getResourceAsStream("/version.properties")) { + versionProperties.load(is); + } catch (IOException ex) { + LOGGER.error("Error loading version properties", ex); + return UNREADABLE_VERSION; + } + + String version = versionProperties.getProperty("version", UNKNOWN_VERSION).trim(); + if (VERSION_PLACEHOLDER.equals(version)) { + return UNSET_VERSION; + } else { + return version; + } + } + + @Override + public void run() { + String version = readVersionFromResources(); + System.out.println(version); + } + +} diff --git a/modules/swagger-codegen-cli/src/main/resources/version.properties b/modules/swagger-codegen-cli/src/main/resources/version.properties new file mode 100644 index 00000000000..410af8cc687 --- /dev/null +++ b/modules/swagger-codegen-cli/src/main/resources/version.properties @@ -0,0 +1 @@ +version = ${project.version} From 2aadbee8edc4f27d72756f99ced5d326d18c148f Mon Sep 17 00:00:00 2001 From: Adam Panzer Date: Fri, 30 Sep 2016 11:56:12 -0700 Subject: [PATCH 5/7] validate(s)_presence_of Migration should create pluralized table names Change controller filenames --- .../codegen/languages/Rails5ServerCodegen.java | 4 ++-- .../src/main/resources/rails5/migrate.mustache | 2 +- .../src/main/resources/rails5/model.mustache | 2 +- .../{pet_controllers.rb => pets_controller.rb} | 0 .../{store_controllers.rb => stores_controller.rb} | 0 .../{user_controllers.rb => users_controller.rb} | 0 samples/server/petstore/rails5/app/models/pet.rb | 4 ++-- .../petstore/rails5/db/migrate/0_init_tables.rb | 12 ++++++------ 8 files changed, 12 insertions(+), 12 deletions(-) rename samples/server/petstore/rails5/app/controllers/{pet_controllers.rb => pets_controller.rb} (100%) rename samples/server/petstore/rails5/app/controllers/{store_controllers.rb => stores_controller.rb} (100%) rename samples/server/petstore/rails5/app/controllers/{user_controllers.rb => users_controller.rb} (100%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Rails5ServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Rails5ServerCodegen.java index e03622b5919..5147d4a5b00 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Rails5ServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/Rails5ServerCodegen.java @@ -281,8 +281,8 @@ public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig // replace - with _ e.g. created-at => created_at name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. - // e.g. PhoneNumberApi.rb => phone_number_api.rb - return underscore(name) + "_controllers"; + // e.g. DefaultController => defaults_controller.rb + return underscore(name) + "s_controller"; } @Override diff --git a/modules/swagger-codegen/src/main/resources/rails5/migrate.mustache b/modules/swagger-codegen/src/main/resources/rails5/migrate.mustache index 508b0ce7ede..d9d5db407be 100644 --- a/modules/swagger-codegen/src/main/resources/rails5/migrate.mustache +++ b/modules/swagger-codegen/src/main/resources/rails5/migrate.mustache @@ -4,7 +4,7 @@ class InitTables < ActiveRecord::Migration def change{{#models}}{{#model}} - create_table :{{classFilename}}, id: false do |t|{{#vars}}{{#isContainer}} + create_table "{{classFilename}}".pluralize.to_sym, id: false do |t|{{#vars}}{{#isContainer}} t.string :{{name}}{{/isContainer}}{{^isContainer}} t.{{datatype}} :{{{name}}}{{/isContainer}}{{/vars}} diff --git a/modules/swagger-codegen/src/main/resources/rails5/model.mustache b/modules/swagger-codegen/src/main/resources/rails5/model.mustache index edfe9fac56c..8fc9455c2b7 100644 --- a/modules/swagger-codegen/src/main/resources/rails5/model.mustache +++ b/modules/swagger-codegen/src/main/resources/rails5/model.mustache @@ -5,7 +5,7 @@ {{#models}}{{#model}} class {{classname}} < ApplicationRecord {{#requiredVars}} - validate_presence_of :{{name}} + validates_presence_of :{{name}} {{/requiredVars}}{{#vars}}{{#isListContainer}} serialize :{{name}}, Array{{/isListContainer}}{{#isMapContainer}} serialize :{{name}}, Hash{{/isMapContainer}}{{/vars}} diff --git a/samples/server/petstore/rails5/app/controllers/pet_controllers.rb b/samples/server/petstore/rails5/app/controllers/pets_controller.rb similarity index 100% rename from samples/server/petstore/rails5/app/controllers/pet_controllers.rb rename to samples/server/petstore/rails5/app/controllers/pets_controller.rb diff --git a/samples/server/petstore/rails5/app/controllers/store_controllers.rb b/samples/server/petstore/rails5/app/controllers/stores_controller.rb similarity index 100% rename from samples/server/petstore/rails5/app/controllers/store_controllers.rb rename to samples/server/petstore/rails5/app/controllers/stores_controller.rb diff --git a/samples/server/petstore/rails5/app/controllers/user_controllers.rb b/samples/server/petstore/rails5/app/controllers/users_controller.rb similarity index 100% rename from samples/server/petstore/rails5/app/controllers/user_controllers.rb rename to samples/server/petstore/rails5/app/controllers/users_controller.rb diff --git a/samples/server/petstore/rails5/app/models/pet.rb b/samples/server/petstore/rails5/app/models/pet.rb index da927b6260e..e077b528bc7 100644 --- a/samples/server/petstore/rails5/app/models/pet.rb +++ b/samples/server/petstore/rails5/app/models/pet.rb @@ -23,8 +23,8 @@ limitations under the License. class Pet < ApplicationRecord - validate_presence_of :name - validate_presence_of :photo_urls + validates_presence_of :name + validates_presence_of :photo_urls serialize :photo_urls, Array serialize :tags, Array diff --git a/samples/server/petstore/rails5/db/migrate/0_init_tables.rb b/samples/server/petstore/rails5/db/migrate/0_init_tables.rb index 5fa060fb4dc..7bc2663f162 100644 --- a/samples/server/petstore/rails5/db/migrate/0_init_tables.rb +++ b/samples/server/petstore/rails5/db/migrate/0_init_tables.rb @@ -23,7 +23,7 @@ limitations under the License. class InitTables < ActiveRecord::Migration def change - create_table :api_response, id: false do |t| + create_table "api_response".pluralize.to_sym, id: false do |t| t.integer :code t.string :type t.string :message @@ -31,14 +31,14 @@ class InitTables < ActiveRecord::Migration t.timestamps end - create_table :category, id: false do |t| + create_table "category".pluralize.to_sym, id: false do |t| t.integer :id t.string :name t.timestamps end - create_table :order, id: false do |t| + create_table "order".pluralize.to_sym, id: false do |t| t.integer :id t.integer :pet_id t.integer :quantity @@ -49,7 +49,7 @@ class InitTables < ActiveRecord::Migration t.timestamps end - create_table :pet, id: false do |t| + create_table "pet".pluralize.to_sym, id: false do |t| t.integer :id t.string :category t.string :name @@ -60,14 +60,14 @@ class InitTables < ActiveRecord::Migration t.timestamps end - create_table :tag, id: false do |t| + create_table "tag".pluralize.to_sym, id: false do |t| t.integer :id t.string :name t.timestamps end - create_table :user, id: false do |t| + create_table "user".pluralize.to_sym, id: false do |t| t.integer :id t.string :username t.string :first_name From 3ca98930132ccc7dad21dd2c96991cc53395d7f3 Mon Sep 17 00:00:00 2001 From: wing328 Date: Tue, 4 Oct 2016 11:18:10 +0800 Subject: [PATCH 6/7] add undertow --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f75aa258941..93f84437bf6 100644 --- a/README.md +++ b/README.md @@ -881,6 +881,7 @@ Here is a list of template creators: * Erlang Server: @galaxie * Go Server: @guohuang * Haskell Servant: @algas + * Java Undertow: @stevehu * Java Spring Boot: @diyfr * JAX-RS RestEasy: @chameleon82 * JAX-RS CXF: @hiveship From ed4200f5c6bde0d6a9a40f770202ce0cd230d3f2 Mon Sep 17 00:00:00 2001 From: wing328 Date: Wed, 5 Oct 2016 10:51:54 +0800 Subject: [PATCH 7/7] add http://onedata.org --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 93f84437bf6..9c3bf295fdb 100644 --- a/README.md +++ b/README.md @@ -782,6 +782,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you - [Mporium](http://mporium.com/) - [nViso](http://www.nviso.ch/) - [Okiok](https://www.okiok.com) +- [Onedata](http://onedata.org) - [OSDN](https://osdn.jp) - [PagerDuty](https://www.pagerduty.com) - [Pepipost](https://www.pepipost.com)