Merge branch 'develop' into features/sparser-1.0.18

# Conflicts:
#	src/main/java/io/github/robwin/swagger2markup/utils/ExamplesUtil.java
This commit is contained in:
Hugo de Paix de Coeur
2016-03-03 17:49:53 +01:00
17 changed files with 1149 additions and 93 deletions

View File

@@ -4,8 +4,8 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.2'
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.8'
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.10.1'
classpath 'io.spring.gradle:dependency-management-plugin:0.5.5.RELEASE'
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.0.1'
classpath 'org.asciidoctor:asciidoctorj:1.5.2'
@@ -55,6 +55,7 @@ dependencies {
testCompile 'org.asciidoctor:asciidoctorj:1.5.4'
testCompile 'ch.qos.logback:logback-classic'
testCompile 'org.assertj:assertj-core'
testCompile 'com.sksamuel.diff:diff'
}
dependencyManagement {
@@ -67,6 +68,7 @@ dependencyManagement {
dependency "org.slf4j:slf4j-api:1.7.12"
dependency "ch.qos.logback:logback-classic:1.1.2"
dependency "org.assertj:assertj-core:2.2.0"
dependency "com.sksamuel.diff:diff:1.1.11"
}
}

View File

@@ -40,6 +40,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import static io.github.robwin.swagger2markup.utils.IOUtils.normalizeName;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

View File

@@ -28,8 +28,8 @@ import io.github.robwin.swagger2markup.type.Type;
import io.github.robwin.swagger2markup.utils.IOUtils;
import io.github.robwin.swagger2markup.utils.PropertyUtils;
import io.swagger.models.properties.Property;
import io.swagger.util.Json;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,7 +38,6 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Pattern;
import static org.apache.commons.lang3.StringUtils.defaultString;
@@ -47,15 +46,12 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
*/
public abstract class MarkupDocument {
private static final Pattern NAME_FORBIDDEN_PATTERN = Pattern.compile("[^0-9A-Za-z-_]+");
protected final String DEFAULT_COLUMN;
protected final String EXAMPLE_COLUMN;
protected final String REQUIRED_COLUMN;
protected final String SCHEMA_COLUMN;
protected final String NAME_COLUMN;
protected final String DESCRIPTION_COLUMN;
protected final String SCOPES_COLUMN;
protected final String DESCRIPTION;
protected final String PRODUCES;
@@ -118,21 +114,6 @@ public abstract class MarkupDocument {
markupDocBuilder.writeToFile(file, charset);
}
/**
* Create a normalized name from an arbitrary string.<br/>
* Paths separators are replaced, so this function can't be applied on a whole path, but must be called on each path sections.
*
* @param name current name of the file
* @return a normalized filename
*/
public static String normalizeName(String name) {
String fileName = NAME_FORBIDDEN_PATTERN.matcher(name).replaceAll("_");
fileName = fileName.replaceAll(String.format("([%1$s])([%1$s]+)", "-_"), "$1");
fileName = StringUtils.strip(fileName, "_-");
fileName = fileName.trim();
return fileName;
}
/**
* Build a generic property table for any ObjectType
*
@@ -175,13 +156,15 @@ public abstract class MarkupDocument {
}
}
Object example = PropertyUtils.getExample(globalContext.config.isGeneratedExamplesEnabled(), property, markupDocBuilder);
List<String> content = Arrays.asList(
propertyName,
propertyDescriptor.getDescription(property, propertyName),
Boolean.toString(property.getRequired()),
propertyType.displaySchema(docBuilder),
PropertyUtils.getDefaultValue(property),
PropertyUtils.getExample(property, markupDocBuilder)
example != null ? Json.pretty(example) : ""
);
cells.add(content);
}

View File

@@ -49,6 +49,7 @@ import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static io.github.robwin.swagger2markup.utils.IOUtils.normalizeName;
import static io.github.robwin.swagger2markup.utils.TagUtils.convertTagsListToMap;
import static io.github.robwin.swagger2markup.utils.TagUtils.getTagDescription;
import static org.apache.commons.lang3.StringUtils.defaultString;
@@ -66,6 +67,7 @@ public class PathsDocument extends MarkupDocument {
private final String PARAMETERS;
private final String BODY_PARAMETER;
private final String RESPONSES;
private final String HEADERS_COLUMN;
private final String EXAMPLE_REQUEST;
private final String EXAMPLE_RESPONSE;
@@ -91,6 +93,7 @@ public class PathsDocument extends MarkupDocument {
PARAMETERS = labels.getString("parameters");
BODY_PARAMETER = labels.getString("body_parameter");
RESPONSES = labels.getString("responses");
HEADERS_COLUMN = labels.getString("headers_column");
EXAMPLE_REQUEST = labels.getString("example_request");
EXAMPLE_RESPONSE = labels.getString("example_response");
SECURITY = labels.getString("security");

View File

@@ -58,7 +58,7 @@ public class ExamplesUtil {
example = generateExampleForRefModel(generateMissingExamples, simpleRef, definitions, markupDocBuilder);
}
if (example == null && generateMissingExamples) {
example = PropertyUtils.exampleFromType(schema.getType(), schema, markupDocBuilder);
example = PropertyUtils.generateExample(schema, markupDocBuilder);
}
}
}
@@ -117,11 +117,11 @@ public class ExamplesUtil {
if (item != null) {
abstractSerializableParameterExample = item.getExample();
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyUtils.exampleFromType(item.getType(), item, markupDocBuilder);
abstractSerializableParameterExample = PropertyUtils.generateExample(item, markupDocBuilder);
}
}
if (abstractSerializableParameterExample == null) {
abstractSerializableParameterExample = PropertyUtils.exampleFromType(((AbstractSerializableParameter) parameter).getType(), null, markupDocBuilder);
abstractSerializableParameterExample = ParameterUtils.generateExample((AbstractSerializableParameter)parameter);
}
}
if (parameter instanceof PathParameter) {
@@ -221,7 +221,7 @@ public class ExamplesUtil {
}
if (exampleObject == null) {
Property valueProperty = property.getValue();
exampleObject = PropertyUtils.exampleFromType(valueProperty.getType(), valueProperty, markupDocBuilder);
exampleObject = PropertyUtils.generateExample(valueProperty, markupDocBuilder);
}
}
exampleMap.put(property.getKey(), exampleObject);
@@ -238,7 +238,7 @@ public class ExamplesUtil {
if (valueProperty.getExample() != null) {
return valueProperty.getExample();
}
exampleMap.put("string", PropertyUtils.exampleFromType(valueProperty.getType(), valueProperty, markupDocBuilder));
exampleMap.put("string", PropertyUtils.generateExample(valueProperty, markupDocBuilder));
return exampleMap;
}
@@ -256,7 +256,7 @@ public class ExamplesUtil {
} else if (itemProperty instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) itemProperty).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyUtils.exampleFromType(itemProperty.getType(), itemProperty, markupDocBuilder)};
return new Object[]{PropertyUtils.generateExample(itemProperty, markupDocBuilder)};
}
}
}
@@ -276,29 +276,8 @@ public class ExamplesUtil {
} else if (property instanceof RefProperty) {
return new Object[]{generateExampleForRefModel(true, ((RefProperty) property).getSimpleRef(), definitions, markupDocBuilder)};
} else {
return new Object[]{PropertyUtils.exampleFromType(property.getType(), property, markupDocBuilder)};
return new Object[]{PropertyUtils.generateExample(property, markupDocBuilder)};
}
}
public static Object convertStringToType(String value, String type) {
if (value == null) {
return null;
}
try {
switch (type) {
case "integer":
return new Integer(value);
case "number":
return new Float(value);
case "boolean":
return new Boolean(value);
case "string":
return value;
default:
return value;
}
} catch (NumberFormatException e) {
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
}
}
}

View File

@@ -16,6 +16,7 @@
package io.github.robwin.swagger2markup.utils;
import com.google.common.base.Function;
import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.type.*;
import io.swagger.models.Model;
import io.swagger.models.parameters.AbstractSerializableParameter;
@@ -87,4 +88,24 @@ public final class ParameterUtils {
return defaultString(defaultValue);
}
/**
* Generate a default example value for parameter.
*
* @param parameter parameter
* @return a generated example for the parameter
*/
public static Object generateExample(AbstractSerializableParameter parameter) {
switch (parameter.getType()) {
case "integer":
return 0;
case "number":
return 0.0;
case "boolean":
return true;
case "string":
return "string";
default:
return parameter.getType();
}
}
}

View File

@@ -20,7 +20,6 @@ import io.github.robwin.markup.builder.MarkupDocBuilder;
import io.github.robwin.swagger2markup.type.*;
import io.swagger.models.properties.*;
import io.swagger.models.refs.RefFormat;
import io.swagger.util.Json;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.Validate;
@@ -106,37 +105,47 @@ public final class PropertyUtils {
/**
* Return example display string for the given {@code property}.
*
* @param property property
* @param property property
* @param markupDocBuilder doc builder
* @return property example display string
*/
public static String getExample(Property property, MarkupDocBuilder markupDocBuilder) {
public static Object getExample(boolean generateMissingExamples, Property property, MarkupDocBuilder markupDocBuilder) {
Validate.notNull(property, "property must not be null");
Object examplesValue;
Object examplesValue = null;
if (property.getExample() != null) {
examplesValue = property.getExample();
} else if (property instanceof MapProperty) {
Map<String, Object> exampleMap = new HashMap<>();
Property additionalProperty = ((MapProperty) property).getAdditionalProperties();
if (additionalProperty.getExample() != null) {
examplesValue = additionalProperty.getExample();
} else {
exampleMap.put("string", exampleFromType(additionalProperty.getType(), additionalProperty, markupDocBuilder));
examplesValue = Json.pretty(exampleMap);
} else if (generateMissingExamples) {
Map<String, Object> exampleMap = new HashMap<>();
exampleMap.put("string", generateExample(additionalProperty, markupDocBuilder));
examplesValue = exampleMap;
}
} else if (property instanceof ArrayProperty) {
List<Object> exampleArray = new ArrayList<>();
Property itemProperty = ((ArrayProperty) property).getItems();
exampleArray.add(exampleFromType(itemProperty.getType(), itemProperty, markupDocBuilder));
examplesValue = Json.pretty(exampleArray);
} else {
examplesValue = Json.pretty(exampleFromType(property.getType(), property, markupDocBuilder));
if (generateMissingExamples) {
Property itemProperty = ((ArrayProperty) property).getItems();
List<Object> exampleArray = new ArrayList<>();
exampleArray.add(generateExample(itemProperty, markupDocBuilder));
examplesValue = exampleArray;
}
} else if (generateMissingExamples) {
examplesValue = generateExample(property, markupDocBuilder);
}
return String.valueOf(examplesValue);
return examplesValue;
}
public static Object exampleFromType(String type, Property property, MarkupDocBuilder markupDocBuilder) {
switch (type) {
/**
* Generate a default example value for property.
*
* @param property property
* @param markupDocBuilder doc builder
* @return a generated example for the property
*/
public static Object generateExample(Property property, MarkupDocBuilder markupDocBuilder) {
switch (property.getType()) {
case "integer":
return 0;
case "number":
@@ -146,11 +155,41 @@ public final class PropertyUtils {
case "string":
return "string";
case "ref":
if (property != null && property instanceof RefProperty) {
if (property instanceof RefProperty) {
return markupDocBuilder.copy().crossReference(((RefProperty) property).getSimpleRef()).toString();
}
default:
return type;
return property.getType();
}
}
/**
* Convert a string {@code value} to specified {@code type}.
*
* @param value value to convert
* @param type target conversion type
* @return converted value as object
*/
public static Object convertExample(String value, String type) {
if (value == null) {
return null;
}
try {
switch (type) {
case "integer":
return Integer.valueOf(value);
case "number":
return Float.valueOf(value);
case "boolean":
return Boolean.valueOf(value);
case "string":
return value;
default:
return value;
}
} catch (NumberFormatException e) {
throw new RuntimeException(String.format("Value '%s' cannot be converted to '%s'", value, type), e);
}
}
}

View File

@@ -8,6 +8,7 @@ required_column=Required
schema_column=Schema
name_column=Name
description_column=Description
headers_column=Headers
scopes_column=Scopes
produces=Produces
consumes=Consumes

View File

@@ -8,6 +8,7 @@ required_column=Requis
schema_column=Sch\u00E9ma
name_column=Nom
description_column=Description
headers_column=En-t\u00EAtes
scopes_column=P\u00E9rim\u00E8tre
produces=Produit
consumes=Consomme

View File

@@ -8,6 +8,7 @@ example_column=Example
schema_column=\u0421\u0445\u0435\u043C\u0430
name_column=\u0418\u043C\u044F
description_column=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435
headers_column=Headers
scopes_column=Scopes
produces=\u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442
consumes=\u041F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442

View File

@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.github.robwin.markup.builder.MarkupLanguage;
import io.github.robwin.swagger2markup.assertions.DiffAssertions;
import io.github.robwin.swagger2markup.config.Swagger2MarkupConfig;
import io.github.robwin.swagger2markup.extension.Swagger2MarkupExtensionRegistry;
import io.github.robwin.swagger2markup.extension.repository.DynamicDefinitionsContentExtension;
@@ -147,10 +148,12 @@ public class Swagger2MarkupConverterTest {
.contains("==== Response 200\n" + orderExample);
String definitionsDocument = new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")));
assertThat(definitionsDocument)
.contains("|name||true|string||\"doggie\"");
assertThat(definitionsDocument)
.contains("|id||false|integer(int64)||77");
assertThat(definitionsDocument).contains("|pictures||false|string(byte) array||[ \"string\" ]");
assertThat(definitionsDocument).contains("|shipDate||false|string(date-time)||\"string\"");
assertThat(definitionsDocument).contains("|pictures||false|string(byte) array||");
assertThat(definitionsDocument).contains("|shipDate||false|string(date-time)||");
assertThat(definitionsDocument)
.doesNotContain("99");
}
@@ -234,9 +237,13 @@ public class Swagger2MarkupConverterTest {
String definitionsDocument = new String(Files.readAllBytes(outputDirectory.resolve("definitions.adoc")));
assertThat(definitionsDocument)
.contains("|id||false|integer(int64)||77");
.contains("|name||true|string||\"doggie\"");
assertThat(definitionsDocument)
.contains("|name||true|string||doggie");
.contains("|id||false|integer(int64)||77");
assertThat(definitionsDocument).contains("|pictures||false|string(byte) array||[ \"string\" ]");
assertThat(definitionsDocument).contains("|shipDate||false|string(date-time)||\"string\"");
assertThat(definitionsDocument)
.doesNotContain("99");
assertThat(definitionsDocument)
.contains("|nicknames||false|object||{\n" +
" \"string\" : \"string\"\n" +
@@ -280,6 +287,13 @@ public class Swagger2MarkupConverterTest {
String[] directories = outputDirectory.toFile().list();
assertThat(directories).hasSize(4).containsAll(
asList("definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"));
Path actual = outputDirectory.resolve("overview.adoc");
Path expected = Paths.get(Swagger2MarkupConverterTest.class.getResource("/results/asciidoc/default/overview.adoc").toURI());
DiffAssertions.assertThat(actual)
.isEqualTo(expected,"testSwagger2AsciiDocConversion.html");
}
@Test
@@ -299,8 +313,8 @@ public class Swagger2MarkupConverterTest {
.intoFolder(outputDirectory);
//Then
String[] directories = outputDirectory.toFile().list();
assertThat(directories).hasSize(4).containsAll(
String[] files = outputDirectory.toFile().list();
assertThat(files).hasSize(4).containsAll(
asList("definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"));
}
@@ -348,23 +362,6 @@ public class Swagger2MarkupConverterTest {
}
}
@Test
public void testOldSwaggerSpec2AsciiDocConversion() throws IOException, URISyntaxException {
//Given
Path file = Paths.get(Swagger2MarkupConverterTest.class.getResource("/json/error_swagger_12.json").toURI());
Path outputDirectory = Paths.get("build/docs/asciidoc/generated");
FileUtils.deleteQuietly(outputDirectory.toFile());
//When
Swagger2MarkupConverter.from(file).build()
.intoFolder(outputDirectory);
//Then
String[] directories = outputDirectory.toFile().list();
assertThat(directories).hasSize(4).containsAll(
asList("definitions.adoc", "overview.adoc", "paths.adoc", "security.adoc"));
}
@Test
public void testSwagger2AsciiDocConversionWithDefinitionDescriptions() throws IOException, URISyntaxException {
//Given

View File

@@ -0,0 +1,90 @@
/*
*
* Copyright 2015 Robert Winkler
*
* 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
*
* 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.
*
*
*/
package io.github.robwin.swagger2markup.assertions;
import com.sksamuel.diffpatch.DiffMatchPatch;
import org.apache.commons.io.IOUtils;
import org.assertj.core.api.AbstractAssert;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import static org.assertj.core.api.Assertions.assertThat;
public class DiffAssert extends AbstractAssert<DiffAssert, Path>{
public DiffAssert(Path actual) {
super(actual, DiffAssert.class);
}
/**
* Verifies that the content of the actual File is equal to the given one.
*
* @param expected the given value to compare the actual value to.
* @param reportName the name of the report which should be generated if the files differ.
* @return {@code this} assertion object.
* @throws AssertionError if the actual value is not equal to the given one or if the actual value is {@code null}..
*/
public DiffAssert isEqualTo(Path expected, String reportName) {
LinkedList<DiffMatchPatch.Diff> diffs = diff(actual, expected);
boolean allDiffsAreEqual = assertThatAllDiffsAreEqual(diffs);
if(!allDiffsAreEqual){
writeHtmlReport(reportName, diffs);
}
assertThat(allDiffsAreEqual).as("The content of the files differ. Check the HTML report for more details.").isTrue();
return myself;
}
public boolean assertThatAllDiffsAreEqual(LinkedList<DiffMatchPatch.Diff> diffs){
for(DiffMatchPatch.Diff diff : diffs){
if(diff.operation == DiffMatchPatch.Operation.DELETE || diff.operation == DiffMatchPatch.Operation.INSERT){
return false;
}
}
return true;
}
private static LinkedList<DiffMatchPatch.Diff> diff(Path actual, Path expected){
DiffMatchPatch differ = new DiffMatchPatch();
try {
return differ.diff_main(IOUtils.toString(expected.toUri()), IOUtils.toString(actual.toUri()), false);
} catch (IOException e) {
throw new RuntimeException("Failed to diff files.", e);
}
}
private static void writeHtmlReport(String reportName, LinkedList<DiffMatchPatch.Diff> diffs){
DiffMatchPatch differ = new DiffMatchPatch();
String reportFolder = "build/diff-report";
try {
Files.createDirectories(Paths.get(reportFolder));
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(reportFolder, reportName), Charset.forName("UTF-8"))) {
writer.write(differ.diff_prettyHtml(diffs));
}
} catch (IOException e) {
throw new RuntimeException(String.format("Failed to write report into folder %s", reportFolder), e);
}
}
}

View File

@@ -0,0 +1,43 @@
/*
*
* Copyright 2015 Robert Winkler
*
* 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
*
* 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.
*
*
*/
package io.github.robwin.swagger2markup.assertions;
import org.apache.commons.lang3.Validate;
import java.nio.file.Path;
/**
* Entry point for assertion methods for diffing files.
*
* @author Robert Winkler
*/
public class DiffAssertions {
/**
* Creates a new instance of <code>{@link DiffAssert}</code>.
*
* @param actual the the actual File path.
* @return the created assertion object.
*/
public static DiffAssert assertThat(Path actual) {
Validate.notNull(actual, "actual must not be null");
return new DiffAssert(actual);
}
}

View File

@@ -0,0 +1,69 @@
[[_definitions]]
== Definitions
=== Category
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||0
|name||false|string||string
|===
=== Order
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|complete||false|boolean||true
|id||false|integer(int64)||0
|petId||false|integer(int64)||0
|quantity||false|integer(int32)||0
|shipDate||false|string(date-time)||string
|status|Order Status|false|string||string
|===
=== Pet
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|category||false|<<_category,Category>>||<<_category>>
|id||false|integer(int64)||0
|name||true|string||doggie
|photoUrls||true|string array||[ string ]
|status|pet status in the store|false|string||string
|tags||false|<<_tag,Tag>> array||[ <<_tag>> ]
|===
=== Tag
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|id||false|integer(int64)||0
|name||false|string||string
|===
=== User
[options="header", cols=".^1h,.^6,.^1,.^1,.^1,.^1"]
|===
|Name|Description|Required|Schema|Default|Example
|email||false|string||string
|firstName||false|string||string
|id||false|integer(int64)||0
|lastName||false|string||string
|password||false|string||string
|phone||false|string||string
|userStatus|User Status|false|integer(int32)||0
|username||false|string||string
|===

View File

@@ -0,0 +1,36 @@
= Swagger Petstore
[[_overview]]
== Overview
This is a sample server Petstore server.
[Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
For this sample, you can use the api key `special-key` to test the authorization filters
=== Version information
Version : 1.0.0
=== Contact information
Contact : apiteam@swagger.io
=== License information
License : Apache 2.0
License URL : http://www.apache.org/licenses/LICENSE-2.0.html
Terms of service : http://helloreverb.com/terms/
=== URI scheme
Host : petstore.swagger.io
BasePath : /v2
Schemes : HTTP
=== Tags
* pet : Pet resource
* store : Store resource
* user : User resource

View File

@@ -0,0 +1,767 @@
[[_paths]]
== Paths
=== Add a new pet to the store
----
POST /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Update an existing pet
----
PUT /pets
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Pet object that needs to be added to the store|false|<<_pet,Pet>>|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|400|Invalid ID supplied|No Content
|404|Pet not found|No Content
|405|Validation exception|No Content
|===
==== Consumes
* application/json
* application/xml
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by status
----
GET /pets/findByStatus
----
==== Description
[%hardbreaks]
Multiple status values can be provided with comma seperated strings
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|status|Status values that need to be considered for filter|false|multi string array|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_pet,Pet>> array
|400|Invalid status value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Finds Pets by tags
----
GET /pets/findByTags
----
==== Description
[%hardbreaks]
Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|tags|Tags to filter by|false|multi string array|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_pet,Pet>> array
|400|Invalid tag value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Deletes a pet
----
DELETE /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Header|api_key||true|string|
|Path|petId|Pet id to delete|true|integer(int64)|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|400|Invalid pet value|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Updates a pet in the store with form data
----
POST /pets/{petId}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be updated|true|string|
|FormData|name|Updated name of the pet|true|string|
|FormData|status|Updated status of the pet|true|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|405|Invalid input|No Content
|===
==== Consumes
* application/x-www-form-urlencoded
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Find pet by ID
----
GET /pets/{petId}
----
==== Description
[%hardbreaks]
Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|petId|ID of pet that needs to be fetched|true|integer(int64)|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_pet,Pet>>
|400|Invalid ID supplied|No Content
|404|Pet not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* pet
==== Security
[options="header", cols=".^1,.^1h,.^6"]
|===
|Type|Name|Scopes
|apiKey|<<_api_key,api_key>>|
|oauth2|<<_petstore_auth,petstore_auth>>|write_pets,read_pets
|===
=== Place an order for a pet
----
POST /stores/order
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|order placed for purchasing the pet|false|<<_order,Order>>|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_order,Order>>
|400|Invalid Order|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Delete purchase order by ID
----
DELETE /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of the order that needs to be deleted|true|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|400|Invalid ID supplied|No Content
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Find purchase order by ID
----
GET /stores/order/{orderId}
----
==== Description
[%hardbreaks]
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|orderId|ID of pet that needs to be fetched|true|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_order,Order>>
|400|Invalid ID supplied|No Content
|404|Order not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* store
=== Create user
----
POST /users
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|Created user object|false|<<_user,User>>|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithArray
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Creates list of users with given input array
----
POST /users/createWithList
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Body|body|List of user object|false|<<_user,User>> array|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs user into the system
----
GET /users/login
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Query|password|The password for login in clear text|false|string|
|Query|username|The user name for login|false|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|string
|400|Invalid username/password supplied|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Logs out current logged in user session
----
GET /users/logout
----
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|default|successful operation|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Delete user
----
DELETE /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be deleted|true|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|400|Invalid username supplied|No Content
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Updated user
----
PUT /users/{username}
----
==== Description
[%hardbreaks]
This can only be done by the logged in user.
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|name that need to be deleted|true|string|
|Body|body|Updated user object|false|<<_user,User>>|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|400|Invalid user supplied|No Content
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user
=== Get user by user name
----
GET /users/{username}
----
==== Parameters
[options="header", cols=".^1h,.^1h,.^6,.^1,.^1,.^1"]
|===
|Type|Name|Description|Required|Schema|Default
|Path|username|The name that needs to be fetched. Use user1 for testing.|true|string|
|===
==== Responses
[options="header", cols=".^1h,.^3,.^3,.^1"]
|===
|HTTP Code|Description|Headers|Schema
|200|successful operation|<<_user,User>>
|400|Invalid username supplied|No Content
|404|User not found|No Content
|===
==== Produces
* application/json
* application/xml
==== Tags
* user

View File

@@ -0,0 +1,23 @@
[[_security]]
== Security
=== api_key
Type : apiKey
Name : api_key
In : HEADER
=== petstore_auth
Type : oauth2
Flow : implicit
Token URL : http://petstore.swagger.io/api/oauth/dialog
[options="header", cols="1,6"]
|===
|Name|Description
|write_pets|modify pets in your account
|read_pets|read your pets
|===