Skip to content

Commit 8fec429

Browse files
craffaelwing328
authored andcommitted
[NancyFx] Support Async (#6755)
* add support for async routes/endpoints you can now set --optional-properties async=true to generate a nancyfx server stub that uses asynchronous programming. (cherry picked from commit 126869c) * add nancyfx-petstore-server-async.sh to generate sample of async nancyfx. * Rename async => asyncServer * update bin/nancyfx-petstore-server-async.sh * rename async => asyncServer in api.mustache + small bugfix * run ./bin/nancyfx-petstore-server.sh and ./bin/nancyfx-petstore-server-async.sh * remove additional new line in api.mustache + add space after if * run ./bin/nancyfx-petstore-server.sh and ./bin/nancyfx-petstore-server-async.sh
1 parent c97b63d commit 8fec429

File tree

21 files changed

+2549
-14
lines changed

21 files changed

+2549
-14
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/sh
2+
3+
SCRIPT="$0"
4+
5+
while [ -h "$SCRIPT" ] ; do
6+
ls=`ls -ld "$SCRIPT"`
7+
link=`expr "$ls" : '.*-> \(.*\)$'`
8+
if expr "$link" : '/.*' > /dev/null; then
9+
SCRIPT="$link"
10+
else
11+
SCRIPT=`dirname "$SCRIPT"`/"$link"
12+
fi
13+
done
14+
15+
if [ ! -d "${APP_DIR}" ]; then
16+
APP_DIR=`dirname "$SCRIPT"`/..
17+
APP_DIR=`cd "${APP_DIR}"; pwd`
18+
fi
19+
20+
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
21+
22+
if [ ! -f "$executable" ]
23+
then
24+
mvn clean package
25+
fi
26+
27+
# if you've executed sbt assembly previously it will use that instead.
28+
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
29+
ags="generate $@ -t modules/swagger-codegen/src/main/resources/nancyfx -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nancyfx -o samples/server/petstore/nancyfx-async --additional-properties packageGuid={768B8DC6-54EE-4D40-9B20-7857E1D742A4},asyncServer=true"
30+
31+
java $JAVA_OPTS -jar $executable $ags

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NancyFXServerCodegen.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
4646
private static final String IMMUTABLE_OPTION = "immutable";
4747
private static final String USE_BASE_PATH = "writeModulePath";
4848
private static final String PACKAGE_CONTEXT = "packageContext";
49+
private static final String ASYNC_SERVER = "asyncServer";
4950

5051
private static final Map<String, Predicate<Property>> propertyToSwaggerTypeMapping =
5152
createPropertyToSwaggerTypeMapping();
@@ -57,6 +58,9 @@ public class NancyFXServerCodegen extends AbstractCSharpCodegen {
5758
private final Multimap<String, CodegenModel> childrenByParent = ArrayListMultimap.create();
5859
private final BiMap<String, String> modelNameMapping = HashBiMap.create();
5960

61+
/** If set to true, we will generate c# async endpoints and service interfaces */
62+
private boolean asyncServer = false;
63+
6064
public NancyFXServerCodegen() {
6165
outputFolder = "generated-code" + File.separator + getName();
6266
apiTemplateFiles.put("api.mustache", ".cs");
@@ -87,6 +91,7 @@ public NancyFXServerCodegen() {
8791
addSwitch(RETURN_ICOLLECTION, RETURN_ICOLLECTION_DESC, returnICollection);
8892
addSwitch(IMMUTABLE_OPTION, "Enabled by default. If disabled generates model classes with setters", true);
8993
addSwitch(USE_BASE_PATH, "Enabled by default. If disabled, module paths will not mirror api base path", true);
94+
addSwitch(ASYNC_SERVER, "Set to true to enable the generation of async routes/endpoints.", false);
9095
typeMapping.putAll(nodaTimeTypesMappings());
9196
languageSpecificPrimitives.addAll(nodaTimePrimitiveTypes());
9297

@@ -128,6 +133,10 @@ public void processOpts() {
128133
setPackageGuid((String) additionalProperties.get(OPTIONAL_PROJECT_GUID));
129134
}
130135

136+
if (additionalProperties.containsKey(ASYNC_SERVER)) {
137+
setAsyncServer(Boolean.parseBoolean((String)additionalProperties.get(ASYNC_SERVER)));
138+
}
139+
131140
additionalProperties.put("packageGuid", packageGuid);
132141

133142
setupModelTemplate();
@@ -199,7 +208,11 @@ private String sourceFile(final String fileName) {
199208
public void setPackageGuid(String packageGuid) {
200209
this.packageGuid = packageGuid;
201210
}
202-
211+
212+
public void setAsyncServer(boolean asyncServer) {
213+
this.asyncServer = asyncServer;
214+
}
215+
203216
@Override
204217
public String apiFileFolder() {
205218
return outputFolder + File.separator + sourceFolder() + File.separator + API_NAMESPACE;

modules/swagger-codegen/src/main/resources/nancyfx/api.mustache

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ using System.Collections.Generic;
55
using Sharpility.Base;
66
using {{packageName}}.{{packageContext}}.Models;
77
using {{packageName}}.{{packageContext}}.Utils;
8-
using NodaTime;
8+
using NodaTime;{{#asyncServer}}
9+
using System.Threading.Tasks;{{/asyncServer}}
910
{{#imports}}using {{import}};
1011
{{/imports}}
1112

@@ -24,13 +25,13 @@ namespace {{packageName}}.{{packageContext}}.Modules
2425
/// <param name="service">Service handling requests</param>
2526
public {{classname}}Module({{interfacePrefix}}{{classname}}Service service) : base("{{{baseContext}}}")
2627
{ {{#operation}}
27-
{{httpMethod}}["{{{path}}}"] = parameters =>
28+
{{httpMethod}}["{{{path}}}"{{#asyncServer}}, true{{/asyncServer}}] = {{#asyncServer}}async (parameters, ct){{/asyncServer}}{{^asyncServer}}parameters{{/asyncServer}} =>
2829
{
2930
{{#allParams}}{{#isBodyParam}}var {{paramName}} = this.Bind<{{&dataType}}>();{{/isBodyParam}}{{^isBodyParam}}{{#isEnum}}var {{paramName}} = Parameters.ValueOf<{{>innerApiEnumName}}?>({{>innerParameterValueOfArgs}});{{/isEnum}}{{^isEnum}}var {{paramName}} = Parameters.ValueOf<{{&dataType}}>({{>innerParameterValueOfArgs}});{{/isEnum}}{{#hasMore}}
3031
{{/hasMore}}{{/isBodyParam}}{{/allParams}}{{#allParams}}{{#required}}
3132
Preconditions.IsNotNull({{paramName}}, "Required parameter: '{{paramName}}' is missing at '{{operationId}}'");
3233
{{/required}}{{/allParams}}
33-
{{#returnType}}return {{/returnType}}service.{{operationId}}(Context{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}{{#isListContainer}}.ToArray(){{/isListContainer}}{{/returnType}};{{^returnType}}
34+
{{#returnType}}return {{/returnType}}{{#asyncServer}}await {{/asyncServer}}service.{{operationId}}(Context{{#allParams.0}}, {{/allParams.0}}{{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}{{#isListContainer}}.ToArray(){{/isListContainer}}{{/returnType}};{{^returnType}}
3435
return new Response { ContentType = "{{produces.0.mediaType}}"};{{/returnType}}
3536
};
3637
{{/operation}}
@@ -48,7 +49,7 @@ namespace {{packageName}}.{{packageContext}}.Modules
4849
/// <param name="context">Context of request</param>
4950
{{#allParams}}/// <param name="{{paramName}}">{{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}</param>
5051
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
51-
{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}}
52+
{{#asyncServer}}{{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}}{{/asyncServer}}{{^asyncServer}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}{{/asyncServer}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}});{{#hasMore}}
5253

5354
{{/hasMore}}{{/operation}}
5455
}
@@ -58,14 +59,14 @@ namespace {{packageName}}.{{packageContext}}.Modules
5859
/// </summary>
5960
public abstract class Abstract{{classname}}Service: {{interfacePrefix}}{{classname}}Service
6061
{
61-
{{#operation}}public virtual {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}})
62+
{{#operation}}public virtual {{#asyncServer}}{{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}}{{/asyncServer}}{{^asyncServer}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}{{/asyncServer}} {{operationId}}(NancyContext context{{#allParams.0}}, {{/allParams.0}}{{>paramsList}})
6263
{
63-
{{#returnType}}return {{/returnType}}{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
64+
{{^asyncServer}}{{#returnType}}return {{/returnType}}{{/asyncServer}}{{#asyncServer}}return {{/asyncServer}}{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
6465
}{{#hasMore}}
6566

6667
{{/hasMore}}{{/operation}}
6768

68-
{{#operation}}protected abstract {{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}}({{>paramsList}});{{#hasMore}}
69+
{{#operation}}protected abstract {{#asyncServer}}{{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}}{{/asyncServer}}{{^asyncServer}}{{#returnType}}{{&returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}{{/asyncServer}} {{operationId}}({{>paramsList}});{{#hasMore}}
6970

7071
{{/hasMore}}{{/operation}}
7172
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Swagger Codegen Ignore
2+
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.3.0-SNAPSHOT
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio 2012
3+
VisualStudioVersion = 12.0.0.0
4+
MinimumVisualStudioVersion = 10.0.0.1
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IO.Swagger", "src\IO.Swagger\IO.Swagger.csproj", "{768B8DC6-54EE-4D40-9B20-7857E1D742A4}"
6+
EndProject
7+
Global
8+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9+
Debug|Any CPU = Debug|Any CPU
10+
Release|Any CPU = Release|Any CPU
11+
EndGlobalSection
12+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13+
{768B8DC6-54EE-4D40-9B20-7857E1D742A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14+
{768B8DC6-54EE-4D40-9B20-7857E1D742A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
15+
{768B8DC6-54EE-4D40-9B20-7857E1D742A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
16+
{768B8DC6-54EE-4D40-9B20-7857E1D742A4}.Release|Any CPU.Build.0 = Release|Any CPU
17+
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18+
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU
19+
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU
20+
{19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU
21+
EndGlobalSection
22+
GlobalSection(SolutionProperties) = preSolution
23+
HideSolutionNode = FALSE
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProjectGuid>{768B8DC6-54EE-4D40-9B20-7857E1D742A4}</ProjectGuid>
7+
<OutputType>Library</OutputType>
8+
<AppDesignerFolder>Properties</AppDesignerFolder>
9+
<RootNamespace>IO.Swagger.v2</RootNamespace>
10+
<AssemblyName>IO.Swagger</AssemblyName>
11+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12+
<FileAlignment>512</FileAlignment>
13+
</PropertyGroup>
14+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15+
<DebugSymbols>true</DebugSymbols>
16+
<DebugType>full</DebugType>
17+
<Optimize>false</Optimize>
18+
<OutputPath>bin\Debug\</OutputPath>
19+
<DefineConstants>DEBUG;TRACE</DefineConstants>
20+
<ErrorReport>prompt</ErrorReport>
21+
<WarningLevel>4</WarningLevel>
22+
<DocumentationFile>bin\Debug\IO.Swagger.XML</DocumentationFile>
23+
</PropertyGroup>
24+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25+
<DebugType>pdbonly</DebugType>
26+
<Optimize>true</Optimize>
27+
<OutputPath>bin\Release\</OutputPath>
28+
<DefineConstants>TRACE</DefineConstants>
29+
<ErrorReport>prompt</ErrorReport>
30+
<WarningLevel>4</WarningLevel>
31+
<DocumentationFile>bin\Release\IO.Swagger.XML</DocumentationFile>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
35+
<HintPath>..\..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
36+
<Private>True</Private>
37+
</Reference>
38+
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
39+
<HintPath>..\..\packages\NodaTime.1.3.1\lib\net35-Client\NodaTime.dll</HintPath>
40+
<Private>True</Private>
41+
</Reference>
42+
<Reference Include="Sharpility, Version=1.2.2.0, Culture=neutral, processorArchitecture=MSIL">
43+
<HintPath>..\..\packages\Sharpility.1.2.2\lib\net45\Sharpility.dll</HintPath>
44+
<Private>True</Private>
45+
</Reference>
46+
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
47+
<HintPath>..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
48+
<Private>True</Private>
49+
</Reference> <Reference Include="System"/>
50+
<Reference Include="System.Core"/>
51+
<Reference Include="System.Xml.Linq"/>
52+
<Reference Include="System.Data.DataSetExtensions"/>
53+
<Reference Include="Microsoft.CSharp"/>
54+
<Reference Include="System.Data"/>
55+
<Reference Include="System.Runtime.Serialization"/>
56+
<Reference Include="System.Xml"/>
57+
</ItemGroup>
58+
<ItemGroup>
59+
<Compile Include="**\*.cs" Exclude="obj\**"/>
60+
</ItemGroup>
61+
<ItemGroup>
62+
<Content Include="packages.config"/>
63+
</ItemGroup>
64+
<Import Project="$(MsBuildToolsPath)\Microsoft.CSharp.targets"/>
65+
</Project>
66+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<package>
3+
<metadata>
4+
<id>IO.Swagger</id>
5+
<title>IO.Swagger</title>
6+
<version>1.0.0</version>
7+
<authors>swagger-codegen</authors>
8+
<owners>swagger-codegen</owners>
9+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
10+
<description>NancyFx IO.Swagger API</description>
11+
<copyright>http://swagger.io/terms/</copyright>
12+
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0.html</licenseUrl>
13+
</metadata>
14+
</package>

0 commit comments

Comments
 (0)