diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..542991f9550 --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +Copyright 2015 SmartBear Software + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at [apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index cb649e07da5..03876e61ed9 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ NAME SYNOPSIS swagger generate [(-a | --auth )] + [(-c | --config )] + [-D ] (-i | --input-spec ) (-l | --lang ) [(-o | --output )] @@ -72,6 +74,16 @@ OPTIONS remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values + -c , --config + Path to json configuration file. File content should be in a json + format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} + Supported options can be different for each language. Run + config-help -l {lang} command for language specific config options. + + -D + sets specified system properties in the format of + name=value,name=value + -i , --input-spec location of the swagger spec, as URL or file (required) @@ -166,8 +178,60 @@ SwaggerYamlGenerator.java TizenClientCodegen.java ``` -Each of these files creates reasonable defaults so you can get running quickly. But if you want to configure package names, prefixes, model folders, etc., you may want to extend these. +Each of these files creates reasonable defaults so you can get running quickly. But if you want to configure package names, prefixes, model folders, etc. you can use a json config file to pass the values. +``` +java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ + -i http://petstore.swagger.io/v2/swagger.json \ + -l java \ + -o samples/client/petstore/java \ + -c path/to/config.json +``` +Supported config options can be different per language. Running `config-help -l {lang}` will show available options. + +``` +java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jarr config-help -l java +``` + +Output + +``` +CONFIG OPTIONS + modelPackage + package for generated models + + apiPackage + package for generated api classes + + invokerPackage + root package for generated code + + groupId + groupId in generated pom.xml + + artifactId + artifactId in generated pom.xml + + artifactVersion + artifact version in generated pom.xml + + sourceFolder + source folder for generated code +``` + +Your config file for java can look like + +``` +{ + "groupId":"com.my.company", + "artifactId":"MyClent", + "artifactVersion":"1.2.0" +} +``` + +For all the unspecified options default values will be used. + +Another way to override default options is to extend config class for specific language. To change, for example, the prefix for the Objective-C generated files, simply subclass the ObjcClientCodegen.java: ``` @@ -273,7 +337,7 @@ Note! The templates are included in the library generated. If you want to modi License ------- -Copyright 2015 Reverb Technologies, Inc. +Copyright 2015 SmartBear Software Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh index 0f97790e75a..72797973a32 100755 --- a/bin/all-petstore.sh +++ b/bin/all-petstore.sh @@ -27,6 +27,7 @@ cd $APP_DIR ./bin/qt5-petstore.sh ./bin/php-petstore.sh ./bin/python-petstore.sh +./bin/retrofit-petstore.sh ./bin/ruby-petstore.sh ./bin/objc-petstore.sh ./bin/scala-petstore.sh diff --git a/bin/retrofit-petstore.sh b/bin/retrofit-petstore.sh new file mode 100755 index 00000000000..10b82e61963 --- /dev/null +++ b/bin/retrofit-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/retrofit -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l retrofit -o samples/client/petstore/retrofit" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/SwaggerCodegen.java b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/SwaggerCodegen.java index c8c718fb67b..f2c794776ce 100644 --- a/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/SwaggerCodegen.java +++ b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/SwaggerCodegen.java @@ -1,5 +1,6 @@ package com.wordnik.swagger.codegen; +import com.wordnik.swagger.codegen.cmd.ConfigHelp; import com.wordnik.swagger.codegen.cmd.Generate; import com.wordnik.swagger.codegen.cmd.Langs; import com.wordnik.swagger.codegen.cmd.Meta; @@ -27,7 +28,8 @@ public class SwaggerCodegen { Generate.class, Meta.class, Langs.class, - Help.class + Help.class, + ConfigHelp.class ); builder.build().parse(args).run(); diff --git a/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/ConfigHelp.java b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/ConfigHelp.java new file mode 100644 index 00000000000..fbdca12e6e8 --- /dev/null +++ b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/ConfigHelp.java @@ -0,0 +1,49 @@ +package com.wordnik.swagger.codegen.cmd; + +import com.wordnik.swagger.codegen.CliOption; +import com.wordnik.swagger.codegen.CodegenConfig; +import io.airlift.airline.Command; +import io.airlift.airline.Option; +import java.util.ServiceLoader; +import static java.util.ServiceLoader.load; + +@Command(name = "config-help", description = "Config help for chosen lang") +public class ConfigHelp implements Runnable { + + @Option(name = {"-l", "--lang"}, title = "language", required = true, + description = "language to get config help for") + private String lang; + + @Override + public void run() { + System.out.println(); + CodegenConfig config = forName(lang); + System.out.println("CONFIG OPTIONS"); + for (CliOption langCliOption : config.cliOptions()) { + System.out.println("\t" + langCliOption.getOpt()); + System.out.println("\t " + langCliOption.getDescription()); + System.out.println(); + } + } + + /** + * Tries to load config class with SPI first, then with class name directly from classpath + * @param name name of config, or full qualified class name in classpath + * @return config class + */ + private static CodegenConfig forName(String name) { + ServiceLoader loader = load(CodegenConfig.class); + for (CodegenConfig config : loader) { + if (config.getName().equals(name)) { + return config; + } + } + + // else try to load directly + try { + return (CodegenConfig) Class.forName(name).newInstance(); + } catch (Exception e) { + throw new RuntimeException("Can't load config class with name ".concat(name), e); + } + } +} diff --git a/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java index 47449d84286..3485eb8dd24 100644 --- a/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java +++ b/modules/swagger-codegen-cli/src/main/java/com/wordnik/swagger/codegen/cmd/Generate.java @@ -1,10 +1,13 @@ package com.wordnik.swagger.codegen.cmd; +import com.wordnik.swagger.codegen.CliOption; import com.wordnik.swagger.codegen.ClientOptInput; import com.wordnik.swagger.codegen.ClientOpts; import com.wordnik.swagger.codegen.CodegenConfig; import com.wordnik.swagger.codegen.DefaultGenerator; import com.wordnik.swagger.models.Swagger; +import config.Config; +import config.ConfigParser; import io.airlift.airline.Command; import io.airlift.airline.Option; import io.swagger.parser.SwaggerParser; @@ -57,6 +60,11 @@ public class Generate implements Runnable { @Option( name= {"-D"}, title = "system properties", description = "sets specified system properties in " + "the format of name=value,name=value") private String systemProperties; + + @Option( name= {"-c", "--config"}, title = "configuration file", description = "Path to json configuration file. " + + "File content should be in a json format {\"optionKey\":\"optionValue\", \"optionKey1\":\"optionValue1\"...} " + + "Supported options can be different for each language. Run config-help -l {lang} command for language specific config options.") + private String configFile; @Override public void run() { @@ -76,6 +84,17 @@ public class Generate implements Runnable { if (null != templateDir) { config.additionalProperties().put(TEMPLATE_DIR_PARAM, new File(templateDir).getAbsolutePath()); } + + if(null != configFile){ + Config genConfig = ConfigParser.read(configFile); + if (null != genConfig) { + for (CliOption langCliOption : config.cliOptions()) { + if (genConfig.hasOption(langCliOption.getOpt())) { + config.additionalProperties().put(langCliOption.getOpt(), genConfig.getOption(langCliOption.getOpt())); + } + } + } + } input.setConfig(config); diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CliOption.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CliOption.java new file mode 100644 index 00000000000..8ea0b60db26 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CliOption.java @@ -0,0 +1,23 @@ +package com.wordnik.swagger.codegen; + +public class CliOption { + private final String opt; + private String description; + + public CliOption(String opt, String description) { + this.opt = opt; + this.description = description; + } + + public String getOpt() { + return opt; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/Codegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/Codegen.java index efda171ff82..c28031a9f27 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/Codegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/Codegen.java @@ -140,4 +140,4 @@ public class Codegen extends DefaultGenerator { } } } -} +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java index 167610fcd70..b112923b6d7 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java @@ -27,6 +27,7 @@ public interface CodegenConfig { String getTypeDeclaration(Property p); String getTypeDeclaration(String name); void processOpts(); + List cliOptions(); String generateExamplePath(String path, Operation operation); Set reservedWords(); diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java index 7f8d390f371..76055110b92 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java @@ -7,7 +7,7 @@ import java.util.*; public class CodegenOperation { public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer, isListContainer, - hasMore = Boolean.TRUE; + hasMore = Boolean.TRUE, isMultipart; public String path, operationId, returnType, httpMethod, returnBaseType, returnContainer, summary, notes, baseName, defaultResponse; diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java index 2513bedfcb9..d7788ef8865 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java @@ -77,11 +77,24 @@ public class DefaultCodegen { protected String templateDir; protected Map additionalProperties = new HashMap(); protected List supportingFiles = new ArrayList(); + protected List cliOptions = new ArrayList(); + + public List cliOptions() { + return cliOptions; + } public void processOpts(){ if(additionalProperties.containsKey("templateDir")) { this.setTemplateDir((String)additionalProperties.get("templateDir")); } + + if(additionalProperties.containsKey("modelPackage")) { + this.setModelPackage((String)additionalProperties.get("modelPackage")); + } + + if(additionalProperties.containsKey("apiPackage")) { + this.setApiPackage((String)additionalProperties.get("apiPackage")); + } } // override with any special post-processing @@ -178,6 +191,14 @@ public class DefaultCodegen { this.templateDir = templateDir; } + public void setModelPackage(String modelPackage) { + this.modelPackage = modelPackage; + } + + public void setApiPackage(String apiPackage) { + this.apiPackage = apiPackage; + } + public String toApiFilename(String name) { return toApiName(name); } @@ -281,6 +302,9 @@ public class DefaultCodegen { importMapping.put("LocalDateTime", "org.joda.time.*"); importMapping.put("LocalDate", "org.joda.time.*"); importMapping.put("LocalTime", "org.joda.time.*"); + + cliOptions.add(new CliOption("modelPackage", "package for generated models")); + cliOptions.add(new CliOption("apiPackage", "package for generated api classes")); } diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/AndroidClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/AndroidClientCodegen.java index 62fc70efdea..377c8de24d9 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/AndroidClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/AndroidClientCodegen.java @@ -47,26 +47,6 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi "native", "super", "while") ); - additionalProperties.put("invokerPackage", invokerPackage); - additionalProperties.put("groupId", groupId); - additionalProperties.put("artifactId", artifactId); - additionalProperties.put("artifactVersion", artifactVersion); - - supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); - additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin); - - supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); - supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle")); - supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml")); - supportingFiles.add(new SupportingFile("apiInvoker.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java")); - supportingFiles.add(new SupportingFile("httpPatch.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "HttpPatch.java")); - supportingFiles.add(new SupportingFile("jsonUtil.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); - supportingFiles.add(new SupportingFile("apiException.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); - languageSpecificPrimitives = new HashSet( Arrays.asList( "String", @@ -80,6 +60,13 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi ); instantiationTypes.put("array", "ArrayList"); instantiationTypes.put("map", "HashMap"); + + cliOptions.add(new CliOption("invokerPackage", "root package to use for the generated code")); + cliOptions.add(new CliOption("groupId", "groupId for use in the generated build.gradle and pom.xml")); + cliOptions.add(new CliOption("artifactId", "artifactId for use in the generated build.gradle and pom.xml")); + cliOptions.add(new CliOption("artifactVersion", "artifact version for use in the generated build.gradle and pom.xml")); + cliOptions.add(new CliOption("sourceFolder", "source folder for generated code")); + cliOptions.add(new CliOption("useAndroidMavenGradlePlugin", "A flag to toggle android-maven gradle plugin. Default is true.")); } @Override @@ -177,6 +164,96 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi return camelize(operationId, true); } + + @Override + public void processOpts() { + super.processOpts(); + + if(additionalProperties.containsKey("invokerPackage")) { + this.setInvokerPackage((String)additionalProperties.get("invokerPackage")); + } + else{ + //not set, use default to be passed to template + additionalProperties.put("invokerPackage", invokerPackage); + } + + if(additionalProperties.containsKey("groupId")) { + this.setGroupId((String)additionalProperties.get("groupId")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("groupId", groupId); + } + + if(additionalProperties.containsKey("artifactId")) { + this.setArtifactId((String)additionalProperties.get("artifactId")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("artifactId", artifactId); + } + + if(additionalProperties.containsKey("artifactVersion")) { + this.setArtifactVersion((String)additionalProperties.get("artifactVersion")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("artifactVersion", artifactVersion); + } + + if(additionalProperties.containsKey("sourceFolder")) { + this.setSourceFolder((String)additionalProperties.get("sourceFolder")); + } + if(additionalProperties.containsKey("useAndroidMavenGradlePlugin")) { + this.setUseAndroidMavenGradlePlugin((Boolean)additionalProperties.get("useAndroidMavenGradlePlugin")); + } + else{ + additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin); + } + + supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); + additionalProperties.put("useAndroidMavenGradlePlugin", useAndroidMavenGradlePlugin); + + supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle")); + supportingFiles.add(new SupportingFile("build.mustache", "", "build.gradle")); + supportingFiles.add(new SupportingFile("manifest.mustache", projectFolder, "AndroidManifest.xml")); + supportingFiles.add(new SupportingFile("apiInvoker.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java")); + supportingFiles.add(new SupportingFile("httpPatch.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "HttpPatch.java")); + supportingFiles.add(new SupportingFile("jsonUtil.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); + supportingFiles.add(new SupportingFile("apiException.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); + } + + public Boolean getUseAndroidMavenGradlePlugin() { + return useAndroidMavenGradlePlugin; + } + + public void setUseAndroidMavenGradlePlugin(Boolean useAndroidMavenGradlePlugin) { + this.useAndroidMavenGradlePlugin = useAndroidMavenGradlePlugin; + } + + public void setInvokerPackage(String invokerPackage) { + this.invokerPackage = invokerPackage; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public void setSourceFolder(String sourceFolder) { + this.sourceFolder = sourceFolder; + } } diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/CSharpClientCodegen.java index 9de427058a1..abac0db5d9f 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/CSharpClientCodegen.java @@ -41,11 +41,14 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig additionalProperties.put("invokerPackage", invokerPackage); - supportingFiles.add(new SupportingFile("apiInvoker.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.cs")); - supportingFiles.add(new SupportingFile("apiException.mustache", + supportingFiles.add(new SupportingFile("Configuration.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.cs")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.cs")); + supportingFiles.add(new SupportingFile("ApiException.mustache", (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.cs")); 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")); languageSpecificPrimitives = new HashSet( @@ -59,7 +62,7 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig "byte[]", "List", "Dictionary", - "DateTime", + "DateTime?", "String", "Boolean", "Double", @@ -79,9 +82,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig typeMapping.put("long", "long?"); typeMapping.put("double", "double?"); typeMapping.put("number", "double?"); - typeMapping.put("Date", "DateTime"); + typeMapping.put("datetime", "DateTime?"); + typeMapping.put("date", "DateTime?"); typeMapping.put("file", "string"); // path to file typeMapping.put("array", "List"); + typeMapping.put("list", "List"); typeMapping.put("map", "Dictionary"); typeMapping.put("object", "Object"); @@ -94,11 +99,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig @Override public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar); + return (outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', '/')).replace('.', File.separatorChar); } public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar); + return (outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', '/')).replace('.', File.separatorChar); } @Override @@ -165,8 +170,8 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig public String getSwaggerType(Property p) { String swaggerType = super.getSwaggerType(p); String type = null; - if(typeMapping.containsKey(swaggerType)) { - type = typeMapping.get(swaggerType); + if(typeMapping.containsKey(swaggerType.toLowerCase())) { + type = typeMapping.get(swaggerType.toLowerCase()); if(languageSpecificPrimitives.contains(type)) return type; } diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java index 7c0ac7422ff..6d67e971923 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java @@ -36,28 +36,15 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { reservedWords = new HashSet ( 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", + "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") ); - additionalProperties.put("invokerPackage", invokerPackage); - additionalProperties.put("groupId", groupId); - additionalProperties.put("artifactId", artifactId); - additionalProperties.put("artifactVersion", artifactVersion); - - supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); - supportingFiles.add(new SupportingFile("apiInvoker.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.java")); - supportingFiles.add(new SupportingFile("JsonUtil.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); - supportingFiles.add(new SupportingFile("apiException.mustache", - (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); - languageSpecificPrimitives = new HashSet( Arrays.asList( "String", @@ -71,8 +58,67 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { ); instantiationTypes.put("array", "ArrayList"); instantiationTypes.put("map", "HashMap"); + + cliOptions.add(new CliOption("invokerPackage", "root package for generated code")); + cliOptions.add(new CliOption("groupId", "groupId in generated pom.xml")); + cliOptions.add(new CliOption("artifactId", "artifactId in generated pom.xml")); + cliOptions.add(new CliOption("artifactVersion", "artifact version in generated pom.xml")); + cliOptions.add(new CliOption("sourceFolder", "source folder for generated code")); } + @Override + public void processOpts() { + super.processOpts(); + + if(additionalProperties.containsKey("invokerPackage")) { + this.setInvokerPackage((String)additionalProperties.get("invokerPackage")); + } + else{ + //not set, use default to be passed to template + additionalProperties.put("invokerPackage", invokerPackage); + } + + if(additionalProperties.containsKey("groupId")) { + this.setGroupId((String)additionalProperties.get("groupId")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("groupId", groupId); + } + + if(additionalProperties.containsKey("artifactId")) { + this.setArtifactId((String)additionalProperties.get("artifactId")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("artifactId", artifactId); + } + + if(additionalProperties.containsKey("artifactVersion")) { + this.setArtifactVersion((String)additionalProperties.get("artifactVersion")); + } + else{ + //not set, use to be passed to template + additionalProperties.put("artifactVersion", artifactVersion); + } + + if(additionalProperties.containsKey("sourceFolder")) { + this.setSourceFolder((String)additionalProperties.get("sourceFolder")); + } + + supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiClient.java")); + supportingFiles.add(new SupportingFile("Configuration.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "Configuration.java")); + supportingFiles.add(new SupportingFile("JsonUtil.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "JsonUtil.java")); + supportingFiles.add(new SupportingFile("apiException.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiException.java")); + } + + + @Override public String escapeReservedWord(String name) { return "_" + name; @@ -169,5 +215,23 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { return camelize(operationId, true); } + public void setInvokerPackage(String invokerPackage) { + this.invokerPackage = invokerPackage; + } + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public void setSourceFolder(String sourceFolder) { + this.sourceFolder = sourceFolder; + } } diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java index d1e227ce744..ab1cf2ec8d7 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java @@ -1,6 +1,5 @@ package com.wordnik.swagger.codegen.languages; -import com.wordnik.swagger.util.Json; import com.wordnik.swagger.codegen.*; import com.wordnik.swagger.models.properties.*; @@ -10,7 +9,8 @@ import java.io.File; public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { protected Set foundationClasses = new HashSet(); protected String sourceFolder = "client"; - protected static String PREFIX = "SWG"; + protected String classPrefix = "SWG"; + protected String projectName = "swaggerClient"; public CodegenType getTag() { return CodegenType.CLIENT; @@ -26,7 +26,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { public ObjcClientCodegen() { super(); - outputFolder = "generated-code/objc"; + outputFolder = "generated-code" + File.separator + "objc"; modelTemplateFiles.put("model-header.mustache", ".h"); modelTemplateFiles.put("model-body.mustache", ".m"); apiTemplateFiles.put("api-header.mustache", ".h"); @@ -34,12 +34,6 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { templateDir = "objc"; modelPackage = ""; - String appName = System.getProperty("appName"); - if(appName == null) { - appName = "swaggerClient"; - } - additionalProperties.put("projectName", appName); - defaultIncludes = new HashSet( Arrays.asList( "bool", @@ -111,7 +105,31 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { instantiationTypes.put("array", "NSMutableArray"); instantiationTypes.put("map", "NSMutableDictionary"); + + cliOptions.add(new CliOption("classPrefix", "prefix for generated classes")); + cliOptions.add(new CliOption("sourceFolder", "source folder for generated code")); + cliOptions.add(new CliOption("projectName", "name of the Xcode project in generated Podfile")); + } + @Override + public void processOpts() { + super.processOpts(); + + if(additionalProperties.containsKey("sourceFolder")) { + this.setSourceFolder((String)additionalProperties.get("sourceFolder")); + } + + if(additionalProperties.containsKey("classPrefix")) { + this.setClassPrefix((String)additionalProperties.get("classPrefix")); + } + + if(additionalProperties.containsKey("projectName")) { + this.setProjectName((String)additionalProperties.get("projectName")); + } + else{ + additionalProperties.put("projectName", projectName); + } + supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h")); supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m")); supportingFiles.add(new SupportingFile("SWGQueryParamCollection.h", sourceFolder, "SWGQueryParamCollection.h")); @@ -122,6 +140,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.h", sourceFolder, "JSONValueTransformer+ISO8601.h")); + supportingFiles.add(new SupportingFile("SWGConfiguration-body.mustache", sourceFolder, "SWGConfiguration.m")); + supportingFiles.add(new SupportingFile("SWGConfiguration-header.mustache", sourceFolder, "SWGConfiguration.h")); supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile")); } @@ -220,7 +240,7 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { } // custom classes else { - return PREFIX + camelize(type); + return classPrefix + camelize(type); } } @@ -266,11 +286,11 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String toApiName(String name) { - return PREFIX + camelize(name) + "Api"; + return classPrefix + camelize(name) + "Api"; } public String toApiFilename(String name) { - return PREFIX + camelize(name) + "Api"; + return classPrefix + camelize(name) + "Api"; } @Override @@ -313,4 +333,15 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { return camelize(operationId, true); } + public void setSourceFolder(String sourceFolder) { + this.sourceFolder = sourceFolder; + } + + public void setClassPrefix(String classPrefix) { + this.classPrefix = classPrefix; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } } diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PerlClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PerlClientCodegen.java index b25e4490e85..b96b012abba 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PerlClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PerlClientCodegen.java @@ -27,8 +27,8 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { public PerlClientCodegen() { super(); - modelPackage = "Object"; - outputFolder = "generated-code/perl"; + modelPackage = File.separatorChar + "Object"; + outputFolder = "generated-code" + File.separatorChar + "perl"; modelTemplateFiles.put("object.mustache", ".pm"); apiTemplateFiles.put("api.mustache", ".pm"); templateDir = "perl"; @@ -63,6 +63,7 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { languageSpecificPrimitives.add("DateTime"); languageSpecificPrimitives.add("ARRAY"); languageSpecificPrimitives.add("HASH"); + languageSpecificPrimitives.add("object"); typeMapping.put("integer", "int"); typeMapping.put("long", "int"); @@ -75,9 +76,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("password", "string"); typeMapping.put("array", "ARRAY"); typeMapping.put("map", "HASH"); + typeMapping.put("object", "object"); - supportingFiles.add(new SupportingFile("APIClient.mustache", "lib/WWW/" + invokerPackage, "APIClient.pm")); - supportingFiles.add(new SupportingFile("BaseObject.mustache", "lib/WWW/" + invokerPackage, "Object/BaseObject.pm")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "ApiClient.pm")); + supportingFiles.add(new SupportingFile("Configuration.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Configuration.pm")); + supportingFiles.add(new SupportingFile("BaseObject.mustache", ("lib/WWW/" + invokerPackage).replace('/', File.separatorChar), "Object/BaseObject.pm")); } @Override @@ -87,11 +90,11 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return outputFolder + "/lib/WWW/" + invokerPackage + apiPackage().replace('.', File.separatorChar); + return (outputFolder + "/lib/WWW/" + invokerPackage + apiPackage()).replace('/', File.separatorChar); } public String modelFileFolder() { - return outputFolder + "/lib/WWW/" + invokerPackage + "/" + modelPackage().replace('.', File.separatorChar); + return (outputFolder + "/lib/WWW/" + invokerPackage + modelPackage()).replace('/', File.separatorChar); } @Override diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PhpClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PhpClientCodegen.java index 55d358154f8..2f643724b14 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PhpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PhpClientCodegen.java @@ -82,12 +82,13 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("map", "map"); typeMapping.put("array", "array"); typeMapping.put("list", "array"); + typeMapping.put("object", "object"); - supportingFiles.add(new SupportingFile("composer.mustache", packagePath, "composer.json")); - supportingFiles.add(new SupportingFile("configuration.mustache", packagePath + "/lib", "Configuration.php")); - supportingFiles.add(new SupportingFile("APIClient.mustache", packagePath + "/lib", "APIClient.php")); - supportingFiles.add(new SupportingFile("APIClientException.mustache", packagePath + "/lib", "APIClientException.php")); - supportingFiles.add(new SupportingFile("require.mustache", packagePath, invokerPackage + ".php")); + supportingFiles.add(new SupportingFile("composer.mustache", packagePath.replace('/', File.separatorChar), "composer.json")); + supportingFiles.add(new SupportingFile("configuration.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "Configuration.php")); + supportingFiles.add(new SupportingFile("ApiClient.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiClient.php")); + supportingFiles.add(new SupportingFile("ApiException.mustache", (packagePath + "/lib").replace('/', File.separatorChar), "ApiException.php")); + supportingFiles.add(new SupportingFile("require.mustache", packagePath.replace('/', File.separatorChar), invokerPackage + ".php")); } @Override @@ -97,11 +98,11 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig { @Override public String apiFileFolder() { - return outputFolder + "/" + apiPackage().replace('.', File.separatorChar); + return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar); } public String modelFileFolder() { - return outputFolder + "/" + modelPackage().replace('.', File.separatorChar); + return (outputFolder + "/" + modelPackage()).replace('/', File.separatorChar); } @Override diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java index 7896bf66878..590e17f6326 100755 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/PythonClientCodegen.java @@ -71,6 +71,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig supportingFiles.add(new SupportingFile("swagger.mustache", invokerPackage, "swagger.py")); supportingFiles.add(new SupportingFile("rest.mustache", invokerPackage, "rest.py")); supportingFiles.add(new SupportingFile("util.mustache", invokerPackage, "util.py")); + supportingFiles.add(new SupportingFile("config.mustache", invokerPackage, "config.py")); supportingFiles.add(new SupportingFile("__init__package.mustache", invokerPackage, "__init__.py")); supportingFiles.add(new SupportingFile("__init__model.mustache", modelPackage.replace('.', File.separatorChar), "__init__.py")); supportingFiles.add(new SupportingFile("__init__api.mustache", apiPackage.replace('.', File.separatorChar), "__init__.py")); diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java new file mode 100644 index 00000000000..6f80f8a5c5e --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java @@ -0,0 +1,190 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.Operation; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig { + protected String invokerPackage = "io.swagger.client"; + protected String groupId = "io.swagger"; + protected String artifactId = "swagger-java-client"; + protected String artifactVersion = "1.0.0"; + protected String sourceFolder = "src/main/java"; + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "retrofit"; + } + + public String getHelp() { + return "Generates a Retrofit client library."; + } + + public RetrofitClientCodegen() { + super(); + outputFolder = "generated-code/java"; + modelTemplateFiles.put("model.mustache", ".java"); + apiTemplateFiles.put("api.mustache", ".java"); + templateDir = "retrofit"; + apiPackage = "io.swagger.client.api"; + modelPackage = "io.swagger.client.model"; + + reservedWords = new HashSet ( + 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") + ); + + additionalProperties.put("invokerPackage", invokerPackage); + additionalProperties.put("groupId", groupId); + additionalProperties.put("artifactId", artifactId); + additionalProperties.put("artifactVersion", artifactVersion); + + supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); + supportingFiles.add(new SupportingFile("service.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ServiceGenerator.java")); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float", + "Object") + ); + instantiationTypes.put("array", "ArrayList"); + instantiationTypes.put("map", "HashMap"); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar); + } + + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar); + } + + @Override + public String toVarName(String name) { + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // if it's all uppper case, do nothing + if (name.matches("^[A-Z_]*$")) + return name; + + // camelize (lower first character) the variable name + // pet_id => petId + name = camelize(name, true); + + // for reserved word or word starting with number, append _ + if(reservedWords.contains(name) || name.matches("^\\d.*")) + name = escapeReservedWord(name); + + return name; + } + + @Override + public String toParamName(String name) { + // should be the same as variable name + return toVarName(name); + } + + @Override + public String toModelName(String name) { + // model name cannot use reserved keyword, e.g. return + if(reservedWords.contains(name)) + throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); + + // camelize the model name + // phone_number => PhoneNumber + return camelize(name); + } + + @Override + public String toModelFilename(String name) { + // should be the same as the model name + return toModelName(name); + } + + + @Override + public String getTypeDeclaration(Property p) { + if(p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">"; + } + else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + + return getSwaggerType(p) + ""; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type)) + return toModelName(type); + } + else + type = swaggerType; + return toModelName(type); + } + + @Override + public String toOperationId(String operationId) { + // method name cannot use reserved keyword, e.g. return + if(reservedWords.contains(operationId)) + throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); + + return camelize(operationId, true); + } + + public Map postProcessOperations(Map objs) { + Map operations = (Map)objs.get("operations"); + if(operations != null) { + List ops = (List) operations.get("operation"); + for(CodegenOperation operation : ops) { + if (operation.hasConsumes == Boolean.TRUE) { + Map firstType = operation.consumes.get(0); + if (firstType != null) { + if ("multipart/form-data".equals(firstType.get("mediaType"))) { + operation.isMultipart = Boolean.TRUE; + } + } + } + if(operation.returnType == null) { + operation.returnType = "Void"; + } + } + } + return objs; + } +} diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java index 939c0eb0e0a..3ca7758b1a3 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RubyClientCodegen.java @@ -36,7 +36,7 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { moduleName = generateModuleName(); modelPackage = gemName + "/models"; apiPackage = gemName + "/api"; - outputFolder = "generated-code/ruby"; + outputFolder = "generated-code" + File.separatorChar + "ruby"; modelTemplateFiles.put("model.mustache", ".rb"); apiTemplateFiles.put("api.mustache", ".rb"); templateDir = "ruby"; @@ -69,17 +69,17 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { typeMapping.put("List", "array"); typeMapping.put("map", "map"); - String baseFolder = "lib/" + gemName; - String swaggerFolder = baseFolder + "/swagger"; - String modelFolder = baseFolder + "/models"; + String baseFolder = "lib" + File.separatorChar + gemName; + String swaggerFolder = baseFolder + File.separatorChar + "swagger"; + String modelFolder = baseFolder + File.separatorChar + "models"; supportingFiles.add(new SupportingFile("swagger_client.gemspec.mustache", "", gemName + ".gemspec")); supportingFiles.add(new SupportingFile("swagger_client.mustache", "lib", gemName + ".rb")); supportingFiles.add(new SupportingFile("monkey.mustache", baseFolder, "monkey.rb")); supportingFiles.add(new SupportingFile("swagger.mustache", baseFolder, "swagger.rb")); - supportingFiles.add(new SupportingFile("swagger/request.mustache", swaggerFolder, "request.rb")); - supportingFiles.add(new SupportingFile("swagger/response.mustache", swaggerFolder, "response.rb")); - supportingFiles.add(new SupportingFile("swagger/version.mustache", swaggerFolder, "version.rb")); - supportingFiles.add(new SupportingFile("swagger/configuration.mustache", swaggerFolder, "configuration.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "request.mustache", swaggerFolder, "request.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "response.mustache", swaggerFolder, "response.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "version.mustache", swaggerFolder, "version.rb")); + supportingFiles.add(new SupportingFile("swagger" + File.separatorChar + "configuration.mustache", swaggerFolder, "configuration.rb")); supportingFiles.add(new SupportingFile("base_object.mustache", modelFolder, "base_object.rb")); } diff --git a/modules/swagger-codegen/src/main/java/config/Config.java b/modules/swagger-codegen/src/main/java/config/Config.java new file mode 100644 index 00000000000..9bc4bf58624 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/config/Config.java @@ -0,0 +1,33 @@ +package config; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; + +public class Config { + private Map options; + + public Config() { + this.options = new HashMap(); + } + + public Config(Map properties) { + this.options = properties; + } + + public Map getOptions() { + return ImmutableMap.copyOf(options); + } + + public boolean hasOption(String opt){ + return options.containsKey(opt); + } + + public String getOption(String opt){ + return options.get(opt); + } + + public void setOption(String opt, String value){ + options.put(opt, value); + } +} diff --git a/modules/swagger-codegen/src/main/java/config/ConfigParser.java b/modules/swagger-codegen/src/main/java/config/ConfigParser.java new file mode 100644 index 00000000000..cbb1b78f645 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/config/ConfigParser.java @@ -0,0 +1,41 @@ +package config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.util.Iterator; +import java.util.Map; + +public class ConfigParser { + + public static Config read(String location) { + + System.out.println("reading config from " + location); + + ObjectMapper mapper = new ObjectMapper(); + + Config config = new Config(); + + try { + JsonNode rootNode = mapper.readTree(new File(location)); + Iterator> optionNodes = rootNode.fields(); + + while (optionNodes.hasNext()) { + Map.Entry optionNode = (Map.Entry) optionNodes.next(); + + if(optionNode.getValue().isValueNode()){ + config.setOption(optionNode.getKey(), optionNode.getValue().asText()); + } + else{ + System.out.println("omitting non-value node " + optionNode.getKey()); + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + return null; + } + + return config; + } +} diff --git a/modules/swagger-codegen/src/main/resources/Java/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache similarity index 62% rename from modules/swagger-codegen/src/main/resources/Java/apiInvoker.mustache rename to modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache index c30ba4cdd12..ae79a726280 100644 --- a/modules/swagger-codegen/src/main/resources/Java/apiInvoker.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/ApiClient.mustache @@ -29,69 +29,116 @@ import java.net.URLEncoder; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.text.ParseException; -public class ApiInvoker { - private static ApiInvoker INSTANCE = new ApiInvoker(); +public class ApiClient { private Map hostMap = new HashMap(); private Map defaultHeaderMap = new HashMap(); - private boolean isDebug = false; + private boolean debugging = false; + private String basePath = "{{basePath}}"; - /** - * ISO 8601 date time format. - * @see https://en.wikipedia.org/wiki/ISO_8601 - */ - public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + private DateFormat dateFormat; - /** - * ISO 8601 date format. - * @see https://en.wikipedia.org/wiki/ISO_8601 - */ - public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + public ApiClient() { + // Use ISO 8601 format for date and datetime. + // See https://en.wikipedia.org/wiki/ISO_8601 + this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - static { // Use UTC as the default time zone. - DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); - DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); // Set default User-Agent. setUserAgent("Java-Swagger"); } - public static void setUserAgent(String userAgent) { - INSTANCE.addDefaultHeader("User-Agent", userAgent); + public String getBasePath() { + return basePath; } - public static Date parseDateTime(String str) { + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + return this; + } + + /** + * Get the date format used to parse/format date parameters. + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + */ + public ApiClient getDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + return this; + } + + /** + * Parse the given string into Date object. + */ + public Date parseDate(String str) { try { - return DATE_TIME_FORMAT.parse(str); + return dateFormat.parse(str); } catch (java.text.ParseException e) { throw new RuntimeException(e); } } - public static Date parseDate(String str) { - try { - return DATE_FORMAT.parse(str); - } catch (java.text.ParseException e) { - throw new RuntimeException(e); - } + /** + * Format the given Date object into string. + */ + public String formatDate(Date date) { + return dateFormat.format(date); } - public static String formatDateTime(Date datetime) { - return DATE_TIME_FORMAT.format(datetime); - } - - public static String formatDate(Date date) { - return DATE_FORMAT.format(date); - } - - public static String parameterToString(Object param) { + /** + * Format the given parameter object into string. + */ + public String parameterToString(Object param) { if (param == null) { return ""; } else if (param instanceof Date) { - return formatDateTime((Date) param); + return formatDate((Date) param); } else if (param instanceof Collection) { StringBuilder b = new StringBuilder(); for(Object o : (Collection)param) { @@ -105,28 +152,27 @@ public class ApiInvoker { return String.valueOf(param); } } - public void enableDebug() { - isDebug = true; - } - - public static ApiInvoker getInstance() { - return INSTANCE; - } - - public void addDefaultHeader(String key, String value) { - defaultHeaderMap.put(key, value); - } + /** + * Escape the given string to be used as URL query value. + */ public String escapeString(String str) { - try{ + try { return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); - } - catch(UnsupportedEncodingException e) { + } catch (UnsupportedEncodingException e) { return str; } } - public static Object deserialize(String json, String containerType, Class cls) throws ApiException { + /** + * Deserialize the given JSON string to Java object. + * + * @param json The JSON string + * @param containerType The container type, one of "list", "array" or "" + * @param cls The type of the Java object + * @return The deserialized Java object + */ + public Object deserialize(String json, String containerType, Class cls) throws ApiException { if(null != containerType) { containerType = containerType.toLowerCase(); } @@ -147,11 +193,14 @@ public class ApiInvoker { } } catch (IOException e) { - throw new ApiException(500, e.getMessage()); + throw new ApiException(500, e.getMessage(), null, json); } } - public static String serialize(Object obj) throws ApiException { + /** + * Serialize the given Java object into JSON string. + */ + public String serialize(Object obj) throws ApiException { try { if (obj != null) return JsonUtil.getJsonMapper().writeValueAsString(obj); @@ -163,8 +212,20 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { - Client client = getClient(host); + /** + * Invoke API by sending HTTP request with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param contentType The request Content-Type + * @return The response body in type of string + */ + public String invokeAPI(String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + Client client = getClient(); StringBuilder b = new StringBuilder(); @@ -180,7 +241,7 @@ public class ApiInvoker { } String querystring = b.toString(); - Builder builder = client.resource(host + path + querystring).accept("application/json"); + Builder builder = client.resource(basePath + path + querystring).accept("application/json"); for(String key : headerParams.keySet()) { builder = builder.header(key, headerParams.get(key)); } @@ -236,6 +297,7 @@ public class ApiInvoker { else { throw new ApiException(500, "unknown method type " + method); } + if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) { return null; } @@ -249,9 +311,11 @@ public class ApiInvoker { } else { String message = "error"; + String respBody = null; if(response.hasEntity()) { try{ - message = String.valueOf(response.getEntity(String.class)); + respBody = String.valueOf(response.getEntity(String.class)); + message = respBody; } catch (RuntimeException e) { // e.printStackTrace(); @@ -259,16 +323,21 @@ public class ApiInvoker { } throw new ApiException( response.getClientResponseStatus().getStatusCode(), - message); + message, + response.getHeaders(), + respBody); } } + /** + * Encode the given form parameters as request body. + */ private String getXWWWFormUrlencodedParams(Map formParams) { StringBuilder formParamBuilder = new StringBuilder(); for (Entry param : formParams.entrySet()) { - String keyStr = ApiInvoker.parameterToString(param.getKey()); - String valueStr = ApiInvoker.parameterToString(param.getValue()); + String keyStr = parameterToString(param.getKey()); + String valueStr = parameterToString(param.getValue()); try { formParamBuilder.append(URLEncoder.encode(keyStr, "utf8")) @@ -287,14 +356,16 @@ public class ApiInvoker { return encodedFormParams; } - - private Client getClient(String host) { - if(!hostMap.containsKey(host)) { + /** + * Get an existing client or create a new client to handle HTTP request. + */ + private Client getClient() { + if(!hostMap.containsKey(basePath)) { Client client = Client.create(); - if(isDebug) + if (debugging) client.addFilter(new LoggingFilter()); - hostMap.put(host, client); + hostMap.put(basePath, client); } - return hostMap.get(host); + return hostMap.get(basePath); } -} \ No newline at end of file +} diff --git a/modules/swagger-codegen/src/main/resources/Java/Configuration.mustache b/modules/swagger-codegen/src/main/resources/Java/Configuration.mustache new file mode 100644 index 00000000000..9d7523d1fb3 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Java/Configuration.mustache @@ -0,0 +1,21 @@ +package {{invokerPackage}}; + +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/modules/swagger-codegen/src/main/resources/Java/api.mustache b/modules/swagger-codegen/src/main/resources/Java/api.mustache index 78bac41d9d6..b33fd7f3733 100644 --- a/modules/swagger-codegen/src/main/resources/Java/api.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/api.mustache @@ -1,7 +1,8 @@ package {{package}}; import {{invokerPackage}}.ApiException; -import {{invokerPackage}}.ApiInvoker; +import {{invokerPackage}}.ApiClient; +import {{invokerPackage}}.Configuration; import {{modelPackage}}.*; @@ -21,19 +22,22 @@ import java.util.HashMap; {{#operations}} public class {{classname}} { - String basePath = "{{basePath}}"; - ApiInvoker apiInvoker = ApiInvoker.getInstance(); + private ApiClient apiClient; - public ApiInvoker getInvoker() { - return apiInvoker; + public {{classname}}() { + this(Configuration.getDefaultApiClient()); } - public void setBasePath(String basePath) { - this.basePath = basePath; + public {{classname}}(ApiClient apiClient) { + this.apiClient = apiClient; } - public String getBasePath() { - return basePath; + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; } {{#operation}} @@ -54,7 +58,7 @@ public class {{classname}} { // create path and map variables String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}} - .replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}}; + .replaceAll("\\{" + "{{paramName}}" + "\\}", apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}}; // query params Map queryParams = new HashMap(); @@ -62,9 +66,10 @@ public class {{classname}} { Map formParams = new HashMap(); {{#queryParams}}if ({{paramName}} != null) - queryParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}})); + queryParams.put("{{baseName}}", apiClient.parameterToString({{paramName}})); {{/queryParams}} - {{#headerParams}}headerParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}})); + {{#headerParams}}if ({{paramName}} != null) + headerParams.put("{{baseName}}", apiClient.parameterToString({{paramName}})); {{/headerParams}} String[] contentTypes = { {{#consumes}}"{{mediaType}}"{{#hasMore}},{{/hasMore}}{{/consumes}} @@ -76,25 +81,30 @@ public class {{classname}} { boolean hasFields = false; FormDataMultiPart mp = new FormDataMultiPart(); {{#formParams}}{{#notFile}} - hasFields = true; - mp.field("{{baseName}}", ApiInvoker.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE); + if ({{paramName}} != null) { + hasFields = true; + mp.field("{{baseName}}", apiClient.parameterToString({{paramName}}), MediaType.MULTIPART_FORM_DATA_TYPE); + } {{/notFile}}{{#isFile}} - hasFields = true; - mp.field("{{baseName}}", file.getName()); - mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE)); + if ({{paramName}} != null) { + hasFields = true; + mp.field("{{baseName}}", {{paramName}}.getName()); + mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE)); + } {{/isFile}}{{/formParams}} if(hasFields) postBody = mp; } else { - {{#formParams}}{{#notFile}}formParams.put("{{baseName}}", ApiInvoker.parameterToString({{paramName}}));{{/notFile}} + {{#formParams}}{{#notFile}}if ({{paramName}} != null) + formParams.put("{{baseName}}", apiClient.parameterToString({{paramName}}));{{/notFile}} {{/formParams}} } try { - String response = apiInvoker.invokeAPI(basePath, path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "{{httpMethod}}", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return {{#returnType}}({{{returnType}}}) ApiInvoker.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}}; + return {{#returnType}}({{{returnType}}}) apiClient.deserialize(response, "{{returnContainer}}", {{returnBaseType}}.class){{/returnType}}; } else { return {{#returnType}}null{{/returnType}}; diff --git a/modules/swagger-codegen/src/main/resources/Java/apiException.mustache b/modules/swagger-codegen/src/main/resources/Java/apiException.mustache index a6bcba75b7c..9afe96c6ffb 100644 --- a/modules/swagger-codegen/src/main/resources/Java/apiException.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/apiException.mustache @@ -1,8 +1,13 @@ package {{invokerPackage}}; +import java.util.Map; +import java.util.List; + public class ApiException extends Exception { - int code = 0; - String message = null; + private int code = 0; + private String message = null; + private Map> responseHeaders = null; + private String responseBody = null; public ApiException() {} @@ -11,19 +16,32 @@ public class ApiException extends Exception { this.message = message; } + public ApiException(int code, String message, Map> responseHeaders, String responseBody) { + this.code = code; + this.message = message; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + public int getCode() { return code; } - - public void setCode(int code) { - this.code = code; - } - + public String getMessage() { return message; } - - public void setMessage(String message) { - this.message = message; + + /** + * Get the HTTP response headers. + */ + public Map> getResponseHeaders() { + return responseHeaders; } -} \ No newline at end of file + + /** + * Get the HTTP response body. + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig index 73dbeae62ef..4dec8a51df5 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig @@ -10,6 +10,7 @@ com.wordnik.swagger.codegen.languages.PhpClientCodegen com.wordnik.swagger.codegen.languages.PythonClientCodegen com.wordnik.swagger.codegen.languages.Python3ClientCodegen com.wordnik.swagger.codegen.languages.Qt5CPPGenerator +com.wordnik.swagger.codegen.languages.RetrofitClientCodegen com.wordnik.swagger.codegen.languages.RubyClientCodegen com.wordnik.swagger.codegen.languages.ScalaClientCodegen com.wordnik.swagger.codegen.languages.ScalatraServerCodegen diff --git a/modules/swagger-codegen/src/main/resources/android-java/build.mustache b/modules/swagger-codegen/src/main/resources/android-java/build.mustache index 62a56bf066e..66fcef2a371 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/build.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/build.mustache @@ -60,10 +60,10 @@ dependencies { compile "com.google.code.gson:gson:$gson_version" compile "org.apache.httpcomponents:httpcore:$httpclient_version" compile "org.apache.httpcomponents:httpclient:$httpclient_version" - compile ("org.apache.httpcomponents:httpcore:$httpcore_version") { + compile ("org.apache.httpcomponents:httpcore:$httpclient_version") { exclude(group: 'org.apache.httpcomponents', module: 'httpclient') } - compile ("org.apache.httpcomponents:httpmime:$httpmime_version") { + compile ("org.apache.httpcomponents:httpmime:$httpclient_version") { exclude(group: 'org.apache.httpcomponents', module: 'httpclient') } testCompile "junit:junit:$junit_version" diff --git a/modules/swagger-codegen/src/main/resources/android-java/jsonUtil.mustache b/modules/swagger-codegen/src/main/resources/android-java/jsonUtil.mustache index 3a6ff4111d1..ae8d18d3731 100644 --- a/modules/swagger-codegen/src/main/resources/android-java/jsonUtil.mustache +++ b/modules/swagger-codegen/src/main/resources/android-java/jsonUtil.mustache @@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.List; -import io.swagger.client.model.*; +import {{modelPackage}}.*; public class JsonUtil { public static GsonBuilder gsonBuilder; diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache new file mode 100644 index 00000000000..ad57cffdf34 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -0,0 +1,217 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using RestSharp; + +namespace {{invokerPackage}} { + /// + /// API client is mainly responible for making the HTTP call to the API backend + /// + public class ApiClient { + + /// + /// Initializes a new instance of the class. + /// + /// The base path. + public ApiClient(String basePath="{{basePath}}") { + this.basePath = basePath; + this.restClient = new RestClient(this.basePath); + } + + /// + /// Gets or sets the base path. + /// + /// The base path. + public string basePath { get; set; } + + /// + /// Gets or sets the RestClient + /// + /// The RestClient. + public RestClient restClient { get; set; } + + private Dictionary defaultHeaderMap = new Dictionary(); + + public Object CallApi(String Path, RestSharp.Method Method, Dictionary QueryParams, String PostBody, + Dictionary HeaderParams, Dictionary FormParams, Dictionary FileParams, String[] AuthSettings) { + var response = Task.Run(async () => { + var resp = await CallApiAsync(Path, Method, QueryParams, PostBody, HeaderParams, FormParams, FileParams, AuthSettings); + return resp; + }); + return response.Result; + } + + public async Task CallApiAsync(String Path, RestSharp.Method Method, Dictionary QueryParams, String PostBody, + Dictionary HeaderParams, Dictionary FormParams, Dictionary FileParams, String[] AuthSettings) { + + var request = new RestRequest(Path, Method); + + UpdateParamsForAuth(QueryParams, HeaderParams, AuthSettings); + + // add default header, if any + foreach(KeyValuePair defaultHeader in this.defaultHeaderMap) + request.AddHeader(defaultHeader.Key, defaultHeader.Value); + + // add header parameter, if any + foreach(KeyValuePair param in HeaderParams) + request.AddHeader(param.Key, param.Value); + + // add query parameter, if any + foreach(KeyValuePair param in QueryParams) + request.AddQueryParameter(param.Key, param.Value); + + // add form parameter, if any + foreach(KeyValuePair param in FormParams) + request.AddParameter(param.Key, param.Value); + + // add file parameter, if any + foreach(KeyValuePair param in FileParams) + request.AddFile(param.Key, param.Value); + + if (PostBody != null) { + request.AddParameter("application/json", PostBody, ParameterType.RequestBody); // http body (model) parameter + } + + return (Object) await restClient.ExecuteTaskAsync(request); + + } + + /// + /// Add default header + /// + /// Header field name + /// Header field value + /// + public void AddDefaultHeader(string key, string value) { + defaultHeaderMap.Add(key, value); + } + + /// + /// Get default header + /// + /// Dictionary of default header + public Dictionary GetDefaultHeader() { + return defaultHeaderMap; + } + + /// + /// escape string (url-encoded) + /// + /// String to be escaped + /// Escaped string + public string EscapeString(string str) { + return str; + } + + /// + /// if parameter is DateTime, output in ISO8601 format + /// if parameter is a list of string, join the list with "," + /// otherwise just return the string + /// + /// The parameter (header, path, query, form) + /// Formatted string + public string ParameterToString(object obj) + { + if (obj is DateTime) { + return ((DateTime)obj).ToString ("u"); + } else if (obj is List) { + return String.Join(",", obj as List); + } else { + return Convert.ToString (obj); + } + } + + /// + /// Deserialize the JSON string into a proper object + /// + /// JSON string + /// Object type + /// Object representation of the JSON string + public object Deserialize(string content, Type type) { + if (type.GetType() == typeof(Object)) + return (Object)content; + + try + { + return JsonConvert.DeserializeObject(content, type); + } + catch (IOException e) { + throw new ApiException(500, e.Message); + } + } + + /// + /// Serialize an object into JSON string + /// + /// Object + /// JSON string + public string Serialize(object obj) { + try + { + return obj != null ? JsonConvert.SerializeObject(obj) : null; + } + catch (Exception e) { + throw new ApiException(500, e.Message); + } + } + + /// + /// Get the API key with prefix + /// + /// Object + /// API key with prefix + public string GetApiKeyWithPrefix (string apiKey) + { + var apiKeyValue = ""; + Configuration.apiKey.TryGetValue (apiKey, out apiKeyValue); + var apiKeyPrefix = ""; + if (Configuration.apiKeyPrefix.TryGetValue (apiKey, out apiKeyPrefix)) { + return apiKeyPrefix + " " + apiKeyValue; + } else { + return apiKeyValue; + } + } + + /// + /// Update parameters based on authentication + /// + /// Query parameters + /// Header parameters + /// Authentication settings + public void UpdateParamsForAuth(Dictionary QueryParams, Dictionary HeaderParams, string[] AuthSettings) { + if (AuthSettings == null || AuthSettings.Length == 0) + return; + + foreach (string auth in AuthSettings) { + // determine which one to use + switch(auth) { + {{#authMethods}} + case "{{name}}": + {{#isApiKey}}{{#isKeyInHeader}}HeaderParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInHeader}}{{#isKeyInQuery}}QueryParams["{{keyParamName}}"] = GetApiKeyWithPrefix("{{keyParamName}}");{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}HeaderParams["Authorization"] = "Basic " + Base64Encode(Configuration.username + ":" + Configuration.password);{{/isBasic}} + {{#isOAuth}}//TODO support oauth{{/isOAuth}} + break; + {{/authMethods}} + default: + //TODO show warning about security definition not found + break; + } + } + + } + + /// + /// Encode string in base64 format + /// + /// String to be encoded + public static string Base64Encode(string text) { + var textByte = System.Text.Encoding.UTF8.GetBytes(text); + return System.Convert.ToBase64String(textByte); + } + + } +} diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache new file mode 100644 index 00000000000..1f5c00a356d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using {{invokerPackage}}; + +namespace {{invokerPackage}} { + /// + /// Represents a set of configuration settings + /// + public class Configuration{ + + /// + /// Gets or sets the API client. This is the default API client for making HTTP calls. + /// + /// The API client. + public static ApiClient apiClient = new ApiClient(); + + /// + /// Gets or sets the username (HTTP basic authentication) + /// + /// The username. + public static String username { get; set; } + + /// + /// Gets or sets the password (HTTP basic authentication) + /// + /// The password. + public static String password { get; set; } + + /// + /// Gets or sets the API key based on the authentication name + /// + /// The API key. + public static Dictionary apiKey = new Dictionary(); + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name + /// + /// The prefix of the API key. + public static Dictionary apiKeyPrefix = new Dictionary(); + + + } +} diff --git a/modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll b/modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll new file mode 100644 index 00000000000..c1da1b588cd Binary files /dev/null and b/modules/swagger-codegen/src/main/resources/csharp/RestSharp.dll differ diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 7d69bea2488..117446441fa 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -12,118 +12,155 @@ namespace {{package}} { public interface I{{classname}} { {{#operation}} + /// + /// {{summary}} {{notes}} + /// + {{#allParams}}/// {{description}}{{/allParams}} + /// {{#returnType}}{{{returnType}}}{{/returnType}} {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + /// + /// {{summary}} {{notes}} + /// + {{#allParams}}/// {{description}}{{/allParams}} + /// {{#returnType}}{{{returnType}}}{{/returnType}} {{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); {{/operation}} } + /// + /// Represents a collection of functions to interact with the API endpoints + /// public class {{classname}} : I{{classname}} { - string basePath; - protected RestClient restClient; - - public {{classname}}(String basePath = "{{basePath}}") - { - this.basePath = basePath; - this.restClient = new RestClient(basePath); - } /// - /// Sets the endpoint base url for the services being accessed + /// Initializes a new instance of the class. /// - /// Base URL + /// an instance of ApiClient (optional) /// - public void SetBasePath(string basePath) { - this.basePath = basePath; + public {{classname}}(ApiClient apiClient = null) { + if (apiClient == null) { // use the default one in Configuration + this.apiClient = Configuration.apiClient; + } else { + this.apiClient = apiClient; + } } /// - /// Gets the endpoint base url for the services being accessed - /// Base URL + /// Initializes a new instance of the class. /// - public String GetBasePath() { - return this.basePath; + /// + public {{classname}}(String basePath) + { + this.apiClient = new ApiClient(basePath); } + /// + /// Sets the base path of the API client. + /// + /// The base path + public void SetBasePath(String basePath) { + this.apiClient.basePath = basePath; + } + + /// + /// Gets the base path of the API client. + /// + /// The base path + public String GetBasePath(String basePath) { + return this.apiClient.basePath; + } + + /// + /// Gets or sets the API client. + /// + /// The API client + public ApiClient apiClient {get; set;} + + {{#operation}} - /// /// {{summary}} {{notes}} /// -{{#allParams}} /// {{description}} -{{/allParams}} + {{#allParams}}/// {{description}}{{/allParams}} /// {{#returnType}}{{{returnType}}}{{/returnType}} public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { - var _request = new RestRequest("{{path}}", Method.{{httpMethod}}); - {{#allParams}}{{#required}} // verify the required parameter '{{paramName}}' is set if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}"); {{/required}}{{/allParams}} - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } - - _request.AddUrlSegment("format", "json"); // set format to json by default - {{#pathParams}}_request.AddUrlSegment("{{baseName}}", ApiInvoker.ParameterToString({{{paramName}}})); // path (url segment) parameter + var path = "{{path}}"; + path = path.Replace("{format}", "json"); + {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}})); {{/pathParams}} - {{#queryParams}} if ({{paramName}} != null) _request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // query parameter + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; + + {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter {{/queryParams}} - {{#headerParams}} if ({{paramName}} != null) _request.AddHeader("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // header parameter + {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter {{/headerParams}} - {{#formParams}}if ({{paramName}} != null) {{#isFile}}_request.AddFile("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}_request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // form parameter{{/isFile}} + {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{/formParams}} - {{#bodyParam}}_request.AddParameter("application/json", ApiInvoker.Serialize({{paramName}}), ParameterType.RequestBody); // http body (model) parameter + {{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // http body (model) parameter {{/bodyParam}} + // authentication setting, if any + String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content); } - {{#returnType}}return ({{{returnType}}}) ApiInvoker.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} + {{#returnType}}return ({{{returnType}}}) apiClient.Deserialize(response.Content, typeof({{{returnType}}}));{{/returnType}}{{^returnType}} return;{{/returnType}} } /// /// {{summary}} {{notes}} /// -{{#allParams}} /// {{description}} -{{/allParams}} + {{#allParams}}/// {{description}}{{/allParams}} /// {{#returnType}}{{{returnType}}}{{/returnType}} public async {{#returnType}}Task<{{{returnType}}}>{{/returnType}}{{^returnType}}Task{{/returnType}} {{nickname}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { - var _request = new RestRequest("{{path}}", Method.{{httpMethod}}); - {{#allParams}}{{#required}} - // verify the required parameter '{{paramName}}' is set - if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}"); + // verify the required parameter '{{paramName}}' is set + if ({{paramName}} == null) throw new ApiException(400, "Missing required parameter '{{paramName}}' when calling {{nickname}}"); {{/required}}{{/allParams}} - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } - - _request.AddUrlSegment("format", "json"); // set format to json by default - {{#pathParams}}_request.AddUrlSegment("{{baseName}}", ApiInvoker.ParameterToString({{{paramName}}})); // path (url segment) parameter + var path = "{{path}}"; + path = path.Replace("{format}", "json"); + {{#pathParams}}path = path.Replace("{" + "{{baseName}}" + "}", apiClient.ParameterToString({{{paramName}}})); {{/pathParams}} - {{#queryParams}} if ({{paramName}} != null) _request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // query parameter + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; + + {{#queryParams}} if ({{paramName}} != null) queryParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // query parameter {{/queryParams}} - {{#headerParams}} if ({{paramName}} != null) _request.AddHeader("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // header parameter + {{#headerParams}} if ({{paramName}} != null) headerParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // header parameter {{/headerParams}} - {{#formParams}}if ({{paramName}} != null) {{#isFile}}_request.AddFile("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}_request.AddParameter("{{baseName}}", ApiInvoker.ParameterToString({{paramName}})); // form parameter{{/isFile}} + {{#formParams}}if ({{paramName}} != null) {{#isFile}}fileParams.Add("{{baseName}}", {{paramName}});{{/isFile}}{{^isFile}}formParams.Add("{{baseName}}", apiClient.ParameterToString({{paramName}})); // form parameter{{/isFile}} {{/formParams}} - {{#bodyParam}}_request.AddParameter("application/json", ApiInvoker.Serialize({{paramName}}), ParameterType.RequestBody); // http body (model) parameter + {{#bodyParam}}postBody = apiClient.Serialize({{paramName}}); // http body (model) parameter {{/bodyParam}} + // authentication setting, if any + String[] authSettings = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} }; + // make the HTTP request - IRestResponse response = await restClient.ExecuteTaskAsync(_request); + IRestResponse response = (IRestResponse) await apiClient.CallApiAsync(path, Method.{{httpMethod}}, queryParams, postBody, headerParams, formParams, fileParams, authSettings); if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling {{nickname}}: " + response.Content, response.Content); } diff --git a/modules/swagger-codegen/src/main/resources/csharp/apiException.mustache b/modules/swagger-codegen/src/main/resources/csharp/apiException.mustache index 5b2509d0f0b..aee6302d025 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/apiException.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/apiException.mustache @@ -1,15 +1,29 @@ using System; namespace {{invokerPackage}} { - + /// + /// API Exception + /// public class ApiException : Exception { - + /// + /// Gets or sets the error code (HTTP status code) + /// + /// The error code (HTTP status code). public int ErrorCode { get; set; } public dynamic ErrorContent { get; private set; } + /// + /// Initializes a new instance of the class. + /// + /// The base path. public ApiException() {} + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. public ApiException(int errorCode, string message) : base(message) { this.ErrorCode = errorCode; } diff --git a/modules/swagger-codegen/src/main/resources/csharp/apiInvoker.mustache b/modules/swagger-codegen/src/main/resources/csharp/apiInvoker.mustache deleted file mode 100644 index 9760e44d81a..00000000000 --- a/modules/swagger-codegen/src/main/resources/csharp/apiInvoker.mustache +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using Newtonsoft.Json; - -namespace {{invokerPackage}} { - public class ApiInvoker { - private static Dictionary defaultHeaderMap = new Dictionary(); - - /// - /// Add default header - /// - /// Header field name - /// Header field value - /// - public static void AddDefaultHeader(string key, string value) { - defaultHeaderMap.Add(key, value); - } - - /// - /// Get default header - /// - /// Dictionary of default header - public static Dictionary GetDefaultHeader() { - return defaultHeaderMap; - } - - /// - /// escape string (url-encoded) - /// - /// String to be escaped - /// Escaped string - public static string EscapeString(string str) { - return str; - } - - /// - /// if parameter is DateTime, output in ISO8601 format, otherwise just return the string - /// - /// The parameter (header, path, query, form) - /// Formatted string - public static string ParameterToString(object obj) - { - return (obj is DateTime) ? ((DateTime)obj).ToString ("u") : Convert.ToString (obj); - } - - /// - /// Deserialize the JSON string into a proper object - /// - /// JSON string - /// Object type - /// Object representation of the JSON string - public static object Deserialize(string content, Type type) { - if (type.GetType() == typeof(Object)) - return (Object)content; - - try - { - return JsonConvert.DeserializeObject(content, type); - } - catch (IOException e) { - throw new ApiException(500, e.Message); - } - } - - /// - /// Serialize an object into JSON string - /// - /// Object - /// JSON string - public static string Serialize(object obj) { - try - { - return obj != null ? JsonConvert.SerializeObject(obj) : null; - } - catch (Exception e) { - throw new ApiException(500, e.Message); - } - } - } -} diff --git a/modules/swagger-codegen/src/main/resources/csharp/compile.mustache b/modules/swagger-codegen/src/main/resources/csharp/compile.mustache index be16fb1636e..ed4481bb4bb 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/compile.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/compile.mustache @@ -1,2 +1,3 @@ SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319 -%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs /doc:bin/{{invokerPackage}}.xml \ No newline at end of file +%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll;bin/RestSharp.dll /target:library /out:bin/{{invokerPackage}}.dll /recurse:src\*.cs /doc:bin/{{invokerPackage}}.xml + diff --git a/modules/swagger-codegen/src/main/resources/csharp/model.mustache b/modules/swagger-codegen/src/main/resources/csharp/model.mustache index a8a3aa3a7a2..ce0e62de192 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/model.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/model.mustache @@ -3,10 +3,15 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; {{#models}} {{#model}} namespace {{package}} { + + /// + /// {{description}} + /// [DataContract] public class {{classname}} { {{#vars}} @@ -15,6 +20,11 @@ namespace {{package}} { public {{{datatype}}} {{name}} { get; set; } {{/vars}} + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class {{classname}} {\n"); @@ -24,7 +34,16 @@ namespace {{package}} { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} {{/model}} {{/models}} } diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h index cd6f52db5c6..250811c4016 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.h @@ -3,7 +3,7 @@ /** * A key for `NSError` user info dictionaries. - * + * * The corresponding value is the parsed response body for an HTTP error. */ extern NSString *const SWGResponseObjectErrorKey; @@ -20,56 +20,197 @@ extern NSString *const SWGResponseObjectErrorKey; @property(nonatomic, assign) BOOL logHTTP; @property(nonatomic, readonly) NSOperationQueue* queue; +/** + * Get the Api Client instance from pool + * + * @param baseUrl The base url of api client. + * + * @return The SWGApiClient instance. + */ +(SWGApiClient *)sharedClientFromPool:(NSString *)baseUrl; +/** + * Get the operations queue + * + * @return The `shardQueue` static variable. + */ +(NSOperationQueue*) sharedQueue; +/** + * Turn on logging + * + * @param state logging state, must be `YES` or `NO` + */ +(void)setLoggingEnabled:(bool) state; +/** + * Clear Cache + */ +(void)clearCache; +/** + * Turn on cache + * + * @param enabled If the cached is enable, must be `YES` or `NO` + */ +(void)setCacheEnabled:(BOOL) enabled; +/** + * Get the request queue size + * + * @return The size of `queuedRequests` static variable. + */ +(unsigned long)requestQueueSize; +/** + * Set the client unreachable + * + * @param state off line state, must be `YES` or `NO` + */ +(void) setOfflineState:(BOOL) state; +/** + * Get the client reachability + * + * @return The client reachability. + */ +(AFNetworkReachabilityStatus) getReachabilityStatus; +/** + * Get the next request id + * + * @return The next executed request id. + */ +(NSNumber*) nextRequestId; +/** + * Generate request id and add it to the queue + * + * @return The next executed request id. + */ +(NSNumber*) queueRequest; +/** + * Remove request id from the queue + * + * @param requestId The request which will be removed. + */ +(void) cancelRequest:(NSNumber*)requestId; +/** + * URL encode NSString + * + * @param unescaped The string which will be escaped. + * + * @return The escaped string. + */ +(NSString*) escape:(id)unescaped; +/** + * Customize the behavior when the reachability changed + * + * @param changeBlock The block will be executed when the reachability changed. + */ +(void) setReachabilityChangeBlock:(void(^)(int))changeBlock; +/** + * Set the client reachability strategy + * + * @param host The host of SWGApiClient. + */ +(void) configureCacheReachibilityForHost:(NSString*)host; +/** + * Detect Accept header from accepts NSArray + * + * @param accepts NSArray of header + * + * @return The Accept header + */ +(NSString *) selectHeaderAccept:(NSArray *)accepts; + +/** + * Detect Content-Type header from contentTypes NSArray + * + * @param contentTypes NSArray of header + * + * @return The Content-Type header + */ +(NSString *) selectHeaderContentType:(NSArray *)contentTypes; +/** + * Set header for request + * + * @param value The header value + * @param forKey The header key + */ -(void)setHeaderValue:(NSString*) value - forKey:(NSString*) forKey; + forKey:(NSString*) forKey; +/** + * Update header parameters and query parameters for authentication + * + * @param headers The header parameter will be udpated, passed by pointer to pointer. + * @param querys The query parameters will be updated, passed by pointer to pointer. + * @param authSettings The authentication names NSArray. + */ +- (void) updateHeaderParams:(NSDictionary **)headers + queryParams:(NSDictionary **)querys + WithAuthSettings:(NSArray *)authSettings; + +/** + * Perform request + * + * Request with non-empty response + * + * @param path Request url. + * @param method Request method. + * @param queryParams Request query parameters. + * @param body Request body. + * @param headerParams Request header parameters. + * @param authSettings Request authentication names. + * @param requestContentType Request content-type. + * @param responseContentType Response content-type. + * @param completionBlock The block will be executed when the request completed. + * + * @return The request id. + */ -(NSNumber*) dictionary:(NSString*) path method:(NSString*) method queryParams:(NSDictionary*) queryParams body:(id) body headerParams:(NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType:(NSString*) requestContentType responseContentType:(NSString*) responseContentType completionBlock:(void (^)(NSDictionary*, NSError *))completionBlock; +/** + * Perform request + * + * Request with empty response + * + * @param path Request url. + * @param method Request method. + * @param queryParams Request query parameters. + * @param body Request body. + * @param headerParams Request header parameters. + * @param authSettings Request authentication names. + * @param requestContentType Request content-type. + * @param responseContentType Response content-type. + * @param completionBlock The block will be executed when the request completed. + * + * @return The request id. + */ -(NSNumber*) stringWithCompletionBlock:(NSString*) path method:(NSString*) method queryParams:(NSDictionary*) queryParams body:(id) body headerParams:(NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType:(NSString*) requestContentType responseContentType:(NSString*) responseContentType completionBlock:(void (^)(NSString*, NSError *))completionBlock; @end + diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m index 15dbee07459..5e2985bbe79 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient.m @@ -1,6 +1,7 @@ #import "SWGApiClient.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" +#import "SWGConfiguration.h" @implementation SWGApiClient @@ -15,10 +16,22 @@ static NSOperationQueue* sharedQueue; static void (^reachabilityChangeBlock)(int); static bool loggingEnabled = true; +#pragma mark - Log Methods + +(void)setLoggingEnabled:(bool) state { loggingEnabled = state; } +- (void)logRequest:(NSURLRequest*)request { + NSLog(@"request: %@", [self descriptionForRequest:request]); +} + +- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error { + NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data ); +} + +#pragma mark - + +(void)clearCache { [[NSURLCache sharedURLCache] removeAllCachedResponses]; } @@ -134,10 +147,12 @@ static bool loggingEnabled = true; } +(NSNumber*) nextRequestId { - long nextId = ++requestId; - if(loggingEnabled) - NSLog(@"got id %ld", nextId); - return [NSNumber numberWithLong:nextId]; + @synchronized(self) { + long nextId = ++requestId; + if(loggingEnabled) + NSLog(@"got id %ld", nextId); + return [NSNumber numberWithLong:nextId]; + } } +(NSNumber*) queueRequest { @@ -303,19 +318,47 @@ static bool loggingEnabled = true; return [[request URL] absoluteString]; } -- (void)logRequest:(NSURLRequest*)request { - NSLog(@"request: %@", [self descriptionForRequest:request]); + +/** + * Update header and query params based on authentication settings + */ +- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers + queryParams:(NSDictionary *__autoreleasing *)querys + WithAuthSettings:(NSArray *)authSettings { + + if (!authSettings || [authSettings count] == 0) { + return; + } + + NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers]; + NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys]; + + SWGConfiguration *config = [SWGConfiguration sharedConfig]; + for (NSString *auth in authSettings) { + NSDictionary *authSetting = [[config authSettings] objectForKey:auth]; + + if (authSetting) { + if ([authSetting[@"in"] isEqualToString:@"header"]) { + [headersWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]]; + } + else if ([authSetting[@"in"] isEqualToString:@"query"]) { + [querysWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]]; + } + } + } + + *headers = [NSDictionary dictionaryWithDictionary:headersWithAuth]; + *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } -- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error { - NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data ); -} +#pragma mark - Perform Request Methods -(NSNumber*) dictionary: (NSString*) path method: (NSString*) method queryParams: (NSDictionary*) queryParams body: (id) body headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType: (NSString*) requestContentType responseContentType: (NSString*) responseContentType completionBlock: (void (^)(NSDictionary*, NSError *))completionBlock { @@ -340,6 +383,9 @@ static bool loggingEnabled = true; else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; } + + // auth setting + [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; NSMutableURLRequest * request = nil; if (body != nil && [body isKindOfClass:[NSArray class]]){ @@ -474,6 +520,7 @@ static bool loggingEnabled = true; queryParams: (NSDictionary*) queryParams body: (id) body headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType: (NSString*) requestContentType responseContentType: (NSString*) responseContentType completionBlock: (void (^)(NSString*, NSError *))completionBlock { @@ -498,6 +545,9 @@ static bool loggingEnabled = true; else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; } + + // auth setting + [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; NSMutableURLRequest * request = nil; if (body != nil && [body isKindOfClass:[NSArray class]]){ diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-body.mustache new file mode 100644 index 00000000000..1e5e7135574 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-body.mustache @@ -0,0 +1,99 @@ +#import "SWGConfiguration.h" + +@interface SWGConfiguration () + +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKey; +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKeyPrefix; + +@end + +@implementation SWGConfiguration + +#pragma mark - Singletion Methods + ++ (instancetype) sharedConfig { + static SWGConfiguration *shardConfig = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shardConfig = [[self alloc] init]; + }); + return shardConfig; +} + +#pragma mark - Initialize Methods + +- (instancetype) init { + self = [super init]; + if (self) { + self.username = @""; + self.password = @""; + self.mutableApiKey = [NSMutableDictionary dictionary]; + self.mutableApiKeyPrefix = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - Instance Methods + +- (NSString *) getApiKeyWithPrefix:(NSString *)key { + if ([self.apiKeyPrefix objectForKey:key] && [self.apiKey objectForKey:key]) { + return [NSString stringWithFormat:@"%@ %@", [self.apiKeyPrefix objectForKey:key], [self.apiKey objectForKey:key]]; + } + else if ([self.apiKey objectForKey:key]) { + return [NSString stringWithFormat:@"%@", [self.apiKey objectForKey:key]]; + } + else { + return @""; + } +} + +- (NSString *) getBasicAuthToken { + NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", self.username, self.password]; + NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding]; + basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]]; + + return basicAuthCredentials; +} + +#pragma mark - Setter Methods + +- (void) setValue:(NSString *)value forApiKeyField:(NSString *)field { + [self.mutableApiKey setValue:value forKey:field]; +} + +- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field { + [self.mutableApiKeyPrefix setValue:value forKey:field]; +} + +#pragma mark - Getter Methods + +- (NSDictionary *) apiKey { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKey]; +} + +- (NSDictionary *) apiKeyPrefix { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKeyPrefix]; +} + +#pragma mark - + +- (NSDictionary *) authSettings { + return @{ {{#authMethods}}{{#isApiKey}} + @"{{name}}": @{ + @"type": @"api_key", + @"in": {{#isKeyInHeader}}@"header"{{/isKeyInHeader}}{{#isKeyInQuery}}@"query"{{/isKeyInQuery}}, + @"key": @"{{keyParamName}}", + @"value": [self getApiKeyWithPrefix:@"{{keyParamName}}"] + }, + {{/isApiKey}}{{#isBasic}} + @"{{name}}": @{ + @"type": @"basic", + @"in": @"header", + @"key": @"Authorization", + @"value": [self getBasicAuthToken] + }, + {{/isBasic}}{{/authMethods}} + }; +} + +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-header.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-header.mustache new file mode 100644 index 00000000000..33023ca3c6f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGConfiguration-header.mustache @@ -0,0 +1,56 @@ +#import + +@interface SWGConfiguration : NSObject + + +/** + * Api key values for Api Key type Authentication + * + * To add or remove api key, use `setValue:forApiKeyField:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKey; + +/** + * Api key prefix values to be prepend to the respective api key + * + * To add or remove prefix, use `setValue:forApiKeyPrefixField:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix; + +/** + * Usename and Password for Basic type Authentication + */ +@property (nonatomic) NSString *username; +@property (nonatomic) NSString *password; + +/** + * Get configuration singleton instance + */ ++ (instancetype) sharedConfig; + +/** + * Sets field in `apiKey` + */ +- (void) setValue:(NSString *)value forApiKeyField:(NSString*)field; + +/** + * Sets field in `apiKeyPrefix` + */ +- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field; + +/** + * Get API key (with prefix if set) + */ +- (NSString *) getApiKeyWithPrefix:(NSString *) key; + +/** + * Get Basic Auth token + */ +- (NSString *) getBasicAuthToken; + +/** + * Get Authentication Setings + */ +- (NSDictionary *) authSettings; + +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGQueryParamCollection.m b/modules/swagger-codegen/src/main/resources/objc/SWGQueryParamCollection.m index 9ce319940dd..83303045185 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGQueryParamCollection.m +++ b/modules/swagger-codegen/src/main/resources/objc/SWGQueryParamCollection.m @@ -13,4 +13,4 @@ return self; } -@end \ No newline at end of file +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache index b18790e3b6f..40d75bd806b 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-body.mustache @@ -2,7 +2,6 @@ #import "{{classname}}.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" -#import "SWGApiClient.h" {{#imports}}#import "{{import}}.h" {{/imports}} {{newline}} @@ -12,8 +11,36 @@ @end @implementation {{classname}} + static NSString * basePath = @"{{basePath}}"; +#pragma mark - Initialize methods + +- (id) init { + self = [super init]; + if (self) { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +- (id) initWithApiClient:(SWGApiClient *)apiClient { + self = [super init]; + if (self) { + if (apiClient) { + self.apiClient = apiClient; + } + else { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + } + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - + +({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { static {{classname}}* singletonAPI = nil; @@ -32,21 +59,10 @@ static NSString * basePath = @"{{basePath}}"; return basePath; } --(SWGApiClient*) apiClient { - return [SWGApiClient sharedClientFromPool:basePath]; -} - -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } --(id) init { - self = [super init]; - self.defaultHeaders = [NSMutableDictionary dictionary]; - [self apiClient]; - return self; -} - -(void) setHeaderValue:(NSString*) value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; @@ -115,6 +131,9 @@ static NSString * basePath = @"{{basePath}}"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[{{#consumes}}@"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}]]; + // Authentication setting + NSArray *authSettings = @[{{#authMethods}}@"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}}]; + id bodyDictionary = nil; {{#bodyParam}} id __body = {{paramName}}; @@ -177,8 +196,6 @@ static NSString * basePath = @"{{basePath}}"; {{/requiredParams}} {{/requiredParamCount}} - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - {{#returnContainer}} // response is in a container {{>apiBodyResponseWithContainer}}{{/returnContainer}} @@ -206,3 +223,6 @@ static NSString * basePath = @"{{basePath}}"; {{newline}} {{/operations}} @end + + + diff --git a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache index 0cdccf1b39b..65f4c39e0b3 100644 --- a/modules/swagger-codegen/src/main/resources/objc/api-header.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/api-header.mustache @@ -2,11 +2,15 @@ {{#imports}}#import "{{import}}.h" {{/imports}} #import "SWGObject.h" +#import "SWGApiClient.h" {{newline}} {{#operations}} @interface {{classname}}: NSObject +@property(nonatomic, assign)SWGApiClient *apiClient; + +-(instancetype) initWithApiClient:(SWGApiClient *)apiClient; -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +({{classname}}*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; @@ -34,4 +38,4 @@ {{/operation}} {{/operations}} -@end \ No newline at end of file +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache b/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache index 9a53eb2fa06..acaeaf2ddf5 100644 --- a/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/apiBodyResponseWithContainer.mustache @@ -1,9 +1,10 @@ // {{returnContainer}} container response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"{{httpMethod}}" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -34,4 +35,4 @@ {{/returnBaseType}} {{/isListContainer}} }]; - \ No newline at end of file + diff --git a/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache index ff2dcba7a47..da8ea063bfb 100644 --- a/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/apiNonPrimitiveResponse.mustache @@ -1,10 +1,11 @@ {{^returnTypeIsPrimitive}} // comples response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"{{httpMethod}}" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { diff --git a/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache index 8e6588c456e..d44d356526d 100644 --- a/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/apiPrimitiveResponse.mustache @@ -1,9 +1,10 @@ // primitive response type - {{#returnBaseType}}return [client stringWithCompletionBlock: requestUrl + {{#returnBaseType}}return [self.apiClient stringWithCompletionBlock: requestUrl method: @"{{httpMethod}}" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -17,7 +18,7 @@ {{/returnBaseType}} {{^returnBaseType}} // no return base type - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"{{httpMethod}}" queryParams: queryParams body: bodyDictionary @@ -32,4 +33,4 @@ completionBlock(nil); }]; {{/returnBaseType}} - \ No newline at end of file + diff --git a/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache b/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache index b128bfd21cc..7bbbc14c066 100644 --- a/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/voidResponse.mustache @@ -1,8 +1,9 @@ - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"{{httpMethod}}" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { diff --git a/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache new file mode 100644 index 00000000000..38eb2ad8dae --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/perl/Configuration.mustache @@ -0,0 +1,22 @@ +package WWW::{{invokerPackage}}::Configuration; + +use strict; +use warnings; +use utf8; + +use Log::Any qw($log); +use Carp; + +# class/static variables +our $api_client; +our $http_timeout = 180; +our $http_user_agent = 'Perl-Swagger'; + +# authenticaiton setting +our $api_key = {}; +our $api_key_prefix = {}; +our $username; +our $password; + + +1; diff --git a/modules/swagger-codegen/src/main/resources/perl/api.mustache b/modules/swagger-codegen/src/main/resources/perl/api.mustache index 131eb3a3934..5adb50344de 100644 --- a/modules/swagger-codegen/src/main/resources/perl/api.mustache +++ b/modules/swagger-codegen/src/main/resources/perl/api.mustache @@ -27,14 +27,10 @@ use Exporter; use Carp qw( croak ); use Log::Any qw($log); - -#use WWW::Swagger::Model::Category; -#use WWW::Swagger::Model::Pet; +use WWW::{{invokerPackage}}::ApiClient; +use WWW::{{invokerPackage}}::Configuration; {{#operations}} - -use WWW::{{invokerPackage}}::APIClient; - our @EXPORT_OK = qw( {{#operation}}{{{nickname}}} {{/operation}} @@ -42,7 +38,7 @@ our @EXPORT_OK = qw( sub new { my $class = shift; - my $default_api_client = WWW::{{invokerPackage}}::APIClient->new; + my $default_api_client = $WWW::{{invokerPackage}}::Configuration::api_client ? $WWW::{{invokerPackage}}::Configuration::api_client : WWW::{{invokerPackage}}::ApiClient->new; my (%self) = ( 'api_client' => $default_api_client, @_ @@ -92,49 +88,49 @@ sub new { } $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type({{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}); - {{#queryParams}} # query params + {{#queryParams}}# query params if ( exists $args{'{{paramName}}'}) { - $query_params->{'{{baseName}}'} = WWW::{{invokerPacakge}}::APIClient::to_query_value($args{'{{paramName}}'}); + $query_params->{'{{baseName}}'} = $self->{api_client}->to_query_value($args{'{{paramName}}'}); }{{/queryParams}} - {{#headerParams}} # header params + {{#headerParams}}# header params if ( exists $args{'{{paramName}}'}) { - $header_params->{'{{baseName}}'} = WWW::{{invokerPackage}}::APIClient::to_header_value($args{'{{paramName}}'}); + $header_params->{'{{baseName}}'} = $self->{api_client}->to_header_value($args{'{{paramName}}'}); }{{/headerParams}} - {{#pathParams}} # path params + {{#pathParams}}# path params if ( exists $args{'{{paramName}}'}) { my $_base_variable = "{" . "{{baseName}}" . "}"; - my $_base_value = WWW::{{invokerPackage}}::APIClient::to_path_value($args{'{{paramName}}'}); + my $_base_value = $self->{api_client}->to_path_value($args{'{{paramName}}'}); $_resource_path =~ s/$_base_variable/$_base_value/g; }{{/pathParams}} - {{#formParams}} # form params + {{#formParams}}# form params if ( exists $args{'{{paramName}}'} ) { {{#isFile}}$form_params->{'{{baseName}}'} = [] unless defined $form_params->{'{{baseName}}'}; push $form_params->{'{{baseName}}'}, $args{'{{paramName}}'}; {{/isFile}} - {{^isFile}}$form_params->{'{{baseName}}'} = WWW::{{invokerPackage}}::APIClient::to_form_value($args{'{{paramName}}'}); + {{^isFile}}$form_params->{'{{baseName}}'} = $self->{api_client}->to_form_value($args{'{{paramName}}'}); {{/isFile}} }{{/formParams}} my $_body_data; - {{#bodyParams}} # body params + {{#bodyParams}}# body params if ( exists $args{'{{paramName}}'}) { $_body_data = $args{'{{paramName}}'}; }{{/bodyParams}} - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]; # make the API Call {{#returnType}}my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('{{returnType}}', $response); - return $_response_object;{{/returnType}} + my $_response_object = $self->{api_client}->deserialize('{{returnType}}', $response); + return $_response_object;{{/returnType}} {{^returnType}}$self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; {{/returnType}} } diff --git a/modules/swagger-codegen/src/main/resources/perl/APIClient.mustache b/modules/swagger-codegen/src/main/resources/perlApiClient.mustache similarity index 58% rename from modules/swagger-codegen/src/main/resources/perl/APIClient.mustache rename to modules/swagger-codegen/src/main/resources/perlApiClient.mustache index 19079a07922..2bcdd6da690 100644 --- a/modules/swagger-codegen/src/main/resources/perl/APIClient.mustache +++ b/modules/swagger-codegen/src/main/resources/perlApiClient.mustache @@ -1,9 +1,10 @@ -package WWW::{{invokerPackage}}::APIClient; +package WWW::{{invokerPackage}}::ApiClient; use strict; use warnings; use utf8; +use MIME::Base64; use LWP::UserAgent; use HTTP::Headers; use HTTP::Response; @@ -15,20 +16,18 @@ use URI::Escape; use Scalar::Util; use Log::Any qw($log); use Carp; -use Switch; use Module::Runtime qw(use_module); -# class variables -my $ua = LWP::UserAgent->new; -my $http_user_agent = 'Perl-Swagger'; # HTTP user-agent -my $http_timeout; #timeout -my $base_url = "{{basePath}}"; - +use WWW::{{invokerPackage}}::Configuration; sub new { my $class = shift; - my %args = @_; + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'base_url' => '{{basePath}}', + @_ + ); return bless \%args, $class; } @@ -38,8 +37,8 @@ sub new # @param string $user_agent The user agent of the API client # sub set_user_agent { - my $user_agent = shift; - $http_user_agent= $user_agent; + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; } # Set timeout @@ -47,11 +46,11 @@ sub set_user_agent { # @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] # sub set_timeout { - my $seconds = shift; + my ($self, $seconds) = @_; if (!looks_like_number($seconds)) { croak('Timeout variable must be numeric.'); } - $http_timeout = $seconds; + $self->{http_timeout} = $seconds; } # make the HTTP request @@ -63,60 +62,63 @@ sub set_timeout { # @return mixed sub call_api { my $self = shift; - my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data) = @_; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; - my $headers = HTTP::Headers->new(%$header_params); + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); - my $_url = $base_url . $resource_path; + + my $_url = $self->{base_url} . $resource_path; # build query if (%$query_params) { $_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify }); } + # body data $body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string my $_body_data = %$post_params ? $post_params : $body_data; # Make the HTTP request my $_request; - switch ($method) { - case 'POST' { + if ($method eq 'POST') { # multipart - my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? 'form-data' : $header_params->{'Content-Type'}; - - $_request = POST($_url, Accept => $header_params->{Accept}, - Content_Type => $_content_type, Content => $_body_data); - } - case 'PUT' { - # multipart - my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ? - 'form-data' : $header_params->{'Content-Type'}; - $_request = PUT($_url, Accept => $header_params->{Accept}, - Content_Type => $_content_type, Content => $_body_data); - } - case 'GET' { - $_request = GET($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}); - } - case 'HEAD' { - $_request = HEAD($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}); - } - case 'DELETE' { #TODO support form data - $_request = DELETE($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}, Content => $_body_data); - } - case 'PATCH' { #TODO - } + + $_request = POST($_url, %$header_params, Content => $_body_data); } + elsif ($method eq 'PUT') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = PUT($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'GET') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = GET($_url, %$header_params); + } + elsif ($method eq 'HEAD') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = HEAD($_url,%$header_params); + } + elsif ($method eq 'DELETE') { #TODO support form data + my $headers = HTTP::Headers->new(%$header_params); + $_request = DELETE($_url, %$headers); + } + elsif ($method eq 'PATCH') { #TODO + } + else { + } - $ua->timeout($http_timeout); - $ua->agent($http_user_agent); + $self->{ua}->timeout($self->{http_timeout} || $WWW::{{invokerPackage}}::Configuration::http_timeout); + $self->{ua}->agent($self->{http_user_agent} || $WWW::{{invokerPackage}}::Configuration::http_user_agent); - my $_response = $ua->request($_request); + my $_response = $self->{ua}->request($_request); unless ($_response->is_success) { croak("API Exception(".$_response->code."): ".$_response->message); @@ -126,41 +128,13 @@ sub call_api { } - -# Build a JSON POST object -sub sanitize_for_serialization -{ -# my $data = shift; -# if (is_scalar($data) || null === $data) { -# $sanitized = $data; -# } else if ($data instanceof \DateTime) { -# $sanitized = $data->format(\DateTime::ISO8601); -# } else if (is_array($data)) { -# foreach ($data as $property => $value) { -# $data[$property] = $this->sanitizeForSerialization($value); -# } -# $sanitized = $data; -# } else if (is_object($data)) { -# $values = array(); -# foreach (array_keys($data::$swaggerTypes) as $property) { -# $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); -# } -# $sanitized = $values; -# } else { -# $sanitized = (string)$data; -# } -# -# return $sanitized; -} - - # Take value and turn it into a string suitable for inclusion in # the path, by url-encoding. # @param string $value a string which will be part of the path # @return string the serialized object sub to_path_value { - my $value = shift; - return uri_escape(to_string($value)); + my ($self, $value) = @_; + return uri_escape($self->to_string($value)); } @@ -171,11 +145,11 @@ sub to_path_value { # @param object $object an object to be serialized to a string # @return string the serialized object sub to_query_value { - my $object = shift; + my ($self, $object) = @_; if (is_array($object)) { return implode(',', $object); } else { - return toString($object); + return $self->to_string($object); } } @@ -186,8 +160,8 @@ sub to_query_value { # @param string $value a string which will be part of the header # @return string the header string sub to_header_value { - my $value = shift; - return to_string($value); + my ($self, $value) = @_; + return $self->to_string($value); } # Take value and turn it into a string suitable for inclusion in @@ -196,8 +170,8 @@ sub to_header_value { # @param string $value the value of the form parameter # @return string the form string sub to_form_value { - my $value = shift; - return to_string($value); + my ($self, $value) = @_; + return $self->to_string($value); } # Take value and turn it into a string suitable for inclusion in @@ -206,7 +180,7 @@ sub to_form_value { # @param string $value the value of the parameter # @return string the header string sub to_string { - my $value = shift; + my ($self, $value) = @_; if (ref($value) eq "DateTime") { # datetime in ISO8601 format return $value->datetime(); } @@ -242,7 +216,7 @@ sub deserialize $_result = \@_values; } elsif ($class eq 'DateTime') { $_result = DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$data$/, ('string', 'int', 'float', 'bool')) { #TODO revise the primitive type + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type $_result= $data; } else { # model my $_instance = use_module("WWW::{{invokerPackage}}::Object::$class")->new; @@ -287,5 +261,44 @@ sub select_header_content_type } +# Get API key (with prefix if set) +# @param string key name +# @return string API key with the prefix +sub get_api_key_with_prefix +{ + my ($self, $api_key) = @_; + if ($WWW::{{invokerPackage}}::Configuration::api_key_prefix->{$api_key}) { + return $WWW::{{invokerPackage}}::Configuration::api_key_prefix->{$api_key}." ".$WWW::{{invokerPackage}}::Configuration::api_key->{$api_key}; + } else { + return $WWW::{{invokerPackage}}::Configuration::api_key->{$api_key}; + } +} + +# update hearder and query param based on authentication setting +# +# @param array $headerParams header parameters (by ref) +# @param array $queryParams query parameters (by ref) +# @param array $authSettings array of authentication scheme (e.g ['api_key']) +sub update_params_for_auth { + my ($self, $header_params, $query_params, $auth_settings) = @_; + + return if (!defined($auth_settings) || scalar(@$auth_settings) == 0); + + # one endpoint can have more than 1 auth settings + foreach my $auth (@$auth_settings) { + # determine which one to use + if (!defined($auth)) { + } + {{#authMethods}}elsif ($auth eq '{{name}}') { + {{#isApiKey}}{{#isKeyInHeader}}$header_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInHeader}}{{#isKeyInQuery}}$query_params->{'{{keyParamName}}'} = $self->get_api_key_with_prefix('{{keyParamName}}');{{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}$header_params->{'Authorization'} = 'Basic '.encode_base64($WWW::{{invokerPackage}}::Configuration::username.":".$WWW::{{invokerPackage}}::Configuration::password);{{/isBasic}} + {{#isOAuth}}# TODO support oauth{{/isOAuth}} + } + {{/authMethods}} + else { + # TODO show warning about security definition not found + } + } +} + 1; diff --git a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache b/modules/swagger-codegen/src/main/resources/php/APIClient.mustache index 70717056b9e..f2106dc6e43 100644 --- a/modules/swagger-codegen/src/main/resources/php/APIClient.mustache +++ b/modules/swagger-codegen/src/main/resources/php/APIClient.mustache @@ -17,7 +17,7 @@ namespace {{invokerPackage}}; -class APIClient { +class ApiClient { public static $PATCH = "PATCH"; public static $POST = "POST"; @@ -173,7 +173,7 @@ class APIClient { * @param array $headerParams parameters to be place in request header * @return mixed */ - public function callAPI($resourcePath, $method, $queryParams, $postData, + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams, $authSettings) { $headers = array(); @@ -182,13 +182,10 @@ class APIClient { $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); # construct the http header - if ($headerParams != null) { - # add default header - $headerParams = array_merge((array)self::$default_header, $headerParams); + $headerParams = array_merge((array)self::$default_header, (array)$headerParams); - foreach ($headerParams as $key => $val) { - $headers[] = "$key: $val"; - } + foreach ($headerParams as $key => $val) { + $headers[] = "$key: $val"; } // form data @@ -228,35 +225,49 @@ class APIClient { curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); } else if ($method != self::$GET) { - throw new APIClientException('Method ' . $method . ' is not recognized.'); + throw new ApiException('Method ' . $method . ' is not recognized.'); } curl_setopt($curl, CURLOPT_URL, $url); // Set user agent curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + // debugging for curl + if (Configuration::$debug) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + + curl_setopt($curl, CURLOPT_VERBOSE, 1); + curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + } else { + curl_setopt($curl, CURLOPT_VERBOSE, 0); + } + + // obtain the HTTP response headers + curl_setopt($curl, CURLOPT_HEADER, 1); + // Make the request $response = curl_exec($curl); + $http_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); + $http_header = substr($response, 0, $http_header_size); + $http_body = substr($response, $http_header_size); $response_info = curl_getinfo($curl); + // debug HTTP response body + if (Configuration::$debug) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + } + // Handle the response if ($response_info['http_code'] == 0) { - throw new APIClientException("TIMEOUT: api call to " . $url . - " took more than 5s to return", 0, $response_info, $response); + throw new ApiException("API call to $url timed out: ".serialize($response_info), 0, null, null); } else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) { - $data = json_decode($response); + $data = json_decode($http_body); if (json_last_error() > 0) { // if response is a string - $data = $response; + $data = $http_body; } - } else if ($response_info['http_code'] == 401) { - throw new APIClientException("Unauthorized API request to " . $url . - ": " . serialize($response), 0, $response_info, $response); - } else if ($response_info['http_code'] == 404) { - $data = null; } else { - throw new APIClientException("Can't connect to the api: " . $url . - " response code: " . - $response_info['http_code'], 0, $response_info, $response); + throw new ApiException("[".$response_info['http_code']."] Error connecting to the API ($url)", + $response_info['http_code'], $http_header, $http_body); } return $data; } @@ -278,7 +289,9 @@ class APIClient { } else if (is_object($data)) { $values = array(); foreach (array_keys($data::$swaggerTypes) as $property) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); + if ($data->$property !== null) { + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); + } } $sanitized = $values; } else { @@ -383,7 +396,7 @@ class APIClient { $deserialized = $values; } elseif ($class == 'DateTime') { $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool'))) { + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { settype($data, $class); $deserialized = $data; } else { diff --git a/modules/swagger-codegen/src/main/resources/php/APIClientException.mustache b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache similarity index 50% rename from modules/swagger-codegen/src/main/resources/php/APIClientException.mustache rename to modules/swagger-codegen/src/main/resources/php/ApiException.mustache index 3cf74d69288..d108c3d2902 100644 --- a/modules/swagger-codegen/src/main/resources/php/APIClientException.mustache +++ b/modules/swagger-codegen/src/main/resources/php/ApiException.mustache @@ -19,20 +19,40 @@ namespace {{invokerPackage}}; use \Exception; -class APIClientException extends Exception { - protected $response, $response_info; +class ApiException extends Exception { - public function __construct($message="", $code=0, $response_info=null, $response=null) { + /** + * The HTTP body of the server response. + */ + protected $response_body; + + /** + * The HTTP header of the server response. + */ + protected $response_headers; + + public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_info = $response_info; - $this->response = $response; + $this->response_headers = $responseHeaders; + $this->response_body = $responseBody; } - public function getResponse() { - return $this->response; + /** + * Get the HTTP response header + * + * @return string HTTP response header + */ + public function getResponseHeaders() { + return $this->response_headers; } - public function getResponseInfo() { - return $this->response_info; + /** + * Get the HTTP response body + * + * @return string HTTP response body + */ + public function getResponseBody() { + return $this->response_body; } + } diff --git a/modules/swagger-codegen/src/main/resources/php/api.mustache b/modules/swagger-codegen/src/main/resources/php/api.mustache index 1c32eeb01c5..6b4e6e3db16 100644 --- a/modules/swagger-codegen/src/main/resources/php/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php/api.mustache @@ -28,7 +28,7 @@ class {{classname}} { function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { - Configuration::$apiClient = new APIClient(); // create a new API client if not present + Configuration::$apiClient = new ApiClient(); // create a new API client if not present $this->apiClient = Configuration::$apiClient; } else @@ -38,7 +38,7 @@ class {{classname}} { } } - private $apiClient; // instance of the APIClient + private $apiClient; // instance of the ApiClient /** * get the API client diff --git a/modules/swagger-codegen/src/main/resources/php/configuration.mustache b/modules/swagger-codegen/src/main/resources/php/configuration.mustache index 3eaa8dba1f1..7099a2cb234 100644 --- a/modules/swagger-codegen/src/main/resources/php/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/php/configuration.mustache @@ -19,27 +19,47 @@ namespace {{invokerPackage}}; class Configuration { - public static $PATCH = "PATCH"; - public static $POST = "POST"; - public static $GET = "GET"; - public static $PUT = "PUT"; - public static $DELETE = "DELETE"; - - // authentication setting + /** + * Associate array to store API key(s) + */ public static $apiKey = array(); + + /** + * Associate array to store API prefix (e.g. Bearer) + */ public static $apiKeyPrefix = array(); + + /** + * Username for HTTP basic authentication + */ public static $username = ''; + + /** + * Password for HTTP basic authentication + */ public static $password = ''; - // an instance of APIClient + /** + * The default instance of ApiClient + */ public static $apiClient; - /* - * manually initalize API client - */ + /** + * Debug switch (default set to false) + */ + public static $debug = false; + + /** + * Debug file location (log to STDOUT by default) + */ + public static $debug_file = 'php://output'; + + /* + * manually initalize ApiClient + */ public static function init() { if (self::$apiClient === null) - self::$apiClient = new APIClient(); + self::$apiClient = new ApiClient(); } } diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index fc779a66653..d5e24398f0e 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -29,13 +29,16 @@ from six import iteritems from ..util import remove_none -from ..swagger import ApiClient +from .. import config {{#operations}} class {{classname}}(object): - def __init__(self, api_client): - self.api_client = api_client + def __init__(self, api_client=None): + if api_client: + self.api_client = api_client + else: + self.api_client = config.api_client {{#operation}} def {{nickname}}(self, {{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}**kwargs): """ @@ -71,12 +74,12 @@ class {{classname}}(object): body_params = {{#bodyParam}}params.get('{{paramName}}'){{/bodyParam}}{{^bodyParam}}None{{/bodyParam}} # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]) + header_params['Accept'] = self.api_client.select_header_accept([{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]) + header_params['Content-Type'] = self.api_client.select_header_content_type([{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, diff --git a/modules/swagger-codegen/src/main/resources/python/config.mustache b/modules/swagger-codegen/src/main/resources/python/config.mustache new file mode 100644 index 00000000000..e8c36aee77b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/python/config.mustache @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +from .swagger import ApiClient + +# Configuration variables + +api_client = ApiClient("{{basePath}}") + diff --git a/modules/swagger-codegen/src/main/resources/python/rest.mustache b/modules/swagger-codegen/src/main/resources/python/rest.mustache index 06b817da757..da99abc2493 100644 --- a/modules/swagger-codegen/src/main/resources/python/rest.mustache +++ b/modules/swagger-codegen/src/main/resources/python/rest.mustache @@ -2,6 +2,8 @@ import sys import io import json +import ssl +import certifi # python 2 and python 3 compatibility library from six import iteritems @@ -42,10 +44,30 @@ class RESTResponse(io.IOBase): class RESTClientObject(object): def __init__(self, pools_size=4): + # http pool manager self.pool_manager = urllib3.PoolManager( num_pools=pools_size ) + # https pool manager + # certificates validated using Mozilla’s root certificates + self.ssl_pool_manager = urllib3.PoolManager( + num_pools=pools_size, + cert_reqs=ssl.CERT_REQUIRED, + ca_certs=certifi.where() + ) + + def agent(self, url): + """ + Return proper pool manager for the http\https schemes. + """ + url = urllib3.util.url.parse_url(url) + scheme = url.scheme + if scheme == 'https': + return self.ssl_pool_manager + else: + return self.pool_manager + def request(self, method, url, query_params=None, headers=None, body=None, post_params=None): """ @@ -56,7 +78,6 @@ class RESTClientObject(object): :param body: request json body, for `application/json` :param post_params: request post parameters, `application/x-www-form-urlencode` and `multipart/form-data` - :param raw_response: if return the raw response """ method = method.upper() assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'] @@ -75,27 +96,27 @@ class RESTClientObject(object): if query_params: url += '?' + urlencode(query_params) if headers['Content-Type'] == 'application/json': - r = self.pool_manager.request(method, url, - body=json.dumps(body), - headers=headers) + r = self.agent(url).request(method, url, + body=json.dumps(body), + headers=headers) if headers['Content-Type'] == 'application/x-www-form-urlencoded': - r = self.pool_manager.request(method, url, - fields=post_params, - encode_multipart=False, - headers=headers) + r = self.agent(url).request(method, url, + fields=post_params, + encode_multipart=False, + headers=headers) if headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct Content-Type # which generated by urllib3 will be overwritten. del headers['Content-Type'] - r = self.pool_manager.request(method, url, - fields=post_params, - encode_multipart=True, - headers=headers) + r = self.agent(url).request(method, url, + fields=post_params, + encode_multipart=True, + headers=headers) # For `GET`, `HEAD`, `DELETE` else: - r = self.pool_manager.request(method, url, - fields=query_params, - headers=headers) + r = self.agent(url).request(method, url, + fields=query_params, + headers=headers) r = RESTResponse(r) if r.status not in range(200, 206): diff --git a/modules/swagger-codegen/src/main/resources/python/setup.mustache b/modules/swagger-codegen/src/main/resources/python/setup.mustache index a049057c920..f1ba52d2930 100644 --- a/modules/swagger-codegen/src/main/resources/python/setup.mustache +++ b/modules/swagger-codegen/src/main/resources/python/setup.mustache @@ -12,7 +12,7 @@ from setuptools import setup, find_packages # Try reading the setuptools documentation: # http://pypi.python.org/pypi/setuptools -REQUIRES = ["urllib3 >= 1.10", "six >= 1.9"] +REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"] setup( name="{{module}}", diff --git a/modules/swagger-codegen/src/main/resources/python/swagger.mustache b/modules/swagger-codegen/src/main/resources/python/swagger.mustache index ab45eace646..21430c469c8 100644 --- a/modules/swagger-codegen/src/main/resources/python/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/python/swagger.mustache @@ -66,28 +66,28 @@ class ApiClient(object): if self.cookie: headers['Cookie'] = self.cookie if headers: - headers = ApiClient.sanitize_for_serialization(headers) + headers = self.sanitize_for_serialization(headers) # path parameters if path_params: - path_params = ApiClient.sanitize_for_serialization(path_params) + path_params = self.sanitize_for_serialization(path_params) for k, v in iteritems(path_params): replacement = quote(str(self.to_path_value(v))) resource_path = resource_path.replace('{' + k + '}', replacement) # query parameters if query_params: - query_params = ApiClient.sanitize_for_serialization(query_params) + query_params = self.sanitize_for_serialization(query_params) query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)} # post parameters if post_params: post_params = self.prepare_post_parameters(post_params, files) - post_params = ApiClient.sanitize_for_serialization(post_params) + post_params = self.sanitize_for_serialization(post_params) # body if body: - body = ApiClient.sanitize_for_serialization(body) + body = self.sanitize_for_serialization(body) # request url url = self.host + resource_path @@ -115,8 +115,7 @@ class ApiClient(object): else: return str(obj) - @staticmethod - def sanitize_for_serialization(obj): + def sanitize_for_serialization(self, obj): """ Sanitize an object for Request. @@ -132,7 +131,7 @@ class ApiClient(object): elif isinstance(obj, (str, int, float, bool, tuple)): return obj elif isinstance(obj, list): - return [ApiClient.sanitize_for_serialization(sub_obj) for sub_obj in obj] + return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() else: @@ -145,7 +144,7 @@ class ApiClient(object): obj_dict = {obj.attribute_map[key]: val for key, val in iteritems(obj.__dict__) if key != 'swagger_types' and key != 'attribute_map' and val is not None} - return {key: ApiClient.sanitize_for_serialization(val) + return {key: self.sanitize_for_serialization(val) for key, val in iteritems(obj_dict)} def deserialize(self, obj, obj_class): @@ -253,8 +252,7 @@ class ApiClient(object): return params - @staticmethod - def select_header_accept(accepts): + def select_header_accept(self, accepts): """ Return `Accept` based on an array of accepts provided """ @@ -268,8 +266,7 @@ class ApiClient(object): else: return ', '.join(accepts) - @staticmethod - def select_header_content_type(content_types): + def select_header_content_type(self, content_types): """ Return `Content-Type` baseed on an array of content_types provided """ diff --git a/modules/swagger-codegen/src/main/resources/retrofit/api.mustache b/modules/swagger-codegen/src/main/resources/retrofit/api.mustache new file mode 100644 index 00000000000..a916f363ff5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/api.mustache @@ -0,0 +1,29 @@ +package {{package}}; + +import {{modelPackage}}.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +{{#imports}}import {{import}}; +{{/imports}} + +{{#operations}} +public interface {{classname}} { + {{#operation}} + /** + * {{summary}} + * {{notes}} +{{#allParams}} * @param {{paramName}} {{description}} +{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} + */ + {{#formParams}}{{#-first}} + {{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}} + @{{httpMethod}}("{{path}}") + {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}} + {{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}} + );{{/hasMore}}{{/allParams}} + {{/operation}} +} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache new file mode 100644 index 00000000000..f8788583db5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache new file mode 100644 index 00000000000..9853bc0bf11 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache new file mode 100644 index 00000000000..29206e1546b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/model.mustache b/modules/swagger-codegen/src/main/resources/retrofit/model.mustache new file mode 100644 index 00000000000..f4446d5a1ef --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/model.mustache @@ -0,0 +1,50 @@ +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; +{{#models}} + +{{#model}}{{#description}} +/** + * {{description}} + **/{{/description}} +@ApiModel(description = "{{{description}}}") +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} { + {{#vars}}{{#isEnum}} + public enum {{datatypeWithEnum}} { + {{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}} + };{{/isEnum}} + + /**{{#description}} + * {{{description}}}{{/description}}{{#minimum}} + * minimum: {{minimum}}{{/minimum}}{{#maximum}} + * maximum: {{maximum}}{{/maximum}} + **/ + @ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") + @SerializedName("{{baseName}}"){{#isEnum}} + private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}} + private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}} + + {{#vars}} + public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + } + public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + } + {{/vars}} + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}} + {{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n"); + {{/vars}}sb.append("}\n"); + return sb.toString(); + } +} +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache new file mode 100644 index 00000000000..8a8bdc74c88 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache b/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache new file mode 100644 index 00000000000..fd631871054 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache @@ -0,0 +1,143 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + + scm:git:git@github.com:wordnik/swagger-mustache.git + scm:git:git@github.com:wordnik/swagger-codegen.git + https://github.com/wordnik/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + com.wordnik + swagger-annotations + ${swagger-annotations-version} + + + com.google.code.gson + gson + ${gson-version} + compile + + + com.squareup.retrofit + retrofit + ${retrofit-version} + compile + + + + + junit + junit + ${junit-version} + test + + + + 1.5.3-M1 + 2.3.1 + 1.9.0 + 1.0.0 + 4.12 + + diff --git a/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache new file mode 100644 index 00000000000..e0a58533e5f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@Query("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/service.mustache b/modules/swagger-codegen/src/main/resources/retrofit/service.mustache new file mode 100644 index 00000000000..218a9304071 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/service.mustache @@ -0,0 +1,23 @@ +package {{invokerPackage}}; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import retrofit.RestAdapter; +import retrofit.converter.GsonConverter; + +public class ServiceGenerator { + // No need to instantiate this class. + private ServiceGenerator() { } + + public static S createService(Class serviceClass) { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .create(); + RestAdapter adapter = new RestAdapter.Builder() + .setEndpoint("{{basePath}}") + .setConverter(new GsonConverter(gson)) + .build(); + + return adapter.create(serviceClass); + } +} diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index e9f90087db1..3e1ac14014e 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -50,8 +50,9 @@ module {{moduleName}} {{/bodyParam}}{{#bodyParam}}post_body = Swagger::Request.object_to_http_body({{#required}}{{{paramName}}}{{/required}}{{^required}}opts[:'{{{paramName}}}']{{/required}}) {{/bodyParam}} - {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body - {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] + {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body + {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil{{/returnType}} end {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache index 750e6ac5155..dd2f630a8c9 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger.mustache @@ -16,9 +16,9 @@ module {{moduleName}} # # @example # Swagger.configure do |config| - # config.api_key = '1234567890abcdef' # required - # config.username = 'wordlover' # optional, but needed for user-related functions - # config.password = 'i<3words' # optional, but needed for user-related functions + # config.api_key['api_key'] = '1234567890abcdef' # api key authentication + # config.username = 'wordlover' # http basic authentication + # config.password = 'i<3words' # http basic authentication # config.format = 'json' # optional, defaults to 'json' # end # diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache index e780a9c8e7d..e9a8af9c162 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/configuration.mustache @@ -1,8 +1,8 @@ module {{moduleName}} module Swagger class Configuration - attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent - + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Defaults go in here.. def initialize @format = 'json' @@ -13,6 +13,16 @@ module {{moduleName}} @inject_format = false @force_ending_format = false @camelize_params = true + + # keys for API key authentication (param-name => api-key) + @api_key = {} + # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) + @api_key_prefix = {} + + # whether to verify SSL certificate, default to true + # Note: do NOT set it to false in production code, otherwise you would + # face multiple types of cryptographic attacks + @verify_ssl = true end end end diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache index 14718bb6b3c..99b58d58be8 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/request.mustache @@ -5,7 +5,7 @@ module {{moduleName}} require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -16,21 +16,9 @@ module {{moduleName}} # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", - :api_key => Swagger.configuration.api_key, 'User-Agent' => Swagger.configuration.user_agent } - # api_key from headers hash trumps the default, even if its value is blank - if attributes[:headers].present? && attributes[:headers].has_key?(:api_key) - default_headers.delete(:api_key) - end - - # api_key from params hash trumps all others (headers and default_headers) - if attributes[:params].present? && attributes[:params].has_key?(:api_key) - default_headers.delete(:api_key) - attributes[:headers].delete(:api_key) if attributes[:headers].present? - end - # Merge argument headers into defaults attributes[:headers] = default_headers.merge(attributes[:headers] || {}) @@ -44,6 +32,33 @@ module {{moduleName}} attributes.each do |name, value| send("#{name.to_s.underscore.to_sym}=", value) end + + update_params_for_auth! + end + + # Update hearder and query params based on authentication settings. + def update_params_for_auth! + (@auth_names || []).each do |auth_name| + case auth_name + {{#authMethods}}when '{{name}}' + {{#isApiKey}}{{#isKeyInHeader}}@headers ||= {} + @headers['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInHeader}}{{#isKeyInQuery}}@params ||= {} + @params['{{keyParamName}}'] = get_api_key_with_prefix('{{keyParamName}}'){{/isKeyInQuery}}{{/isApiKey}}{{#isBasic}}@headers ||= {} + http_auth_header = 'Basic ' + ["#{Swagger.configuration.username}:#{Swagger.configuration.password}"].pack('m').delete("\r\n") + @headers['Authorization'] = http_auth_header{{/isBasic}}{{#isOAuth}}# TODO: support oauth{{/isOAuth}} + {{/authMethods}} + end + end + end + + # Get API key (with prefix if set). + # @param [String] param_name the parameter name of API key auth + def get_api_key_with_prefix(param_name) + if Swagger.configuration.api_key_prefix[param_name].present? + "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" + else + Swagger.configuration.api_key[param_name] + end end # Construct a base URL @@ -58,9 +73,6 @@ module {{moduleName}} # Drop trailing question mark, if present u.sub! /\?$/, '' - # Obfuscate API key? - u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated] - u end @@ -108,14 +120,16 @@ module {{moduleName}} # For form parameters, remove empty value def outgoing_body # http form - if @body.nil? && @form_params && !@form_params.empty? + if headers['Content-Type'] == 'application/x-www-form-urlencoded' data = form_params.dup data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end data - else # http body is JSON + elsif @body # http body is JSON @body.is_a?(String) ? @body : @body.to_json + else + nil end end @@ -129,7 +143,7 @@ module {{moduleName}} next if self.path.include? "{#{key}}" # skip path params next if value.blank? && value.class != FalseClass # skip empties if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param + key = key.to_s.camelize(:lower).to_sym end query_values[key] = value.to_s end @@ -148,39 +162,40 @@ module {{moduleName}} #TODO use configuration setting to determine if debugging #logger = Logger.new STDOUT #logger.debug self.url + + request_options = { + :ssl_verifypeer => Swagger.configuration.verify_ssl, + :headers => self.headers.stringify_keys + } response = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, - :headers => self.headers.stringify_keys, + request_options ) when :post,:POST Typhoeus::Request.post( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :patch,:PATCH Typhoeus::Request.patch( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :put,:PUT Typhoeus::Request.put( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :delete,:DELETE Typhoeus::Request.delete( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) end Response.new(response) diff --git a/pom.xml b/pom.xml index 6fbb36464f8..c8d223cfb2c 100644 --- a/pom.xml +++ b/pom.xml @@ -350,6 +350,18 @@ samples/client/petstore/ruby + + retrofit-client + + + env + java + + + + samples/client/petstore/retrofit + + spring-mvc diff --git a/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml b/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml new file mode 100644 index 00000000000..3042699fd86 --- /dev/null +++ b/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/samples/client/petstore/csharp/bin/RestSharp.dll b/samples/client/petstore/csharp/bin/RestSharp.dll new file mode 100644 index 00000000000..c1da1b588cd Binary files /dev/null and b/samples/client/petstore/csharp/bin/RestSharp.dll differ diff --git a/samples/client/petstore/csharp/compile.bat b/samples/client/petstore/csharp/compile.bat index 1ced2568767..63b79e03eed 100644 --- a/samples/client/petstore/csharp/compile.bat +++ b/samples/client/petstore/csharp/compile.bat @@ -1,2 +1,3 @@ SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319 -%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll /target:library /out:bin/IO.Swagger.Client.dll /recurse:src\*.cs /doc:bin/IO.Swagger.Client.xml \ No newline at end of file +%CSCPATH%\csc /reference:bin/Newtonsoft.Json.dll;bin/RestSharp.dll /target:library /out:bin/IO.Swagger.Client.dll /recurse:src\*.cs /doc:bin/IO.Swagger.Client.xml + diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs index 6a39ce7ba75..1f7ddccfb26 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/PetApi.cs @@ -6,34 +6,55 @@ using IO.Swagger.Model; namespace IO.Swagger.Api { + /// + /// Represents a collection of functions to interact with the API endpoints + /// public class PetApi { - string basePath; - protected RestClient restClient; - - public PetApi(String basePath = "http://petstore.swagger.io/v2") - { - this.basePath = basePath; - this.restClient = new RestClient(basePath); - } - /// - /// Sets the endpoint base url for the services being accessed + /// Initializes a new instance of the class. /// - /// Base URL + /// an instance of ApiClient (optional) /// - public void SetBasePath(string basePath) { - this.basePath = basePath; + public PetApi(ApiClient apiClient = null) { + if (apiClient == null) { // use the default one in Configuration + this.apiClient = Configuration.apiClient; + } else { + this.apiClient = apiClient; + } } /// - /// Gets the endpoint base url for the services being accessed - /// Base URL + /// Initializes a new instance of the class. /// - public String GetBasePath() { - return this.basePath; + /// + public PetApi(String basePath) + { + this.apiClient = new ApiClient(basePath); } - + /// + /// Sets the base path of the API client. + /// + /// The base path + public void SetBasePath(String basePath) { + this.apiClient.basePath = basePath; + } + + /// + /// Gets the base path of the API client. + /// + /// The base path + public String GetBasePath(String basePath) { + return this.apiClient.basePath; + } + + /// + /// Gets or sets the API client. + /// + /// The API client + public ApiClient apiClient {get; set;} + + /// /// Update an existing pet @@ -42,26 +63,30 @@ namespace IO.Swagger.Api { /// public void UpdatePet (Pet Body) { - var _request = new RestRequest("/pet", Method.PUT); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePet: " + response.Content); } @@ -69,7 +94,6 @@ namespace IO.Swagger.Api { return; } - /// /// Add a new pet to the store /// @@ -77,26 +101,30 @@ namespace IO.Swagger.Api { /// public void AddPet (Pet Body) { - var _request = new RestRequest("/pet", Method.POST); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling AddPet: " + response.Content); } @@ -104,7 +132,6 @@ namespace IO.Swagger.Api { return; } - /// /// Finds Pets by status Multiple status values can be provided with comma seperated strings /// @@ -112,33 +139,36 @@ namespace IO.Swagger.Api { /// List public List FindPetsByStatus (List Status) { - var _request = new RestRequest("/pet/findByStatus", Method.GET); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/findByStatus"; + path = path.Replace("{format}", "json"); + - _request.AddUrlSegment("format", "json"); // set format to json by default - - if (Status != null) _request.AddParameter("status", ApiInvoker.ParameterToString(Status)); // query parameter + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; + + if (Status != null) queryParams.Add("status", apiClient.ParameterToString(Status)); // query parameter + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByStatus: " + response.Content); } - return (List) ApiInvoker.Deserialize(response.Content, typeof(List)); + return (List) apiClient.Deserialize(response.Content, typeof(List)); } - /// /// Finds Pets by tags Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. /// @@ -146,33 +176,36 @@ namespace IO.Swagger.Api { /// List public List FindPetsByTags (List Tags) { - var _request = new RestRequest("/pet/findByTags", Method.GET); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/findByTags"; + path = path.Replace("{format}", "json"); + - _request.AddUrlSegment("format", "json"); // set format to json by default - - if (Tags != null) _request.AddParameter("tags", ApiInvoker.ParameterToString(Tags)); // query parameter + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; + + if (Tags != null) queryParams.Add("tags", apiClient.ParameterToString(Tags)); // query parameter + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling FindPetsByTags: " + response.Content); } - return (List) ApiInvoker.Deserialize(response.Content, typeof(List)); + return (List) apiClient.Deserialize(response.Content, typeof(List)); } - /// /// Find pet by ID Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions /// @@ -180,36 +213,39 @@ namespace IO.Swagger.Api { /// Pet public Pet GetPetById (long? PetId) { - var _request = new RestRequest("/pet/{petId}", Method.GET); - // verify the required parameter 'PetId' is set if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling GetPetById"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/{petId}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("petId", ApiInvoker.ParameterToString(PetId)); // path (url segment) parameter - + // authentication setting, if any + String[] authSettings = new String[] { "api_key", "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetPetById: " + response.Content); } - return (Pet) ApiInvoker.Deserialize(response.Content, typeof(Pet)); + return (Pet) apiClient.Deserialize(response.Content, typeof(Pet)); } - /// /// Updates a pet in the store with form data /// @@ -219,31 +255,35 @@ namespace IO.Swagger.Api { /// public void UpdatePetWithForm (string PetId, string Name, string Status) { - var _request = new RestRequest("/pet/{petId}", Method.POST); - // verify the required parameter 'PetId' is set if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UpdatePetWithForm"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/{petId}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("petId", ApiInvoker.ParameterToString(PetId)); // path (url segment) parameter - - if (Name != null) _request.AddParameter("name", ApiInvoker.ParameterToString(Name)); // form parameter - if (Status != null) _request.AddParameter("status", ApiInvoker.ParameterToString(Status)); // form parameter + if (Name != null) formParams.Add("name", apiClient.ParameterToString(Name)); // form parameter + if (Status != null) formParams.Add("status", apiClient.ParameterToString(Status)); // form parameter + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdatePetWithForm: " + response.Content); } @@ -251,7 +291,6 @@ namespace IO.Swagger.Api { return; } - /// /// Deletes a pet /// @@ -260,30 +299,34 @@ namespace IO.Swagger.Api { /// public void DeletePet (string ApiKey, long? PetId) { - var _request = new RestRequest("/pet/{petId}", Method.DELETE); - // verify the required parameter 'PetId' is set if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling DeletePet"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/{petId}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("petId", ApiInvoker.ParameterToString(PetId)); // path (url segment) parameter - - if (ApiKey != null) _request.AddHeader("api_key", ApiInvoker.ParameterToString(ApiKey)); // header parameter + if (ApiKey != null) headerParams.Add("api_key", apiClient.ParameterToString(ApiKey)); // header parameter + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeletePet: " + response.Content); } @@ -291,7 +334,6 @@ namespace IO.Swagger.Api { return; } - /// /// uploads an image /// @@ -301,31 +343,35 @@ namespace IO.Swagger.Api { /// public void UploadFile (long? PetId, string AdditionalMetadata, string File) { - var _request = new RestRequest("/pet/{petId}/uploadImage", Method.POST); - // verify the required parameter 'PetId' is set if (PetId == null) throw new ApiException(400, "Missing required parameter 'PetId' when calling UploadFile"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/pet/{petId}/uploadImage"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "petId" + "}", apiClient.ParameterToString(PetId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("petId", ApiInvoker.ParameterToString(PetId)); // path (url segment) parameter - - if (AdditionalMetadata != null) _request.AddParameter("additionalMetadata", ApiInvoker.ParameterToString(AdditionalMetadata)); // form parameter - if (File != null) _request.AddFile("file", File); + if (AdditionalMetadata != null) formParams.Add("additionalMetadata", apiClient.ParameterToString(AdditionalMetadata)); // form parameter + if (File != null) fileParams.Add("file", File); + // authentication setting, if any + String[] authSettings = new String[] { "petstore_auth" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UploadFile: " + response.Content); } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs index 5b4236c7a77..a789b3502a0 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/StoreApi.cs @@ -6,34 +6,55 @@ using IO.Swagger.Model; namespace IO.Swagger.Api { + /// + /// Represents a collection of functions to interact with the API endpoints + /// public class StoreApi { - string basePath; - protected RestClient restClient; - - public StoreApi(String basePath = "http://petstore.swagger.io/v2") - { - this.basePath = basePath; - this.restClient = new RestClient(basePath); - } - /// - /// Sets the endpoint base url for the services being accessed + /// Initializes a new instance of the class. /// - /// Base URL + /// an instance of ApiClient (optional) /// - public void SetBasePath(string basePath) { - this.basePath = basePath; + public StoreApi(ApiClient apiClient = null) { + if (apiClient == null) { // use the default one in Configuration + this.apiClient = Configuration.apiClient; + } else { + this.apiClient = apiClient; + } } /// - /// Gets the endpoint base url for the services being accessed - /// Base URL + /// Initializes a new instance of the class. /// - public String GetBasePath() { - return this.basePath; + /// + public StoreApi(String basePath) + { + this.apiClient = new ApiClient(basePath); } - + /// + /// Sets the base path of the API client. + /// + /// The base path + public void SetBasePath(String basePath) { + this.apiClient.basePath = basePath; + } + + /// + /// Gets the base path of the API client. + /// + /// The base path + public String GetBasePath(String basePath) { + return this.apiClient.basePath; + } + + /// + /// Gets or sets the API client. + /// + /// The API client + public ApiClient apiClient {get; set;} + + /// /// Returns pet inventories by status Returns a map of status codes to quantities @@ -41,32 +62,35 @@ namespace IO.Swagger.Api { /// Dictionary public Dictionary GetInventory () { - var _request = new RestRequest("/store/inventory", Method.GET); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/store/inventory"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - + // authentication setting, if any + String[] authSettings = new String[] { "api_key" }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetInventory: " + response.Content); } - return (Dictionary) ApiInvoker.Deserialize(response.Content, typeof(Dictionary)); + return (Dictionary) apiClient.Deserialize(response.Content, typeof(Dictionary)); } - /// /// Place an order for a pet /// @@ -74,33 +98,36 @@ namespace IO.Swagger.Api { /// Order public Order PlaceOrder (Order Body) { - var _request = new RestRequest("/store/order", Method.POST); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/store/order"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling PlaceOrder: " + response.Content); } - return (Order) ApiInvoker.Deserialize(response.Content, typeof(Order)); + return (Order) apiClient.Deserialize(response.Content, typeof(Order)); } - /// /// Find purchase order by ID For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions /// @@ -108,36 +135,39 @@ namespace IO.Swagger.Api { /// Order public Order GetOrderById (string OrderId) { - var _request = new RestRequest("/store/order/{orderId}", Method.GET); - // verify the required parameter 'OrderId' is set if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling GetOrderById"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/store/order/{orderId}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("orderId", ApiInvoker.ParameterToString(OrderId)); // path (url segment) parameter - + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetOrderById: " + response.Content); } - return (Order) ApiInvoker.Deserialize(response.Content, typeof(Order)); + return (Order) apiClient.Deserialize(response.Content, typeof(Order)); } - /// /// Delete purchase order by ID For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors /// @@ -145,29 +175,33 @@ namespace IO.Swagger.Api { /// public void DeleteOrder (string OrderId) { - var _request = new RestRequest("/store/order/{orderId}", Method.DELETE); - // verify the required parameter 'OrderId' is set if (OrderId == null) throw new ApiException(400, "Missing required parameter 'OrderId' when calling DeleteOrder"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/store/order/{orderId}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "orderId" + "}", apiClient.ParameterToString(OrderId)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("orderId", ApiInvoker.ParameterToString(OrderId)); // path (url segment) parameter - + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteOrder: " + response.Content); } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs index ff8f23a18b2..35de41c2257 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Api/UserApi.cs @@ -6,34 +6,55 @@ using IO.Swagger.Model; namespace IO.Swagger.Api { + /// + /// Represents a collection of functions to interact with the API endpoints + /// public class UserApi { - string basePath; - protected RestClient restClient; - - public UserApi(String basePath = "http://petstore.swagger.io/v2") - { - this.basePath = basePath; - this.restClient = new RestClient(basePath); - } - /// - /// Sets the endpoint base url for the services being accessed + /// Initializes a new instance of the class. /// - /// Base URL + /// an instance of ApiClient (optional) /// - public void SetBasePath(string basePath) { - this.basePath = basePath; + public UserApi(ApiClient apiClient = null) { + if (apiClient == null) { // use the default one in Configuration + this.apiClient = Configuration.apiClient; + } else { + this.apiClient = apiClient; + } } /// - /// Gets the endpoint base url for the services being accessed - /// Base URL + /// Initializes a new instance of the class. /// - public String GetBasePath() { - return this.basePath; + /// + public UserApi(String basePath) + { + this.apiClient = new ApiClient(basePath); } - + /// + /// Sets the base path of the API client. + /// + /// The base path + public void SetBasePath(String basePath) { + this.apiClient.basePath = basePath; + } + + /// + /// Gets the base path of the API client. + /// + /// The base path + public String GetBasePath(String basePath) { + return this.apiClient.basePath; + } + + /// + /// Gets or sets the API client. + /// + /// The API client + public ApiClient apiClient {get; set;} + + /// /// Create user This can only be done by the logged in user. @@ -42,26 +63,30 @@ namespace IO.Swagger.Api { /// public void CreateUser (User Body) { - var _request = new RestRequest("/user", Method.POST); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUser: " + response.Content); } @@ -69,7 +94,6 @@ namespace IO.Swagger.Api { return; } - /// /// Creates list of users with given input array /// @@ -77,26 +101,30 @@ namespace IO.Swagger.Api { /// public void CreateUsersWithArrayInput (List Body) { - var _request = new RestRequest("/user/createWithArray", Method.POST); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/createWithArray"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithArrayInput: " + response.Content); } @@ -104,7 +132,6 @@ namespace IO.Swagger.Api { return; } - /// /// Creates list of users with given input array /// @@ -112,26 +139,30 @@ namespace IO.Swagger.Api { /// public void CreateUsersWithListInput (List Body) { - var _request = new RestRequest("/user/createWithList", Method.POST); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/createWithList"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling CreateUsersWithListInput: " + response.Content); } @@ -139,7 +170,6 @@ namespace IO.Swagger.Api { return; } - /// /// Logs user into the system /// @@ -148,59 +178,66 @@ namespace IO.Swagger.Api { /// string public string LoginUser (string Username, string Password) { - var _request = new RestRequest("/user/login", Method.GET); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/login"; + path = path.Replace("{format}", "json"); + - _request.AddUrlSegment("format", "json"); // set format to json by default - - if (Username != null) _request.AddParameter("username", ApiInvoker.ParameterToString(Username)); // query parameter - if (Password != null) _request.AddParameter("password", ApiInvoker.ParameterToString(Password)); // query parameter + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; + + if (Username != null) queryParams.Add("username", apiClient.ParameterToString(Username)); // query parameter + if (Password != null) queryParams.Add("password", apiClient.ParameterToString(Password)); // query parameter + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LoginUser: " + response.Content); } - return (string) ApiInvoker.Deserialize(response.Content, typeof(string)); + return (string) apiClient.Deserialize(response.Content, typeof(string)); } - /// /// Logs out current logged in user session /// /// public void LogoutUser () { - var _request = new RestRequest("/user/logout", Method.GET); - - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/logout"; + path = path.Replace("{format}", "json"); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling LogoutUser: " + response.Content); } @@ -208,7 +245,6 @@ namespace IO.Swagger.Api { return; } - /// /// Get user by user name /// @@ -216,36 +252,39 @@ namespace IO.Swagger.Api { /// User public User GetUserByName (string Username) { - var _request = new RestRequest("/user/{username}", Method.GET); - // verify the required parameter 'Username' is set if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling GetUserByName"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/{username}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("username", ApiInvoker.ParameterToString(Username)); // path (url segment) parameter - + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling GetUserByName: " + response.Content); } - return (User) ApiInvoker.Deserialize(response.Content, typeof(User)); + return (User) apiClient.Deserialize(response.Content, typeof(User)); } - /// /// Updated user This can only be done by the logged in user. /// @@ -254,30 +293,34 @@ namespace IO.Swagger.Api { /// public void UpdateUser (string Username, User Body) { - var _request = new RestRequest("/user/{username}", Method.PUT); - // verify the required parameter 'Username' is set if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling UpdateUser"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/{username}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("username", ApiInvoker.ParameterToString(Username)); // path (url segment) parameter + postBody = apiClient.Serialize(Body); // http body (model) parameter - _request.AddParameter("application/json", ApiInvoker.Serialize(Body), ParameterType.RequestBody); // http body (model) parameter - + + // authentication setting, if any + String[] authSettings = new String[] { }; // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.PUT, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling UpdateUser: " + response.Content); } @@ -285,7 +328,6 @@ namespace IO.Swagger.Api { return; } - /// /// Delete user This can only be done by the logged in user. /// @@ -293,29 +335,33 @@ namespace IO.Swagger.Api { /// public void DeleteUser (string Username) { - var _request = new RestRequest("/user/{username}", Method.DELETE); - // verify the required parameter 'Username' is set if (Username == null) throw new ApiException(400, "Missing required parameter 'Username' when calling DeleteUser"); - // add default header, if any - foreach(KeyValuePair defaultHeader in ApiInvoker.GetDefaultHeader()) - { - _request.AddHeader(defaultHeader.Key, defaultHeader.Value); - } + var path = "/user/{username}"; + path = path.Replace("{format}", "json"); + path = path.Replace("{" + "username" + "}", apiClient.ParameterToString(Username)); + + + var queryParams = new Dictionary(); + var headerParams = new Dictionary(); + var formParams = new Dictionary(); + var fileParams = new Dictionary(); + String postBody = null; - _request.AddUrlSegment("format", "json"); // set format to json by default - _request.AddUrlSegment("username", ApiInvoker.ParameterToString(Username)); // path (url segment) parameter - + // authentication setting, if any + String[] authSettings = new String[] { }; + // make the HTTP request - IRestResponse response = restClient.Execute(_request); + IRestResponse response = (IRestResponse) apiClient.CallApi(path, Method.DELETE, queryParams, postBody, headerParams, formParams, fileParams, authSettings); + if (((int)response.StatusCode) >= 400) { throw new ApiException ((int)response.StatusCode, "Error calling DeleteUser: " + response.Content); } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs index 04867ca365f..74121762af9 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Category.cs @@ -3,8 +3,13 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; namespace IO.Swagger.Model { + + /// + /// + /// [DataContract] public class Category { @@ -18,6 +23,11 @@ namespace IO.Swagger.Model { public string Name { get; set; } + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class Category {\n"); @@ -29,7 +39,16 @@ namespace IO.Swagger.Model { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs index cf773a7a150..7451619050c 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Order.cs @@ -3,8 +3,13 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; namespace IO.Swagger.Model { + + /// + /// + /// [DataContract] public class Order { @@ -25,7 +30,7 @@ namespace IO.Swagger.Model { [DataMember(Name="shipDate", EmitDefaultValue=false)] - public DateTime ShipDate { get; set; } + public DateTime? ShipDate { get; set; } /* Order Status */ @@ -38,6 +43,11 @@ namespace IO.Swagger.Model { public bool? Complete { get; set; } + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class Order {\n"); @@ -57,7 +67,16 @@ namespace IO.Swagger.Model { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs index 41f4081d371..0bfba35b1e3 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Pet.cs @@ -3,8 +3,13 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; namespace IO.Swagger.Model { + + /// + /// + /// [DataContract] public class Pet { @@ -38,6 +43,11 @@ namespace IO.Swagger.Model { public string Status { get; set; } + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class Pet {\n"); @@ -57,7 +67,16 @@ namespace IO.Swagger.Model { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs index 44b6ae29297..53901491a47 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/Tag.cs @@ -3,8 +3,13 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; namespace IO.Swagger.Model { + + /// + /// + /// [DataContract] public class Tag { @@ -18,6 +23,11 @@ namespace IO.Swagger.Model { public string Name { get; set; } + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class Tag {\n"); @@ -29,7 +39,16 @@ namespace IO.Swagger.Model { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs index 0fb3bfc86ce..e58d0296a06 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/Model/User.cs @@ -3,8 +3,13 @@ using System.Text; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; +using Newtonsoft.Json; namespace IO.Swagger.Model { + + /// + /// + /// [DataContract] public class User { @@ -48,6 +53,11 @@ namespace IO.Swagger.Model { public int? UserStatus { get; set; } + + /// + /// Get the string presentation of the object + /// + /// String presentation of the object public override string ToString() { var sb = new StringBuilder(); sb.Append("class User {\n"); @@ -71,7 +81,16 @@ namespace IO.Swagger.Model { sb.Append("}\n"); return sb.ToString(); } - } + + /// + /// Get the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + +} } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiClient.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiClient.cs new file mode 100644 index 00000000000..39d59f063f2 --- /dev/null +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiClient.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using Newtonsoft.Json; +using RestSharp; + +namespace IO.Swagger.Client { + /// + /// API client is mainly responible for making the HTTP call to the API backend + /// + public class ApiClient { + + /// + /// Initializes a new instance of the class. + /// + /// The base path. + public ApiClient(String basePath="http://petstore.swagger.io/v2") { + this.basePath = basePath; + this.restClient = new RestClient(this.basePath); + } + + /// + /// Gets or sets the base path. + /// + /// The base path. + public string basePath { get; set; } + + /// + /// Gets or sets the RestClient + /// + /// The RestClient. + public RestClient restClient { get; set; } + + private Dictionary defaultHeaderMap = new Dictionary(); + + public Object CallApi(String Path, RestSharp.Method Method, Dictionary QueryParams, String PostBody, + Dictionary HeaderParams, Dictionary FormParams, Dictionary FileParams, String[] AuthSettings) { + + var request = new RestRequest(Path, Method); + + UpdateParamsForAuth(QueryParams, HeaderParams, AuthSettings); + + // add default header, if any + foreach(KeyValuePair defaultHeader in this.defaultHeaderMap) + request.AddHeader(defaultHeader.Key, defaultHeader.Value); + + // add header parameter, if any + foreach(KeyValuePair param in HeaderParams) + request.AddHeader(param.Key, param.Value); + + // add query parameter, if any + foreach(KeyValuePair param in QueryParams) + request.AddQueryParameter(param.Key, param.Value); + + // add form parameter, if any + foreach(KeyValuePair param in FormParams) + request.AddParameter(param.Key, param.Value); + + // add file parameter, if any + foreach(KeyValuePair param in FileParams) + request.AddFile(param.Key, param.Value); + + if (PostBody != null) { + request.AddParameter("application/json", PostBody, ParameterType.RequestBody); // http body (model) parameter + } + + return (Object)restClient.Execute(request); + + } + + /// + /// Add default header + /// + /// Header field name + /// Header field value + /// + public void AddDefaultHeader(string key, string value) { + defaultHeaderMap.Add(key, value); + } + + /// + /// Get default header + /// + /// Dictionary of default header + public Dictionary GetDefaultHeader() { + return defaultHeaderMap; + } + + /// + /// escape string (url-encoded) + /// + /// String to be escaped + /// Escaped string + public string EscapeString(string str) { + return str; + } + + /// + /// if parameter is DateTime, output in ISO8601 format + /// if parameter is a list of string, join the list with "," + /// otherwise just return the string + /// + /// The parameter (header, path, query, form) + /// Formatted string + public string ParameterToString(object obj) + { + if (obj is DateTime) { + return ((DateTime)obj).ToString ("u"); + } else if (obj is List) { + return String.Join(",", obj as List); + } else { + return Convert.ToString (obj); + } + } + + /// + /// Deserialize the JSON string into a proper object + /// + /// JSON string + /// Object type + /// Object representation of the JSON string + public object Deserialize(string content, Type type) { + if (type.GetType() == typeof(Object)) + return (Object)content; + + try + { + return JsonConvert.DeserializeObject(content, type); + } + catch (IOException e) { + throw new ApiException(500, e.Message); + } + } + + /// + /// Serialize an object into JSON string + /// + /// Object + /// JSON string + public string Serialize(object obj) { + try + { + return obj != null ? JsonConvert.SerializeObject(obj) : null; + } + catch (Exception e) { + throw new ApiException(500, e.Message); + } + } + + /// + /// Get the API key with prefix + /// + /// Object + /// API key with prefix + public string GetApiKeyWithPrefix (string apiKey) + { + var apiKeyValue = ""; + Configuration.apiKey.TryGetValue (apiKey, out apiKeyValue); + var apiKeyPrefix = ""; + if (Configuration.apiKeyPrefix.TryGetValue (apiKey, out apiKeyPrefix)) { + return apiKeyPrefix + " " + apiKeyValue; + } else { + return apiKeyValue; + } + } + + /// + /// Update parameters based on authentication + /// + /// Query parameters + /// Header parameters + /// Authentication settings + public void UpdateParamsForAuth(Dictionary QueryParams, Dictionary HeaderParams, string[] AuthSettings) { + if (AuthSettings == null || AuthSettings.Length == 0) + return; + + foreach (string auth in AuthSettings) { + // determine which one to use + switch(auth) { + + case "api_key": + HeaderParams["api_key"] = GetApiKeyWithPrefix("api_key"); + + break; + + case "petstore_auth": + + //TODO support oauth + break; + + default: + //TODO show warning about security definition not found + break; + } + } + + } + + /// + /// Encode string in base64 format + /// + /// String to be encoded + public static string Base64Encode(string text) { + var textByte = System.Text.Encoding.UTF8.GetBytes(text); + return System.Convert.ToBase64String(textByte); + } + + } +} diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs index 7c4a7934681..691c2cd3fa2 100644 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiException.cs @@ -1,13 +1,27 @@ using System; namespace IO.Swagger.Client { - + /// + /// API Exception + /// public class ApiException : Exception { - + /// + /// Gets or sets the error code (HTTP status code) + /// + /// The error code (HTTP status code). public int ErrorCode { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The base path. public ApiException() {} + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. public ApiException(int errorCode, string message) : base(message) { this.ErrorCode = errorCode; } diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiInvoker.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiInvoker.cs deleted file mode 100644 index 8bb36472835..00000000000 --- a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/ApiInvoker.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using Newtonsoft.Json; - -namespace IO.Swagger.Client { - public class ApiInvoker { - private static Dictionary defaultHeaderMap = new Dictionary(); - - /// - /// Add default header - /// - /// Header field name - /// Header field value - /// - public static void AddDefaultHeader(string key, string value) { - defaultHeaderMap.Add(key, value); - } - - /// - /// Get default header - /// - /// Dictionary of default header - public static Dictionary GetDefaultHeader() { - return defaultHeaderMap; - } - - /// - /// escape string (url-encoded) - /// - /// String to be escaped - /// Escaped string - public static string EscapeString(string str) { - return str; - } - - /// - /// if parameter is DateTime, output in ISO8601 format, otherwise just return the string - /// - /// The parameter (header, path, query, form) - /// Formatted string - public static string ParameterToString(object obj) - { - return (obj is DateTime) ? ((DateTime)obj).ToString ("u") : Convert.ToString (obj); - } - - /// - /// Deserialize the JSON string into a proper object - /// - /// JSON string - /// Object type - /// Object representation of the JSON string - public static object Deserialize(string content, Type type) { - if (type.GetType() == typeof(Object)) - return (Object)content; - - try - { - return JsonConvert.DeserializeObject(content, type); - } - catch (IOException e) { - throw new ApiException(500, e.Message); - } - } - - /// - /// Serialize an object into JSON string - /// - /// Object - /// JSON string - public static string Serialize(object obj) { - try - { - return obj != null ? JsonConvert.SerializeObject(obj) : null; - } - catch (Exception e) { - throw new ApiException(500, e.Message); - } - } - } -} diff --git a/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs new file mode 100644 index 00000000000..4e7975e3ad0 --- /dev/null +++ b/samples/client/petstore/csharp/src/main/csharp/io/swagger/client/Configuration.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using IO.Swagger.Client; + +namespace IO.Swagger.Client { + /// + /// Represents a set of configuration settings + /// + public class Configuration{ + + /// + /// Gets or sets the API client. This is the default API client for making HTTP calls. + /// + /// The API client. + public static ApiClient apiClient = new ApiClient(); + + /// + /// Gets or sets the username (HTTP basic authentication) + /// + /// The username. + public static String username { get; set; } + + /// + /// Gets or sets the password (HTTP basic authentication) + /// + /// The password. + public static String password { get; set; } + + /// + /// Gets or sets the API key based on the authentication name + /// + /// The API key. + public static Dictionary apiKey = new Dictionary(); + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name + /// + /// The prefix of the API key. + public static Dictionary apiKeyPrefix = new Dictionary(); + + + } +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiInvoker.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java similarity index 62% rename from samples/client/petstore/java/src/main/java/io/swagger/client/ApiInvoker.java rename to samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java index 69d13136274..38f021aab22 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiInvoker.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiClient.java @@ -29,69 +29,116 @@ import java.net.URLEncoder; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.text.ParseException; -public class ApiInvoker { - private static ApiInvoker INSTANCE = new ApiInvoker(); +public class ApiClient { private Map hostMap = new HashMap(); private Map defaultHeaderMap = new HashMap(); - private boolean isDebug = false; + private boolean debugging = false; + private String basePath = "http://petstore.swagger.io/v2"; - /** - * ISO 8601 date time format. - * @see https://en.wikipedia.org/wiki/ISO_8601 - */ - public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + private DateFormat dateFormat; - /** - * ISO 8601 date format. - * @see https://en.wikipedia.org/wiki/ISO_8601 - */ - public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + public ApiClient() { + // Use ISO 8601 format for date and datetime. + // See https://en.wikipedia.org/wiki/ISO_8601 + this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - static { // Use UTC as the default time zone. - DATE_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); - DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); // Set default User-Agent. setUserAgent("Java-Swagger"); } - public static void setUserAgent(String userAgent) { - INSTANCE.addDefaultHeader("User-Agent", userAgent); + public String getBasePath() { + return basePath; } - public static Date parseDateTime(String str) { + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + */ + public ApiClient setDebugging(boolean debugging) { + this.debugging = debugging; + return this; + } + + /** + * Get the date format used to parse/format date parameters. + */ + public DateFormat getDateFormat() { + return dateFormat; + } + + /** + * Set the date format used to parse/format date parameters. + */ + public ApiClient getDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + return this; + } + + /** + * Parse the given string into Date object. + */ + public Date parseDate(String str) { try { - return DATE_TIME_FORMAT.parse(str); + return dateFormat.parse(str); } catch (java.text.ParseException e) { throw new RuntimeException(e); } } - public static Date parseDate(String str) { - try { - return DATE_FORMAT.parse(str); - } catch (java.text.ParseException e) { - throw new RuntimeException(e); - } + /** + * Format the given Date object into string. + */ + public String formatDate(Date date) { + return dateFormat.format(date); } - public static String formatDateTime(Date datetime) { - return DATE_TIME_FORMAT.format(datetime); - } - - public static String formatDate(Date date) { - return DATE_FORMAT.format(date); - } - - public static String parameterToString(Object param) { + /** + * Format the given parameter object into string. + */ + public String parameterToString(Object param) { if (param == null) { return ""; } else if (param instanceof Date) { - return formatDateTime((Date) param); + return formatDate((Date) param); } else if (param instanceof Collection) { StringBuilder b = new StringBuilder(); for(Object o : (Collection)param) { @@ -105,28 +152,27 @@ public class ApiInvoker { return String.valueOf(param); } } - public void enableDebug() { - isDebug = true; - } - - public static ApiInvoker getInstance() { - return INSTANCE; - } - - public void addDefaultHeader(String key, String value) { - defaultHeaderMap.put(key, value); - } + /** + * Escape the given string to be used as URL query value. + */ public String escapeString(String str) { - try{ + try { return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); - } - catch(UnsupportedEncodingException e) { + } catch (UnsupportedEncodingException e) { return str; } } - public static Object deserialize(String json, String containerType, Class cls) throws ApiException { + /** + * Deserialize the given JSON string to Java object. + * + * @param json The JSON string + * @param containerType The container type, one of "list", "array" or "" + * @param cls The type of the Java object + * @return The deserialized Java object + */ + public Object deserialize(String json, String containerType, Class cls) throws ApiException { if(null != containerType) { containerType = containerType.toLowerCase(); } @@ -147,11 +193,14 @@ public class ApiInvoker { } } catch (IOException e) { - throw new ApiException(500, e.getMessage()); + throw new ApiException(500, e.getMessage(), null, json); } } - public static String serialize(Object obj) throws ApiException { + /** + * Serialize the given Java object into JSON string. + */ + public String serialize(Object obj) throws ApiException { try { if (obj != null) return JsonUtil.getJsonMapper().writeValueAsString(obj); @@ -163,8 +212,20 @@ public class ApiInvoker { } } - public String invokeAPI(String host, String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { - Client client = getClient(host); + /** + * Invoke API by sending HTTP request with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "POST", "PUT", and "DELETE" + * @param queryParams The query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param contentType The request Content-Type + * @return The response body in type of string + */ + public String invokeAPI(String path, String method, Map queryParams, Object body, Map headerParams, Map formParams, String contentType) throws ApiException { + Client client = getClient(); StringBuilder b = new StringBuilder(); @@ -180,7 +241,7 @@ public class ApiInvoker { } String querystring = b.toString(); - Builder builder = client.resource(host + path + querystring).accept("application/json"); + Builder builder = client.resource(basePath + path + querystring).accept("application/json"); for(String key : headerParams.keySet()) { builder = builder.header(key, headerParams.get(key)); } @@ -236,6 +297,7 @@ public class ApiInvoker { else { throw new ApiException(500, "unknown method type " + method); } + if(response.getClientResponseStatus() == ClientResponse.Status.NO_CONTENT) { return null; } @@ -249,9 +311,11 @@ public class ApiInvoker { } else { String message = "error"; + String respBody = null; if(response.hasEntity()) { try{ - message = String.valueOf(response.getEntity(String.class)); + respBody = String.valueOf(response.getEntity(String.class)); + message = respBody; } catch (RuntimeException e) { // e.printStackTrace(); @@ -259,16 +323,21 @@ public class ApiInvoker { } throw new ApiException( response.getClientResponseStatus().getStatusCode(), - message); + message, + response.getHeaders(), + respBody); } } + /** + * Encode the given form parameters as request body. + */ private String getXWWWFormUrlencodedParams(Map formParams) { StringBuilder formParamBuilder = new StringBuilder(); for (Entry param : formParams.entrySet()) { - String keyStr = ApiInvoker.parameterToString(param.getKey()); - String valueStr = ApiInvoker.parameterToString(param.getValue()); + String keyStr = parameterToString(param.getKey()); + String valueStr = parameterToString(param.getValue()); try { formParamBuilder.append(URLEncoder.encode(keyStr, "utf8")) @@ -287,14 +356,16 @@ public class ApiInvoker { return encodedFormParams; } - - private Client getClient(String host) { - if(!hostMap.containsKey(host)) { + /** + * Get an existing client or create a new client to handle HTTP request. + */ + private Client getClient() { + if(!hostMap.containsKey(basePath)) { Client client = Client.create(); - if(isDebug) + if (debugging) client.addFilter(new LoggingFilter()); - hostMap.put(host, client); + hostMap.put(basePath, client); } - return hostMap.get(host); + return hostMap.get(basePath); } -} \ No newline at end of file +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiException.java b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiException.java index 31bc8a0978a..a39785eb47e 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/ApiException.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/ApiException.java @@ -1,8 +1,13 @@ package io.swagger.client; +import java.util.Map; +import java.util.List; + public class ApiException extends Exception { - int code = 0; - String message = null; + private int code = 0; + private String message = null; + private Map> responseHeaders = null; + private String responseBody = null; public ApiException() {} @@ -11,19 +16,32 @@ public class ApiException extends Exception { this.message = message; } + public ApiException(int code, String message, Map> responseHeaders, String responseBody) { + this.code = code; + this.message = message; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + public int getCode() { return code; } - - public void setCode(int code) { - this.code = code; - } - + public String getMessage() { return message; } - - public void setMessage(String message) { - this.message = message; + + /** + * Get the HTTP response headers. + */ + public Map> getResponseHeaders() { + return responseHeaders; } -} \ No newline at end of file + + /** + * Get the HTTP response body. + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/Configuration.java b/samples/client/petstore/java/src/main/java/io/swagger/client/Configuration.java new file mode 100644 index 00000000000..f7c360d6122 --- /dev/null +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/Configuration.java @@ -0,0 +1,21 @@ +package io.swagger.client; + +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java index 10326d8a2d6..1c3cc4cb483 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/PetApi.java @@ -1,7 +1,8 @@ package io.swagger.client.api; import io.swagger.client.ApiException; -import io.swagger.client.ApiInvoker; +import io.swagger.client.ApiClient; +import io.swagger.client.Configuration; import io.swagger.client.model.*; @@ -20,19 +21,22 @@ import java.util.Map; import java.util.HashMap; public class PetApi { - String basePath = "http://petstore.swagger.io/v2"; - ApiInvoker apiInvoker = ApiInvoker.getInstance(); + private ApiClient apiClient; - public ApiInvoker getInvoker() { - return apiInvoker; + public PetApi() { + this(Configuration.getDefaultApiClient()); } - public void setBasePath(String basePath) { - this.basePath = basePath; + public PetApi(ApiClient apiClient) { + this.apiClient = apiClient; } - public String getBasePath() { - return basePath; + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; } @@ -74,7 +78,7 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "PUT", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -124,7 +128,7 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -155,7 +159,7 @@ public class PetApi { Map formParams = new HashMap(); if (status != null) - queryParams.put("status", ApiInvoker.parameterToString(status)); + queryParams.put("status", apiClient.parameterToString(status)); String[] contentTypes = { @@ -176,9 +180,9 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (List) ApiInvoker.deserialize(response, "array", Pet.class); + return (List) apiClient.deserialize(response, "array", Pet.class); } else { return null; @@ -207,7 +211,7 @@ public class PetApi { Map formParams = new HashMap(); if (tags != null) - queryParams.put("tags", ApiInvoker.parameterToString(tags)); + queryParams.put("tags", apiClient.parameterToString(tags)); String[] contentTypes = { @@ -228,9 +232,9 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (List) ApiInvoker.deserialize(response, "array", Pet.class); + return (List) apiClient.deserialize(response, "array", Pet.class); } else { return null; @@ -257,7 +261,7 @@ public class PetApi { // create path and map variables String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params Map queryParams = new HashMap(); @@ -284,9 +288,9 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (Pet) ApiInvoker.deserialize(response, "", Pet.class); + return (Pet) apiClient.deserialize(response, "", Pet.class); } else { return null; @@ -315,7 +319,7 @@ public class PetApi { // create path and map variables String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params Map queryParams = new HashMap(); @@ -334,23 +338,29 @@ public class PetApi { boolean hasFields = false; FormDataMultiPart mp = new FormDataMultiPart(); - hasFields = true; - mp.field("name", ApiInvoker.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); + if (name != null) { + hasFields = true; + mp.field("name", apiClient.parameterToString(name), MediaType.MULTIPART_FORM_DATA_TYPE); + } - hasFields = true; - mp.field("status", ApiInvoker.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); + if (status != null) { + hasFields = true; + mp.field("status", apiClient.parameterToString(status), MediaType.MULTIPART_FORM_DATA_TYPE); + } if(hasFields) postBody = mp; } else { - formParams.put("name", ApiInvoker.parameterToString(name)); - formParams.put("status", ApiInvoker.parameterToString(status)); + if (name != null) + formParams.put("name", apiClient.parameterToString(name)); + if (status != null) + formParams.put("status", apiClient.parameterToString(status)); } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -380,7 +390,7 @@ public class PetApi { // create path and map variables String path = "/pet/{petId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params Map queryParams = new HashMap(); @@ -388,7 +398,8 @@ public class PetApi { Map formParams = new HashMap(); - headerParams.put("api_key", ApiInvoker.parameterToString(apiKey)); + if (apiKey != null) + headerParams.put("api_key", apiClient.parameterToString(apiKey)); String[] contentTypes = { @@ -408,7 +419,7 @@ public class PetApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -439,7 +450,7 @@ public class PetApi { // create path and map variables String path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "petId" + "\\}", apiInvoker.escapeString(petId.toString())); + .replaceAll("\\{" + "petId" + "\\}", apiClient.escapeString(petId.toString())); // query params Map queryParams = new HashMap(); @@ -458,24 +469,29 @@ public class PetApi { boolean hasFields = false; FormDataMultiPart mp = new FormDataMultiPart(); - hasFields = true; - mp.field("additionalMetadata", ApiInvoker.parameterToString(additionalMetadata), MediaType.MULTIPART_FORM_DATA_TYPE); + if (additionalMetadata != null) { + hasFields = true; + mp.field("additionalMetadata", apiClient.parameterToString(additionalMetadata), MediaType.MULTIPART_FORM_DATA_TYPE); + } - hasFields = true; - mp.field("file", file.getName()); - mp.bodyPart(new FileDataBodyPart("file", file, MediaType.MULTIPART_FORM_DATA_TYPE)); + if (file != null) { + hasFields = true; + mp.field("file", file.getName()); + mp.bodyPart(new FileDataBodyPart("file", file, MediaType.MULTIPART_FORM_DATA_TYPE)); + } if(hasFields) postBody = mp; } else { - formParams.put("additionalMetadata", ApiInvoker.parameterToString(additionalMetadata)); + if (additionalMetadata != null) + formParams.put("additionalMetadata", apiClient.parameterToString(additionalMetadata)); } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java index 6da7b5abb2f..7b956f79a22 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/StoreApi.java @@ -1,7 +1,8 @@ package io.swagger.client.api; import io.swagger.client.ApiException; -import io.swagger.client.ApiInvoker; +import io.swagger.client.ApiClient; +import io.swagger.client.Configuration; import io.swagger.client.model.*; @@ -20,19 +21,22 @@ import java.util.Map; import java.util.HashMap; public class StoreApi { - String basePath = "http://petstore.swagger.io/v2"; - ApiInvoker apiInvoker = ApiInvoker.getInstance(); + private ApiClient apiClient; - public ApiInvoker getInvoker() { - return apiInvoker; + public StoreApi() { + this(Configuration.getDefaultApiClient()); } - public void setBasePath(String basePath) { - this.basePath = basePath; + public StoreApi(ApiClient apiClient) { + this.apiClient = apiClient; } - public String getBasePath() { - return basePath; + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; } @@ -73,9 +77,9 @@ public class StoreApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (Map) ApiInvoker.deserialize(response, "map", Map.class); + return (Map) apiClient.deserialize(response, "map", Map.class); } else { return null; @@ -123,9 +127,9 @@ public class StoreApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (Order) ApiInvoker.deserialize(response, "", Order.class); + return (Order) apiClient.deserialize(response, "", Order.class); } else { return null; @@ -152,7 +156,7 @@ public class StoreApi { // create path and map variables String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); + .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params Map queryParams = new HashMap(); @@ -179,9 +183,9 @@ public class StoreApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (Order) ApiInvoker.deserialize(response, "", Order.class); + return (Order) apiClient.deserialize(response, "", Order.class); } else { return null; @@ -208,7 +212,7 @@ public class StoreApi { // create path and map variables String path = "/store/order/{orderId}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "orderId" + "\\}", apiInvoker.escapeString(orderId.toString())); + .replaceAll("\\{" + "orderId" + "\\}", apiClient.escapeString(orderId.toString())); // query params Map queryParams = new HashMap(); @@ -235,7 +239,7 @@ public class StoreApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java index d0974d95a52..0c6f331abe0 100644 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java +++ b/samples/client/petstore/java/src/main/java/io/swagger/client/api/UserApi.java @@ -1,7 +1,8 @@ package io.swagger.client.api; import io.swagger.client.ApiException; -import io.swagger.client.ApiInvoker; +import io.swagger.client.ApiClient; +import io.swagger.client.Configuration; import io.swagger.client.model.*; @@ -20,19 +21,22 @@ import java.util.Map; import java.util.HashMap; public class UserApi { - String basePath = "http://petstore.swagger.io/v2"; - ApiInvoker apiInvoker = ApiInvoker.getInstance(); + private ApiClient apiClient; - public ApiInvoker getInvoker() { - return apiInvoker; + public UserApi() { + this(Configuration.getDefaultApiClient()); } - public void setBasePath(String basePath) { - this.basePath = basePath; + public UserApi(ApiClient apiClient) { + this.apiClient = apiClient; } - public String getBasePath() { - return basePath; + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; } @@ -74,7 +78,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -124,7 +128,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -174,7 +178,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "POST", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -206,9 +210,9 @@ public class UserApi { Map formParams = new HashMap(); if (username != null) - queryParams.put("username", ApiInvoker.parameterToString(username)); + queryParams.put("username", apiClient.parameterToString(username)); if (password != null) - queryParams.put("password", ApiInvoker.parameterToString(password)); + queryParams.put("password", apiClient.parameterToString(password)); String[] contentTypes = { @@ -229,9 +233,9 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (String) ApiInvoker.deserialize(response, "", String.class); + return (String) apiClient.deserialize(response, "", String.class); } else { return null; @@ -278,7 +282,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -307,7 +311,7 @@ public class UserApi { // create path and map variables String path = "/user/{username}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); + .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params Map queryParams = new HashMap(); @@ -334,9 +338,9 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "GET", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "GET", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ - return (User) ApiInvoker.deserialize(response, "", User.class); + return (User) apiClient.deserialize(response, "", User.class); } else { return null; @@ -364,7 +368,7 @@ public class UserApi { // create path and map variables String path = "/user/{username}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); + .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params Map queryParams = new HashMap(); @@ -391,7 +395,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "PUT", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "PUT", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } @@ -420,7 +424,7 @@ public class UserApi { // create path and map variables String path = "/user/{username}".replaceAll("\\{format\\}","json") - .replaceAll("\\{" + "username" + "\\}", apiInvoker.escapeString(username.toString())); + .replaceAll("\\{" + "username" + "\\}", apiClient.escapeString(username.toString())); // query params Map queryParams = new HashMap(); @@ -447,7 +451,7 @@ public class UserApi { } try { - String response = apiInvoker.invokeAPI(basePath, path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); + String response = apiClient.invokeAPI(path, "DELETE", queryParams, postBody, headerParams, formParams, contentType); if(response != null){ return ; } diff --git a/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java b/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java deleted file mode 100644 index cd9ff24975c..00000000000 --- a/samples/client/petstore/java/src/main/java/io/swagger/client/model/ApiResponse.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.swagger.client.model; - - -import com.wordnik.swagger.annotations.*; -import com.fasterxml.jackson.annotation.JsonProperty; - - -@ApiModel(description = "") -public class ApiResponse { - - private Integer code = null; - private String type = null; - private String message = null; - - - /** - **/ - @ApiModelProperty(required = false, value = "") - @JsonProperty("code") - public Integer getCode() { - return code; - } - public void setCode(Integer code) { - this.code = code; - } - - - /** - **/ - @ApiModelProperty(required = false, value = "") - @JsonProperty("type") - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - - - /** - **/ - @ApiModelProperty(required = false, value = "") - @JsonProperty("message") - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponse {\n"); - - sb.append(" code: ").append(code).append("\n"); - sb.append(" type: ").append(type).append("\n"); - sb.append(" message: ").append(message).append("\n"); - sb.append("}\n"); - return sb.toString(); - } -} diff --git a/samples/client/petstore/java/src/test/java/io/swagger/client/ConfigurationTest.java b/samples/client/petstore/java/src/test/java/io/swagger/client/ConfigurationTest.java new file mode 100644 index 00000000000..9801be416fb --- /dev/null +++ b/samples/client/petstore/java/src/test/java/io/swagger/client/ConfigurationTest.java @@ -0,0 +1,14 @@ +package io.swagger.client; + +import static org.junit.Assert.*; +import org.junit.*; + +public class ConfigurationTest { + @Test + public void testDefaultApiClient() { + ApiClient apiClient = Configuration.getDefaultApiClient(); + assertNotNull(apiClient); + assertEquals("http://petstore.swagger.io/v2", apiClient.getBasePath()); + assertFalse(apiClient.isDebugging()); + } +} diff --git a/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java b/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java index 1bee31e0748..4ea5474eb59 100644 --- a/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java +++ b/samples/client/petstore/java/src/test/java/io/swagger/petstore/test/PetApiTest.java @@ -1,6 +1,8 @@ package io.swagger.petstore.test; import io.swagger.client.ApiException; +import io.swagger.client.ApiClient; +import io.swagger.client.Configuration; import io.swagger.client.api.*; import io.swagger.client.model.*; @@ -18,6 +20,33 @@ public class PetApiTest { api = new PetApi(); } + @Test + public void testApiClient() { + // the default api client is used + assertEquals(Configuration.getDefaultApiClient(), api.getApiClient()); + assertNotNull(api.getApiClient()); + assertEquals("http://petstore.swagger.io/v2", api.getApiClient().getBasePath()); + assertFalse(api.getApiClient().isDebugging()); + + ApiClient oldClient = api.getApiClient(); + + ApiClient newClient = new ApiClient(); + newClient.setBasePath("http://example.com"); + newClient.setDebugging(true); + + // set api client via constructor + api = new PetApi(newClient); + assertNotNull(api.getApiClient()); + assertEquals("http://example.com", api.getApiClient().getBasePath()); + assertTrue(api.getApiClient().isDebugging()); + + // set api client via setter method + api.setApiClient(oldClient); + assertNotNull(api.getApiClient()); + assertEquals("http://petstore.swagger.io/v2", api.getApiClient().getBasePath()); + assertFalse(api.getApiClient().isDebugging()); + } + @Test public void testCreateAndGetPet() throws Exception { Pet pet = createRandomPet(); @@ -100,7 +129,7 @@ public class PetApiTest { api.addPet(pet); Pet fetched = api.getPetById(pet.getId()); - + api.updatePetWithForm(String.valueOf(fetched.getId()), "furt", null); Pet updated = api.getPetById(fetched.getId()); @@ -152,4 +181,4 @@ public class PetApiTest { return pet; } -} \ No newline at end of file +} diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/project.pbxproj b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/project.pbxproj index 723caec2cdb..5c1bfabf608 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/project.pbxproj +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ BA525648922D4C0E9F44D4F1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73DA4F1067C343C3962F1542 /* libPods.a */; }; + CF0560EB1B1855CF00C0D4EC /* SWGConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */; }; CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF31D0981B105E4B00509935 /* SWGApiClientTest.m */; }; CFD1B6701B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; @@ -56,6 +57,8 @@ /* Begin PBXFileReference section */ 73DA4F1067C343C3962F1542 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; A425648B5C0A4849C7668069 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "../Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + CF0560E91B1855CF00C0D4EC /* SWGConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGConfiguration.h; sourceTree = ""; }; + CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGConfiguration.m; sourceTree = ""; }; CF31D0981B105E4B00509935 /* SWGApiClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGApiClientTest.m; sourceTree = ""; }; CFD1B66E1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSONValueTransformer+ISO8601.h"; sourceTree = ""; }; CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSONValueTransformer+ISO8601.m"; sourceTree = ""; }; @@ -234,6 +237,8 @@ EA8B8AA31AC6683700638FBB /* SWGQueryParamCollection.m */, EAEA85CC1811D3AE00F06E69 /* SWGApiClient.h */, EAEA85CD1811D3AE00F06E69 /* SWGApiClient.m */, + CF0560E91B1855CF00C0D4EC /* SWGConfiguration.h */, + CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */, EAEA85CE1811D3AE00F06E69 /* SWGCategory.h */, EAEA85CF1811D3AE00F06E69 /* SWGCategory.m */, EAEA85D21811D3AE00F06E69 /* SWGFile.h */, @@ -395,6 +400,7 @@ buildActionMask = 2147483647; files = ( EAEA85E51811D3AE00F06E69 /* SWGCategory.m in Sources */, + CF0560EB1B1855CF00C0D4EC /* SWGConfiguration.m in Sources */, EAEA85ED1811D3AE00F06E69 /* SWGTag.m in Sources */, EA6699B31811D2FA00A70D03 /* ViewController.m in Sources */, EA6699AA1811D2FA00A70D03 /* AppDelegate.m in Sources */, diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/PetstoreClient.xcscheme b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/PetstoreClient.xcscheme new file mode 100644 index 00000000000..1a2a738abea --- /dev/null +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/PetstoreClient.xcscheme @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000000..912710bdccc --- /dev/null +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClient.xcodeproj/xcuserdata/geekerzp.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + PetstoreClient.xcscheme + + orderHint + 4 + + + SuppressBuildableAutocreation + + EA6699951811D2FA00A70D03 + + primary + + + EA6699B91811D2FB00A70D03 + + primary + + + + + diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m index 7c47bb1f271..d56bc037206 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClient/ViewController.m @@ -8,6 +8,7 @@ #import "ViewController.h" #import "SWGPetApi.h" +#import "SWGConfiguration.h" @interface ViewController () @@ -53,6 +54,14 @@ // } ]; */ + SWGConfiguration *config = [SWGConfiguration sharedConfig]; + config.username = @"foo"; + config.password = @"bar"; + SWGPetApi *api = [[SWGPetApi alloc] init]; + [api addPetWithCompletionBlock:nil + completionHandler:^(NSError *error) { + + }]; } - (void)didReceiveMemoryWarning diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m index 6fb2b6e57c2..5b5f145cc12 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/PetApiTest.m @@ -12,6 +12,16 @@ [super tearDown]; } +- (void)testCreatePetApi { + SWGPetApi *api1 = [[SWGPetApi alloc] init]; + SWGPetApi *api2 = [[SWGPetApi alloc] init]; + XCTAssertEqual(api1.apiClient, api2.apiClient); + + SWGApiClient *client = [[SWGApiClient alloc] init]; + SWGPetApi *api3 = [[SWGPetApi alloc] initWithApiClient:client]; + XCTAssertNotEqual(api1.apiClient, api3.apiClient); +} + - (void)testCreateAndGetPet { XCTestExpectation *expectation = [self expectationWithDescription:@"testGetPetById"]; SWGPet* pet = [self createPet]; @@ -27,6 +37,24 @@ } if(output){ XCTAssertNotNil([output _id], @"token was nil"); + + // test category of pet is correct + XCTAssertEqualObjects(output.category._id, pet.category._id); + XCTAssertEqualObjects(output.category.name, pet.category.name); + + // test tags of pet is correct + XCTAssertTrue([output.tags isKindOfClass:[NSArray class]]); + [pet.tags enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + SWGTag *foundTag = [[SWGTag alloc] init]; + for (SWGTag *tag in output.tags) { + if ([tag _id] == [obj _id]) { + foundTag = tag; + } + } + XCTAssertNotNil(foundTag); + XCTAssertEqualObjects([foundTag _id], [obj _id]); + XCTAssertEqualObjects([foundTag name], [obj name]); + }]; } [expectation fulfill]; }]; @@ -221,10 +249,20 @@ SWGPet * pet = [[SWGPet alloc] init]; pet._id = [[NSNumber alloc] initWithLong:[[NSDate date] timeIntervalSince1970]]; pet.name = @"monkey"; + SWGCategory * category = [[SWGCategory alloc] init]; + category._id = [[NSNumber alloc] initWithInteger:arc4random_uniform(100000)]; category.name = @"super-happy"; - pet.category = category; + + SWGTag *tag1 = [[SWGTag alloc] init]; + tag1._id = [[NSNumber alloc] initWithInteger:arc4random_uniform(100000)]; + tag1.name = @"test tag 1"; + SWGTag *tag2 = [[SWGTag alloc] init]; + tag2._id = [[NSNumber alloc] initWithInteger:arc4random_uniform(100000)]; + tag2.name = @"test tag 2"; + pet.tags = (NSArray *)[[NSArray alloc] initWithObjects:tag1, tag2, nil]; + pet.status = @"available"; NSArray * photos = [[NSArray alloc] initWithObjects:@"http://foo.bar.com/3", @"http://foo.bar.com/4", nil]; diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m index 0464bf569e9..61925b16960 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/SWGApiClientTest.m @@ -1,16 +1,19 @@ #import #import #import "SWGApiClient.h" +#import "SWGConfiguration.h" @interface SWGApiClientTest : XCTestCase +@property (nonatomic) SWGApiClient *apiClient; + @end @implementation SWGApiClientTest - (void)setUp { [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + self.apiClient = [[SWGApiClient alloc] init]; } - (void)tearDown { @@ -56,4 +59,43 @@ XCTAssertEqualObjects([SWGApiClient selectHeaderContentType:contentTypes], @"application/json"); } +- (void)testConfiguration { + SWGConfiguration *config = [SWGConfiguration sharedConfig]; + [config setValue:@"123456" forApiKeyField:@"api_key"]; + [config setValue:@"PREFIX" forApiKeyPrefixField:@"api_key"]; + config.username = @"test_username"; + config.password = @"test_password"; + + NSDictionary *headerParams = @{@"test1": @"value1"}; + NSDictionary *queryParams = @{@"test2": @"value2"}; + NSArray *authSettings = @[@"api_key", @"unknown"]; + + // test prefix + XCTAssertEqualObjects(@"PREFIX", config.apiKeyPrefix[@"api_key"]); + [self.apiClient updateHeaderParams:&headerParams + queryParams:&queryParams + WithAuthSettings:authSettings]; + + // test api key auth + XCTAssertEqualObjects(headerParams[@"test1"], @"value1"); + XCTAssertEqualObjects(headerParams[@"api_key"], @"PREFIX 123456"); + XCTAssertEqualObjects(queryParams[@"test2"], @"value2"); + + // test basic auth + XCTAssertEqualObjects(@"test_username", config.username); + XCTAssertEqualObjects(@"test_password", config.password); +} + +- (void)testGetBasicAuthToken { + SWGConfiguration *config = [SWGConfiguration sharedConfig]; + config.username = @"test_username"; + config.password = @"test_password"; + + NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", config.username, config.password]; + NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding]; + basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]]; + + XCTAssertEqualObjects(basicAuthCredentials, [config getBasicAuthToken]); +} + @end diff --git a/samples/client/petstore/objc/Podfile.lock b/samples/client/petstore/objc/Podfile.lock index 6ac776ab37a..48b1f809658 100644 --- a/samples/client/petstore/objc/Podfile.lock +++ b/samples/client/petstore/objc/Podfile.lock @@ -20,7 +20,7 @@ PODS: - AFNetworking/UIKit (2.5.4): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - ISO8601 (0.2.0) + - ISO8601 (0.3.0) - JSONModel (1.1.0) DEPENDENCIES: @@ -30,7 +30,7 @@ DEPENDENCIES: SPEC CHECKSUMS: AFNetworking: 05edc0ac4c4c8cf57bcf4b84be5b0744b6d8e71e - ISO8601: 962282de75074c38bbfaa7b133b0e743ed6deb8d + ISO8601: 8d8a22d5edf0554a1cf75bac028c76c1dc0ffaef JSONModel: ec77e9865236a7a09d9cf7668df6b4b328d9ec1d COCOAPODS: 0.37.1 diff --git a/samples/client/petstore/objc/client/SWGApiClient.h b/samples/client/petstore/objc/client/SWGApiClient.h index cd6f52db5c6..250811c4016 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.h +++ b/samples/client/petstore/objc/client/SWGApiClient.h @@ -3,7 +3,7 @@ /** * A key for `NSError` user info dictionaries. - * + * * The corresponding value is the parsed response body for an HTTP error. */ extern NSString *const SWGResponseObjectErrorKey; @@ -20,56 +20,197 @@ extern NSString *const SWGResponseObjectErrorKey; @property(nonatomic, assign) BOOL logHTTP; @property(nonatomic, readonly) NSOperationQueue* queue; +/** + * Get the Api Client instance from pool + * + * @param baseUrl The base url of api client. + * + * @return The SWGApiClient instance. + */ +(SWGApiClient *)sharedClientFromPool:(NSString *)baseUrl; +/** + * Get the operations queue + * + * @return The `shardQueue` static variable. + */ +(NSOperationQueue*) sharedQueue; +/** + * Turn on logging + * + * @param state logging state, must be `YES` or `NO` + */ +(void)setLoggingEnabled:(bool) state; +/** + * Clear Cache + */ +(void)clearCache; +/** + * Turn on cache + * + * @param enabled If the cached is enable, must be `YES` or `NO` + */ +(void)setCacheEnabled:(BOOL) enabled; +/** + * Get the request queue size + * + * @return The size of `queuedRequests` static variable. + */ +(unsigned long)requestQueueSize; +/** + * Set the client unreachable + * + * @param state off line state, must be `YES` or `NO` + */ +(void) setOfflineState:(BOOL) state; +/** + * Get the client reachability + * + * @return The client reachability. + */ +(AFNetworkReachabilityStatus) getReachabilityStatus; +/** + * Get the next request id + * + * @return The next executed request id. + */ +(NSNumber*) nextRequestId; +/** + * Generate request id and add it to the queue + * + * @return The next executed request id. + */ +(NSNumber*) queueRequest; +/** + * Remove request id from the queue + * + * @param requestId The request which will be removed. + */ +(void) cancelRequest:(NSNumber*)requestId; +/** + * URL encode NSString + * + * @param unescaped The string which will be escaped. + * + * @return The escaped string. + */ +(NSString*) escape:(id)unescaped; +/** + * Customize the behavior when the reachability changed + * + * @param changeBlock The block will be executed when the reachability changed. + */ +(void) setReachabilityChangeBlock:(void(^)(int))changeBlock; +/** + * Set the client reachability strategy + * + * @param host The host of SWGApiClient. + */ +(void) configureCacheReachibilityForHost:(NSString*)host; +/** + * Detect Accept header from accepts NSArray + * + * @param accepts NSArray of header + * + * @return The Accept header + */ +(NSString *) selectHeaderAccept:(NSArray *)accepts; + +/** + * Detect Content-Type header from contentTypes NSArray + * + * @param contentTypes NSArray of header + * + * @return The Content-Type header + */ +(NSString *) selectHeaderContentType:(NSArray *)contentTypes; +/** + * Set header for request + * + * @param value The header value + * @param forKey The header key + */ -(void)setHeaderValue:(NSString*) value - forKey:(NSString*) forKey; + forKey:(NSString*) forKey; +/** + * Update header parameters and query parameters for authentication + * + * @param headers The header parameter will be udpated, passed by pointer to pointer. + * @param querys The query parameters will be updated, passed by pointer to pointer. + * @param authSettings The authentication names NSArray. + */ +- (void) updateHeaderParams:(NSDictionary **)headers + queryParams:(NSDictionary **)querys + WithAuthSettings:(NSArray *)authSettings; + +/** + * Perform request + * + * Request with non-empty response + * + * @param path Request url. + * @param method Request method. + * @param queryParams Request query parameters. + * @param body Request body. + * @param headerParams Request header parameters. + * @param authSettings Request authentication names. + * @param requestContentType Request content-type. + * @param responseContentType Response content-type. + * @param completionBlock The block will be executed when the request completed. + * + * @return The request id. + */ -(NSNumber*) dictionary:(NSString*) path method:(NSString*) method queryParams:(NSDictionary*) queryParams body:(id) body headerParams:(NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType:(NSString*) requestContentType responseContentType:(NSString*) responseContentType completionBlock:(void (^)(NSDictionary*, NSError *))completionBlock; +/** + * Perform request + * + * Request with empty response + * + * @param path Request url. + * @param method Request method. + * @param queryParams Request query parameters. + * @param body Request body. + * @param headerParams Request header parameters. + * @param authSettings Request authentication names. + * @param requestContentType Request content-type. + * @param responseContentType Response content-type. + * @param completionBlock The block will be executed when the request completed. + * + * @return The request id. + */ -(NSNumber*) stringWithCompletionBlock:(NSString*) path method:(NSString*) method queryParams:(NSDictionary*) queryParams body:(id) body headerParams:(NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType:(NSString*) requestContentType responseContentType:(NSString*) responseContentType completionBlock:(void (^)(NSString*, NSError *))completionBlock; @end + diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index 15dbee07459..5e2985bbe79 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -1,6 +1,7 @@ #import "SWGApiClient.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" +#import "SWGConfiguration.h" @implementation SWGApiClient @@ -15,10 +16,22 @@ static NSOperationQueue* sharedQueue; static void (^reachabilityChangeBlock)(int); static bool loggingEnabled = true; +#pragma mark - Log Methods + +(void)setLoggingEnabled:(bool) state { loggingEnabled = state; } +- (void)logRequest:(NSURLRequest*)request { + NSLog(@"request: %@", [self descriptionForRequest:request]); +} + +- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error { + NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data ); +} + +#pragma mark - + +(void)clearCache { [[NSURLCache sharedURLCache] removeAllCachedResponses]; } @@ -134,10 +147,12 @@ static bool loggingEnabled = true; } +(NSNumber*) nextRequestId { - long nextId = ++requestId; - if(loggingEnabled) - NSLog(@"got id %ld", nextId); - return [NSNumber numberWithLong:nextId]; + @synchronized(self) { + long nextId = ++requestId; + if(loggingEnabled) + NSLog(@"got id %ld", nextId); + return [NSNumber numberWithLong:nextId]; + } } +(NSNumber*) queueRequest { @@ -303,19 +318,47 @@ static bool loggingEnabled = true; return [[request URL] absoluteString]; } -- (void)logRequest:(NSURLRequest*)request { - NSLog(@"request: %@", [self descriptionForRequest:request]); + +/** + * Update header and query params based on authentication settings + */ +- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers + queryParams:(NSDictionary *__autoreleasing *)querys + WithAuthSettings:(NSArray *)authSettings { + + if (!authSettings || [authSettings count] == 0) { + return; + } + + NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers]; + NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys]; + + SWGConfiguration *config = [SWGConfiguration sharedConfig]; + for (NSString *auth in authSettings) { + NSDictionary *authSetting = [[config authSettings] objectForKey:auth]; + + if (authSetting) { + if ([authSetting[@"in"] isEqualToString:@"header"]) { + [headersWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]]; + } + else if ([authSetting[@"in"] isEqualToString:@"query"]) { + [querysWithAuth setObject:authSetting[@"value"] forKey:authSetting[@"key"]]; + } + } + } + + *headers = [NSDictionary dictionaryWithDictionary:headersWithAuth]; + *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; } -- (void)logResponse:(id)data forRequest:(NSURLRequest*)request error:(NSError*)error { - NSLog(@"request: %@ response: %@ ", [self descriptionForRequest:request], data ); -} +#pragma mark - Perform Request Methods -(NSNumber*) dictionary: (NSString*) path method: (NSString*) method queryParams: (NSDictionary*) queryParams body: (id) body headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType: (NSString*) requestContentType responseContentType: (NSString*) responseContentType completionBlock: (void (^)(NSDictionary*, NSError *))completionBlock { @@ -340,6 +383,9 @@ static bool loggingEnabled = true; else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; } + + // auth setting + [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; NSMutableURLRequest * request = nil; if (body != nil && [body isKindOfClass:[NSArray class]]){ @@ -474,6 +520,7 @@ static bool loggingEnabled = true; queryParams: (NSDictionary*) queryParams body: (id) body headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings requestContentType: (NSString*) requestContentType responseContentType: (NSString*) responseContentType completionBlock: (void (^)(NSString*, NSError *))completionBlock { @@ -498,6 +545,9 @@ static bool loggingEnabled = true; else { self.responseSerializer = [AFHTTPResponseSerializer serializer]; } + + // auth setting + [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; NSMutableURLRequest * request = nil; if (body != nil && [body isKindOfClass:[NSArray class]]){ diff --git a/samples/client/petstore/objc/client/SWGConfiguration.h b/samples/client/petstore/objc/client/SWGConfiguration.h new file mode 100644 index 00000000000..33023ca3c6f --- /dev/null +++ b/samples/client/petstore/objc/client/SWGConfiguration.h @@ -0,0 +1,56 @@ +#import + +@interface SWGConfiguration : NSObject + + +/** + * Api key values for Api Key type Authentication + * + * To add or remove api key, use `setValue:forApiKeyField:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKey; + +/** + * Api key prefix values to be prepend to the respective api key + * + * To add or remove prefix, use `setValue:forApiKeyPrefixField:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix; + +/** + * Usename and Password for Basic type Authentication + */ +@property (nonatomic) NSString *username; +@property (nonatomic) NSString *password; + +/** + * Get configuration singleton instance + */ ++ (instancetype) sharedConfig; + +/** + * Sets field in `apiKey` + */ +- (void) setValue:(NSString *)value forApiKeyField:(NSString*)field; + +/** + * Sets field in `apiKeyPrefix` + */ +- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field; + +/** + * Get API key (with prefix if set) + */ +- (NSString *) getApiKeyWithPrefix:(NSString *) key; + +/** + * Get Basic Auth token + */ +- (NSString *) getBasicAuthToken; + +/** + * Get Authentication Setings + */ +- (NSDictionary *) authSettings; + +@end diff --git a/samples/client/petstore/objc/client/SWGConfiguration.m b/samples/client/petstore/objc/client/SWGConfiguration.m new file mode 100644 index 00000000000..89d5a597946 --- /dev/null +++ b/samples/client/petstore/objc/client/SWGConfiguration.m @@ -0,0 +1,92 @@ +#import "SWGConfiguration.h" + +@interface SWGConfiguration () + +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKey; +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableApiKeyPrefix; + +@end + +@implementation SWGConfiguration + +#pragma mark - Singletion Methods + ++ (instancetype) sharedConfig { + static SWGConfiguration *shardConfig = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shardConfig = [[self alloc] init]; + }); + return shardConfig; +} + +#pragma mark - Initialize Methods + +- (instancetype) init { + self = [super init]; + if (self) { + self.username = @""; + self.password = @""; + self.mutableApiKey = [NSMutableDictionary dictionary]; + self.mutableApiKeyPrefix = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - Instance Methods + +- (NSString *) getApiKeyWithPrefix:(NSString *)key { + if ([self.apiKeyPrefix objectForKey:key] && [self.apiKey objectForKey:key]) { + return [NSString stringWithFormat:@"%@ %@", [self.apiKeyPrefix objectForKey:key], [self.apiKey objectForKey:key]]; + } + else if ([self.apiKey objectForKey:key]) { + return [NSString stringWithFormat:@"%@", [self.apiKey objectForKey:key]]; + } + else { + return @""; + } +} + +- (NSString *) getBasicAuthToken { + NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", self.username, self.password]; + NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding]; + basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]]; + + return basicAuthCredentials; +} + +#pragma mark - Setter Methods + +- (void) setValue:(NSString *)value forApiKeyField:(NSString *)field { + [self.mutableApiKey setValue:value forKey:field]; +} + +- (void) setValue:(NSString *)value forApiKeyPrefixField:(NSString *)field { + [self.mutableApiKeyPrefix setValue:value forKey:field]; +} + +#pragma mark - Getter Methods + +- (NSDictionary *) apiKey { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKey]; +} + +- (NSDictionary *) apiKeyPrefix { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKeyPrefix]; +} + +#pragma mark - + +- (NSDictionary *) authSettings { + return @{ + @"api_key": @{ + @"type": @"api_key", + @"in": @"header", + @"key": @"api_key", + @"value": [self getApiKeyWithPrefix:@"api_key"] + }, + + }; +} + +@end diff --git a/samples/client/petstore/objc/client/SWGPetApi.h b/samples/client/petstore/objc/client/SWGPetApi.h index e7a3a84a9f5..aa255cd144e 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.h +++ b/samples/client/petstore/objc/client/SWGPetApi.h @@ -2,10 +2,14 @@ #import "SWGPet.h" #import "SWGFile.h" #import "SWGObject.h" +#import "SWGApiClient.h" @interface SWGPetApi: NSObject +@property(nonatomic, assign)SWGApiClient *apiClient; + +-(instancetype) initWithApiClient:(SWGApiClient *)apiClient; -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; @@ -150,4 +154,4 @@ -@end \ No newline at end of file +@end diff --git a/samples/client/petstore/objc/client/SWGPetApi.m b/samples/client/petstore/objc/client/SWGPetApi.m index 9f2b79c51f8..c14da125af5 100644 --- a/samples/client/petstore/objc/client/SWGPetApi.m +++ b/samples/client/petstore/objc/client/SWGPetApi.m @@ -1,7 +1,6 @@ #import "SWGPetApi.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" -#import "SWGApiClient.h" #import "SWGPet.h" #import "SWGFile.h" @@ -11,8 +10,36 @@ @end @implementation SWGPetApi + static NSString * basePath = @"http://petstore.swagger.io/v2"; +#pragma mark - Initialize methods + +- (id) init { + self = [super init]; + if (self) { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +- (id) initWithApiClient:(SWGApiClient *)apiClient { + self = [super init]; + if (self) { + if (apiClient) { + self.apiClient = apiClient; + } + else { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + } + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - + +(SWGPetApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { static SWGPetApi* singletonAPI = nil; @@ -31,21 +58,10 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return basePath; } --(SWGApiClient*) apiClient { - return [SWGApiClient sharedClientFromPool:basePath]; -} - -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } --(id) init { - self = [super init]; - self.defaultHeaders = [NSMutableDictionary dictionary]; - [self apiClient]; - return self; -} - -(void) setHeaderValue:(NSString*) value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; @@ -101,6 +117,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[@"application/json", @"application/xml"]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; id __body = body; @@ -135,19 +154,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"PUT" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -206,6 +224,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[@"application/json", @"application/xml"]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; id __body = body; @@ -240,19 +261,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -317,6 +337,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; @@ -328,16 +351,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // response is in a container // array container response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -362,6 +384,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; }]; + @@ -418,6 +441,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; @@ -429,16 +455,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // response is in a container // array container response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -463,6 +488,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; }]; + @@ -517,6 +543,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[@"api_key", @"petstore_auth"]; + id bodyDictionary = nil; @@ -528,8 +557,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - @@ -541,11 +568,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // complex response // comples response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -621,6 +649,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[@"application/x-www-form-urlencoded"]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; @@ -648,19 +679,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -727,6 +757,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; @@ -738,19 +771,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"DELETE" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -817,6 +849,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[@"multipart/form-data"]]; + // Authentication setting + NSArray *authSettings = @[@"petstore_auth"]; + id bodyDictionary = nil; @@ -851,19 +886,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -880,3 +914,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; @end + + + diff --git a/samples/client/petstore/objc/client/SWGQueryParamCollection.m b/samples/client/petstore/objc/client/SWGQueryParamCollection.m index 9ce319940dd..83303045185 100644 --- a/samples/client/petstore/objc/client/SWGQueryParamCollection.m +++ b/samples/client/petstore/objc/client/SWGQueryParamCollection.m @@ -13,4 +13,4 @@ return self; } -@end \ No newline at end of file +@end diff --git a/samples/client/petstore/objc/client/SWGStoreApi.h b/samples/client/petstore/objc/client/SWGStoreApi.h index b4b8e5af5dc..49d8db806c8 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.h +++ b/samples/client/petstore/objc/client/SWGStoreApi.h @@ -1,10 +1,14 @@ #import #import "SWGOrder.h" #import "SWGObject.h" +#import "SWGApiClient.h" @interface SWGStoreApi: NSObject +@property(nonatomic, assign)SWGApiClient *apiClient; + +-(instancetype) initWithApiClient:(SWGApiClient *)apiClient; -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; @@ -73,4 +77,4 @@ -@end \ No newline at end of file +@end diff --git a/samples/client/petstore/objc/client/SWGStoreApi.m b/samples/client/petstore/objc/client/SWGStoreApi.m index 75875ff4eae..a112db6d639 100644 --- a/samples/client/petstore/objc/client/SWGStoreApi.m +++ b/samples/client/petstore/objc/client/SWGStoreApi.m @@ -1,7 +1,6 @@ #import "SWGStoreApi.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" -#import "SWGApiClient.h" #import "SWGOrder.h" @@ -10,8 +9,36 @@ @end @implementation SWGStoreApi + static NSString * basePath = @"http://petstore.swagger.io/v2"; +#pragma mark - Initialize methods + +- (id) init { + self = [super init]; + if (self) { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +- (id) initWithApiClient:(SWGApiClient *)apiClient { + self = [super init]; + if (self) { + if (apiClient) { + self.apiClient = apiClient; + } + else { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + } + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - + +(SWGStoreApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { static SWGStoreApi* singletonAPI = nil; @@ -30,21 +57,10 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return basePath; } --(SWGApiClient*) apiClient { - return [SWGApiClient sharedClientFromPool:basePath]; -} - -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } --(id) init { - self = [super init]; - self.defaultHeaders = [NSMutableDictionary dictionary]; - [self apiClient]; - return self; -} - -(void) setHeaderValue:(NSString*) value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; @@ -98,6 +114,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[@"api_key"]; + id bodyDictionary = nil; @@ -109,16 +128,15 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // response is in a container // map container response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -136,6 +154,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; }]; + @@ -186,6 +205,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; id __body = body; @@ -220,8 +242,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - @@ -233,11 +253,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // complex response // comples response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -309,6 +330,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -320,8 +344,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - @@ -333,11 +355,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // complex response // comples response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -409,6 +432,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -420,19 +446,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"DELETE" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -449,3 +474,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; @end + + + diff --git a/samples/client/petstore/objc/client/SWGUserApi.h b/samples/client/petstore/objc/client/SWGUserApi.h index 47a5dd95e09..e6e73ddfba6 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.h +++ b/samples/client/petstore/objc/client/SWGUserApi.h @@ -1,10 +1,14 @@ #import #import "SWGUser.h" #import "SWGObject.h" +#import "SWGApiClient.h" @interface SWGUserApi: NSObject +@property(nonatomic, assign)SWGApiClient *apiClient; + +-(instancetype) initWithApiClient:(SWGApiClient *)apiClient; -(void) addHeader:(NSString*)value forKey:(NSString*)key; -(unsigned long) requestQueueSize; +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key; @@ -141,4 +145,4 @@ -@end \ No newline at end of file +@end diff --git a/samples/client/petstore/objc/client/SWGUserApi.m b/samples/client/petstore/objc/client/SWGUserApi.m index 3e87268a4c6..e2fe69aca8d 100644 --- a/samples/client/petstore/objc/client/SWGUserApi.m +++ b/samples/client/petstore/objc/client/SWGUserApi.m @@ -1,7 +1,6 @@ #import "SWGUserApi.h" #import "SWGFile.h" #import "SWGQueryParamCollection.h" -#import "SWGApiClient.h" #import "SWGUser.h" @@ -10,8 +9,36 @@ @end @implementation SWGUserApi + static NSString * basePath = @"http://petstore.swagger.io/v2"; +#pragma mark - Initialize methods + +- (id) init { + self = [super init]; + if (self) { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +- (id) initWithApiClient:(SWGApiClient *)apiClient { + self = [super init]; + if (self) { + if (apiClient) { + self.apiClient = apiClient; + } + else { + self.apiClient = [SWGApiClient sharedClientFromPool:basePath]; + } + self.defaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - + +(SWGUserApi*) apiWithHeader:(NSString*)headerValue key:(NSString*)key { static SWGUserApi* singletonAPI = nil; @@ -30,21 +57,10 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; return basePath; } --(SWGApiClient*) apiClient { - return [SWGApiClient sharedClientFromPool:basePath]; -} - -(void) addHeader:(NSString*)value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; } --(id) init { - self = [super init]; - self.defaultHeaders = [NSMutableDictionary dictionary]; - [self apiClient]; - return self; -} - -(void) setHeaderValue:(NSString*) value forKey:(NSString*)key { [self.defaultHeaders setValue:value forKey:key]; @@ -100,6 +116,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; id __body = body; @@ -134,19 +153,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -205,6 +223,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; id __body = body; @@ -239,19 +260,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -310,6 +330,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; id __body = body; @@ -344,19 +367,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"POST" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -425,6 +447,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -436,8 +461,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - @@ -446,11 +469,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // primitive response // primitive response type - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -465,6 +489,7 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; + // complex response @@ -517,6 +542,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -528,19 +556,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -603,6 +630,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -614,8 +644,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - @@ -627,11 +655,12 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // complex response // comples response type - return [client dictionary: requestUrl + return [self.apiClient dictionary: requestUrl method: @"GET" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSDictionary *data, NSError *error) { @@ -705,6 +734,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; id __body = body; @@ -739,19 +771,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"PUT" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -814,6 +845,9 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; // request content type NSString *requestContentType = [SWGApiClient selectHeaderContentType:@[]]; + // Authentication setting + NSArray *authSettings = @[]; + id bodyDictionary = nil; @@ -825,19 +859,18 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; - SWGApiClient* client = [SWGApiClient sharedClientFromPool:basePath]; - // it's void - return [client stringWithCompletionBlock: requestUrl + return [self.apiClient stringWithCompletionBlock: requestUrl method: @"DELETE" queryParams: queryParams body: bodyDictionary headerParams: headerParams + authSettings: authSettings requestContentType: requestContentType responseContentType: responseContentType completionBlock: ^(NSString *data, NSError *error) { @@ -854,3 +887,6 @@ static NSString * basePath = @"http://petstore.swagger.io/v2"; @end + + + diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/APIClient.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/APIClient.pm index 0f0fea793e3..da29b3e246a 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/APIClient.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/APIClient.pm @@ -1,9 +1,10 @@ -package WWW::SwaggerClient::APIClient; +package WWW::SwaggerClient::ApiClient; use strict; use warnings; use utf8; +use MIME::Base64; use LWP::UserAgent; use HTTP::Headers; use HTTP::Response; @@ -15,20 +16,18 @@ use URI::Escape; use Scalar::Util; use Log::Any qw($log); use Carp; -use Switch; use Module::Runtime qw(use_module); -# class variables -my $ua = LWP::UserAgent->new; -my $http_user_agent = 'Perl-Swagger'; # HTTP user-agent -my $http_timeout; #timeout -my $base_url = "http://petstore.swagger.io/v2"; - +use WWW::SwaggerClient::Configuration; sub new { my $class = shift; - my %args = @_; + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'base_url' => 'http://petstore.swagger.io/v2', + @_ + ); return bless \%args, $class; } @@ -38,8 +37,8 @@ sub new # @param string $user_agent The user agent of the API client # sub set_user_agent { - my $user_agent = shift; - $http_user_agent= $user_agent; + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; } # Set timeout @@ -47,11 +46,11 @@ sub set_user_agent { # @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] # sub set_timeout { - my $seconds = shift; + my ($self, $seconds) = @_; if (!looks_like_number($seconds)) { croak('Timeout variable must be numeric.'); } - $http_timeout = $seconds; + $self->{http_timeout} = $seconds; } # make the HTTP request @@ -63,60 +62,63 @@ sub set_timeout { # @return mixed sub call_api { my $self = shift; - my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data) = @_; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; - my $headers = HTTP::Headers->new(%$header_params); + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); - my $_url = $base_url . $resource_path; + + my $_url = $self->{base_url} . $resource_path; # build query if (%$query_params) { $_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify }); } + # body data $body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string my $_body_data = %$post_params ? $post_params : $body_data; # Make the HTTP request my $_request; - switch ($method) { - case 'POST' { + if ($method eq 'POST') { # multipart - my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? 'form-data' : $header_params->{'Content-Type'}; - - $_request = POST($_url, Accept => $header_params->{Accept}, - Content_Type => $_content_type, Content => $_body_data); - } - case 'PUT' { - # multipart - my $_content_type = lc $header_params->{'Content-Type'} eq 'multipart/form' ? - 'form-data' : $header_params->{'Content-Type'}; - $_request = PUT($_url, Accept => $header_params->{Accept}, - Content_Type => $_content_type, Content => $_body_data); - } - case 'GET' { - $_request = GET($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}); - } - case 'HEAD' { - $_request = HEAD($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}); - } - case 'DELETE' { #TODO support form data - $_request = DELETE($_url, Accept => $header_params->{'Accept'}, - Content_Type => $header_params->{'Content-Type'}, Content => $_body_data); - } - case 'PATCH' { #TODO - } + + $_request = POST($_url, %$header_params, Content => $_body_data); } + elsif ($method eq 'PUT') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = PUT($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'GET') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = GET($_url, %$header_params); + } + elsif ($method eq 'HEAD') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = HEAD($_url,%$header_params); + } + elsif ($method eq 'DELETE') { #TODO support form data + my $headers = HTTP::Headers->new(%$header_params); + $_request = DELETE($_url, %$headers); + } + elsif ($method eq 'PATCH') { #TODO + } + else { + } - $ua->timeout($http_timeout); - $ua->agent($http_user_agent); + $self->{ua}->timeout($self->{http_timeout} || $WWW::SwaggerClient::Configuration::http_timeout); + $self->{ua}->agent($self->{http_user_agent} || $WWW::SwaggerClient::Configuration::http_user_agent); - my $_response = $ua->request($_request); + my $_response = $self->{ua}->request($_request); unless ($_response->is_success) { croak("API Exception(".$_response->code."): ".$_response->message); @@ -126,41 +128,13 @@ sub call_api { } - -# Build a JSON POST object -sub sanitize_for_serialization -{ -# my $data = shift; -# if (is_scalar($data) || null === $data) { -# $sanitized = $data; -# } else if ($data instanceof \DateTime) { -# $sanitized = $data->format(\DateTime::ISO8601); -# } else if (is_array($data)) { -# foreach ($data as $property => $value) { -# $data[$property] = $this->sanitizeForSerialization($value); -# } -# $sanitized = $data; -# } else if (is_object($data)) { -# $values = array(); -# foreach (array_keys($data::$swaggerTypes) as $property) { -# $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); -# } -# $sanitized = $values; -# } else { -# $sanitized = (string)$data; -# } -# -# return $sanitized; -} - - # Take value and turn it into a string suitable for inclusion in # the path, by url-encoding. # @param string $value a string which will be part of the path # @return string the serialized object sub to_path_value { - my $value = shift; - return uri_escape(to_string($value)); + my ($self, $value) = @_; + return uri_escape($self->to_string($value)); } @@ -171,11 +145,11 @@ sub to_path_value { # @param object $object an object to be serialized to a string # @return string the serialized object sub to_query_value { - my $object = shift; + my ($self, $object) = @_; if (is_array($object)) { return implode(',', $object); } else { - return toString($object); + return $self->to_string($object); } } @@ -186,8 +160,8 @@ sub to_query_value { # @param string $value a string which will be part of the header # @return string the header string sub to_header_value { - my $value = shift; - return to_string($value); + my ($self, $value) = @_; + return $self->to_string($value); } # Take value and turn it into a string suitable for inclusion in @@ -196,8 +170,8 @@ sub to_header_value { # @param string $value the value of the form parameter # @return string the form string sub to_form_value { - my $value = shift; - return to_string($value); + my ($self, $value) = @_; + return $self->to_string($value); } # Take value and turn it into a string suitable for inclusion in @@ -206,7 +180,7 @@ sub to_form_value { # @param string $value the value of the parameter # @return string the header string sub to_string { - my $value = shift; + my ($self, $value) = @_; if (ref($value) eq "DateTime") { # datetime in ISO8601 format return $value->datetime(); } @@ -242,7 +216,7 @@ sub deserialize $_result = \@_values; } elsif ($class eq 'DateTime') { $_result = DateTime->from_epoch(epoch => str2time($data)); - } elsif (grep /^$data$/, ('string', 'int', 'float', 'bool')) { #TODO revise the primitive type + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type $_result= $data; } else { # model my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; @@ -287,5 +261,48 @@ sub select_header_content_type } +# Get API key (with prefix if set) +# @param string key name +# @return string API key with the prefix +sub get_api_key_with_prefix +{ + my ($self, $api_key) = @_; + if ($WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}) { + return $WWW::SwaggerClient::Configuration::api_key_prefix->{$api_key}." ".$WWW::SwaggerClient::Configuration::api_key->{$api_key}; + } else { + return $WWW::SwaggerClient::Configuration::api_key->{$api_key}; + } +} + +# update hearder and query param based on authentication setting +# +# @param array $headerParams header parameters (by ref) +# @param array $queryParams query parameters (by ref) +# @param array $authSettings array of authentication scheme (e.g ['api_key']) +sub update_params_for_auth { + my ($self, $header_params, $query_params, $auth_settings) = @_; + + return if (!defined($auth_settings) || scalar(@$auth_settings) == 0); + + # one endpoint can have more than 1 auth settings + foreach my $auth (@$auth_settings) { + # determine which one to use + if (!defined($auth)) { + } + elsif ($auth eq 'api_key') { + $header_params->{'api_key'} = $self->get_api_key_with_prefix('api_key'); + + } + elsif ($auth eq 'petstore_auth') { + + # TODO support oauth + } + + else { + # TODO show warning about security definition not found + } + } +} + 1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm new file mode 100644 index 00000000000..bbce9d74759 --- /dev/null +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/Configuration.pm @@ -0,0 +1,22 @@ +package WWW::SwaggerClient::Configuration; + +use strict; +use warnings; +use utf8; + +use Log::Any qw($log); +use Carp; + +# class/static variables +our $api_client; +our $http_timeout = 180; +our $http_user_agent = 'Perl-Swagger'; + +# authenticaiton setting +our $api_key = {}; +our $api_key_prefix = {}; +our $username; +our $password; + + +1; diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm index 57237a96974..44bc1567a3d 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/PetApi.pm @@ -27,12 +27,8 @@ use Exporter; use Carp qw( croak ); use Log::Any qw($log); - -#use WWW::Swagger::Model::Category; -#use WWW::Swagger::Model::Pet; - - -use WWW::SwaggerClient::APIClient; +use WWW::SwaggerClient::ApiClient; +use WWW::SwaggerClient::Configuration; our @EXPORT_OK = qw( update_pet @@ -48,7 +44,7 @@ our @EXPORT_OK = qw( sub new { my $class = shift; - my $default_api_client = WWW::SwaggerClient::APIClient->new; + my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( 'api_client' => $default_api_client, @_ @@ -91,26 +87,26 @@ sub new { if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml', ); + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -142,26 +138,26 @@ sub new { if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml', ); + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/json', 'application/xml'); my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -195,9 +191,9 @@ sub new { } $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params + # query params if ( exists $args{'status'}) { - $query_params->{'status'} = WWW::::APIClient::to_query_value($args{'status'}); + $query_params->{'status'} = $self->{api_client}->to_query_value($args{'status'}); } @@ -205,18 +201,18 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); + return $_response_object; } @@ -249,9 +245,9 @@ sub new { } $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params + # query params if ( exists $args{'tags'}) { - $query_params->{'tags'} = WWW::::APIClient::to_query_value($args{'tags'}); + $query_params->{'tags'} = $self->{api_client}->to_query_value($args{'tags'}); } @@ -259,18 +255,18 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('ARRAY[Pet]', $response); + return $_response_object; } @@ -310,28 +306,28 @@ sub new { - # path params + # path params if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'pet_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['api_key', 'petstore_auth']; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('Pet', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('Pet', $response); + return $_response_object; } @@ -369,38 +365,38 @@ sub new { if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded', ); + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded'); - # path params + # path params if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'pet_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } - # form params + # form params if ( exists $args{'name'} ) { - $form_params->{'name'} = WWW::SwaggerClient::APIClient::to_form_value($args{'name'}); + $form_params->{'name'} = $self->{api_client}->to_form_value($args{'name'}); - } # form params + }# form params if ( exists $args{'status'} ) { - $form_params->{'status'} = WWW::SwaggerClient::APIClient::to_form_value($args{'status'}); + $form_params->{'status'} = $self->{api_client}->to_form_value($args{'status'}); } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -441,28 +437,28 @@ sub new { $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # header params + # header params if ( exists $args{'api_key'}) { - $header_params->{'api_key'} = WWW::SwaggerClient::APIClient::to_header_value($args{'api_key'}); + $header_params->{'api_key'} = $self->{api_client}->to_header_value($args{'api_key'}); } - # path params + # path params if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'pet_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -501,22 +497,22 @@ sub new { if ($_header_accept) { $header_params->{'Accept'} = $_header_accept; } - $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('multipart/form-data', ); + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('multipart/form-data'); - # path params + # path params if ( exists $args{'pet_id'}) { my $_base_variable = "{" . "petId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'pet_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'pet_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } - # form params + # form params if ( exists $args{'additional_metadata'} ) { - $form_params->{'additionalMetadata'} = WWW::SwaggerClient::APIClient::to_form_value($args{'additional_metadata'}); + $form_params->{'additionalMetadata'} = $self->{api_client}->to_form_value($args{'additional_metadata'}); - } # form params + }# form params if ( exists $args{'file'} ) { $form_params->{'file'} = [] unless defined $form_params->{'file'}; push $form_params->{'file'}, $args{'file'}; @@ -526,14 +522,14 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['petstore_auth']; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm index d4261c6bbec..6e22d4dbcc0 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/StoreApi.pm @@ -27,12 +27,8 @@ use Exporter; use Carp qw( croak ); use Log::Any qw($log); - -#use WWW::Swagger::Model::Category; -#use WWW::Swagger::Model::Pet; - - -use WWW::SwaggerClient::APIClient; +use WWW::SwaggerClient::ApiClient; +use WWW::SwaggerClient::Configuration; our @EXPORT_OK = qw( get_inventory @@ -44,7 +40,7 @@ our @EXPORT_OK = qw( sub new { my $class = shift; - my $default_api_client = WWW::SwaggerClient::APIClient->new; + my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( 'api_client' => $default_api_client, @_ @@ -95,18 +91,18 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = ['api_key']; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('HASH[string,int]', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('HASH[string,int]', $response); + return $_response_object; } @@ -144,23 +140,23 @@ sub new { my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('Order', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('Order', $response); + return $_response_object; } @@ -200,28 +196,28 @@ sub new { - # path params + # path params if ( exists $args{'order_id'}) { my $_base_variable = "{" . "orderId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'order_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'order_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('Order', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('Order', $response); + return $_response_object; } @@ -261,24 +257,24 @@ sub new { - # path params + # path params if ( exists $args{'order_id'}) { my $_base_variable = "{" . "orderId" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'order_id'}); + my $_base_value = $self->{api_client}->to_path_value($args{'order_id'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } diff --git a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm index 2e5889ba39e..5b2fc0a0000 100644 --- a/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm +++ b/samples/client/petstore/perl/lib/WWW/SwaggerClient/UserApi.pm @@ -27,12 +27,8 @@ use Exporter; use Carp qw( croak ); use Log::Any qw($log); - -#use WWW::Swagger::Model::Category; -#use WWW::Swagger::Model::Pet; - - -use WWW::SwaggerClient::APIClient; +use WWW::SwaggerClient::ApiClient; +use WWW::SwaggerClient::Configuration; our @EXPORT_OK = qw( create_user @@ -48,7 +44,7 @@ our @EXPORT_OK = qw( sub new { my $class = shift; - my $default_api_client = WWW::SwaggerClient::APIClient->new; + my $default_api_client = $WWW::SwaggerClient::Configuration::api_client ? $WWW::SwaggerClient::Configuration::api_client : WWW::SwaggerClient::ApiClient->new; my (%self) = ( 'api_client' => $default_api_client, @_ @@ -98,19 +94,19 @@ sub new { my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -149,19 +145,19 @@ sub new { my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -200,19 +196,19 @@ sub new { my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -247,12 +243,12 @@ sub new { } $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type(); - # query params + # query params if ( exists $args{'username'}) { - $query_params->{'username'} = WWW::::APIClient::to_query_value($args{'username'}); - } # query params + $query_params->{'username'} = $self->{api_client}->to_query_value($args{'username'}); + }# query params if ( exists $args{'password'}) { - $query_params->{'password'} = WWW::::APIClient::to_query_value($args{'password'}); + $query_params->{'password'} = $self->{api_client}->to_query_value($args{'password'}); } @@ -260,18 +256,18 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('string', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('string', $response); + return $_response_object; } @@ -310,14 +306,14 @@ sub new { my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -358,28 +354,28 @@ sub new { - # path params + # path params if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'username'}); + my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call my $response = $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); if (!$response) { return; } - my $_response_object = $self->{api_client}->deserialize('User', $response); - return $_response_object; + my $_response_object = $self->{api_client}->deserialize('User', $response); + return $_response_object; } @@ -420,27 +416,27 @@ sub new { - # path params + # path params if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'username'}); + my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # body params + # body params if ( exists $args{'body'}) { $_body_data = $args{'body'}; } - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } @@ -481,24 +477,24 @@ sub new { - # path params + # path params if ( exists $args{'username'}) { my $_base_variable = "{" . "username" . "}"; - my $_base_value = WWW::SwaggerClient::APIClient::to_path_value($args{'username'}); + my $_base_value = $self->{api_client}->to_path_value($args{'username'}); $_resource_path =~ s/$_base_variable/$_base_value/g; } my $_body_data; - # for HTTP post (form) - #$_body_data = $_body ? undef : $form_params; + # authentication setting, if any + my $auth_settings = []; # make the API Call $self->{api_client}->call_api($_resource_path, $_method, $query_params, $form_params, - $header_params, $_body_data); + $header_params, $_body_data, $auth_settings); return; } diff --git a/samples/client/petstore/perl/t/01_pet_api.t b/samples/client/petstore/perl/t/01_pet_api.t index 7855254e657..6b731b846fe 100644 --- a/samples/client/petstore/perl/t/01_pet_api.t +++ b/samples/client/petstore/perl/t/01_pet_api.t @@ -1,4 +1,4 @@ -use Test::More tests => 31; +use Test::More tests => 33; use Test::Exception; use lib 'lib'; @@ -6,12 +6,19 @@ use strict; use warnings; use_ok('WWW::SwaggerClient::PetApi'); -use_ok('WWW::SwaggerClient::APIClient'); +use_ok('WWW::SwaggerClient::ApiClient'); use_ok('WWW::SwaggerClient::Object::Pet'); use_ok('WWW::SwaggerClient::Object::Tag'); use_ok('WWW::SwaggerClient::Object::Category'); + +my $api_client = WWW::SwaggerClient::ApiClient->new('base_url' => 'http://testing'); +my $pet_api = WWW::SwaggerClient::PetApi->new('api_client' => $api_client); +is $pet_api->{api_client}->{base_url}, 'http://testing', 'get the proper base URL from api client'; + my $api = WWW::SwaggerClient::PetApi->new(); +is $api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client'; + # test select_header_content_type is $api->{api_client}->select_header_content_type('application/xml', 'Application/JSON'), 'application/json', 'get the proper content type application/json but not application/xml'; is $api->{api_client}->select_header_content_type('application/xml'), 'application/xml', 'get the proper content type application/json'; diff --git a/samples/client/petstore/perl/test.pl b/samples/client/petstore/perl/test.pl index eb06f786f98..d4f3fbb6f4b 100755 --- a/samples/client/petstore/perl/test.pl +++ b/samples/client/petstore/perl/test.pl @@ -5,7 +5,8 @@ use lib 'lib'; use strict; use warnings; use WWW::SwaggerClient::PetApi; -use WWW::SwaggerClient::APIClient; +use WWW::SwaggerClient::ApiClient; +use WWW::SwaggerClient::Configuration; use WWW::SwaggerClient::Object::Pet; use WWW::SwaggerClient::Object::Tag; use WWW::SwaggerClient::Object::Category; @@ -13,6 +14,14 @@ use JSON; use Data::Dumper; use DateTime; +$WWW::SwaggerClient::Configuration::http_user_agent = 'Perl-Swagger-Test'; +$WWW::SwaggerClient::Configuration::api_key->{'api_key'} = 'ZZZZZZZZZZZZZZ'; +$WWW::SwaggerClient::Configuration::api_key_prefix->{'api_key'} = 'BEARER'; + +$WWW::SwaggerClient::Configuration::username = 'username'; +$WWW::SwaggerClient::Configuration::password = 'password'; + + my $api = WWW::SwaggerClient::PetApi->new(); my $pet_id = 10008; diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php b/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php index f7002fba18d..5415ff66972 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/APIClient.php @@ -17,7 +17,7 @@ namespace SwaggerClient; -class APIClient { +class ApiClient { public static $PATCH = "PATCH"; public static $POST = "POST"; @@ -178,7 +178,7 @@ class APIClient { * @param array $headerParams parameters to be place in request header * @return mixed */ - public function callAPI($resourcePath, $method, $queryParams, $postData, + public function callApi($resourcePath, $method, $queryParams, $postData, $headerParams, $authSettings) { $headers = array(); @@ -187,13 +187,10 @@ class APIClient { $this->updateParamsForAuth($headerParams, $queryParams, $authSettings); # construct the http header - if ($headerParams != null) { - # add default header - $headerParams = array_merge((array)self::$default_header, $headerParams); + $headerParams = array_merge((array)self::$default_header, (array)$headerParams); - foreach ($headerParams as $key => $val) { - $headers[] = "$key: $val"; - } + foreach ($headerParams as $key => $val) { + $headers[] = "$key: $val"; } // form data @@ -233,35 +230,49 @@ class APIClient { curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); } else if ($method != self::$GET) { - throw new APIClientException('Method ' . $method . ' is not recognized.'); + throw new ApiException('Method ' . $method . ' is not recognized.'); } curl_setopt($curl, CURLOPT_URL, $url); // Set user agent curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + // debugging for curl + if (Configuration::$debug) { + error_log("[DEBUG] HTTP Request body ~BEGIN~\n".print_r($postData, true)."\n~END~\n", 3, Configuration::$debug_file); + + curl_setopt($curl, CURLOPT_VERBOSE, 1); + curl_setopt($curl, CURLOPT_STDERR, fopen(Configuration::$debug_file, 'a')); + } else { + curl_setopt($curl, CURLOPT_VERBOSE, 0); + } + + // obtain the HTTP response headers + curl_setopt($curl, CURLOPT_HEADER, 1); + // Make the request $response = curl_exec($curl); + $http_header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE); + $http_header = substr($response, 0, $http_header_size); + $http_body = substr($response, $http_header_size); $response_info = curl_getinfo($curl); + // debug HTTP response body + if (Configuration::$debug) { + error_log("[DEBUG] HTTP Response body ~BEGIN~\n".print_r($http_body, true)."\n~END~\n", 3, Configuration::$debug_file); + } + // Handle the response if ($response_info['http_code'] == 0) { - throw new APIClientException("TIMEOUT: api call to " . $url . - " took more than 5s to return", 0, $response_info, $response); + throw new ApiException("API call to $url timed out: ".serialize($response_info), 0, null, null); } else if ($response_info['http_code'] >= 200 && $response_info['http_code'] <= 299 ) { - $data = json_decode($response); + $data = json_decode($http_body); if (json_last_error() > 0) { // if response is a string - $data = $response; + $data = $http_body; } - } else if ($response_info['http_code'] == 401) { - throw new APIClientException("Unauthorized API request to " . $url . - ": " . serialize($response), 0, $response_info, $response); - } else if ($response_info['http_code'] == 404) { - $data = null; } else { - throw new APIClientException("Can't connect to the api: " . $url . - " response code: " . - $response_info['http_code'], 0, $response_info, $response); + throw new ApiException("[".$response_info['http_code']."] Error connecting to the API ($url)", + $response_info['http_code'], $http_header, $http_body); } return $data; } @@ -283,7 +294,9 @@ class APIClient { } else if (is_object($data)) { $values = array(); foreach (array_keys($data::$swaggerTypes) as $property) { - $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); + if ($data->$property !== null) { + $values[$data::$attributeMap[$property]] = $this->sanitizeForSerialization($data->$property); + } } $sanitized = $values; } else { @@ -388,7 +401,7 @@ class APIClient { $deserialized = $values; } elseif ($class == 'DateTime') { $deserialized = new \DateTime($data); - } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool'))) { + } elseif (in_array($class, array('string', 'int', 'float', 'double', 'bool', 'object'))) { settype($data, $class); $deserialized = $data; } else { diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/APIClientException.php b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php similarity index 50% rename from samples/client/petstore/php/SwaggerClient-php/lib/APIClientException.php rename to samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php index 8d83da0186e..40158cf76e6 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/APIClientException.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/ApiException.php @@ -19,20 +19,40 @@ namespace SwaggerClient; use \Exception; -class APIClientException extends Exception { - protected $response, $response_info; +class ApiException extends Exception { - public function __construct($message="", $code=0, $response_info=null, $response=null) { + /** + * The HTTP body of the server response. + */ + protected $response_body; + + /** + * The HTTP header of the server response. + */ + protected $response_headers; + + public function __construct($message="", $code=0, $responseHeaders=null, $responseBody=null) { parent::__construct($message, $code); - $this->response_info = $response_info; - $this->response = $response; + $this->response_headers = $responseHeaders; + $this->response_body = $responseBody; } - public function getResponse() { - return $this->response; + /** + * Get the HTTP response header + * + * @return string HTTP response header + */ + public function getResponseHeaders() { + return $this->response_headers; } - public function getResponseInfo() { - return $this->response_info; + /** + * Get the HTTP response body + * + * @return string HTTP response body + */ + public function getResponseBody() { + return $this->response_body; } + } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php index 1f91f8d9063..8a0dc734a0d 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/Configuration.php @@ -19,27 +19,47 @@ namespace SwaggerClient; class Configuration { - public static $PATCH = "PATCH"; - public static $POST = "POST"; - public static $GET = "GET"; - public static $PUT = "PUT"; - public static $DELETE = "DELETE"; - - // authentication setting + /** + * Associate array to store API key(s) + */ public static $apiKey = array(); + + /** + * Associate array to store API prefix (e.g. Bearer) + */ public static $apiKeyPrefix = array(); + + /** + * Username for HTTP basic authentication + */ public static $username = ''; + + /** + * Password for HTTP basic authentication + */ public static $password = ''; - // an instance of APIClient + /** + * The default instance of ApiClient + */ public static $apiClient; - /* - * manually initalize API client - */ + /** + * Debug switch (default set to false) + */ + public static $debug = false; + + /** + * Debug file location (log to STDOUT by default) + */ + public static $debug_file = 'php://output'; + + /* + * manually initalize ApiClient + */ public static function init() { if (self::$apiClient === null) - self::$apiClient = new APIClient(); + self::$apiClient = new ApiClient(); } } diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php index 9456f42bc15..338646bfefe 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/PetApi.php @@ -27,7 +27,7 @@ class PetApi { function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { - Configuration::$apiClient = new APIClient(); // create a new API client if not present + Configuration::$apiClient = new ApiClient(); // create a new API client if not present $this->apiClient = Configuration::$apiClient; } else @@ -37,7 +37,7 @@ class PetApi { } } - private $apiClient; // instance of the APIClient + private $apiClient; // instance of the ApiClient /** * get the API client diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php index 629201965dc..73a060f421d 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/StoreApi.php @@ -27,7 +27,7 @@ class StoreApi { function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { - Configuration::$apiClient = new APIClient(); // create a new API client if not present + Configuration::$apiClient = new ApiClient(); // create a new API client if not present $this->apiClient = Configuration::$apiClient; } else @@ -37,7 +37,7 @@ class StoreApi { } } - private $apiClient; // instance of the APIClient + private $apiClient; // instance of the ApiClient /** * get the API client diff --git a/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php b/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php index 0f4a1bf2dac..1e4f7dbc293 100644 --- a/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php +++ b/samples/client/petstore/php/SwaggerClient-php/lib/UserApi.php @@ -27,7 +27,7 @@ class UserApi { function __construct($apiClient = null) { if (null === $apiClient) { if (Configuration::$apiClient === null) { - Configuration::$apiClient = new APIClient(); // create a new API client if not present + Configuration::$apiClient = new ApiClient(); // create a new API client if not present $this->apiClient = Configuration::$apiClient; } else @@ -37,7 +37,7 @@ class UserApi { } } - private $apiClient; // instance of the APIClient + private $apiClient; // instance of the ApiClient /** * get the API client diff --git a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php index 39c5cecd018..d02b8e74558 100644 --- a/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php +++ b/samples/client/petstore/php/SwaggerClient-php/tests/PetApiTest.php @@ -7,8 +7,11 @@ class PetApiTest extends \PHPUnit_Framework_TestCase // add a new pet (id 10005) to ensure the pet object is available for all the tests public static function setUpBeforeClass() { + // enable debugging + //SwaggerClient\Configuration::$debug = true; + // skip initializing the API client as it should be automatic - //$api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + //$api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); // new pet $new_pet_id = 10005; $new_pet = new SwaggerClient\models\Pet; @@ -31,36 +34,36 @@ class PetApiTest extends \PHPUnit_Framework_TestCase $add_response = $pet_api->addPet($new_pet); } - // test static functions defined in APIClient - public function testAPIClient() + // test static functions defined in ApiClient + public function testApiClient() { // test selectHeaderAccept - $this->assertSame('application/json', SwaggerClient\APIClient::selectHeaderAccept(array('application/xml','application/json'))); - $this->assertSame(NULL, SwaggerClient\APIClient::selectHeaderAccept(array())); - $this->assertSame('application/yaml,application/xml', SwaggerClient\APIClient::selectHeaderAccept(array('application/yaml','application/xml'))); + $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderAccept(array('application/xml','application/json'))); + $this->assertSame(NULL, SwaggerClient\ApiClient::selectHeaderAccept(array())); + $this->assertSame('application/yaml,application/xml', SwaggerClient\ApiClient::selectHeaderAccept(array('application/yaml','application/xml'))); // test selectHeaderContentType - $this->assertSame('application/json', SwaggerClient\APIClient::selectHeaderContentType(array('application/xml','application/json'))); - $this->assertSame('application/json', SwaggerClient\APIClient::selectHeaderContentType(array())); - $this->assertSame('application/yaml,application/xml', SwaggerClient\APIClient::selectHeaderContentType(array('application/yaml','application/xml'))); + $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderContentType(array('application/xml','application/json'))); + $this->assertSame('application/json', SwaggerClient\ApiClient::selectHeaderContentType(array())); + $this->assertSame('application/yaml,application/xml', SwaggerClient\ApiClient::selectHeaderContentType(array('application/yaml','application/xml'))); // test addDefaultHeader and getDefaultHeader - SwaggerClient\APIClient::addDefaultHeader('test1', 'value1'); - SwaggerClient\APIClient::addDefaultHeader('test2', 200); - $defaultHeader = SwaggerClient\APIClient::getDefaultHeader(); + SwaggerClient\ApiClient::addDefaultHeader('test1', 'value1'); + SwaggerClient\ApiClient::addDefaultHeader('test2', 200); + $defaultHeader = SwaggerClient\ApiClient::getDefaultHeader(); $this->assertSame('value1', $defaultHeader['test1']); $this->assertSame(200, $defaultHeader['test2']); // test deleteDefaultHeader - SwaggerClient\APIClient::deleteDefaultHeader('test2'); - $defaultHeader = SwaggerClient\APIClient::getDefaultHeader(); + SwaggerClient\ApiClient::deleteDefaultHeader('test2'); + $defaultHeader = SwaggerClient\ApiClient::getDefaultHeader(); $this->assertFalse(isset($defaultHeader['test2'])); $pet_api = new SwaggerClient\PetAPI(); $pet_api2 = new SwaggerClient\PetAPI(); - $apiClient3 = new SwaggerClient\APIClient(); + $apiClient3 = new SwaggerClient\ApiClient(); $apiClient3->setUserAgent = 'api client 3'; - $apiClient4 = new SwaggerClient\APIClient(); + $apiClient4 = new SwaggerClient\ApiClient(); $apiClient4->setUserAgent = 'api client 4'; $pet_api3 = new SwaggerClient\PetAPI($apiClient3); @@ -85,7 +88,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testGetPetById() { // initialize the API client without host - $api_client = new SwaggerClient\APIClient(); + $api_client = new SwaggerClient\ApiClient(); SwaggerClient\Configuration::$apiKey['api_key'] = '111222333444555'; $pet_id = 10005; // ID of pet that needs to be fetched $pet_api = new SwaggerClient\PetAPI($api_client); @@ -103,7 +106,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testFindPetByStatus() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); $pet_api = new SwaggerClient\PetAPI($api_client); // return Pet (model) $response = $pet_api->findPetsByStatus("available"); @@ -122,7 +125,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePet() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new SwaggerClient\PetAPI($api_client); // create updated pet object @@ -145,7 +148,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUpdatePetWithForm() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); $pet_id = 10001; // ID of pet that needs to be fetched $pet_api = new SwaggerClient\PetAPI($api_client); // update Pet (form) @@ -162,7 +165,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testAddPet() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); $new_pet_id = 10001; $new_pet = new SwaggerClient\models\Pet; $new_pet->id = $new_pet_id; @@ -182,7 +185,7 @@ class PetApiTest extends \PHPUnit_Framework_TestCase public function testUploadFile() { // initialize the API client - $api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); + $api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); $pet_api = new SwaggerClient\PetAPI($api_client); // upload file $pet_id = 10001; diff --git a/samples/client/petstore/php/test.php b/samples/client/petstore/php/test.php index 41c206ee6b0..f39e0dae4cf 100644 --- a/samples/client/petstore/php/test.php +++ b/samples/client/petstore/php/test.php @@ -3,18 +3,54 @@ require_once('SwaggerClient-php/SwaggerClient.php'); // initialize the API client -//$api_client = new SwaggerClient\APIClient('http://petstore.swagger.io/v2'); +//$api_client = new SwaggerClient\ApiClient('http://petstore.swagger.io/v2'); //$api_client->addDefaultHeader("test1", "value1"); +// to enable logging +//SwaggerClient\Configuration::$debug = true; +//SwaggerClient\Configuration::$debug_file = '/var/tmp/php_debug.log'; + $petId = 10005; // ID of pet that needs to be fetched try { + // get pet by id //$pet_api = new SwaggerClient\PetAPI($api_client); $pet_api = new SwaggerClient\PetAPI(); + // test default header + $pet_api->getApiClient()->addDefaultHeader("TEST_API_KEY", "09182sdkanafndsl903"); // return Pet (model) $response = $pet_api->getPetById($petId); var_dump($response); + + // test upload file (exception) + $upload_response = $pet_api->uploadFile($petId, "test meta", NULL); + + // add pet (post json) + $new_pet_id = 10005; + $new_pet = new SwaggerClient\models\Pet; + $new_pet->id = $new_pet_id; + $new_pet->name = "PHP Unit Test"; + // new tag + $tag= new SwaggerClient\models\Tag; + $tag->id = $new_pet_id; // use the same id as pet + //$tag->name = "test php tag"; + // new category + $category = new SwaggerClient\models\Category; + $category->id = 0; // use the same id as pet + //$category->name = "test php category"; + + $new_pet->tags = array($tag); + $new_pet->category = $category; + + $pet_api = new SwaggerClient\PetAPI(); + // add a new pet (model) + $add_response = $pet_api->addPet($new_pet); + } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; + echo 'HTTP response headers: ', $e->getResponseHeaders(), "\n"; + echo 'HTTP response body: ', $e->getResponseBody(), "\n"; + echo 'HTTP status code: ', $e->getCode(), "\n"; } + ?> diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py index a599aeaabc1..ad4bad57412 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/pet_api.py @@ -29,12 +29,15 @@ from six import iteritems from ..util import remove_none -from ..swagger import ApiClient +from .. import config class PetApi(object): - def __init__(self, api_client): - self.api_client = api_client + def __init__(self, api_client=None): + if api_client: + self.api_client = api_client + else: + self.api_client = config.api_client def update_pet(self, **kwargs): """ @@ -66,12 +69,12 @@ class PetApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type(['application/json', 'application/xml']) + header_params['Content-Type'] = self.api_client.select_header_content_type(['application/json', 'application/xml']) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -107,12 +110,12 @@ class PetApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type(['application/json', 'application/xml']) + header_params['Content-Type'] = self.api_client.select_header_content_type(['application/json', 'application/xml']) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -148,12 +151,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -191,12 +194,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -238,12 +241,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -287,12 +290,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type(['application/x-www-form-urlencoded']) + header_params['Content-Type'] = self.api_client.select_header_content_type(['application/x-www-form-urlencoded']) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -333,12 +336,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -380,12 +383,12 @@ class PetApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type(['multipart/form-data']) + header_params['Content-Type'] = self.api_client.select_header_content_type(['multipart/form-data']) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py index 7f9b852f7ca..e973d3a6ba5 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/store_api.py @@ -29,12 +29,15 @@ from six import iteritems from ..util import remove_none -from ..swagger import ApiClient +from .. import config class StoreApi(object): - def __init__(self, api_client): - self.api_client = api_client + def __init__(self, api_client=None): + if api_client: + self.api_client = api_client + else: + self.api_client = config.api_client def get_inventory(self, **kwargs): """ @@ -65,12 +68,12 @@ class StoreApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -108,12 +111,12 @@ class StoreApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -155,12 +158,12 @@ class StoreApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -202,12 +205,12 @@ class StoreApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py index 2471970c436..82874000d59 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/apis/user_api.py @@ -29,12 +29,15 @@ from six import iteritems from ..util import remove_none -from ..swagger import ApiClient +from .. import config class UserApi(object): - def __init__(self, api_client): - self.api_client = api_client + def __init__(self, api_client=None): + if api_client: + self.api_client = api_client + else: + self.api_client = config.api_client def create_user(self, **kwargs): """ @@ -66,12 +69,12 @@ class UserApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -107,12 +110,12 @@ class UserApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -148,12 +151,12 @@ class UserApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -190,12 +193,12 @@ class UserApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -232,12 +235,12 @@ class UserApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -277,12 +280,12 @@ class UserApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -325,12 +328,12 @@ class UserApi(object): body_params = params.get('body') # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, @@ -370,12 +373,12 @@ class UserApi(object): body_params = None # HTTP header `Accept` - header_params['Accept'] = ApiClient.select_header_accept(['application/json', 'application/xml']) + header_params['Accept'] = self.api_client.select_header_accept(['application/json', 'application/xml']) if not header_params['Accept']: del header_params['Accept'] # HTTP header `Content-Type` - header_params['Content-Type'] = ApiClient.select_header_content_type([]) + header_params['Content-Type'] = self.api_client.select_header_content_type([]) response = self.api_client.call_api(resource_path, method, path_params, query_params, header_params, body=body_params, post_params=form_params, files=files, diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/config.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/config.py new file mode 100644 index 00000000000..6e158eedd70 --- /dev/null +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/config.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +from .swagger import ApiClient + +# Configuration variables + +api_client = ApiClient("http://petstore.swagger.io/v2") + diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py index 06b817da757..da99abc2493 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/rest.py @@ -2,6 +2,8 @@ import sys import io import json +import ssl +import certifi # python 2 and python 3 compatibility library from six import iteritems @@ -42,10 +44,30 @@ class RESTResponse(io.IOBase): class RESTClientObject(object): def __init__(self, pools_size=4): + # http pool manager self.pool_manager = urllib3.PoolManager( num_pools=pools_size ) + # https pool manager + # certificates validated using Mozilla’s root certificates + self.ssl_pool_manager = urllib3.PoolManager( + num_pools=pools_size, + cert_reqs=ssl.CERT_REQUIRED, + ca_certs=certifi.where() + ) + + def agent(self, url): + """ + Return proper pool manager for the http\https schemes. + """ + url = urllib3.util.url.parse_url(url) + scheme = url.scheme + if scheme == 'https': + return self.ssl_pool_manager + else: + return self.pool_manager + def request(self, method, url, query_params=None, headers=None, body=None, post_params=None): """ @@ -56,7 +78,6 @@ class RESTClientObject(object): :param body: request json body, for `application/json` :param post_params: request post parameters, `application/x-www-form-urlencode` and `multipart/form-data` - :param raw_response: if return the raw response """ method = method.upper() assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'] @@ -75,27 +96,27 @@ class RESTClientObject(object): if query_params: url += '?' + urlencode(query_params) if headers['Content-Type'] == 'application/json': - r = self.pool_manager.request(method, url, - body=json.dumps(body), - headers=headers) + r = self.agent(url).request(method, url, + body=json.dumps(body), + headers=headers) if headers['Content-Type'] == 'application/x-www-form-urlencoded': - r = self.pool_manager.request(method, url, - fields=post_params, - encode_multipart=False, - headers=headers) + r = self.agent(url).request(method, url, + fields=post_params, + encode_multipart=False, + headers=headers) if headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct Content-Type # which generated by urllib3 will be overwritten. del headers['Content-Type'] - r = self.pool_manager.request(method, url, - fields=post_params, - encode_multipart=True, - headers=headers) + r = self.agent(url).request(method, url, + fields=post_params, + encode_multipart=True, + headers=headers) # For `GET`, `HEAD`, `DELETE` else: - r = self.pool_manager.request(method, url, - fields=query_params, - headers=headers) + r = self.agent(url).request(method, url, + fields=query_params, + headers=headers) r = RESTResponse(r) if r.status not in range(200, 206): diff --git a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py index ab45eace646..21430c469c8 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/SwaggerPetstore/swagger.py @@ -66,28 +66,28 @@ class ApiClient(object): if self.cookie: headers['Cookie'] = self.cookie if headers: - headers = ApiClient.sanitize_for_serialization(headers) + headers = self.sanitize_for_serialization(headers) # path parameters if path_params: - path_params = ApiClient.sanitize_for_serialization(path_params) + path_params = self.sanitize_for_serialization(path_params) for k, v in iteritems(path_params): replacement = quote(str(self.to_path_value(v))) resource_path = resource_path.replace('{' + k + '}', replacement) # query parameters if query_params: - query_params = ApiClient.sanitize_for_serialization(query_params) + query_params = self.sanitize_for_serialization(query_params) query_params = {k: self.to_path_value(v) for k, v in iteritems(query_params)} # post parameters if post_params: post_params = self.prepare_post_parameters(post_params, files) - post_params = ApiClient.sanitize_for_serialization(post_params) + post_params = self.sanitize_for_serialization(post_params) # body if body: - body = ApiClient.sanitize_for_serialization(body) + body = self.sanitize_for_serialization(body) # request url url = self.host + resource_path @@ -115,8 +115,7 @@ class ApiClient(object): else: return str(obj) - @staticmethod - def sanitize_for_serialization(obj): + def sanitize_for_serialization(self, obj): """ Sanitize an object for Request. @@ -132,7 +131,7 @@ class ApiClient(object): elif isinstance(obj, (str, int, float, bool, tuple)): return obj elif isinstance(obj, list): - return [ApiClient.sanitize_for_serialization(sub_obj) for sub_obj in obj] + return [self.sanitize_for_serialization(sub_obj) for sub_obj in obj] elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() else: @@ -145,7 +144,7 @@ class ApiClient(object): obj_dict = {obj.attribute_map[key]: val for key, val in iteritems(obj.__dict__) if key != 'swagger_types' and key != 'attribute_map' and val is not None} - return {key: ApiClient.sanitize_for_serialization(val) + return {key: self.sanitize_for_serialization(val) for key, val in iteritems(obj_dict)} def deserialize(self, obj, obj_class): @@ -253,8 +252,7 @@ class ApiClient(object): return params - @staticmethod - def select_header_accept(accepts): + def select_header_accept(self, accepts): """ Return `Accept` based on an array of accepts provided """ @@ -268,8 +266,7 @@ class ApiClient(object): else: return ', '.join(accepts) - @staticmethod - def select_header_content_type(content_types): + def select_header_content_type(self, content_types): """ Return `Content-Type` baseed on an array of content_types provided """ diff --git a/samples/client/petstore/python/SwaggerPetstore-python/setup.py b/samples/client/petstore/python/SwaggerPetstore-python/setup.py index fd0b786efa3..50a6ffeb00c 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/setup.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/setup.py @@ -12,7 +12,7 @@ from setuptools import setup, find_packages # Try reading the setuptools documentation: # http://pypi.python.org/pypi/setuptools -REQUIRES = ["urllib3 >= 1.10", "six >= 1.9"] +REQUIRES = ["urllib3 >= 1.10", "six >= 1.9", "certifi"] setup( name="SwaggerPetstore", diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py index 9adf7cdb99d..5243430a93a 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_api_client.py @@ -23,44 +23,42 @@ class ApiClientTests(unittest.TestCase): def test_select_header_accept(self): accepts = ['APPLICATION/JSON', 'APPLICATION/XML'] - accept = SwaggerPetstore.ApiClient.select_header_accept(accepts) + accept = self.api_client.select_header_accept(accepts) self.assertEqual(accept, 'application/json') accepts = ['application/json', 'application/xml'] - accept = SwaggerPetstore.ApiClient.select_header_accept(accepts) + accept = self.api_client.select_header_accept(accepts) self.assertEqual(accept, 'application/json') accepts = ['application/xml', 'application/json'] - accept = SwaggerPetstore.ApiClient.select_header_accept(accepts) + accept = self.api_client.select_header_accept(accepts) self.assertEqual(accept, 'application/json') accepts = ['text/plain', 'application/xml'] - accept = SwaggerPetstore.ApiClient.select_header_accept(accepts) + accept = self.api_client.select_header_accept(accepts) self.assertEqual(accept, 'text/plain, application/xml') accepts = [] - accept = SwaggerPetstore.ApiClient.select_header_accept(accepts) + accept = self.api_client.select_header_accept(accepts) self.assertEqual(accept, None) def test_select_header_content_type(self): content_types = ['APPLICATION/JSON', 'APPLICATION/XML'] - content_type = SwaggerPetstore.ApiClient.select_header_content_type(content_types) + content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'application/json') content_types = ['application/json', 'application/xml'] - content_type = SwaggerPetstore.ApiClient.select_header_content_type(content_types) + content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'application/json') content_types = ['application/xml', 'application/json'] - content_type = SwaggerPetstore.ApiClient.select_header_content_type(content_types) + content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'application/json') content_types = ['text/plain', 'application/xml'] - content_type = SwaggerPetstore.ApiClient.select_header_content_type(content_types) + content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'text/plain') content_types = [] - content_type = SwaggerPetstore.ApiClient.select_header_content_type(content_types) + content_type = self.api_client.select_header_content_type(content_types) self.assertEqual(content_type, 'application/json') - - diff --git a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py index f0b8ab03d81..ee8c5dde14e 100644 --- a/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py +++ b/samples/client/petstore/python/SwaggerPetstore-python/tests/test_pet_api.py @@ -13,6 +13,7 @@ import unittest import SwaggerPetstore from SwaggerPetstore.rest import ErrorResponse +from SwaggerPetstore import config HOST = 'http://petstore.swagger.io/v2' @@ -49,6 +50,26 @@ class PetApiTests(unittest.TestCase): self.test_file_dir = os.path.realpath(self.test_file_dir) self.foo = os.path.join(self.test_file_dir, "foo.png") + def test_create_api_instance(self): + pet_api = SwaggerPetstore.PetApi() + pet_api2 = SwaggerPetstore.PetApi() + api_client3 = SwaggerPetstore.ApiClient() + api_client3.user_agent = 'api client 3' + api_client4 = SwaggerPetstore.ApiClient() + api_client4.user_agent = 'api client 4' + pet_api3 = SwaggerPetstore.PetApi(api_client3) + + # same default api client + self.assertEqual(pet_api.api_client, pet_api2.api_client) + # confirm using the default api client in the config module + self.assertEqual(pet_api.api_client, config.api_client) + # 2 different api clients are not the same + self.assertNotEqual(api_client3, api_client4) + # customized pet api not using the default api client + self.assertNotEqual(pet_api3.api_client, config.api_client) + # customized pet api not using the old pet api's api client + self.assertNotEqual(pet_api3.api_client, pet_api2.api_client) + def test_add_pet_and_get_pet_by_id(self): self.pet_api.add_pet(body=self.pet) diff --git a/samples/client/petstore/retrofit/pom.xml b/samples/client/petstore/retrofit/pom.xml new file mode 100644 index 00000000000..4a95855cac9 --- /dev/null +++ b/samples/client/petstore/retrofit/pom.xml @@ -0,0 +1,143 @@ + + 4.0.0 + io.swagger + swagger-java-client + jar + swagger-java-client + 1.0.0 + + scm:git:git@github.com:wordnik/swagger-mustache.git + scm:git:git@github.com:wordnik/swagger-codegen.git + https://github.com/wordnik/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + com.wordnik + swagger-annotations + ${swagger-annotations-version} + + + com.google.code.gson + gson + ${gson-version} + compile + + + com.squareup.retrofit + retrofit + ${retrofit-version} + compile + + + + + junit + junit + ${junit-version} + test + + + + 1.5.3-M1 + 2.3.1 + 1.9.0 + 1.0.0 + 4.12 + + diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java new file mode 100644 index 00000000000..e443c984fd0 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java @@ -0,0 +1,23 @@ +package io.swagger.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import retrofit.RestAdapter; +import retrofit.converter.GsonConverter; + +public class ServiceGenerator { + // No need to instantiate this class. + private ServiceGenerator() { } + + public static S createService(Class serviceClass) { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .create(); + RestAdapter adapter = new RestAdapter.Builder() + .setEndpoint("http://petstore.swagger.io/v2") + .setConverter(new GsonConverter(gson)) + .build(); + + return adapter.create(serviceClass); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java new file mode 100644 index 00000000000..3d1b0893b61 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java @@ -0,0 +1,117 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import io.swagger.client.model.Pet; +import java.io.File; + +public interface PetApi { + + /** + * Update an existing pet + * + * @param body Pet object that needs to be added to the store + * @return Void + */ + + @PUT("/pet") + Void updatePet( + @Body Pet body + ); + + /** + * Add a new pet to the store + * + * @param body Pet object that needs to be added to the store + * @return Void + */ + + @POST("/pet") + Void addPet( + @Body Pet body + ); + + /** + * Finds Pets by status + * Multiple status values can be provided with comma seperated strings + * @param status Status values that need to be considered for filter + * @return List + */ + + @GET("/pet/findByStatus") + List findPetsByStatus( + @Query("status") List status + ); + + /** + * Finds Pets by tags + * Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + * @return List + */ + + @GET("/pet/findByTags") + List findPetsByTags( + @Query("tags") List tags + ); + + /** + * Find pet by ID + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @return Pet + */ + + @GET("/pet/{petId}") + Pet getPetById( + @Path("petId") Long petId + ); + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @return Void + */ + + @FormUrlEncoded + @POST("/pet/{petId}") + Void updatePetWithForm( + @Path("petId") String petId,@Field("name") String name,@Field("status") String status + ); + + /** + * Deletes a pet + * + * @param apiKey + * @param petId Pet id to delete + * @return Void + */ + + @DELETE("/pet/{petId}") + Void deletePet( + @Header("api_key") String apiKey,@Path("petId") Long petId + ); + + /** + * uploads an image + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server + * @param file file to upload + * @return Void + */ + + @Multipart + @POST("/pet/{petId}/uploadImage") + Void uploadFile( + @Path("petId") Long petId,@Part("additionalMetadata") String additionalMetadata,@Part("file") TypedFile file + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java new file mode 100644 index 00000000000..fcd47b4b735 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java @@ -0,0 +1,60 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import java.util.Map; +import io.swagger.client.model.Order; + +public interface StoreApi { + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + * @return Map + */ + + @GET("/store/inventory") + Map getInventory(); + + + /** + * Place an order for a pet + * + * @param body order placed for purchasing the pet + * @return Order + */ + + @POST("/store/order") + Order placeOrder( + @Body Order body + ); + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + * @param orderId ID of pet that needs to be fetched + * @return Order + */ + + @GET("/store/order/{orderId}") + Order getOrderById( + @Path("orderId") String orderId + ); + + /** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + * @return Void + */ + + @DELETE("/store/order/{orderId}") + Void deleteOrder( + @Path("orderId") String orderId + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java new file mode 100644 index 00000000000..4aa39c52e2c --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java @@ -0,0 +1,110 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import io.swagger.client.model.User; +import java.util.*; + +public interface UserApi { + + /** + * Create user + * This can only be done by the logged in user. + * @param body Created user object + * @return Void + */ + + @POST("/user") + Void createUser( + @Body User body + ); + + /** + * Creates list of users with given input array + * + * @param body List of user object + * @return Void + */ + + @POST("/user/createWithArray") + Void createUsersWithArrayInput( + @Body List body + ); + + /** + * Creates list of users with given input array + * + * @param body List of user object + * @return Void + */ + + @POST("/user/createWithList") + Void createUsersWithListInput( + @Body List body + ); + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + * @return String + */ + + @GET("/user/login") + String loginUser( + @Query("username") String username,@Query("password") String password + ); + + /** + * Logs out current logged in user session + * + * @return Void + */ + + @GET("/user/logout") + Void logoutUser(); + + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + * @return User + */ + + @GET("/user/{username}") + User getUserByName( + @Path("username") String username + ); + + /** + * Updated user + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param body Updated user object + * @return Void + */ + + @PUT("/user/{username}") + Void updateUser( + @Path("username") String username,@Body User body + ); + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @return Void + */ + + @DELETE("/user/{username}") + Void deleteUser( + @Path("username") String username + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java new file mode 100644 index 00000000000..8ba10d629dc --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java @@ -0,0 +1,49 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Category { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("name") + private String name = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Category {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java new file mode 100644 index 00000000000..d7d0b2d9282 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java @@ -0,0 +1,110 @@ +package io.swagger.client.model; + +import java.util.Date; + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Order { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("petId") + private Long petId = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("quantity") + private Integer quantity = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("shipDate") + private Date shipDate = null; + public enum StatusEnum { + placed, approved, delivered, + }; + + /** + * Order Status + **/ + @ApiModelProperty(value = "Order Status") + @SerializedName("status") + private StatusEnum status = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("complete") + private Boolean complete = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public Long getPetId() { + return petId; + } + public void setPetId(Long petId) { + this.petId = petId; + } + + public Integer getQuantity() { + return quantity; + } + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Date getShipDate() { + return shipDate; + } + public void setShipDate(Date shipDate) { + this.shipDate = shipDate; + } + + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + public Boolean getComplete() { + return complete; + } + public void setComplete(Boolean complete) { + this.complete = complete; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Order {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" petId: ").append(petId).append("\n"); + sb.append(" quantity: ").append(quantity).append("\n"); + sb.append(" shipDate: ").append(shipDate).append("\n"); + sb.append(" status: ").append(status).append("\n"); + sb.append(" complete: ").append(complete).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java new file mode 100644 index 00000000000..66a02367c90 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java @@ -0,0 +1,112 @@ +package io.swagger.client.model; + +import io.swagger.client.model.Category; +import java.util.*; +import io.swagger.client.model.Tag; + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Pet { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("category") + private Category category = null; + + /** + **/ + @ApiModelProperty(required = true, value = "") + @SerializedName("name") + private String name = null; + + /** + **/ + @ApiModelProperty(required = true, value = "") + @SerializedName("photoUrls") + private List photoUrls = new ArrayList() ; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("tags") + private List tags = new ArrayList() ; + public enum StatusEnum { + available, pending, sold, + }; + + /** + * pet status in the store + **/ + @ApiModelProperty(value = "pet status in the store") + @SerializedName("status") + private StatusEnum status = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public Category getCategory() { + return category; + } + public void setCategory(Category category) { + this.category = category; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public List getPhotoUrls() { + return photoUrls; + } + public void setPhotoUrls(List photoUrls) { + this.photoUrls = photoUrls; + } + + public List getTags() { + return tags; + } + public void setTags(List tags) { + this.tags = tags; + } + + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pet {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" category: ").append(category).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append(" photoUrls: ").append(photoUrls).append("\n"); + sb.append(" tags: ").append(tags).append("\n"); + sb.append(" status: ").append(status).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java new file mode 100644 index 00000000000..e6ddd4c92cd --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java @@ -0,0 +1,49 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Tag { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("name") + private String name = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Tag {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java new file mode 100644 index 00000000000..f42f77b9773 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java @@ -0,0 +1,134 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class User { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("username") + private String username = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("firstName") + private String firstName = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("lastName") + private String lastName = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("email") + private String email = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("password") + private String password = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("phone") + private String phone = null; + + /** + * User Status + **/ + @ApiModelProperty(value = "User Status") + @SerializedName("userStatus") + private Integer userStatus = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + this.phone = phone; + } + + public Integer getUserStatus() { + return userStatus; + } + public void setUserStatus(Integer userStatus) { + this.userStatus = userStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" username: ").append(username).append("\n"); + sb.append(" firstName: ").append(firstName).append("\n"); + sb.append(" lastName: ").append(lastName).append("\n"); + sb.append(" email: ").append(email).append("\n"); + sb.append(" password: ").append(password).append("\n"); + sb.append(" phone: ").append(phone).append("\n"); + sb.append(" userStatus: ").append(userStatus).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java new file mode 100644 index 00000000000..c588a04adcc --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java @@ -0,0 +1,158 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import retrofit.RetrofitError; +import retrofit.mime.TypedFile; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class PetApiTest { + PetApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(PetApi.class); + } + + @Test + public void testCreateAndGetPet() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + assertNotNull(fetched); + assertEquals(pet.getId(), fetched.getId()); + assertNotNull(fetched.getCategory()); + assertEquals(fetched.getCategory().getName(), pet.getCategory().getName()); + } + + @Test + public void testUpdatePet() throws Exception { + Pet pet = createRandomPet(); + pet.setName("programmer"); + + api.updatePet(pet); + + Pet fetched = api.getPetById(pet.getId()); + assertNotNull(fetched); + assertEquals(pet.getId(), fetched.getId()); + assertNotNull(fetched.getCategory()); + assertEquals(fetched.getCategory().getName(), pet.getCategory().getName()); + } + + @Test + public void testFindPetsByStatus() throws Exception { + Pet pet = createRandomPet(); + pet.setName("programmer"); + pet.setStatus(Pet.StatusEnum.available); + + api.updatePet(pet); + + List pets = api.findPetsByStatus(Arrays.asList(new String[]{"available"})); + assertNotNull(pets); + + boolean found = false; + for(Pet fetched : pets) { + if(fetched.getId().equals(pet.getId())) { + found = true; + break; + } + } + + assertTrue(found); + } + + @Test + public void testFindPetsByTags() throws Exception { + Pet pet = createRandomPet(); + pet.setName("monster"); + pet.setStatus(Pet.StatusEnum.available); + + List tags = new ArrayList(); + Tag tag1 = new Tag(); + tag1.setName("friendly"); + tags.add(tag1); + pet.setTags(tags); + + api.updatePet(pet); + + List pets = api.findPetsByTags(Arrays.asList(new String[]{"friendly"})); + assertNotNull(pets); + + boolean found = false; + for(Pet fetched : pets) { + if(fetched.getId().equals(pet.getId())) { + found = true; + break; + } + } + assertTrue(found); + } + + @Test + public void testUpdatePetWithForm() throws Exception { + Pet pet = createRandomPet(); + pet.setName("frank"); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + + api.updatePetWithForm(String.valueOf(fetched.getId()), "furt", null); + Pet updated = api.getPetById(fetched.getId()); + + assertEquals(updated.getName(), fetched.getName()); + } + + @Test + public void testDeletePet() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + api.deletePet(null, fetched.getId()); + + try { + fetched = api.getPetById(fetched.getId()); + fail("expected an error"); + } + catch (RetrofitError e) { + assertEquals(404, e.getResponse().getStatus()); + } + } + + @Test + public void testUploadFile() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + File file = new File("hello.txt"); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write("Hello world!"); + writer.close(); + + api.uploadFile(pet.getId(), "a test file", new TypedFile("text/plain", file)); + } + + private Pet createRandomPet() { + Pet pet = new Pet(); + pet.setId(System.currentTimeMillis()); + pet.setName("gorilla"); + + Category category = new Category(); + category.setName("really-happy"); + + pet.setCategory(category); + pet.setStatus(Pet.StatusEnum.available); + List photos = Arrays.asList(new String[]{"http://foo.bar.com/1", "http://foo.bar.com/2"}); + pet.setPhotoUrls(photos); + + return pet; + } +} \ No newline at end of file diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java new file mode 100644 index 00000000000..733b597fefc --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java @@ -0,0 +1,70 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import retrofit.RetrofitError; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class StoreApiTest { + StoreApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(StoreApi.class); + } + + @Test + public void testGetInventory() throws Exception { + Map inventory = api.getInventory(); + assertTrue(inventory.keySet().size() > 0); + } + + @Test + public void testPlaceOrder() throws Exception { + Order order = createOrder(); + api.placeOrder(order); + + Order fetched = api.getOrderById(String.valueOf(order.getId())); + assertEquals(order.getId(), fetched.getId()); + assertEquals(order.getPetId(), fetched.getPetId()); + assertEquals(order.getQuantity(), fetched.getQuantity()); + } + + @Test + public void testDeleteOrder() throws Exception { + Order order = createOrder(); + api.placeOrder(order); + + Order fetched = api.getOrderById(String.valueOf(order.getId())); + assertEquals(fetched.getId(), order.getId()); + + api.deleteOrder(String.valueOf(order.getId())); + + try { + api.getOrderById(String.valueOf(order.getId())); + // fail("expected an error"); + } + catch (RetrofitError e) { + // ok + } + } + + private Order createOrder() { + Order order = new Order(); + order.setId(new Long(System.currentTimeMillis())); + order.setPetId(new Long(200)); + order.setQuantity(new Integer(13)); + order.setShipDate(new java.util.Date()); + order.setStatus(Order.StatusEnum.placed); + order.setComplete(true); + + return order; + } +} \ No newline at end of file diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java new file mode 100644 index 00000000000..c7748bc492d --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java @@ -0,0 +1,84 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class UserApiTest { + UserApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(UserApi.class); + } + + @Test + public void testCreateUser() throws Exception { + User user = createUser(); + + api.createUser(user); + + User fetched = api.getUserByName(user.getUsername()); + assertEquals(user.getId(), fetched.getId()); + } + + @Test + public void testCreateUsersWithArray() throws Exception { + User user1 = createUser(); + user1.setUsername("abc123"); + User user2 = createUser(); + user2.setUsername("123abc"); + + api.createUsersWithArrayInput(Arrays.asList(new User[]{user1, user2})); + + User fetched = api.getUserByName(user1.getUsername()); + assertEquals(user1.getId(), fetched.getId()); + } + + @Test + public void testCreateUsersWithList() throws Exception { + User user1 = createUser(); + user1.setUsername("abc123"); + User user2 = createUser(); + user2.setUsername("123abc"); + + api.createUsersWithListInput(Arrays.asList(new User[]{user1, user2})); + + User fetched = api.getUserByName(user1.getUsername()); + assertEquals(user1.getId(), fetched.getId()); + } + + @Test + public void testLoginUser() throws Exception { + User user = createUser(); + api.createUser(user); + + String token = api.loginUser(user.getUsername(), user.getPassword()); + assertTrue(token.startsWith("logged in user session:")); + } + + @Test + public void logoutUser() throws Exception { + api.logoutUser(); + } + + private User createUser() { + User user = new User(); + user.setId(System.currentTimeMillis()); + user.setUsername("fred"); + user.setFirstName("Fred"); + user.setLastName("Meyer"); + user.setEmail("fred@fredmeyer.com"); + user.setPassword("xxXXxx"); + user.setPhone("408-867-5309"); + user.setUserStatus(123); + + return user; + } +} \ No newline at end of file diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb index 40e5f1e3177..7bed9b47780 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/pet_api.rb @@ -37,7 +37,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -73,7 +74,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -110,7 +112,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } end @@ -147,7 +150,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = Pet.new() and obj.build_from_hash(response) } end @@ -186,7 +190,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['api_key', 'petstore_auth'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Pet.new() and obj.build_from_hash(response) end @@ -229,7 +234,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -270,7 +276,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -313,7 +320,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = ['petstore_auth'] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb index 594c30a0775..010d170945b 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/store_api.rb @@ -36,7 +36,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = ['api_key'] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body response.map {|response| obj = map.new() and obj.build_from_hash(response) } end @@ -72,7 +73,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:POST, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Order.new() and obj.build_from_hash(response) end @@ -111,7 +113,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = Order.new() and obj.build_from_hash(response) end @@ -150,7 +153,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb index 96fe0cabada..a3a57503b01 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/api/user_api.rb @@ -37,7 +37,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -73,7 +74,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -109,7 +111,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:POST, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -148,7 +151,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = string.new() and obj.build_from_hash(response) end @@ -183,7 +187,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:GET, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:GET, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -222,7 +227,8 @@ module SwaggerClient post_body = nil - response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body}).make.body + auth_names = [] + response = Swagger::Request.new(:GET, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body obj = User.new() and obj.build_from_hash(response) end @@ -262,7 +268,8 @@ module SwaggerClient post_body = Swagger::Request.object_to_http_body(opts[:'body']) - Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:PUT, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end @@ -301,7 +308,8 @@ module SwaggerClient post_body = nil - Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body}).make + auth_names = [] + Swagger::Request.new(:DELETE, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb index 278db36e4ca..2e2632c169d 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger.rb @@ -16,9 +16,9 @@ module SwaggerClient # # @example # Swagger.configure do |config| - # config.api_key = '1234567890abcdef' # required - # config.username = 'wordlover' # optional, but needed for user-related functions - # config.password = 'i<3words' # optional, but needed for user-related functions + # config.api_key['api_key'] = '1234567890abcdef' # api key authentication + # config.username = 'wordlover' # http basic authentication + # config.password = 'i<3words' # http basic authentication # config.format = 'json' # optional, defaults to 'json' # end # diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb index 51f9539a9ab..a2d4fe0e291 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/configuration.rb @@ -1,8 +1,8 @@ module SwaggerClient module Swagger class Configuration - attr_accessor :format, :api_key, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent - + attr_accessor :format, :api_key, :api_key_prefix, :username, :password, :auth_token, :scheme, :host, :base_path, :user_agent, :logger, :inject_format, :force_ending_format, :camelize_params, :user_agent, :verify_ssl + # Defaults go in here.. def initialize @format = 'json' @@ -13,6 +13,16 @@ module SwaggerClient @inject_format = false @force_ending_format = false @camelize_params = true + + # keys for API key authentication (param-name => api-key) + @api_key = {} + # api-key prefix for API key authentication, e.g. "Bearer" (param-name => api-key-prefix) + @api_key_prefix = {} + + # whether to verify SSL certificate, default to true + # Note: do NOT set it to false in production code, otherwise you would + # face multiple types of cryptographic attacks + @verify_ssl = true end end end diff --git a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb index d5f266267da..4cd5d84b0b9 100644 --- a/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb +++ b/samples/client/petstore/ruby/lib/swagger_client/swagger/request.rb @@ -5,7 +5,7 @@ module SwaggerClient require 'addressable/uri' require 'typhoeus' - attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params + attr_accessor :host, :path, :format, :params, :body, :http_method, :headers, :form_params, :auth_names # All requests must have an HTTP method and a path # Optionals parameters are :params, :headers, :body, :format, :host @@ -16,21 +16,9 @@ module SwaggerClient # Set default headers default_headers = { 'Content-Type' => "application/#{attributes[:format].downcase}", - :api_key => Swagger.configuration.api_key, 'User-Agent' => Swagger.configuration.user_agent } - # api_key from headers hash trumps the default, even if its value is blank - if attributes[:headers].present? && attributes[:headers].has_key?(:api_key) - default_headers.delete(:api_key) - end - - # api_key from params hash trumps all others (headers and default_headers) - if attributes[:params].present? && attributes[:params].has_key?(:api_key) - default_headers.delete(:api_key) - attributes[:headers].delete(:api_key) if attributes[:headers].present? - end - # Merge argument headers into defaults attributes[:headers] = default_headers.merge(attributes[:headers] || {}) @@ -44,6 +32,32 @@ module SwaggerClient attributes.each do |name, value| send("#{name.to_s.underscore.to_sym}=", value) end + + update_params_for_auth! + end + + # Update hearder and query params based on authentication settings. + def update_params_for_auth! + (@auth_names || []).each do |auth_name| + case auth_name + when 'api_key' + @headers ||= {} + @headers['api_key'] = get_api_key_with_prefix('api_key') + when 'petstore_auth' + # TODO: support oauth + + end + end + end + + # Get API key (with prefix if set). + # @param [String] param_name the parameter name of API key auth + def get_api_key_with_prefix(param_name) + if Swagger.configuration.api_key_prefix[param_name].present? + "#{Swagger.configuration.api_key_prefix[param_name]} #{Swagger.configuration.api_key[param_name]}" + else + Swagger.configuration.api_key[param_name] + end end # Construct a base URL @@ -58,9 +72,6 @@ module SwaggerClient # Drop trailing question mark, if present u.sub! /\?$/, '' - # Obfuscate API key? - u.sub! /api\_key=\w+/, 'api_key=YOUR_API_KEY' if options[:obfuscated] - u end @@ -108,14 +119,16 @@ module SwaggerClient # For form parameters, remove empty value def outgoing_body # http form - if @body.nil? && @form_params && !@form_params.empty? + if headers['Content-Type'] == 'application/x-www-form-urlencoded' data = form_params.dup data.each do |key, value| data[key] = value.to_s if value && !value.is_a?(File) # remove emtpy form parameter end data - else # http body is JSON + elsif @body # http body is JSON @body.is_a?(String) ? @body : @body.to_json + else + nil end end @@ -129,7 +142,7 @@ module SwaggerClient next if self.path.include? "{#{key}}" # skip path params next if value.blank? && value.class != FalseClass # skip empties if Swagger.configuration.camelize_params - key = key.to_s.camelize(:lower).to_sym unless key.to_sym == :api_key # api_key is not a camelCased param + key = key.to_s.camelize(:lower).to_sym end query_values[key] = value.to_s end @@ -148,39 +161,40 @@ module SwaggerClient #TODO use configuration setting to determine if debugging #logger = Logger.new STDOUT #logger.debug self.url + + request_options = { + :ssl_verifypeer => Swagger.configuration.verify_ssl, + :headers => self.headers.stringify_keys + } response = case self.http_method.to_sym when :get,:GET Typhoeus::Request.get( self.url, - :headers => self.headers.stringify_keys, + request_options ) when :post,:POST Typhoeus::Request.post( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :patch,:PATCH Typhoeus::Request.patch( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :put,:PUT Typhoeus::Request.put( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) when :delete,:DELETE Typhoeus::Request.delete( self.url, - :body => self.outgoing_body, - :headers => self.headers.stringify_keys, + request_options.merge(:body => self.outgoing_body) ) end Response.new(response) diff --git a/samples/client/petstore/ruby/spec/request_spec.rb b/samples/client/petstore/ruby/spec/request_spec.rb index 8856a0cf315..49bbc5cdd1e 100644 --- a/samples/client/petstore/ruby/spec/request_spec.rb +++ b/samples/client/petstore/ruby/spec/request_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' describe SwaggerClient::Swagger::Request do - before(:each) do + before(:each) do SwaggerClient::Swagger.configure do |config| inject_format = true - config.api_key = 'special-key' + config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' end @@ -22,7 +22,7 @@ describe SwaggerClient::Swagger::Request do it "sets default response format to json" do @request.format.should == 'json' end - + it "allows params to be nil" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, :params => nil) @request.query_string.should == "" @@ -55,7 +55,7 @@ describe SwaggerClient::Swagger::Request do end end - + describe "body" do it "camelCases parameters" do @@ -67,7 +67,7 @@ describe SwaggerClient::Swagger::Request do })) @request.body.keys.should == [:badDog, :goodDog] end - + end describe "path" do @@ -140,7 +140,7 @@ describe SwaggerClient::Swagger::Request do @request.query_string.should =~ /\?limit=100/ @request.url.should =~ /\?limit=100/ end - + it "camelCases parameters" do @request = SwaggerClient::Swagger::Request.new(@default_http_method, @default_path, @default_params.merge({ :params => { @@ -150,52 +150,35 @@ describe SwaggerClient::Swagger::Request do })) @request.query_string.should == "?badDog=bud&goodDog=dud" end - + it "converts boolean values to their string representation" do params = {:stringy => "fish", :truthy => true, :falsey => false} @request = SwaggerClient::Swagger::Request.new(:get, 'fakeMethod', :params => params) @request.query_string.should == "?falsey=false&stringy=fish&truthy=true" end - + end - - describe "API key" do - - it "is inferred from the Swagger base configuration by default" do - SwaggerClient::Swagger.configure {|c| c.api_key = "xyz" } - SwaggerClient::Swagger::Request.new(:get, "word/json").headers[:api_key].should == "xyz" - end - - it "can be obfuscated for public display" do - @request = SwaggerClient::Swagger::Request.new(:get, "words/fancy", @default_params.merge({ - :params => { - :word => "dog", - :api_key => "123456" - } - })) - @request.url.should =~ /api\_key=123456/ - @request.url(:obfuscated => true).should =~ /api\_key=YOUR\_API\_KEY/ + describe "#update_params_for_auth!" do + it "sets header api-key parameter with prefix" do + SwaggerClient::Swagger.configure do |config| + inject_format = true + config.api_key_prefix['api_key'] = 'PREFIX' + end + @request.auth_names = ['api_key', 'unknown'] + @request.update_params_for_auth! + @request.headers['api_key'].should == 'PREFIX special-key' end - it "allows a key in the params to override the configuration-level key, even if it's blank" do - SwaggerClient::Swagger.configure {|c| c.api_key = "abc" } - @request_with_key = SwaggerClient::Swagger::Request.new(:get, "word/json", :params => {:api_key => "jkl"}) - @request_with_key.headers[:api_key].should be_nil - @request_with_key.params[:api_key].should == "jkl" - - @request_without_key = SwaggerClient::Swagger::Request.new(:get, "word/json", :params => {:api_key => nil}) - @request_without_key.headers[:api_key].should be_nil - @request_without_key.params[:api_key].should be_nil + it "sets header api-key parameter without prefix" do + SwaggerClient::Swagger.configure do |config| + inject_format = true + config.api_key_prefix['api_key'] = nil + end + @request.auth_names = ['api_key', 'unknown'] + @request.update_params_for_auth! + @request.headers['api_key'].should == 'special-key' end - - it "allows a key in the headers to override the configuration-level key, even if it's blank" do - SwaggerClient::Swagger.configure {|c| c.api_key = "hij" } - SwaggerClient::Swagger::Request.new(:get, "word/json").headers[:api_key].should == "hij" - SwaggerClient::Swagger::Request.new(:get, "word/json", :headers => {:api_key => "jkl"}).headers[:api_key].should == "jkl" - SwaggerClient::Swagger::Request.new(:get, "word/json", :headers => {:api_key => nil}).headers[:api_key].should be_nil - end - end end diff --git a/samples/client/petstore/ruby/spec/spec_helper.rb b/samples/client/petstore/ruby/spec/spec_helper.rb index 09012db2998..f9081d3fe08 100644 --- a/samples/client/petstore/ruby/spec/spec_helper.rb +++ b/samples/client/petstore/ruby/spec/spec_helper.rb @@ -38,7 +38,7 @@ end def configure_swagger SwaggerClient::Swagger.configure do |config| - config.api_key = 'special-key' + config.api_key['api_key'] = 'special-key' config.host = 'petstore.swagger.io' config.base_path = '/v2' end