Merge remote-tracking branch 'upstream/master'

This commit is contained in:
11356176
2016-01-13 18:14:06 +00:00
163 changed files with 3824 additions and 1067 deletions

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-project</artifactId>
<version>2.1.5</version>
<version>2.1.6-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -46,6 +46,9 @@ public class CodegenConstants {
public static final String SORT_PARAMS_BY_REQUIRED_FLAG = "sortParamsByRequiredFlag";
public static final String SORT_PARAMS_BY_REQUIRED_FLAG_DESC = "Sort method arguments to place required parameters before optional parameters.";
public static final String USE_DATETIME_OFFSET = "useDateTimeOffset";
public static final String USE_DATETIME_OFFSET_DESC = "Use DateTimeOffset to model date-time properties";
public static final String ENSURE_UNIQUE_PARAMS = "ensureUniqueParams";
public static final String ENSURE_UNIQUE_PARAMS_DESC = "Whether to ensure parameter names are unique in an operation (rename parameters that are not).";
@@ -54,4 +57,9 @@ public class CodegenConstants {
public static final String POD_VERSION = "podVersion";
public static final String OPTIONAL_METHOD_ARGUMENT = "optionalMethodArgument";
public static final String OPTIONAL_METHOD_ARGUMENT_DESC = "Optional method argument, e.g. void square(int x=10) (.net 4.0+ only).";
public static final String OPTIONAL_ASSEMBLY_INFO = "optionalAssemblyInfo";
public static final String OPTIONAL_ASSEMBLY_INFO_DESC = "Generate AssemblyInfo.cs (Default: true).";
}

View File

@@ -42,13 +42,19 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
reservedWords = new HashSet<String>(
Arrays.asList(
"abstract", "continue", "for", "new", "switch", "assert",
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
"native", "super", "while")
// local variable names used in API methods (endpoints)
"postBody", "path", "queryParams", "headerParams", "formParams",
"contentTypes", "contentType", "response", "builder", "httpEntity",
"authNames", "basePath", "apiInvoker",
// android reserved words
"abstract", "continue", "for", "new", "switch", "assert",
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
"native", "super", "while")
);
languageSpecificPrimitives = new HashSet<String>(
@@ -281,10 +287,6 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml"));
supportingFiles.add(new SupportingFile("apiInvoker.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "ApiInvoker.java"));
supportingFiles.add(new SupportingFile("responses.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "Responses.java"));
// supportingFiles.add(new SupportingFile("httpPatch.mustache",
// (sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "HttpPatch.java"));
supportingFiles.add(new SupportingFile("jsonUtil.mustache",
(sourceFolder + File.separator + invokerPackage).replace(".", File.separator), "JsonUtil.java"));
supportingFiles.add(new SupportingFile("apiException.mustache",

View File

@@ -47,11 +47,16 @@ public class AsyncScalaClientCodegen extends DefaultCodegen implements CodegenCo
reservedWords = new HashSet<String>(
Arrays.asList(
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
// local variable names used in API methods (endpoints)
"config", "path", "contentTypes", "contentType", "queryParams", "headerParams",
"formParams", "postBody", "resFuture", "client", "reader",
// scala reserved words
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
);
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);

View File

@@ -23,7 +23,9 @@ import org.slf4j.LoggerFactory;
public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
protected boolean optionalAssemblyInfoFlag = true;
protected boolean optionalMethodArgumentFlag = true;
protected boolean useDateTimeOffsetFlag = false;
protected String packageTitle = "Swagger Library";
protected String packageProductName = "SwaggerLibrary";
protected String packageDescription = "A library generated from a Swagger doc";
@@ -75,6 +77,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"List",
"Dictionary",
"DateTime?",
"DateTimeOffset?",
"String",
"Boolean",
"Double",
@@ -89,6 +92,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping = new HashMap<String, String>();
typeMapping.put("string", "string");
typeMapping.put("binary", "byte[]");
typeMapping.put("boolean", "bool?");
typeMapping.put("integer", "int?");
typeMapping.put("float", "float?");
@@ -111,6 +115,10 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(CliOption.newBoolean(CodegenConstants.OPTIONAL_METHOD_ARGUMENT, "C# Optional method argument, " +
"e.g. void square(int x=10) (.net 4.0+ only)."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.OPTIONAL_ASSEMBLY_INFO,
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue(sourceFolder));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_DATETIME_OFFSET, CodegenConstants.USE_DATETIME_OFFSET_DESC));
}
@Override
@@ -123,6 +131,14 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
}
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)){
setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
}
else
{
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, this.sourceFolder);
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
apiPackage = packageName + ".Api";
@@ -132,6 +148,13 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
}
// Use DateTimeOffset
if (additionalProperties.containsKey(CodegenConstants.USE_DATETIME_OFFSET))
{
useDateTimeOffset(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_DATETIME_OFFSET).toString()));
}
additionalProperties.put(CodegenConstants.USE_DATETIME_OFFSET, useDateTimeOffsetFlag);
additionalProperties.put("clientPackage", clientPackage);
// Add properties used by AssemblyInfo.mustache
@@ -147,6 +170,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
}
additionalProperties.put("optionalMethodArgument", optionalMethodArgumentFlag);
if (additionalProperties.containsKey(CodegenConstants.OPTIONAL_ASSEMBLY_INFO)) {
setOptionalAssemblyInfoFlag(Boolean.valueOf(additionalProperties
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
}
supportingFiles.add(new SupportingFile("Configuration.mustache",
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
@@ -158,8 +186,13 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
supportingFiles.add(new SupportingFile("Newtonsoft.Json.dll", "bin", "Newtonsoft.Json.dll"));
supportingFiles.add(new SupportingFile("RestSharp.dll", "bin", "RestSharp.dll"));
supportingFiles.add(new SupportingFile("compile.mustache", "", "compile.bat"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "compile-mono.sh"));
supportingFiles.add(new SupportingFile("packages.config.mustache", "vendor" + java.io.File.separator, "packages.config"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("AssemblyInfo.mustache", "src" + File.separator + "Properties", "AssemblyInfo.cs"));
if (optionalAssemblyInfoFlag) {
supportingFiles.add(new SupportingFile("AssemblyInfo.mustache", "src" + File.separator + "Properties", "AssemblyInfo.cs"));
}
}
@@ -301,10 +334,23 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
return camelize(sanitizeName(operationId));
}
public void setOptionalAssemblyInfoFlag(boolean flag) {
this.optionalAssemblyInfoFlag = flag;
}
public void setOptionalMethodArgumentFlag(boolean flag) {
this.optionalMethodArgumentFlag = flag;
}
public void useDateTimeOffset(boolean flag) {
this.useDateTimeOffsetFlag = flag;
if (flag)
typeMapping.put("datetime", "DateTimeOffset?");
else
typeMapping.put("datetime", "DateTime?");
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
@@ -313,6 +359,10 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
this.packageVersion = packageVersion;
}
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");

View File

@@ -223,12 +223,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
final String authFolder = (sourceFolder + '/' + invokerPackage + ".auth").replace(".", "/");
if ("feign".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("FormAwareEncoder.mustache", invokerFolder, "FormAwareEncoder.java"));
} else {
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
}
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
if (!("feign".equals(getLibrary()) || "retrofit".equals(getLibrary()) || "retrofit2".equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("apiException.mustache", invokerFolder, "ApiException.java"));

View File

@@ -11,6 +11,7 @@ import com.google.common.collect.Multimap;
import io.swagger.codegen.*;
import io.swagger.models.Swagger;
import io.swagger.models.Info;
import io.swagger.util.Yaml;
import java.io.File;
@@ -246,9 +247,6 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
@Override
public void preprocessSwagger(Swagger swagger) {
if ("/".equals(swagger.getBasePath())) {
swagger.setBasePath("");
}
String host = swagger.getHost();
String port = "8080";
@@ -259,6 +257,16 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
}
this.additionalProperties.put("serverPort", port);
if (swagger.getInfo() != null) {
Info info = swagger.getInfo();
if (info.getTitle() != null) {
// when info.title is defined, use it for projectName
// used in package.json
projectName = dashize(info.getTitle());
this.additionalProperties.put("projectName", projectName);
}
}
}
@Override

View File

@@ -20,7 +20,8 @@ import org.apache.commons.lang.StringUtils;
public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
public static final String MODULE_NAME = "moduleName";
public static final String MODULE_VERSION = "moduleVersion";
protected String moduleName = "SwaggerClient";
protected String moduleName = "WWW::SwaggerClient";
protected String modulePathPart = moduleName.replaceAll("::",String.valueOf(File.separatorChar));
protected String moduleVersion = "1.0.0";
public PerlClientCodegen() {
@@ -72,7 +73,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("object", "object");
cliOptions.clear();
cliOptions.add(new CliOption(MODULE_NAME, "Perl module name (convention: CamelCase).").defaultValue("SwaggerClient"));
cliOptions.add(new CliOption(MODULE_NAME, "Perl module name (convention: CamelCase or Long::Module).").defaultValue("SwaggerClient"));
cliOptions.add(new CliOption(MODULE_VERSION, "Perl module version.").defaultValue("1.0.0"));
cliOptions.add(CliOption.newBoolean(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue(Boolean.TRUE.toString()));
@@ -94,15 +95,16 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey(MODULE_NAME)) {
setModuleName((String) additionalProperties.get(MODULE_NAME));
setModulePathPart(moduleName.replaceAll("::",String.valueOf(File.separatorChar)));
} else {
additionalProperties.put(MODULE_NAME, moduleName);
}
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "ApiFactory.pm"));
supportingFiles.add(new SupportingFile("Role.mustache", ("lib/WWW/" + moduleName).replace('/', File.separatorChar), "Role.pm"));
supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/WWW/" + moduleName + "/Role").replace('/', File.separatorChar), "AutoDoc.pm"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiClient.pm"));
supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "Configuration.pm"));
supportingFiles.add(new SupportingFile("ApiFactory.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "ApiFactory.pm"));
supportingFiles.add(new SupportingFile("Role.mustache", ("lib/" + modulePathPart).replace('/', File.separatorChar), "Role.pm"));
supportingFiles.add(new SupportingFile("AutoDoc.mustache", ("lib/" + modulePathPart + "/Role").replace('/', File.separatorChar), "AutoDoc.pm"));
supportingFiles.add(new SupportingFile("autodoc.script.mustache", "bin", "autodoc"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
@@ -129,12 +131,12 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String apiFileFolder() {
return (outputFolder + "/lib/WWW/" + moduleName + apiPackage()).replace('/', File.separatorChar);
return (outputFolder + "/lib/" + modulePathPart + apiPackage()).replace('/', File.separatorChar);
}
@Override
public String modelFileFolder() {
return (outputFolder + "/lib/WWW/" + moduleName + modelPackage()).replace('/', File.separatorChar);
return (outputFolder + "/lib/" + modulePathPart + modelPackage()).replace('/', File.separatorChar);
}
@Override
@@ -251,6 +253,10 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
this.moduleName = moduleName;
}
public void setModulePathPart(String modulePathPart) {
this.modulePathPart = modulePathPart;
}
public void setModuleVersion(String moduleVersion) {
this.moduleVersion = moduleVersion;
}

View File

@@ -19,10 +19,24 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
public static final String GEM_NAME = "gemName";
public static final String MODULE_NAME = "moduleName";
public static final String GEM_VERSION = "gemVersion";
public static final String GEM_LICENSE = "gemLicense";
public static final String GEM_HOMEPAGE = "gemHomepage";
public static final String GEM_SUMMARY = "gemSummary";
public static final String GEM_DESCRIPTION = "gemDescription";
public static final String GEM_AUTHOR = "gemAuthor";
public static final String GEM_AUTHOR_EMAIL = "gemAuthorEmail";
protected String gemName;
protected String moduleName;
protected String gemVersion = "1.0.0";
protected String libFolder = "lib";
protected String gemLicense = "Apache-2.0";
protected String gemHomepage = "http://swagger.io";
protected String gemSummary = "A ruby wrapper for the swagger APIs";
protected String gemDescription = "This gem maps to a swagger API";
protected String gemAuthor = "";
protected String gemAuthorEmail = "";
public RubyClientCodegen() {
super();
@@ -87,6 +101,23 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption(MODULE_NAME, "top module name (convention: CamelCase, usually corresponding" +
" to gem name).").defaultValue("SwaggerClient"));
cliOptions.add(new CliOption(GEM_VERSION, "gem version.").defaultValue("1.0.0"));
cliOptions.add(new CliOption(GEM_LICENSE, "gem license. ").
defaultValue("Apache-2.0"));
cliOptions.add(new CliOption(GEM_HOMEPAGE, "gem homepage. ").
defaultValue("http://swagger.io"));
cliOptions.add(new CliOption(GEM_SUMMARY, "gem summary. ").
defaultValue("A ruby wrapper for the swagger APIs"));
cliOptions.add(new CliOption(GEM_DESCRIPTION, "gem description. ").
defaultValue("This gem maps to a swagger API"));
cliOptions.add(new CliOption(GEM_AUTHOR, "gem author (only one is supported)."));
cliOptions.add(new CliOption(GEM_AUTHOR_EMAIL, "gem author email (only one is supported)."));
}
@Override
@@ -114,11 +145,36 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey(GEM_VERSION)) {
setGemVersion((String) additionalProperties.get(GEM_VERSION));
} else {
}else {
// not set, pass the default value to template
additionalProperties.put(GEM_VERSION, gemVersion);
}
if (additionalProperties.containsKey(GEM_LICENSE)) {
setGemLicense((String) additionalProperties.get(GEM_LICENSE));
}
if (additionalProperties.containsKey(GEM_HOMEPAGE)) {
setGemHomepage((String) additionalProperties.get(GEM_HOMEPAGE));
}
if (additionalProperties.containsKey(GEM_SUMMARY)) {
setGemSummary((String) additionalProperties.get(GEM_SUMMARY));
}
if (additionalProperties.containsKey(GEM_DESCRIPTION)) {
setGemDescription((String) additionalProperties.get(GEM_DESCRIPTION));
}
if (additionalProperties.containsKey(GEM_AUTHOR)) {
setGemAuthor((String) additionalProperties.get(GEM_AUTHOR));
}
if (additionalProperties.containsKey(GEM_AUTHOR_EMAIL)) {
setGemAuthorEmail((String) additionalProperties.get(GEM_AUTHOR_EMAIL));
}
// use constant model/api package (folder path)
setModelPackage("models");
setApiPackage("api");
@@ -133,6 +189,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
String modelFolder = gemFolder + File.separator + modelPackage.replace("/", File.separator);
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
@@ -354,4 +411,28 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
public void setGemVersion(String gemVersion) {
this.gemVersion = gemVersion;
}
public void setGemDescription(String gemDescription) {
this.gemDescription = gemDescription;
}
public void setGemSummary(String gemSummary) {
this.gemSummary = gemSummary;
}
public void setGemLicense(String gemLicense) {
this.gemLicense = gemLicense;
}
public void setGemHomepage(String gemHomepage) {
this.gemHomepage = gemHomepage;
}
public void setGemAuthor(String gemAuthor) {
this.gemAuthor = gemAuthor;
}
public void setGemAuthorEmail(String gemAuthorEmail) {
this.gemAuthorEmail = gemAuthorEmail;
}
}

View File

@@ -49,11 +49,16 @@ public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig
reservedWords = new HashSet<String>(
Arrays.asList(
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
// local variable names used in API methods (endpoints)
"path", "contentTypes", "contentType", "queryParams", "headerParams",
"formParams", "postBody", "mp", "basePath", "apiInvoker",
// scala reserved words
"abstract", "case", "catch", "class", "def", "do", "else", "extends",
"false", "final", "finally", "for", "forSome", "if", "implicit",
"import", "lazy", "match", "new", "null", "object", "override", "package",
"private", "protected", "return", "sealed", "super", "this", "throw",
"trait", "try", "true", "type", "val", "var", "while", "with", "yield")
);
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);

View File

@@ -159,6 +159,7 @@ namespace {{packageName}}.Client
/// </summary>
/// <param name="content">HTTP body (e.g. string, JSON).</param>
/// <param name="type">Object type.</param>
/// <param name="headers">HTTP headers.</param>
/// <returns>Object representation of the JSON string.</returns>
public object Deserialize(string content, Type type, IList<Parameter> headers=null)
{

View File

@@ -20,7 +20,6 @@ namespace {{packageName}}.Client {
/// <summary>
/// Initializes a new instance of the <see cref="ApiException"/> class.
/// </summary>
/// <param name="basePath">The base path.</param>
public ApiException() {}
/// <summary>

View File

@@ -9,6 +9,9 @@ using {{packageName}}.Client;
namespace {{packageName}}.Api
{
{{#operations}}
/// <summary>
/// Represents a collection of functions to interact with the API endpoints
/// </summary>
public interface I{{classname}}
{
{{#operation}}
@@ -16,7 +19,7 @@ namespace {{packageName}}.Api
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
}
@@ -71,7 +74,7 @@ namespace {{packageName}}.Api
/// <summary>
/// Gets or sets the API client.
/// </summary>
/// <value>An instance of the ApiClient</param>
/// <value>An instance of the ApiClient</value>
public ApiClient ApiClient {get; set;}
{{#operation}}
@@ -79,7 +82,7 @@ namespace {{packageName}}.Api
/// {{summary}} {{notes}}
/// </summary>
{{#allParams}}/// <param name="{{paramName}}">{{description}}</param>
{{/allParams}}/// <returns>{{#returnType}}{{{returnType}}}{{/returnType}}</returns>
{{/allParams}}/// <returns>{{#returnType}}{{returnType}}{{/returnType}}</returns>
public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}{{#required}}

View File

@@ -7,6 +7,6 @@ vendor/RestSharp.Net2.1.1.11/lib/net20/RestSharp.Net2.dll,\
System.Runtime.Serialization.dll \
-target:library \
-out:bin/{{packageName}}.dll \
-recurse:src/*.cs \
-recurse:'src/*.cs' \
-doc:bin/{{packageName}}.xml \
-platform:anycpu
-platform:anycpu

View File

@@ -43,10 +43,12 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Map<String, Client> hostMap = new HashMap<String, Client>();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private boolean debugging = false;
private String basePath = "{{basePath}}";
private boolean debugging = false;
private int connectionTimeout = 0;
private Client httpClient;
private ObjectMapper mapper;
private Map<String, Authentication> authentications;
@@ -64,7 +66,9 @@ public class ApiClient {
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
mapper.registerModule(new JodaModule());
httpClient = buildHttpClient(debugging);
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
@@ -224,9 +228,29 @@ public class ApiClient {
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
// Rebuild HTTP Client according to the new "debugging" value.
this.httpClient = buildHttpClient(debugging);
return this;
}
/**
* Connect timeout (in milliseconds).
*/
public int getConnectTimeout() {
return connectionTimeout;
}
/**
* Set the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
*/
public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
httpClient.setConnectTimeout(connectionTimeout);
return this;
}
/**
* Get the date format used to parse/format date parameters.
*/
@@ -436,8 +460,6 @@ public class ApiClient {
updateParamsForAuth(authNames, queryParams, headerParams);
Client client = getClient();
StringBuilder b = new StringBuilder();
b.append("?");
if (queryParams != null){
@@ -455,9 +477,9 @@ public class ApiClient {
Builder builder;
if (accept == null)
builder = client.resource(basePath + path + querystring).getRequestBuilder();
builder = httpClient.resource(basePath + path + querystring).getRequestBuilder();
else
builder = client.resource(basePath + path + querystring).accept(accept);
builder = httpClient.resource(basePath + path + querystring).accept(accept);
for (String key : headerParams.keySet()) {
builder = builder.header(key, headerParams.get(key));
@@ -571,19 +593,17 @@ public class ApiClient {
}
/**
* Get an existing client or create a new client to handle HTTP request.
* Build the Client used to make HTTP requests.
*/
private Client getClient() {
if(!hostMap.containsKey(basePath)) {
// Add the JSON serialization support to Jersey
JacksonJsonProvider jsonProvider = new JacksonJsonProvider(mapper);
DefaultClientConfig conf = new DefaultClientConfig();
conf.getSingletons().add(jsonProvider);
Client client = Client.create(conf);
if (debugging)
client.addFilter(new LoggingFilter());
hostMap.put(basePath, client);
private Client buildHttpClient(boolean debugging) {
// Add the JSON serialization support to Jersey
JacksonJsonProvider jsonProvider = new JacksonJsonProvider(mapper);
DefaultClientConfig conf = new DefaultClientConfig();
conf.getSingletons().add(jsonProvider);
Client client = Client.create(conf);
if (debugging) {
client.addFilter(new LoggingFilter());
}
return hostMap.get(basePath);
return client;
}
}

View File

@@ -1,12 +1,22 @@
package {{invokerPackage}};
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import feign.Feign;
import feign.RequestInterceptor;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import feign.slf4j.Slf4jLogger;
import {{invokerPackage}}.auth.*;
import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
{{>generatedAnnotation}}
public class ApiClient {
@@ -14,11 +24,80 @@ public class ApiClient {
private ObjectMapper objectMapper;
private String basePath = "{{basePath}}";
private Map<String, RequestInterceptor> apiAuthorizations;
private Feign.Builder feignBuilder;
public ApiClient() {
objectMapper = createObjectMapper();
apiAuthorizations = new LinkedHashMap<String, RequestInterceptor>();
feignBuilder = Feign.builder()
.encoder(new FormAwareEncoder(new JacksonEncoder(objectMapper)))
.decoder(new JacksonDecoder(objectMapper))
.logger(new Slf4jLogger());
}
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) { {{#hasAuthMethods}}
RequestInterceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
}
}
/**
* Basic constructor for single auth name
* @param authName
*/
public ApiClient(String authName) {
this(new String[]{authName});
}
/**
* Helper constructor for single api key
* @param authName
* @param apiKey
*/
public ApiClient(String authName, String apiKey) {
this(authName);
this.setApiKey(apiKey);
}
/**
* Helper constructor for single basic auth or password oauth2
* @param authName
* @param username
* @param password
*/
public ApiClient(String authName, String username, String password) {
this(authName);
this.setCredentials(username, password);
}
/**
* Helper constructor for single password oauth2
* @param authName
* @param clientId
* @param secret
* @param username
* @param password
*/
public ApiClient(String authName, String clientId, String secret, String username, String password) {
this(authName);
this.getTokenEndPoint()
.setClientId(clientId)
.setClientSecret(secret)
.setUsername(username)
.setPassword(password);
}
public String getBasePath() {
return basePath;
}
@@ -28,6 +107,23 @@ public class ApiClient {
return this;
}
public Map<String, RequestInterceptor> getApiAuthorizations() {
return apiAuthorizations;
}
public void setApiAuthorizations(Map<String, RequestInterceptor> apiAuthorizations) {
this.apiAuthorizations = apiAuthorizations;
}
public Feign.Builder getFeignBuilder() {
return feignBuilder;
}
public ApiClient setFeignBuilder(Feign.Builder feignBuilder) {
this.feignBuilder = feignBuilder;
return this;
}
private ObjectMapper createObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
@@ -45,13 +141,7 @@ public class ApiClient {
* XYZResponse response = api.someMethod(...);
*/
public <T extends Api> T buildClient(Class<T> clientClass) {
return Feign.builder()
.encoder(new FormAwareEncoder(new JacksonEncoder(objectMapper)))
.decoder(new JacksonDecoder(objectMapper))
// enable for basic auth:
// .requestInterceptor(new feign.auth.BasicAuthRequestInterceptor(username, password))
.logger(new Slf4jLogger())
.target(clientClass, basePath);
return feignBuilder.target(clientClass, basePath);
}
/**
@@ -83,4 +173,137 @@ public class ApiClient {
if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
return contentTypes[0];
}
/**
* Helper method to configure the first api key found
* @param apiKey
*/
public void setApiKey(String apiKey) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof ApiKeyAuth) {
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
keyAuth.setApiKey(apiKey);
return ;
}
}
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to configure the username/password for basic auth or password OAuth
* @param username
* @param password
*/
public void setCredentials(String username, String password) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof HttpBasicAuth) {
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
basicAuth.setCredentials(username, password);
return;
}
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
return;
}
}
throw new RuntimeException("No Basic authentication or OAuth configured!");
}
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
*/
public TokenRequestBuilder getTokenEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getTokenRequestBuilder();
}
}
return null;
}
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
*/
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getAuthenticationRequestBuilder();
}
}
return null;
}
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken
* @param expiresIn : validity period in seconds
*/
public void setAccessToken(String accessToken, Long expiresIn) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.setAccessToken(accessToken, expiresIn);
return;
}
}
}
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId
* @param clientSecret
* @param redirectURI
*/
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.setRedirectURI(redirectURI);
oauth.getAuthenticationRequestBuilder()
.setClientId(clientId)
.setRedirectURI(redirectURI);
return;
}
}
}
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener
*/
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.registerAccessTokenListener(accessTokenListener);
return;
}
}
}
public RequestInterceptor getAuthorization(String authName) {
return apiAuthorizations.get(authName);
}
/**
* Adds an authorization to be used by the client
* @param authName
* @param authorization
*/
public void addAuthorization(String authName, RequestInterceptor authorization) {
if (apiAuthorizations.containsKey(authName)) {
throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
}
apiAuthorizations.put(authName, authorization);
feignBuilder.requestInterceptor(authorization);
}
}

View File

@@ -19,7 +19,7 @@ public interface {{classname}} extends ApiClient.Api {
{{#allParams}} * @param {{paramName}} {{description}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
@RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{paramName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
@RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
@Headers({
"Content-type: {{vendorExtensions.x-contentType}}",
"Accepts: {{vendorExtensions.x-accepts}}",{{#headerParams}}

View File

@@ -0,0 +1,41 @@
package {{invokerPackage}}.auth;
import feign.RequestInterceptor;
import feign.RequestTemplate;
public class ApiKeyAuth implements RequestInterceptor {
private final String location;
private final String paramName;
private String apiKey;
public ApiKeyAuth(String location, String paramName) {
this.location = location;
this.paramName = paramName;
}
public String getLocation() {
return location;
}
public String getParamName() {
return paramName;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
@Override
public void apply(RequestTemplate template) {
if (location == "query") {
template.query(paramName, apiKey);
} else if (location == "header") {
template.header(paramName, apiKey);
}
}
}

View File

@@ -0,0 +1,41 @@
package {{invokerPackage}}.auth;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.auth.BasicAuthRequestInterceptor;
/**
* An interceptor that adds the request header needed to use HTTP basic authentication.
*/
public class HttpBasicAuth implements RequestInterceptor {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setCredentials(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public void apply(RequestTemplate template) {
RequestInterceptor requestInterceptor = new BasicAuthRequestInterceptor(username, password);
requestInterceptor.apply(template);
}
}

View File

@@ -0,0 +1,203 @@
package {{invokerPackage}}.auth;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.oltu.oauth2.client.HttpClient;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
import org.apache.oltu.oauth2.client.response.OAuthClientResponse;
import org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.oltu.oauth2.common.token.BasicOAuthToken;
import feign.Client;
import feign.Request.Options;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.Util;
import {{invokerPackage}}.StringUtil;
public class OAuth implements RequestInterceptor {
public interface AccessTokenListener {
public void notify(BasicOAuthToken token);
}
private volatile String accessToken;
private Long expirationTimeMillis;
private OAuthClient oauthClient;
private TokenRequestBuilder tokenRequestBuilder;
private AuthenticationRequestBuilder authenticationRequestBuilder;
private AccessTokenListener accessTokenListener;
public OAuth(Client client, TokenRequestBuilder requestBuilder) {
setOauthClient(client);
this.tokenRequestBuilder = requestBuilder;
}
public OAuth(Client client, OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(client, OAuthClientRequest.tokenLocation(tokenUrl).setScope(scopes));
setFlow(flow);
authenticationRequestBuilder = OAuthClientRequest.authorizationLocation(authorizationUrl);
}
public OAuth(OAuthFlow flow, String authorizationUrl, String tokenUrl, String scopes) {
this(new Client.Default(null, null), flow, authorizationUrl, tokenUrl, scopes);
}
public void setFlow(OAuthFlow flow) {
switch(flow) {
case accessCode:
case implicit:
tokenRequestBuilder.setGrantType(GrantType.AUTHORIZATION_CODE);
break;
case password:
tokenRequestBuilder.setGrantType(GrantType.PASSWORD);
break;
case application:
tokenRequestBuilder.setGrantType(GrantType.CLIENT_CREDENTIALS);
break;
default:
break;
}
}
@Override
public void apply(RequestTemplate template) {
// If the request already have an authorization (eg. Basic auth), do nothing
if (template.headers().containsKey("Authorization")) {
return;
}
// If first time, get the token
if (expirationTimeMillis == null || System.currentTimeMillis() >= expirationTimeMillis) {
try {
updateAccessToken();
} catch (OAuthSystemException e) {
e.printStackTrace();
return;
} catch (OAuthProblemException e) {
e.printStackTrace();
return;
}
}
if (getAccessToken() != null) {
template.header("Authorization", "Bearer " + getAccessToken());
}
}
public synchronized void updateAccessToken() throws OAuthSystemException, OAuthProblemException {
if (getAccessToken() == null) {
OAuthJSONAccessTokenResponse accessTokenResponse = oauthClient.accessToken(tokenRequestBuilder.buildBodyMessage());
if (accessTokenResponse != null && accessTokenResponse.getAccessToken() != null) {
setAccessToken(accessTokenResponse.getAccessToken(), accessTokenResponse.getExpiresIn());
if (accessTokenListener != null) {
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
}
}
}
}
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
this.accessTokenListener = accessTokenListener;
}
public synchronized String getAccessToken() {
return accessToken;
}
public synchronized void setAccessToken(String accessToken, Long expiresIn) {
this.accessToken = accessToken;
this.expirationTimeMillis = System.currentTimeMillis() + expiresIn * 1000;
}
public TokenRequestBuilder getTokenRequestBuilder() {
return tokenRequestBuilder;
}
public void setTokenRequestBuilder(TokenRequestBuilder tokenRequestBuilder) {
this.tokenRequestBuilder = tokenRequestBuilder;
}
public AuthenticationRequestBuilder getAuthenticationRequestBuilder() {
return authenticationRequestBuilder;
}
public void setAuthenticationRequestBuilder(AuthenticationRequestBuilder authenticationRequestBuilder) {
this.authenticationRequestBuilder = authenticationRequestBuilder;
}
public OAuthClient getOauthClient() {
return oauthClient;
}
public void setOauthClient(OAuthClient oauthClient) {
this.oauthClient = oauthClient;
}
public void setOauthClient(Client client) {
this.oauthClient = new OAuthClient( new OAuthFeignClient(client));
}
public class OAuthFeignClient implements HttpClient {
private Client client;
public OAuthFeignClient() {
this.client = new Client.Default(null, null);
}
public OAuthFeignClient(Client client) {
this.client = client;
}
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
String requestMethod, Class<T> responseClass)
throws OAuthSystemException, OAuthProblemException {
RequestTemplate req = new RequestTemplate()
.append(request.getLocationUri())
.method(requestMethod)
.body(request.getBody());
for (Entry<String, String> entry : headers.entrySet()) {
req.header(entry.getKey(), entry.getValue());
}
Response feignResponse;
String body = "";
try {
feignResponse = client.execute(req.request(), new Options());
body = Util.toString(feignResponse.body().asReader());
} catch (IOException e) {
throw new OAuthSystemException(e);
}
String contentType = null;
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
if(contentTypeHeader != null) {
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
}
return OAuthClientResponseFactory.createCustomResponse(
body,
contentType,
feignResponse.status(),
responseClass
);
}
public void shutdown() {
// Nothing to do here
}
}
}

View File

@@ -164,6 +164,12 @@
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.oltu.oauth2</groupId>
<artifactId>org.apache.oltu.oauth2.client</artifactId>
<version>${oltu-version}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
@@ -179,5 +185,6 @@
<jodatime-version>2.5</jodatime-version>
<junit-version>4.12</junit-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<oltu-version>1.0.0</oltu-version>
</properties>
</project>

View File

@@ -12,7 +12,9 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.MultiPart;
@@ -43,12 +45,13 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Client client;
private Map<String, Client> hostMap = new HashMap<String, Client>();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private boolean debugging = false;
private String basePath = "{{basePath}}";
private JSON json = new JSON();
private boolean debugging = false;
private int connectionTimeout = 0;
private Client httpClient;
private JSON json;
private Map<String, Authentication> authentications;
@@ -58,6 +61,9 @@ public class ApiClient {
private DateFormat dateFormat;
public ApiClient() {
json = new JSON();
httpClient = buildHttpClient(debugging);
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
@@ -70,8 +76,6 @@ public class ApiClient {
// Set default User-Agent.
setUserAgent("Java-Swagger");
buildClient();
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}
authentications.put("{{name}}", new HttpBasicAuth());{{/isBasic}}{{#isApiKey}}
@@ -226,10 +230,29 @@ public class ApiClient {
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
buildClient();
// Rebuild HTTP Client according to the new "debugging" value.
this.httpClient = buildHttpClient(debugging);
return this;
}
/**
* Connect timeout (in milliseconds).
*/
public int getConnectTimeout() {
return connectionTimeout;
}
/**
* Set the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
*/
public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
httpClient.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout);
return this;
}
/**
* Get the date format used to parse/format date parameters.
*/
@@ -472,7 +495,7 @@ public class ApiClient {
public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
WebTarget target = client.target(this.basePath).path(path);
WebTarget target = httpClient.target(this.basePath).path(path);
if (queryParams != null) {
for (Pair queryParam : queryParams) {
@@ -545,15 +568,18 @@ public class ApiClient {
}
}
private void buildClient() {
/**
* Build the Client used to make HTTP requests.
*/
private Client buildHttpClient(boolean debugging) {
final ClientConfig clientConfig = new ClientConfig();
clientConfig.register(MultiPartFeature.class);
clientConfig.register(json);
clientConfig.register(org.glassfish.jersey.jackson.JacksonFeature.class);
clientConfig.register(JacksonFeature.class);
if (debugging) {
clientConfig.register(LoggingFilter.class);
}
this.client = ClientBuilder.newClient(clientConfig);
return ClientBuilder.newClient(clientConfig);
}
private Map<String, List<String>> buildResponseHeaders(Response response) {

View File

@@ -11,6 +11,8 @@ import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.internal.http.HttpMethod;
import com.squareup.okhttp.logging.HttpLoggingInterceptor;
import com.squareup.okhttp.logging.HttpLoggingInterceptor.Level;
import java.lang.reflect.Type;
@@ -116,6 +118,8 @@ public class ApiClient {
private OkHttpClient httpClient;
private JSON json;
private HttpLoggingInterceptor loggingInterceptor;
public ApiClient() {
httpClient = new OkHttpClient();
@@ -452,6 +456,16 @@ public class ApiClient {
* @param debugging To enable (true) or disable (false) debugging
*/
public ApiClient setDebugging(boolean debugging) {
if (debugging != this.debugging) {
if (debugging) {
loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(Level.BODY);
httpClient.interceptors().add(loggingInterceptor);
} else {
httpClient.interceptors().remove(loggingInterceptor);
loggingInterceptor = null;
}
}
this.debugging = debugging;
return this;
}

View File

@@ -117,6 +117,11 @@
<artifactId>okhttp</artifactId>
<version>${okhttp-version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp-version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
@@ -133,7 +138,7 @@
</dependencies>
<properties>
<swagger-annotations-version>1.5.0</swagger-annotations-version>
<okhttp-version>2.4.0</okhttp-version>
<okhttp-version>2.7.2</okhttp-version>
<gson-version>2.3.1</gson-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.8.1</junit-version>

View File

@@ -27,22 +27,23 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
{{/vars}}
@Override
public boolean equals(Object o) {
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
{{classname}} {{classVarName}} = ({{classname}}) o;{{#hasVars}}
return {{#vars}}Objects.equals({{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{^hasMore}};{{/hasMore}}{{/vars}}{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}}
{{classname}} {{classVarName}} = ({{classname}}) o;
return true {{#hasVars}}&& {{#vars}}Objects.equals({{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{/vars}}{{/hasVars}}
{{#parent}}&& super.equals(o){{/parent}};
}
@Override
public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}});
return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}},{{/hasVars}} super.hashCode(){{/parent}});
}
@Override
@@ -59,7 +60,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}

View File

@@ -1,6 +1,5 @@
package {{package}};
import {{invokerPackage}}.Responses;
import {{invokerPackage}}.ApiInvoker;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.Pair;
@@ -50,7 +49,7 @@ public class {{classname}} {
{{#allParams}} * @param {{paramName}} {{description}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
public void {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}, {{/hasMore}}{{/allParams}}final {{#returnBaseType}}Responses.{{returnBaseType}}{{#isListContainer}}List{{/isListContainer}}Response{{/returnBaseType}}{{^returnBaseType}}Responses.StringResponse{{/returnBaseType}} responseListener, final Response.ErrorListener errorListener) {
public void {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}, {{/hasMore}}{{/allParams}}final Response.Listener<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}String{{/returnType}}> responseListener, final Response.ErrorListener errorListener) {
Object postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}

View File

@@ -28,11 +28,11 @@ apply plugin: 'com.github.dcendents.android-maven'
{{/useAndroidMavenGradlePlugin}}
android {
compileSdkVersion 22
buildToolsVersion '22.0.0'
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
targetSdkVersion 23
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7

View File

@@ -1,24 +0,0 @@
package {{invokerPackage}};
import java.util.List;
import {{modelPackage}}.*;
public class Responses {
{{#models}}
{{#model}}
public static interface {{classname}}Response {
public void onResponse({{classname}} {{classVarName}});
}
public static interface {{classname}}ListResponse {
public void onResponse(List<{{classname}}> {{classVarName}}List);
}
{{/model}}
{{/models}}
public static interface StringResponse {
public void onResponse(String response);
}
public static interface StringListResponse {
public void onResponse(List<String> stringList);
}
}

View File

@@ -77,9 +77,10 @@ namespace {{packageName}}.Client
// Creates and sets up a RestRequest prior to a call.
private RestRequest PrepareRequest(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = new RestRequest(path, method);
@@ -103,8 +104,17 @@ namespace {{packageName}}.Client
foreach(var param in fileParams)
request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);
if (postBody != null) // http body (model) parameter
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
if (postBody != null) // http body (model or byte[]) parameter
{
if (postBody.GetType() == typeof(String))
{
request.AddParameter("application/json", postBody, ParameterType.RequestBody);
}
else if (postBody.GetType() == typeof(byte[]))
{
request.AddParameter(contentType, postBody, ParameterType.RequestBody);
}
}
return request;
}
@@ -120,14 +130,18 @@ namespace {{packageName}}.Client
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="pathParams">Path parameters.</param>
/// <param name="contentType">Content Type of the request</param>
/// <returns>Object</returns>
public Object CallApi(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = PrepareRequest(
path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType);
var response = RestClient.Execute(request);
return (Object) response;
}
@@ -143,14 +157,17 @@ namespace {{packageName}}.Client
/// <param name="formParams">Form parameters.</param>
/// <param name="fileParams">File parameters.</param>
/// <param name="pathParams">Path parameters.</param>
/// <param name="contentType">Content type.</param>
/// <returns>The Task instance.</returns>
public async System.Threading.Tasks.Task<Object> CallApiAsync(
String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
String path, RestSharp.Method method, Dictionary<String, String> queryParams, Object postBody,
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams)
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
String contentType)
{
var request = PrepareRequest(
path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType);
var response = await RestClient.ExecuteTaskAsync(request);
return (Object)response;
}
@@ -194,6 +211,12 @@ namespace {{packageName}}.Client
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
// For example: 2009-06-15T13:45:30.0000000
return ((DateTime)obj).ToString (Configuration.DateTimeFormat);
else if (obj is DateTimeOffset)
// Return a formatted date string - Can be customized with Configuration.DateTimeFormat
// Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o")
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8
// For example: 2009-06-15T13:45:30.0000000
return ((DateTimeOffset)obj).ToString (Configuration.DateTimeFormat);
else if (obj is IList)
{
var flattenedString = new StringBuilder();
@@ -224,6 +247,10 @@ namespace {{packageName}}.Client
{
return content;
}
else if (type == typeof(byte[])) // return byte array
{
return data;
}
if (type == typeof(Stream))
{
@@ -270,11 +297,11 @@ namespace {{packageName}}.Client
}
/// <summary>
/// Serialize an object into JSON string.
/// Serialize an input (model) into JSON string
/// </summary>
/// <param name="obj">Object.</param>
/// <returns>JSON string.</returns>
public string Serialize(object obj)
public String Serialize(object obj)
{
try
{
@@ -286,6 +313,24 @@ namespace {{packageName}}.Client
}
}
/// <summary>
/// Select the Content-Type header's value from the given content-type array:
/// if JSON exists in the given array, use it;
/// otherwise use the first one defined in 'consumes'
/// </summary>
/// <param name="contentTypes">The Content-Type array to select from.</param>
/// <returns>The Content-Type header to use.</returns>
public String SelectHeaderContentType(String[] contentTypes)
{
if (contentTypes.Length == 0)
return null;
if (contentTypes.Contains("application/json", StringComparer.OrdinalIgnoreCase))
return "application/json";
return contentTypes[0]; // use the first content type specified in 'consumes'
}
/// <summary>
/// Select the Accept header's value from the given accepts array:
/// if JSON exists in the given array, use it;

View File

@@ -27,10 +27,10 @@ namespace {{packageName}}.Client
public T Data { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApiResponse"/> class.
/// Initializes a new instance of the <see cref="ApiResponse&lt;T&gt;" /> class.
/// </summary>
/// <param name="statusCode">HTTP status code.</param>
/// <param name="message">Error message.</param>
/// <param name="headers">HTTP headers.</param>
/// <param name="data">Data (parsed HTTP body)</param>
public ApiResponse(int statusCode, IDictionary<string, string> headers, T data)
{

View File

@@ -24,6 +24,7 @@ namespace {{packageName}}.Client
/// <param name="apiKeyPrefix">Dictionary of API key prefix</param>
/// <param name="tempFolderPath">Temp folder path</param>
/// <param name="dateTimeFormat">DateTime format string</param>
/// <param name="timeout">HTTP connection timeout (in milliseconds)</param>
public Configuration(ApiClient apiClient = null,
Dictionary<String, String> defaultHeader = null,
string username = null,

View File

@@ -154,7 +154,8 @@ namespace {{packageName}}.Api
{
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{operationId}}");
if ({{paramName}} == null)
throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}");
{{/required}}{{/allParams}}
var path_ = "{{path}}";
@@ -164,15 +165,21 @@ namespace {{packageName}}.Api
var headerParams = new Dictionary<String, String>(Configuration.DefaultHeader);
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
Object postBody = null;
// to determine the Content-Type header
String[] httpContentTypes = new String[] {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
String httpContentType = Configuration.ApiClient.SelectHeaderContentType(httpContentTypes);
// to determine the Accept header
String[] http_header_accepts = new String[] {
String[] httpHeaderAccepts = new String[] {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
String http_header_accept = Configuration.ApiClient.SelectHeaderAccept(http_header_accepts);
if (http_header_accept != null)
headerParams.Add("Accept", Configuration.ApiClient.SelectHeaderAccept(http_header_accepts));
String httpHeaderAccept = Configuration.ApiClient.SelectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAccept != null)
headerParams.Add("Accept", httpHeaderAccept);
// set "format" to json by default
// e.g. /pet/{petId}.{format} becomes /pet/{petId}.json
@@ -185,11 +192,16 @@ namespace {{packageName}}.Api
{{/headerParams}}
{{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", Configuration.ApiClient.ParameterToFile("{{baseName}}", {{paramName}}));{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", Configuration.ApiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}}
{{/formParams}}
{{#bodyParam}}postBody = Configuration.ApiClient.Serialize({{paramName}}); // http body (model) parameter
{{/bodyParam}}
{{#bodyParam}}if ({{paramName}}.GetType() != typeof(byte[]))
{
postBody = Configuration.ApiClient.Serialize({{paramName}}); // http body (model) parameter
}
else
{
postBody = {{paramName}}; // byte array
}{{/bodyParam}}
{{#authMethods}}
// authentication ({{name}}) required
{{#authMethods}}// authentication ({{name}}) required
{{#isApiKey}}{{#isKeyInHeader}}
var apiKeyValue = Configuration.GetApiKeyWithPrefix("{{keyParamName}}");
if (!String.IsNullOrEmpty(apiKeyValue))
@@ -214,7 +226,9 @@ namespace {{packageName}}.Api
{{/authMethods}}
// make the HTTP request
IRestResponse response = (IRestResponse) Configuration.ApiClient.CallApi(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
IRestResponse response = (IRestResponse) Configuration.ApiClient.CallApi(path_,
Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, httpContentType);
int statusCode = (int) response.StatusCode;
@@ -261,15 +275,21 @@ namespace {{packageName}}.Api
var headerParams = new Dictionary<String, String>();
var formParams = new Dictionary<String, String>();
var fileParams = new Dictionary<String, FileParameter>();
String postBody = null;
Object postBody = null;
// to determine the Content-Type header
String[] httpContentTypes = new String[] {
{{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}
};
String httpContentType = Configuration.ApiClient.SelectHeaderContentType(httpContentTypes);
// to determine the Accept header
String[] http_header_accepts = new String[] {
String[] httpHeaderAccepts = new String[] {
{{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}}
};
String http_header_accept = Configuration.ApiClient.SelectHeaderAccept(http_header_accepts);
if (http_header_accept != null)
headerParams.Add("Accept", Configuration.ApiClient.SelectHeaderAccept(http_header_accepts));
String httpHeaderAccept = Configuration.ApiClient.SelectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAccept != null)
headerParams.Add("Accept", httpHeaderAccept);
// set "format" to json by default
// e.g. /pet/{petId}.{format} becomes /pet/{petId}.json
@@ -311,7 +331,9 @@ namespace {{packageName}}.Api
{{/authMethods}}
// make the HTTP request
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, pathParams);
IRestResponse response = (IRestResponse) await Configuration.ApiClient.CallApiAsync(path_,
Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, httpContentType);
int statusCode = (int) response.StatusCode;

View File

@@ -0,0 +1,12 @@
wget -nc https://nuget.org/nuget.exe;
mozroots --import --sync
mono nuget.exe install vendor/packages.config -o vendor;
mkdir -p bin;
mcs -sdk:45 -r:vendor/Newtonsoft.Json.8.0.2/lib/net45/Newtonsoft.Json.dll,\
vendor/RestSharp.105.2.3/lib/net45/RestSharp.dll,\
System.Runtime.Serialization.dll \
-target:library \
-out:bin/{{packageName}}.dll \
-recurse:'src/*.cs' \
-doc:bin/{{packageName}}.xml \
-platform:anycpu

View File

@@ -74,7 +74,7 @@ namespace {{packageName}}.Model
/// <summary>
/// Returns true if {{classname}} instances are equal
/// </summary>
/// <param name="obj">Instance of {{classname}} to be compared</param>
/// <param name="other">Instance of {{classname}} to be compared</param>
/// <returns>Boolean</returns>
public bool Equals({{classname}} other)
{

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="105.2.3" targetFramework="net45" developmentDependency="true" />
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" developmentDependency="true" />
</packages>

View File

@@ -1,4 +1,4 @@
package WWW::{{moduleName}}::ApiClient;
package {{moduleName}}::ApiClient;
use strict;
use warnings;
@@ -18,7 +18,7 @@ use Log::Any qw($log);
use Carp;
use Module::Runtime qw(use_module);
use WWW::{{moduleName}}::Configuration;
use {{moduleName}}::Configuration;
use base 'Class::Singleton';
@@ -34,7 +34,7 @@ sub _new_instance
return bless \%args, $class;
}
sub _cfg {'WWW::{{moduleName}}::Configuration'}
sub _cfg {'{{moduleName}}::Configuration'}
# Set the user agent of the API client
#
@@ -119,8 +119,8 @@ sub call_api {
else {
}
$self->{ua}->timeout($self->{http_timeout} || $WWW::{{moduleName}}::Configuration::http_timeout);
$self->{ua}->agent($self->{http_user_agent} || $WWW::{{moduleName}}::Configuration::http_user_agent);
$self->{ua}->timeout($self->{http_timeout} || ${{moduleName}}::Configuration::http_timeout);
$self->{ua}->agent($self->{http_user_agent} || ${{moduleName}}::Configuration::http_user_agent);
$log->debugf("REQUEST: %s", $_request->as_string);
my $_response = $self->{ua}->request($_request);
@@ -243,7 +243,7 @@ sub deserialize
} elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) {
return $data;
} else { # model
my $_instance = use_module("WWW::{{moduleName}}::Object::$class")->new;
my $_instance = use_module("{{moduleName}}::Object::$class")->new;
if (ref $data eq "HASH") {
return $_instance->from_hash($data);
} else { # string, need to json decode first
@@ -294,11 +294,11 @@ sub get_api_key_with_prefix
{
my ($self, $key_name) = @_;
my $api_key = $WWW::{{moduleName}}::Configuration::api_key->{$key_name};
my $api_key = ${{moduleName}}::Configuration::api_key->{$key_name};
return unless $api_key;
my $prefix = $WWW::{{moduleName}}::Configuration::api_key_prefix->{$key_name};
my $prefix = ${{moduleName}}::Configuration::api_key_prefix->{$key_name};
return $prefix ? "$prefix $api_key" : $api_key;
}
@@ -329,11 +329,11 @@ sub update_params_for_auth {
if ($api_key) {
$query_params->{'{{keyParamName}}'} = $api_key;
}{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}
if ($WWW::{{moduleName}}::Configuration::username || $WWW::{{moduleName}}::Configuration::password) {
$header_params->{'Authorization'} = 'Basic ' . encode_base64($WWW::{{moduleName}}::Configuration::username . ":" . $WWW::{{moduleName}}::Configuration::password);
if (${{moduleName}}::Configuration::username || ${{moduleName}}::Configuration::password) {
$header_params->{'Authorization'} = 'Basic ' . encode_base64(${{moduleName}}::Configuration::username . ":" . ${{moduleName}}::Configuration::password);
}{{/isBasic}}{{#isOAuth}}
if ($WWW::{{moduleName}}::Configuration::access_token) {
$header_params->{'Authorization'} = 'Bearer ' . $WWW::{{moduleName}}::Configuration::access_token;
if (${{moduleName}}::Configuration::access_token) {
$header_params->{'Authorization'} = 'Bearer ' . ${{moduleName}}::Configuration::access_token;
}{{/isOAuth}}
}
{{/authMethods}}

View File

@@ -1,4 +1,4 @@
package WWW::{{moduleName}}::ApiFactory;
package {{moduleName}}::ApiFactory;
use strict;
use warnings;
@@ -7,26 +7,26 @@ use utf8;
use Carp;
use Module::Find;
usesub WWW::{{moduleName}}::Object;
usesub {{moduleName}}::Object;
use WWW::{{moduleName}}::ApiClient;
use {{moduleName}}::ApiClient;
=head1 Name
WWW::{{moduleName}}::ApiFactory - constructs APIs to retrieve {{moduleName}} objects
{{moduleName}}::ApiFactory - constructs APIs to retrieve {{moduleName}} objects
=head1 Synopsis
package My::Petstore::App;
use WWW::{{moduleName}}::ApiFactory;
use {{moduleName}}::ApiFactory;
my $api_factory = WWW::{{moduleName}}::ApiFactory->new( ... ); # any args for ApiClient constructor
my $api_factory = {{moduleName}}::ApiFactory->new( ... ); # any args for ApiClient constructor
# later...
my $pet_api = $api_factory->get_api('Pet');
# $pet_api isa WWW::{{moduleName}}::PetApi
# $pet_api isa {{moduleName}}::PetApi
my $pet = $pet_api->get_pet_by_id(pet_id => $pet_id);
@@ -39,9 +39,9 @@ use WWW::{{moduleName}}::ApiClient;
=cut
# Load all the API classes and construct a lookup table at startup time
my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ }
my %_apis = map { $_ =~ /^{{moduleName}}::(.*)$/; $1 => $_ }
grep {$_ =~ /Api$/}
usesub 'WWW::{{moduleName}}';
usesub '{{moduleName}}';
=head1 new()
@@ -54,7 +54,7 @@ my %_apis = map { $_ =~ /^WWW::{{moduleName}}::(.*)$/; $1 => $_ }
sub new {
my ($class, %p) = (shift, @_);
$p{api_client} = WWW::{{moduleName}}::ApiClient->instance(%p);
$p{api_client} = {{moduleName}}::ApiClient->instance(%p);
return bless \%p, $class;
}
@@ -64,7 +64,7 @@ sub new {
$which is a nickname for the class:
WWW::FooBarClient::BazApi has nickname 'Baz'
FooBarClient::BazApi has nickname 'Baz'
=cut

View File

@@ -1,4 +1,4 @@
package WWW::{{moduleName}}::Role::AutoDoc;
package {{moduleName}}::Role::AutoDoc;
use List::MoreUtils qw(uniq);
use Moose::Role;
@@ -40,7 +40,7 @@ sub _printisa {
foreach my $role (@roles) {
$rolepkg = $role->{package} || next; # some are anonymous, or something
next if $rolepkg eq 'WWW::{{moduleName}}::Role::AutoDoc';
next if $rolepkg eq '{{moduleName}}::Role::AutoDoc';
$role_reqs = join ', ', keys %{$role->{required_methods}};
$role_reqs ||= '';
$~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES';
@@ -424,4 +424,4 @@ $attrname
1;
1;

View File

@@ -68,7 +68,7 @@ sub _deserialize {
} elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) {
return $data;
} else { # hash(model)
my $_instance = eval "WWW::{{moduleName}}::Object::$type->new()";
my $_instance = eval "{{moduleName}}::Object::$type->new()";
return $_instance->from_hash($data);
}
}

View File

@@ -1,4 +1,4 @@
package WWW::{{moduleName}}::Configuration;
package {{moduleName}}::Configuration;
use strict;
use warnings;

View File

@@ -1,6 +1,6 @@
# NAME
WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
{{moduleName}}::Role - a Moose role for the {{appName}}
## {{appName}} version: {{appVersion}}
@@ -15,7 +15,7 @@ Automatically generated by the Perl Swagger Codegen project:
## A note on Moose
This role is the only component of the library that uses Moose. See
WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
{{moduleName}}::ApiFactory for non-Moosey usage.
# SYNOPSIS
@@ -29,7 +29,7 @@ role.
package MyApp;
use Moose;
with 'WWW::{{moduleName}}::Role';
with '{{moduleName}}::Role';
package main;
@@ -88,37 +88,37 @@ you are accessing. Usually `prefix` and `in` will be determined by the code gene
the spec and you will not need to set them at run time. If not, `in` will
default to 'head' and `prefix` to the empty string.
The tokens will be placed in the `WWW::{{moduleName}}::Configuration` namespace
The tokens will be placed in the `{{moduleName}}::Configuration` namespace
as follows, but you don't need to know about this.
- `$WWW::{{moduleName}}::Configuration::username`
- `${{moduleName}}::Configuration::username`
String. The username for basic auth.
- `$WWW::{{moduleName}}::Configuration::password`
- `${{moduleName}}::Configuration::password`
String. The password for basic auth.
- `$WWW::{{moduleName}}::Configuration::api_key`
- `${{moduleName}}::Configuration::api_key`
Hashref. Keyed on the name of each key (there can be multiple tokens).
$WWW::{{moduleName}}::Configuration::api_key = {
${{moduleName}}::Configuration::api_key = {
secretKey => 'aaaabbbbccccdddd',
anotherKey => '1111222233334444',
};
- `$WWW::{{moduleName}}::Configuration::api_key_prefix`
- `${{moduleName}}::Configuration::api_key_prefix`
Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
all api keys require a prefix.
$WWW::{{moduleName}}::Configuration::api_key_prefix = {
${{moduleName}}::Configuration::api_key_prefix = {
secretKey => 'string',
anotherKey => 'same or some other string',
};
- `$WWW::{{moduleName}}::Configuration::access_token`
- `${{moduleName}}::Configuration::access_token`
String. The OAuth access token.
@@ -134,7 +134,7 @@ created yet) the current value of `base_url`.
Returns an API factory object. You probably won't need to call this directly.
$self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
$self->api_factory('Pet'); # returns a {{moduleName}}::PetApi instance
$self->pet_api; # the same
@@ -162,12 +162,12 @@ you could also call them on class names.
See the homepage `https://github.com/swagger-api/swagger-codegen` for full details.
But briefly, clone the git repository, build the codegen codebase, set up your build
config file, then run the API build script. You will need git, Java 7 and Apache
config file, then run the API build script. You will need git, Java 7 or 8 and Apache
maven 3.0.3 or better already installed.
The config file should specify the project name for the generated library:
{"moduleName":"MyProjectName"}
{"moduleName":"WWW::MyProjectName"}
Your library files will be built under `WWW::MyProjectName`.

View File

@@ -1,11 +1,11 @@
package WWW::{{moduleName}}::Role;
package {{moduleName}}::Role;
use utf8;
use Moose::Role;
use namespace::autoclean;
use Class::Inspector;
use Log::Any qw($log);
use WWW::{{moduleName}}::ApiFactory;
use {{moduleName}}::ApiFactory;
has base_url => ( is => 'ro',
required => 0,
@@ -14,7 +14,7 @@ has base_url => ( is => 'ro',
);
has api_factory => ( is => 'ro',
isa => 'WWW::{{moduleName}}::ApiFactory',
isa => '{{moduleName}}::ApiFactory',
builder => '_build_af',
lazy => 1,
documentation => 'Builds an instance of the endpoint API class',
@@ -29,7 +29,7 @@ has tokens => ( is => 'ro',
has _cfg => ( is => 'ro',
isa => 'Str',
default => 'WWW::{{moduleName}}::Configuration',
default => '{{moduleName}}::Configuration',
);
has version_info => ( is => 'ro',
@@ -88,12 +88,12 @@ sub _build_af {
my $self = shift;
my %args;
$args{base_url} = $self->base_url if $self->base_url;
return WWW::{{moduleName}}::ApiFactory->new(%args);
return {{moduleName}}::ApiFactory->new(%args);
}
=head1 NAME
WWW::{{moduleName}}::Role - a Moose role for the {{appName}}
{{moduleName}}::Role - a Moose role for the {{appName}}
=head2 {{appName}} version: {{appVersion}}
@@ -114,7 +114,7 @@ Automatically generated by the Perl Swagger Codegen project:
=head2 A note on Moose
This role is the only component of the library that uses Moose. See
WWW::{{moduleName}}::ApiFactory for non-Moosey usage.
{{moduleName}}::ApiFactory for non-Moosey usage.
=head1 SYNOPSIS
@@ -128,7 +128,7 @@ role.
package MyApp;
use Moose;
with 'WWW::{{moduleName}}::Role';
with '{{moduleName}}::Role';
package main;
@@ -186,39 +186,39 @@ you are accessing. Usually C<prefix> and C<in> will be determined by the code ge
the spec and you will not need to set them at run time. If not, C<in> will
default to 'head' and C<prefix> to the empty string.
The tokens will be placed in the C<WWW::{{moduleName}}::Configuration> namespace
The tokens will be placed in the C<{{moduleName}}::Configuration> namespace
as follows, but you don't need to know about this.
=over 4
=item C<$WWW::{{moduleName}}::Configuration::username>
=item C<${{moduleName}}::Configuration::username>
String. The username for basic auth.
=item C<$WWW::{{moduleName}}::Configuration::password>
=item C<${{moduleName}}::Configuration::password>
String. The password for basic auth.
=item C<$WWW::{{moduleName}}::Configuration::api_key>
=item C<${{moduleName}}::Configuration::api_key>
Hashref. Keyed on the name of each key (there can be multiple tokens).
$WWW::{{moduleName}}::Configuration::api_key = {
${{moduleName}}::Configuration::api_key = {
secretKey => 'aaaabbbbccccdddd',
anotherKey => '1111222233334444',
};
=item C<$WWW::{{moduleName}}::Configuration::api_key_prefix>
=item C<${{moduleName}}::Configuration::api_key_prefix>
Hashref. Keyed on the name of each key (there can be multiple tokens). Note not
all api keys require a prefix.
$WWW::{{moduleName}}::Configuration::api_key_prefix = {
${{moduleName}}::Configuration::api_key_prefix = {
secretKey => 'string',
anotherKey => 'same or some other string',
};
=item C<$WWW::{{moduleName}}::Configuration::access_token>
=item C<${{moduleName}}::Configuration::access_token>
String. The OAuth access token.
@@ -236,7 +236,7 @@ created yet) the current value of C<base_url>.
Returns an API factory object. You probably won't need to call this directly.
$self->api_factory('Pet'); # returns a WWW::{{moduleName}}::PetApi instance
$self->api_factory('Pet'); # returns a {{moduleName}}::PetApi instance
$self->pet_api; # the same
@@ -264,12 +264,12 @@ you could also call them on class names.
See the homepage C<https://github.com/swagger-api/swagger-codegen> for full details.
But briefly, clone the git repository, build the codegen codebase, set up your build
config file, then run the API build script. You will need git, Java 7 and Apache
config file, then run the API build script. You will need git, Java 7 or 8 and Apache
maven 3.0.3 or better already installed.
The config file should specify the project name for the generated library:
{"moduleName":"MyProjectName"}
{"moduleName":"WWW::MyProjectName"}
Your library files will be built under C<WWW::MyProjectName>.

View File

@@ -1,5 +1,5 @@
#
# Copyright 2015 SmartBear Software
# Copyright 2016 SmartBear Software
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
# NOTE: This class is auto generated by the swagger code generator program.
# Do not edit the class manually.
#
package WWW::{{moduleName}}::{{classname}};
package {{moduleName}}::{{classname}};
require 5.6.0;
use strict;
@@ -27,8 +27,8 @@ use Exporter;
use Carp qw( croak );
use Log::Any qw($log);
use WWW::{{moduleName}}::ApiClient;
use WWW::{{moduleName}}::Configuration;
use {{moduleName}}::ApiClient;
use {{moduleName}}::Configuration;
use base "Class::Data::Inheritable";
@@ -37,7 +37,7 @@ __PACKAGE__->mk_classdata('method_documentation' => {});
sub new {
my $class = shift;
my (%self) = (
'api_client' => WWW::{{moduleName}}::ApiClient->instance,
'api_client' => {{moduleName}}::ApiClient->instance,
@_
);

View File

@@ -15,14 +15,14 @@ my $my_app = $options{c} || 'My::App';
if ($options{c}) {
eval <<LOAD;
use $my_app;
apply_all_roles($my_app, "WWW::{{moduleName}}::Role::AutoDoc");
apply_all_roles($my_app, "{{moduleName}}::Role::AutoDoc");
LOAD
die $@ if $@;
}
else {
package My::App;
use Moose;
with ('WWW::{{moduleName}}::Role', 'WWW::{{moduleName}}::Role::AutoDoc');
with ('{{moduleName}}::Role', '{{moduleName}}::Role::AutoDoc');
}
package main;

View File

@@ -1,6 +1,6 @@
{{#models}}
{{#model}}
package WWW::{{moduleName}}::Object::{{classname}};
package {{moduleName}}::Object::{{classname}};
require 5.6.0;
use strict;

View File

@@ -11,7 +11,7 @@
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -10,7 +10,7 @@
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -11,7 +11,7 @@
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,6 +79,23 @@ class ObjectSerializer
return $sanitized;
}
/**
* Sanitize filename by removing path.
* e.g. ../../sun.gif becomes sun.gif
*
* @param string $filename filename to be sanitized
*
* @return string the sanitized filename
*/
public function sanitizeFilename($filename)
{
if (preg_match("/.*[\/\\\\](.*)$/", $filename, $match)) {
return $match[1];
} else {
return $filename;
}
}
/**
* Take value and turn it into a string suitable for inclusion in
* the path, by url-encoding.
@@ -199,11 +216,11 @@ class ObjectSerializer
*
* @param mixed $data object or primitive to be deserialized
* @param string $class class name is passed as a string
* @param string $httpHeader HTTP headers
* @param string $httpHeaders HTTP headers
*
* @return object an instance of $class
*/
public function deserialize($data, $class, $httpHeader=null)
public function deserialize($data, $class, $httpHeaders=null)
{
if (null === $data) {
$deserialized = null;
@@ -231,8 +248,8 @@ class ObjectSerializer
$deserialized = $data;
} elseif ($class === '\SplFileObject') {
// determine file name
if (array_key_exists('Content-Disposition', $httpHeaders) && preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeader['Content-Disposition'], $match)) {
$filename = Configuration::getDefaultConfiguration()->getTempFolderPath().$match[1];
if (array_key_exists('Content-Disposition', $httpHeaders) && preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeaders['Content-Disposition'], $match)) {
$filename = Configuration::getDefaultConfiguration()->getTempFolderPath() . sanitizeFilename($match[1]);
} else {
$filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), '');
}

View File

@@ -10,7 +10,7 @@
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -126,8 +126,6 @@ use \{{invokerPackage}}\ObjectSerializer;
// parse inputs
$resourcePath = "{{path}}";
$resourcePath = str_replace("{format}", "json", $resourcePath);
$method = "{{httpMethod}}";
$httpBody = '';
$queryParams = array();
$headerParams = array();
@@ -169,6 +167,9 @@ use \{{invokerPackage}}\ObjectSerializer;
$resourcePath
);
}{{/pathParams}}
// default format to json
$resourcePath = str_replace("{format}", "json", $resourcePath);
{{#formParams}}// form params
if (${{paramName}} !== null) {
{{#isFile}}
@@ -213,7 +214,7 @@ use \{{invokerPackage}}\ObjectSerializer;
// make the API Call
try {
list($response, $statusCode, $httpHeader) = $this->apiClient->callApi(
$resourcePath, $method,
$resourcePath, '{{httpMethod}}',
$queryParams, $httpBody,
$headerParams{{#returnType}}, '{{returnType}}'{{/returnType}}
);

View File

@@ -11,7 +11,7 @@
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -13,7 +13,7 @@
* @link https://github.com/swagger-api/swagger-codegen
*/
/**
* Copyright 2015 SmartBear Software
* Copyright 2016 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -2,7 +2,7 @@
"""
{{classname}}.py
Copyright 2015 SmartBear Software
Copyright 2016 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Copyright 2016 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Copyright 2016 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Copyright 2016 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
# coding: utf-8
"""
Copyright 2015 SmartBear Software
Copyright 2016 SmartBear Software
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -6,12 +6,13 @@ Gem::Specification.new do |s|
s.name = "{{gemName}}"
s.version = {{moduleName}}::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Zeke Sikelianos", "Tony Tam"]
s.email = ["zeke@wordnik.com", "fehguy@gmail.com"]
s.homepage = "http://swagger.io"
s.summary = %q{A ruby wrapper for the swagger APIs}
s.description = %q{This gem maps to a swagger API}
s.license = "Apache-2.0"
s.authors = ["{{gemAuthor}}"]
s.email = ["{{gemAuthorEmail}}"]
s.homepage = "{{gemHomepage}}"
s.summary = "{{gemSummary}}"
s.description = "{{gemDescription}}"
s.license = "{{gemLicense}}"
s.add_runtime_dependency 'typhoeus', '~> 0.2', '>= 0.2.1'
s.add_runtime_dependency 'json', '~> 1.4', '>= 1.4.6'
@@ -22,7 +23,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'autotest', '~> 4.4', '>= 4.4.6'
s.add_development_dependency 'autotest-rails-pure', '~> 4.1', '>= 4.1.2'
s.add_development_dependency 'autotest-growl', '~> 0.2', '>= 0.2.16'
s.add_development_dependency 'autotest-fsevent', '~> 0.2', '>= 0.2.10'
s.add_development_dependency 'autotest-fsevent', '~> 0.2', '>= 0.2.11'
s.files = `find *`.split("\n").uniq.sort.select{|f| !f.empty? }
s.test_files = `find spec/*`.split("\n")

View File

@@ -31,6 +31,12 @@ public class CSharpClientOptionsTest extends AbstractOptionsTest {
times = 1;
clientCodegen.setPackageVersion(CSharpClientOptionsProvider.PACKAGE_VERSION_VALUE);
times = 1;
clientCodegen.setOptionalAssemblyInfoFlag(true);
times = 1;
clientCodegen.setSourceFolder(CSharpClientOptionsProvider.SOURCE_FOLDER_VALUE);
times = 1;
clientCodegen.useDateTimeOffset(true);
times = 1;
}};
}
}

View File

@@ -9,7 +9,8 @@ import java.util.Map;
public class CSharpClientOptionsProvider implements OptionsProvider {
public static final String PACKAGE_NAME_VALUE = "swagger_client_csharp";
public static final String PACKAGE_VERSION_VALUE = "1.0.0-SNAPSHOT";
public static final String SOURCE_FOLDER_VALUE = "src_csharp";
@Override
public String getLanguage() {
return "csharp";
@@ -22,6 +23,9 @@ public class CSharpClientOptionsProvider implements OptionsProvider {
.put(CodegenConstants.PACKAGE_VERSION, PACKAGE_VERSION_VALUE)
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, "true")
.put(CodegenConstants.OPTIONAL_METHOD_ARGUMENT, "true")
.put(CodegenConstants.OPTIONAL_ASSEMBLY_INFO, "true")
.put(CodegenConstants.USE_DATETIME_OFFSET, "true")
.put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE)
.build();
}

View File

@@ -13,6 +13,12 @@ public class RubyClientOptionsProvider implements OptionsProvider {
public static final String GEM_VERSION_VALUE = "1.0.0-SNAPSHOT";
public static final String SORT_PARAMS_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String GEM_LICENSE_VALUE = "MIT";
public static final String GEM_HOMEPAGE_VALUE = "homepage";
public static final String GEM_SUMMARY_VALUE = "summary";
public static final String GEM_DESCRIPTION_VALUE = "description";
public static final String GEM_AUTHOR_VALUE = "foo";
public static final String GEM_AUTHOR_EMAIL_VALUE = "foo";
@Override
public String getLanguage() {
@@ -25,6 +31,12 @@ public class RubyClientOptionsProvider implements OptionsProvider {
return builder.put(RubyClientCodegen.GEM_NAME, GEM_NAME_VALUE)
.put(RubyClientCodegen.MODULE_NAME, MODULE_NAME_VALUE)
.put(RubyClientCodegen.GEM_VERSION, GEM_VERSION_VALUE)
.put(RubyClientCodegen.GEM_LICENSE, GEM_LICENSE_VALUE)
.put(RubyClientCodegen.GEM_DESCRIPTION, GEM_DESCRIPTION_VALUE)
.put(RubyClientCodegen.GEM_HOMEPAGE, GEM_HOMEPAGE_VALUE)
.put(RubyClientCodegen.GEM_SUMMARY, GEM_SUMMARY_VALUE)
.put(RubyClientCodegen.GEM_AUTHOR, GEM_AUTHOR_VALUE)
.put(RubyClientCodegen.GEM_AUTHOR_EMAIL, GEM_AUTHOR_EMAIL_VALUE)
.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.build();

View File

@@ -31,6 +31,19 @@ public class RubyClientOptionsTest extends AbstractOptionsTest {
times = 1;
clientCodegen.setGemVersion(RubyClientOptionsProvider.GEM_VERSION_VALUE);
times = 1;
clientCodegen.setGemLicense(RubyClientOptionsProvider.GEM_LICENSE_VALUE);
times = 1;
clientCodegen.setGemHomepage(RubyClientOptionsProvider.GEM_HOMEPAGE_VALUE);
times = 1;
clientCodegen.setGemDescription(RubyClientOptionsProvider.GEM_DESCRIPTION_VALUE);
times = 1;
clientCodegen.setGemSummary(RubyClientOptionsProvider.GEM_SUMMARY_VALUE);
times = 1;
clientCodegen.setGemAuthor(RubyClientOptionsProvider.GEM_AUTHOR_VALUE);
times = 1;
clientCodegen.setGemAuthorEmail(RubyClientOptionsProvider.GEM_AUTHOR_EMAIL_VALUE);
times = 1;
}};
}
}

View File

@@ -19,6 +19,49 @@
"http"
],
"paths": {
"/pet?testing_byte_array=true": {
"post": {
"tags": [
"pet"
],
"summary": "Fake endpoint to test byte array in body parameter for adding a new pet to the store",
"description": "",
"operationId": "addPetUsingByteArray",
"consumes": [
"application/json",
"application/xml"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Pet object in the form of byte array",
"required": false,
"schema": {
"type": "string",
"format": "binary"
}
}
],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet": {
"post": {
"tags": [
@@ -206,6 +249,56 @@
]
}
},
"/pet/{petId}?testing_byte_array=true": {
"get": {
"tags": [
"pet"
],
"summary": "Fake endpoint to test byte array return by 'Find pet by ID'",
"description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions",
"operationId": "getPetByIdWithByteArray",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"404": {
"description": "Pet not found"
},
"200": {
"description": "successful operation",
"schema": {
"type": "string",
"format": "binary"
}
},
"400": {
"description": "Invalid ID supplied"
}
},
"security": [
{
"api_key": []
},
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
},
"/pet/{petId}": {
"get": {
"tags": [