diff --git a/bin/java-play-framework-petstore-server-all.sh b/bin/java-play-framework-petstore-server-all.sh index be25431330..fa4fd9daf9 100755 --- a/bin/java-play-framework-petstore-server-all.sh +++ b/bin/java-play-framework-petstore-server-all.sh @@ -8,4 +8,5 @@ ./bin/java-play-framework-petstore-server-no-swagger-ui.sh ./bin/java-play-framework-petstore-server-no-wrap-calls.sh ./bin/java-play-framework-petstore-server-fake-endpoints.sh -./bin/java-play-framework-petstore-server-api-package-override.sh \ No newline at end of file +./bin/java-play-framework-petstore-server-api-package-override.sh +./bin/java-play-framework-petstore-server-async.sh diff --git a/bin/java-play-framework-petstore-server-async.json b/bin/java-play-framework-petstore-server-async.json new file mode 100755 index 0000000000..69161a46d0 --- /dev/null +++ b/bin/java-play-framework-petstore-server-async.json @@ -0,0 +1,5 @@ +{ + "additionalProperties" : { + "supportAsync" : true + } +} diff --git a/bin/java-play-framework-petstore-server-async.sh b/bin/java-play-framework-petstore-server-async.sh new file mode 100755 index 0000000000..ca5021bc53 --- /dev/null +++ b/bin/java-play-framework-petstore-server-async.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/JavaPlayFramework -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l java-play-framework -c bin/java-play-framework-petstore-server-async.json -o samples/server/petstore/java-play-framework-async -DhideGenerationTimestamp=true" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java index 40af7e2111..ced84fef21 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java @@ -51,10 +51,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code public static final String DEFAULT_LIBRARY = ""; public static final String DATE_LIBRARY = "dateLibrary"; public static final String JAVA8_MODE = "java8"; + public static final String SUPPORT_ASYNC = "supportAsync"; public static final String WITH_XML = "withXml"; public static final String SUPPORT_JAVA6 = "supportJava6"; protected String dateLibrary = "threetenbp"; + protected boolean supportAsync = false; protected boolean java8Mode = false; protected boolean withXml = false; protected String invokerPackage = "io.swagger"; @@ -173,7 +175,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code java8ModeOptions.put("false", "Various third party libraries as needed"); java8Mode.setEnum(java8ModeOptions); cliOptions.add(java8Mode); - } @Override @@ -381,14 +382,21 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code // used later in recursive import in postProcessingModels importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator"); - if(additionalProperties.containsKey(JAVA8_MODE)) { + if (additionalProperties.containsKey(JAVA8_MODE)) { setJava8Mode(Boolean.parseBoolean(additionalProperties.get(JAVA8_MODE).toString())); if ( java8Mode ) { additionalProperties.put("java8", "true"); } } - if(additionalProperties.containsKey(WITH_XML)) { + if (additionalProperties.containsKey(SUPPORT_ASYNC)) { + setSupportAsync(Boolean.parseBoolean(additionalProperties.get(SUPPORT_ASYNC).toString())); + if (supportAsync) { + additionalProperties.put(SUPPORT_ASYNC, "true"); + } + } + + if (additionalProperties.containsKey(WITH_XML)) { setWithXml(Boolean.parseBoolean(additionalProperties.get(WITH_XML).toString())); if ( withXml ) { additionalProperties.put(WITH_XML, "true"); @@ -1217,6 +1225,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code this.java8Mode = enabled; } + public void setSupportAsync(boolean enabled) { + this.supportAsync = enabled; + } + @Override public String escapeQuotationMark(String input) { // remove " to avoid code injection diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache index 6862b7402a..7355eae845 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApi.mustache @@ -16,15 +16,21 @@ import javax.validation.constraints.*; public class {{classname}}ControllerImp {{#useInterfaces}}implements {{classname}}ControllerImpInterface{{/useInterfaces}} { {{#operation}} {{#useInterfaces}}@Override{{/useInterfaces}} - public {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}} { + public {{^returnType}}void{{/returnType}}{{#returnType}}{{#supportAsync}}CompletionStage<{{/supportAsync}}{{>returnTypesNoVoid}}{{#supportAsync}}>{{/supportAsync}}{{/returnType}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}} { //Do your magic!!! {{#returnType}} + {{#supportAsync}} + return CompletableFuture.supplyAsync(() -> { + {{/supportAsync}} {{#isResponseFile}} return new FileInputStream("replace this"); {{/isResponseFile}} {{^isResponseFile}} - return new {{>returnTypesNoVoidNoAbstract}}({{#vendorExtensions.missingReturnInfoIfNeeded}}{{vendorExtensions.missingReturnInfoIfNeeded}}{{/vendorExtensions.missingReturnInfoIfNeeded}}); + {{#supportAsync}} {{/supportAsync}}return new {{>returnTypesNoVoidNoAbstract}}({{#vendorExtensions.missingReturnInfoIfNeeded}}{{vendorExtensions.missingReturnInfoIfNeeded}}{{/vendorExtensions.missingReturnInfoIfNeeded}}); {{/isResponseFile}} + {{#supportAsync}} + }); + {{/supportAsync}} {{/returnType}} } diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache index 906dbd59b8..d492b376d0 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiController.mustache @@ -18,6 +18,11 @@ import java.io.IOException; {{/handleExceptions}} import swagger.SwaggerUtils; import com.fasterxml.jackson.core.type.TypeReference; +{{#supportAsync}} + +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; +{{/supportAsync}} {{#useBeanValidation}} import javax.validation.constraints.*; @@ -54,7 +59,7 @@ public class {{classname}}Controller extends Controller { {{#operation}} {{#wrapCalls}}@ApiAction{{/wrapCalls}} - public Result {{operationId}}({{#pathParams}}{{>pathParams}}{{#hasMore}},{{/hasMore}}{{/pathParams}}) {{^handleExceptions}}{{#bodyParams}}throws IOException{{/bodyParams}}{{/handleExceptions}}{{#handleExceptions}}throws Exception{{/handleExceptions}} { + public {{#supportAsync}}CompletionStage<{{/supportAsync}}Result{{#supportAsync}}>{{/supportAsync}} {{operationId}}({{#pathParams}}{{>pathParams}}{{#hasMore}},{{/hasMore}}{{/pathParams}}) {{^handleExceptions}}{{#bodyParams}}throws IOException{{/bodyParams}}{{/handleExceptions}}{{#handleExceptions}}throws Exception{{/handleExceptions}} { {{#bodyParams}} {{^collectionFormat}} JsonNode node{{paramName}} = request().body().asJson(); @@ -195,11 +200,17 @@ public class {{classname}}Controller extends Controller { {{/collectionFormat}} {{/headerParams}} {{^controllerOnly}} - {{#returnType}}{{>returnTypesNoVoid}} obj = {{/returnType}}imp.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{^returnType}} + {{#supportAsync}} + return CompletableFuture.supplyAsync(() -> { + {{/supportAsync}} + {{/returnType}} + {{#returnType}}{{#supportAsync}}CompletionStage<{{>returnTypesNoVoid}}> stage = {{/supportAsync}}{{^supportAsync}}{{>returnTypesNoVoid}} obj = {{/supportAsync}}{{/returnType}}{{^returnType}}{{#supportAsync}} {{/supportAsync}}{{/returnType}}imp.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}{{#supportAsync}}.thenApply(obj -> { {{/supportAsync}}{{/returnType}}{{^supportAsync}};{{/supportAsync}} {{#returnType}} {{^isResponseFile}} {{^returnTypeIsPrimitive}} {{#useBeanValidation}} + {{^supportAsync}} if (configuration.getBoolean("useOutputBeanValidation")) { {{#isListContainer}} for ({{{returnType}}} curItem : obj) { @@ -215,21 +226,50 @@ public class {{classname}}Controller extends Controller { SwaggerUtils.validate(obj); {{/returnContainer}} } + {{/supportAsync}} + {{#supportAsync}} + if (configuration.getBoolean("useOutputBeanValidation")) { + {{#isListContainer}} + for ({{{returnType}}} curItem : obj) { + SwaggerUtils.validate(curItem); + } + {{/isListContainer}} + {{#isMapContainer}} + for (Map.Entry entry : obj.entrySet()) { + SwaggerUtils.validate(entry.getValue()); + } + {{/isMapContainer}} + {{^returnContainer}} + SwaggerUtils.validate(obj); + {{/returnContainer}} + } + {{/supportAsync}} {{/useBeanValidation}} {{/returnTypeIsPrimitive}} {{/isResponseFile}} + {{#supportAsync}} + return obj; + }); + {{/supportAsync}} {{/returnType}} {{#returnType}} - {{^isResponseFile}}JsonNode result = mapper.valueToTree(obj); - return ok(result); + {{#supportAsync}} + stage.thenApply(obj -> { + {{/supportAsync}} + {{^isResponseFile}} + {{#supportAsync}} {{/supportAsync}}JsonNode result = mapper.valueToTree(obj); + {{#supportAsync}} {{/supportAsync}}return ok(result); {{/isResponseFile}} {{#isResponseFile}} - return ok(obj); + {{#supportAsync}} {{/supportAsync}}return ok(obj); {{/isResponseFile}} {{/returnType}} {{^returnType}} - return ok(); + {{#supportAsync}} {{/supportAsync}}return ok(); {{/returnType}} + {{#supportAsync}} + }); + {{/supportAsync}} {{/controllerOnly}} {{#controllerOnly}} return ok(); diff --git a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiInterface.mustache b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiInterface.mustache index 918ee1f85b..0b60e57db9 100644 --- a/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiInterface.mustache +++ b/modules/swagger-codegen/src/main/resources/JavaPlayFramework/newApiInterface.mustache @@ -7,6 +7,10 @@ import play.mvc.Http; import java.util.List; import java.util.ArrayList; import java.util.HashMap; +{{#supportAsync}} +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; +{{/supportAsync}} {{#useBeanValidation}} import javax.validation.constraints.*; @@ -16,7 +20,7 @@ import javax.validation.constraints.*; @SuppressWarnings("RedundantThrows") public interface {{classname}}ControllerImpInterface { {{#operation}} - {{>returnTypes}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}}; + {{^returnType}}void{{/returnType}}{{#returnType}}{{#supportAsync}}CompletionStage<{{/supportAsync}}{{>returnTypesNoVoid}}{{#supportAsync}}>{{/supportAsync}}{{/returnType}} {{operationId}}({{#allParams}}{{>pathParams}}{{>queryParams}}{{>bodyParams}}{{>formParams}}{{>headerParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {{#handleExceptions}}throws Exception{{/handleExceptions}}; {{/operation}} } diff --git a/samples/server/petstore/java-play-framework-async/.swagger-codegen-ignore b/samples/server/petstore/java-play-framework-async/.swagger-codegen-ignore new file mode 100644 index 0000000000..c5fa491b4c --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/java-play-framework-async/.swagger-codegen/VERSION b/samples/server/petstore/java-play-framework-async/.swagger-codegen/VERSION new file mode 100644 index 0000000000..855ff9501e --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/.swagger-codegen/VERSION @@ -0,0 +1 @@ +2.4.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/LICENSE b/samples/server/petstore/java-play-framework-async/LICENSE new file mode 100644 index 0000000000..4baedcb95f --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/LICENSE @@ -0,0 +1,8 @@ +This software is licensed under the Apache 2 license, quoted below. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project 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. \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/README b/samples/server/petstore/java-play-framework-async/README new file mode 100644 index 0000000000..2fce02950d --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/README @@ -0,0 +1,4 @@ +This is your new Play application +================================= + +This file will be packaged with your application when using `activator dist`. \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/app/Module.java b/samples/server/petstore/java-play-framework-async/app/Module.java new file mode 100644 index 0000000000..f1b062c293 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/Module.java @@ -0,0 +1,13 @@ +import com.google.inject.AbstractModule; + +import controllers.*; + +public class Module extends AbstractModule { + + @Override + protected void configure() { + bind(PetApiControllerImpInterface.class).to(PetApiControllerImp.class); + bind(StoreApiControllerImpInterface.class).to(StoreApiControllerImp.class); + bind(UserApiControllerImpInterface.class).to(UserApiControllerImp.class); + } +} \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/Category.java b/samples/server/petstore/java-play-framework-async/app/apimodels/Category.java new file mode 100644 index 0000000000..9f0206575f --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/Category.java @@ -0,0 +1,96 @@ +package apimodels; + +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * A category for a pet + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class Category { + @JsonProperty("id") + private Long id = null; + + @JsonProperty("name") + private String name = null; + + public Category id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Category name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + **/ + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Category category = (Category) o; + return Objects.equals(id, category.id) && + Objects.equals(name, category.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Category {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/ModelApiResponse.java b/samples/server/petstore/java-play-framework-async/app/apimodels/ModelApiResponse.java new file mode 100644 index 0000000000..07493e8482 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/ModelApiResponse.java @@ -0,0 +1,118 @@ +package apimodels; + +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * Describes the result of uploading an image resource + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class ModelApiResponse { + @JsonProperty("code") + private Integer code = null; + + @JsonProperty("type") + private String type = null; + + @JsonProperty("message") + private String message = null; + + public ModelApiResponse code(Integer code) { + this.code = code; + return this; + } + + /** + * Get code + * @return code + **/ + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public ModelApiResponse type(String type) { + this.type = type; + return this; + } + + /** + * Get type + * @return type + **/ + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ModelApiResponse message(String message) { + this.message = message; + return this; + } + + /** + * Get message + * @return message + **/ + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ModelApiResponse _apiResponse = (ModelApiResponse) o; + return Objects.equals(code, _apiResponse.code) && + Objects.equals(type, _apiResponse.type) && + Objects.equals(message, _apiResponse.message); + } + + @Override + public int hashCode() { + return Objects.hash(code, type, message); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ModelApiResponse {\n"); + + sb.append(" code: ").append(toIndentedString(code)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/Order.java b/samples/server/petstore/java-play-framework-async/app/apimodels/Order.java new file mode 100644 index 0000000000..cdc21f722c --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/Order.java @@ -0,0 +1,219 @@ +package apimodels; + +import java.time.OffsetDateTime; +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * An order for a pets from the pet store + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class Order { + @JsonProperty("id") + private Long id = null; + + @JsonProperty("petId") + private Long petId = null; + + @JsonProperty("quantity") + private Integer quantity = null; + + @JsonProperty("shipDate") + private OffsetDateTime shipDate = null; + + /** + * Order Status + */ + public enum StatusEnum { + PLACED("placed"), + + APPROVED("approved"), + + DELIVERED("delivered"); + + private final String value; + + StatusEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String text) { + for (StatusEnum b : StatusEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + + @JsonProperty("status") + private StatusEnum status = null; + + @JsonProperty("complete") + private Boolean complete = false; + + public Order id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Order petId(Long petId) { + this.petId = petId; + return this; + } + + /** + * Get petId + * @return petId + **/ + public Long getPetId() { + return petId; + } + + public void setPetId(Long petId) { + this.petId = petId; + } + + public Order quantity(Integer quantity) { + this.quantity = quantity; + return this; + } + + /** + * Get quantity + * @return quantity + **/ + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Order shipDate(OffsetDateTime shipDate) { + this.shipDate = shipDate; + return this; + } + + /** + * Get shipDate + * @return shipDate + **/ + @Valid + public OffsetDateTime getShipDate() { + return shipDate; + } + + public void setShipDate(OffsetDateTime shipDate) { + this.shipDate = shipDate; + } + + public Order status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * Order Status + * @return status + **/ + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + public Order complete(Boolean complete) { + this.complete = complete; + return this; + } + + /** + * Get complete + * @return complete + **/ + public Boolean isComplete() { + return complete; + } + + public void setComplete(Boolean complete) { + this.complete = complete; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Order order = (Order) o; + return Objects.equals(id, order.id) && + Objects.equals(petId, order.petId) && + Objects.equals(quantity, order.quantity) && + Objects.equals(shipDate, order.shipDate) && + Objects.equals(status, order.status) && + Objects.equals(complete, order.complete); + } + + @Override + public int hashCode() { + return Objects.hash(id, petId, quantity, shipDate, status, complete); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Order {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" petId: ").append(toIndentedString(petId)).append("\n"); + sb.append(" quantity: ").append(toIndentedString(quantity)).append("\n"); + sb.append(" shipDate: ").append(toIndentedString(shipDate)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" complete: ").append(toIndentedString(complete)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/Pet.java b/samples/server/petstore/java-play-framework-async/app/apimodels/Pet.java new file mode 100644 index 0000000000..5e5ff37629 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/Pet.java @@ -0,0 +1,238 @@ +package apimodels; + +import apimodels.Category; +import apimodels.Tag; +import java.util.ArrayList; +import java.util.List; +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * A pet for sale in the pet store + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class Pet { + @JsonProperty("id") + private Long id = null; + + @JsonProperty("category") + private Category category = null; + + @JsonProperty("name") + private String name = null; + + @JsonProperty("photoUrls") + private List photoUrls = new ArrayList<>(); + + @JsonProperty("tags") + private List tags = null; + + /** + * pet status in the store + */ + public enum StatusEnum { + AVAILABLE("available"), + + PENDING("pending"), + + SOLD("sold"); + + private final String value; + + StatusEnum(String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static StatusEnum fromValue(String text) { + for (StatusEnum b : StatusEnum.values()) { + if (String.valueOf(b.value).equals(text)) { + return b; + } + } + return null; + } + } + + @JsonProperty("status") + private StatusEnum status = null; + + public Pet id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Pet category(Category category) { + this.category = category; + return this; + } + + /** + * Get category + * @return category + **/ + @Valid + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public Pet name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + **/ + @NotNull + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Pet photoUrls(List photoUrls) { + this.photoUrls = photoUrls; + return this; + } + + public Pet addPhotoUrlsItem(String photoUrlsItem) { + photoUrls.add(photoUrlsItem); + return this; + } + + /** + * Get photoUrls + * @return photoUrls + **/ + @NotNull + public List getPhotoUrls() { + return photoUrls; + } + + public void setPhotoUrls(List photoUrls) { + this.photoUrls = photoUrls; + } + + public Pet tags(List tags) { + this.tags = tags; + return this; + } + + public Pet addTagsItem(Tag tagsItem) { + if (tags == null) { + tags = new ArrayList<>(); + } + tags.add(tagsItem); + return this; + } + + /** + * Get tags + * @return tags + **/ + @Valid + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public Pet status(StatusEnum status) { + this.status = status; + return this; + } + + /** + * pet status in the store + * @return status + **/ + public StatusEnum getStatus() { + return status; + } + + public void setStatus(StatusEnum status) { + this.status = status; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Pet pet = (Pet) o; + return Objects.equals(id, pet.id) && + Objects.equals(category, pet.category) && + Objects.equals(name, pet.name) && + Objects.equals(photoUrls, pet.photoUrls) && + Objects.equals(tags, pet.tags) && + Objects.equals(status, pet.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, category, name, photoUrls, tags, status); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pet {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n"); + sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/Tag.java b/samples/server/petstore/java-play-framework-async/app/apimodels/Tag.java new file mode 100644 index 0000000000..15a8774252 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/Tag.java @@ -0,0 +1,96 @@ +package apimodels; + +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * A tag for a pet + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class Tag { + @JsonProperty("id") + private Long id = null; + + @JsonProperty("name") + private String name = null; + + public Tag id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Tag name(String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name + **/ + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Tag tag = (Tag) o; + return Objects.equals(id, tag.id) && + Objects.equals(name, tag.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Tag {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/apimodels/User.java b/samples/server/petstore/java-play-framework-async/app/apimodels/User.java new file mode 100644 index 0000000000..689de76889 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/apimodels/User.java @@ -0,0 +1,228 @@ +package apimodels; + +import com.fasterxml.jackson.annotation.*; +import java.util.Set; +import javax.validation.*; +import java.util.Objects; +import javax.validation.constraints.*; +/** + * A User who is purchasing from the pet store + */ + +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) +public class User { + @JsonProperty("id") + private Long id = null; + + @JsonProperty("username") + private String username = null; + + @JsonProperty("firstName") + private String firstName = null; + + @JsonProperty("lastName") + private String lastName = null; + + @JsonProperty("email") + private String email = null; + + @JsonProperty("password") + private String password = null; + + @JsonProperty("phone") + private String phone = null; + + @JsonProperty("userStatus") + private Integer userStatus = null; + + public User id(Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public User username(String username) { + this.username = username; + return this; + } + + /** + * Get username + * @return username + **/ + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User firstName(String firstName) { + this.firstName = firstName; + return this; + } + + /** + * Get firstName + * @return firstName + **/ + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public User lastName(String lastName) { + this.lastName = lastName; + return this; + } + + /** + * Get lastName + * @return lastName + **/ + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public User email(String email) { + this.email = email; + return this; + } + + /** + * Get email + * @return email + **/ + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public User password(String password) { + this.password = password; + return this; + } + + /** + * Get password + * @return password + **/ + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public User phone(String phone) { + this.phone = phone; + return this; + } + + /** + * Get phone + * @return phone + **/ + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public User userStatus(Integer userStatus) { + this.userStatus = userStatus; + return this; + } + + /** + * User Status + * @return userStatus + **/ + public Integer getUserStatus() { + return userStatus; + } + + public void setUserStatus(Integer userStatus) { + this.userStatus = userStatus; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(id, user.id) && + Objects.equals(username, user.username) && + Objects.equals(firstName, user.firstName) && + Objects.equals(lastName, user.lastName) && + Objects.equals(email, user.email) && + Objects.equals(password, user.password) && + Objects.equals(phone, user.phone) && + Objects.equals(userStatus, user.userStatus); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, firstName, lastName, email, password, phone, userStatus); + } + + @SuppressWarnings("StringBufferReplaceableByString") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" username: ").append(toIndentedString(username)).append("\n"); + sb.append(" firstName: ").append(toIndentedString(firstName)).append("\n"); + sb.append(" lastName: ").append(toIndentedString(lastName)).append("\n"); + sb.append(" email: ").append(toIndentedString(email)).append("\n"); + sb.append(" password: ").append(toIndentedString(password)).append("\n"); + sb.append(" phone: ").append(toIndentedString(phone)).append("\n"); + sb.append(" userStatus: ").append(toIndentedString(userStatus)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} + diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/ApiDocController.java b/samples/server/petstore/java-play-framework-async/app/controllers/ApiDocController.java new file mode 100644 index 0000000000..53536fd241 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/ApiDocController.java @@ -0,0 +1,15 @@ +package controllers; + +import javax.inject.*; +import play.mvc.*; + +public class ApiDocController extends Controller { + + @Inject + private ApiDocController() { + } + + public Result api() { + return redirect("/assets/lib/swagger-ui/index.html?/url=/assets/swagger.json"); + } +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/PetApiController.java b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiController.java new file mode 100644 index 0000000000..d5ab194628 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiController.java @@ -0,0 +1,207 @@ +package controllers; + +import java.io.InputStream; +import apimodels.ModelApiResponse; +import apimodels.Pet; + +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Http; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.inject.Inject; +import java.io.File; +import swagger.SwaggerUtils; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; +import play.Configuration; + +import swagger.SwaggerUtils.ApiAction; + + +public class PetApiController extends Controller { + + private final PetApiControllerImpInterface imp; + private final ObjectMapper mapper; + private final Configuration configuration; + + @Inject + private PetApiController(Configuration configuration, PetApiControllerImpInterface imp) { + this.imp = imp; + mapper = new ObjectMapper(); + this.configuration = configuration; + } + + + @ApiAction + public CompletionStage addPet() throws Exception { + JsonNode nodebody = request().body().asJson(); + Pet body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), Pet.class); + if (configuration.getBoolean("useInputBeanValidation")) { + SwaggerUtils.validate(body); + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.addPet(body) + return ok(); + }); + } + + @ApiAction + public CompletionStage deletePet(Long petId) throws Exception { + String valueapiKey = request().getHeader("api_key"); + String apiKey; + if (valueapiKey != null) { + apiKey = valueapiKey; + } else { + apiKey = null; + } + return CompletableFuture.supplyAsync(() -> { + imp.deletePet(petId, apiKey) + return ok(); + }); + } + + @ApiAction + public CompletionStage findPetsByStatus() throws Exception { + String[] statusArray = request().queryString().get("status"); + if (statusArray == null) { + throw new IllegalArgumentException("'status' parameter is required"); + } + List statusList = SwaggerUtils.parametersToList("csv", statusArray); + List status = new ArrayList(); + for (String curParam : statusList) { + if (!curParam.isEmpty()) { + //noinspection UseBulkOperation + status.add(curParam); + } + } + CompletionStage> stage = imp.findPetsByStatus(status).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + for (Pet curItem : obj) { + SwaggerUtils.validate(curItem); + } + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage findPetsByTags() throws Exception { + String[] tagsArray = request().queryString().get("tags"); + if (tagsArray == null) { + throw new IllegalArgumentException("'tags' parameter is required"); + } + List tagsList = SwaggerUtils.parametersToList("csv", tagsArray); + List tags = new ArrayList(); + for (String curParam : tagsList) { + if (!curParam.isEmpty()) { + //noinspection UseBulkOperation + tags.add(curParam); + } + } + CompletionStage> stage = imp.findPetsByTags(tags).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + for (Pet curItem : obj) { + SwaggerUtils.validate(curItem); + } + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage getPetById(Long petId) throws Exception { + CompletionStage stage = imp.getPetById(petId).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + SwaggerUtils.validate(obj); + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage updatePet() throws Exception { + JsonNode nodebody = request().body().asJson(); + Pet body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), Pet.class); + if (configuration.getBoolean("useInputBeanValidation")) { + SwaggerUtils.validate(body); + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.updatePet(body) + return ok(); + }); + } + + @ApiAction + public CompletionStage updatePetWithForm(Long petId) throws Exception { + String valuename = (request().body().asMultipartFormData().asFormUrlEncoded().get("name"))[0]; + String name; + if (valuename != null) { + name = valuename; + } else { + name = null; + } + String valuestatus = (request().body().asMultipartFormData().asFormUrlEncoded().get("status"))[0]; + String status; + if (valuestatus != null) { + status = valuestatus; + } else { + status = null; + } + return CompletableFuture.supplyAsync(() -> { + imp.updatePetWithForm(petId, name, status) + return ok(); + }); + } + + @ApiAction + public CompletionStage uploadFile(Long petId) throws Exception { + String valueadditionalMetadata = (request().body().asMultipartFormData().asFormUrlEncoded().get("additionalMetadata"))[0]; + String additionalMetadata; + if (valueadditionalMetadata != null) { + additionalMetadata = valueadditionalMetadata; + } else { + additionalMetadata = null; + } + Http.MultipartFormData.FilePart file = request().body().asMultipartFormData().getFile("file"); + CompletionStage stage = imp.uploadFile(petId, additionalMetadata, file).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + SwaggerUtils.validate(obj); + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImp.java b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImp.java new file mode 100644 index 0000000000..550cb37143 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImp.java @@ -0,0 +1,67 @@ +package controllers; + +import java.io.InputStream; +import apimodels.ModelApiResponse; +import apimodels.Pet; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.io.FileInputStream; +import javax.validation.constraints.*; + +public class PetApiControllerImp implements PetApiControllerImpInterface { + @Override + public void addPet(Pet body) throws Exception { + //Do your magic!!! + } + + @Override + public void deletePet(Long petId, String apiKey) throws Exception { + //Do your magic!!! + } + + @Override + public CompletionStage> findPetsByStatus( @NotNull List status) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new ArrayList(); + }); + } + + @Override + public CompletionStage> findPetsByTags( @NotNull List tags) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new ArrayList(); + }); + } + + @Override + public CompletionStage getPetById(Long petId) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new Pet(); + }); + } + + @Override + public void updatePet(Pet body) throws Exception { + //Do your magic!!! + } + + @Override + public void updatePetWithForm(Long petId, String name, String status) throws Exception { + //Do your magic!!! + } + + @Override + public CompletionStage uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new ModelApiResponse(); + }); + } + +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImpInterface.java b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImpInterface.java new file mode 100644 index 0000000000..7e4026b84c --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/PetApiControllerImpInterface.java @@ -0,0 +1,34 @@ +package controllers; + +import java.io.InputStream; +import apimodels.ModelApiResponse; +import apimodels.Pet; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; + +@SuppressWarnings("RedundantThrows") +public interface PetApiControllerImpInterface { + void addPet(Pet body) throws Exception; + + void deletePet(Long petId, String apiKey) throws Exception; + + CompletionStage> findPetsByStatus( @NotNull List status) throws Exception; + + CompletionStage> findPetsByTags( @NotNull List tags) throws Exception; + + CompletionStage getPetById(Long petId) throws Exception; + + void updatePet(Pet body) throws Exception; + + void updatePetWithForm(Long petId, String name, String status) throws Exception; + + CompletionStage uploadFile(Long petId, String additionalMetadata, Http.MultipartFormData.FilePart file) throws Exception; + +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiController.java b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiController.java new file mode 100644 index 0000000000..74c34d1fc5 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiController.java @@ -0,0 +1,98 @@ +package controllers; + +import java.util.Map; +import apimodels.Order; + +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Http; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.inject.Inject; +import java.io.File; +import swagger.SwaggerUtils; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; +import play.Configuration; + +import swagger.SwaggerUtils.ApiAction; + + +public class StoreApiController extends Controller { + + private final StoreApiControllerImpInterface imp; + private final ObjectMapper mapper; + private final Configuration configuration; + + @Inject + private StoreApiController(Configuration configuration, StoreApiControllerImpInterface imp) { + this.imp = imp; + mapper = new ObjectMapper(); + this.configuration = configuration; + } + + + @ApiAction + public CompletionStage deleteOrder(String orderId) throws Exception { + return CompletableFuture.supplyAsync(() -> { + imp.deleteOrder(orderId) + return ok(); + }); + } + + @ApiAction + public CompletionStage getInventory() throws Exception { + CompletionStage> stage = imp.getInventory().thenApply(obj -> { + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage getOrderById( @Min(1) @Max(5)Long orderId) throws Exception { + CompletionStage stage = imp.getOrderById(orderId).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + SwaggerUtils.validate(obj); + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage placeOrder() throws Exception { + JsonNode nodebody = request().body().asJson(); + Order body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), Order.class); + if (configuration.getBoolean("useInputBeanValidation")) { + SwaggerUtils.validate(body); + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + CompletionStage stage = imp.placeOrder(body).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + SwaggerUtils.validate(obj); + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImp.java b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImp.java new file mode 100644 index 0000000000..2d7cea1cf0 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImp.java @@ -0,0 +1,43 @@ +package controllers; + +import java.util.Map; +import apimodels.Order; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.io.FileInputStream; +import javax.validation.constraints.*; + +public class StoreApiControllerImp implements StoreApiControllerImpInterface { + @Override + public void deleteOrder(String orderId) throws Exception { + //Do your magic!!! + } + + @Override + public CompletionStage> getInventory() throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new HashMap(); + }); + } + + @Override + public CompletionStage getOrderById( @Min(1) @Max(5)Long orderId) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new Order(); + }); + } + + @Override + public CompletionStage placeOrder(Order body) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new Order(); + }); + } + +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImpInterface.java b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImpInterface.java new file mode 100644 index 0000000000..60022bb1d2 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/StoreApiControllerImpInterface.java @@ -0,0 +1,25 @@ +package controllers; + +import java.util.Map; +import apimodels.Order; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; + +@SuppressWarnings("RedundantThrows") +public interface StoreApiControllerImpInterface { + void deleteOrder(String orderId) throws Exception; + + CompletionStage> getInventory() throws Exception; + + CompletionStage getOrderById( @Min(1) @Max(5)Long orderId) throws Exception; + + CompletionStage placeOrder(Order body) throws Exception; + +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/UserApiController.java b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiController.java new file mode 100644 index 0000000000..fce7743435 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiController.java @@ -0,0 +1,172 @@ +package controllers; + +import java.util.List; +import apimodels.User; + +import play.mvc.Controller; +import play.mvc.Result; +import play.mvc.Http; +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.inject.Inject; +import java.io.File; +import swagger.SwaggerUtils; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; +import play.Configuration; + +import swagger.SwaggerUtils.ApiAction; + + +public class UserApiController extends Controller { + + private final UserApiControllerImpInterface imp; + private final ObjectMapper mapper; + private final Configuration configuration; + + @Inject + private UserApiController(Configuration configuration, UserApiControllerImpInterface imp) { + this.imp = imp; + mapper = new ObjectMapper(); + this.configuration = configuration; + } + + + @ApiAction + public CompletionStage createUser() throws Exception { + JsonNode nodebody = request().body().asJson(); + User body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), User.class); + if (configuration.getBoolean("useInputBeanValidation")) { + SwaggerUtils.validate(body); + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.createUser(body) + return ok(); + }); + } + + @ApiAction + public CompletionStage createUsersWithArrayInput() throws Exception { + JsonNode nodebody = request().body().asJson(); + List body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), new TypeReference>(){}); + if (configuration.getBoolean("useInputBeanValidation")) { + for (User curItem : body) { + SwaggerUtils.validate(curItem); + } + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.createUsersWithArrayInput(body) + return ok(); + }); + } + + @ApiAction + public CompletionStage createUsersWithListInput() throws Exception { + JsonNode nodebody = request().body().asJson(); + List body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), new TypeReference>(){}); + if (configuration.getBoolean("useInputBeanValidation")) { + for (User curItem : body) { + SwaggerUtils.validate(curItem); + } + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.createUsersWithListInput(body) + return ok(); + }); + } + + @ApiAction + public CompletionStage deleteUser(String username) throws Exception { + return CompletableFuture.supplyAsync(() -> { + imp.deleteUser(username) + return ok(); + }); + } + + @ApiAction + public CompletionStage getUserByName(String username) throws Exception { + CompletionStage stage = imp.getUserByName(username).thenApply(obj -> { + if (configuration.getBoolean("useOutputBeanValidation")) { + SwaggerUtils.validate(obj); + } + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage loginUser() throws Exception { + String valueusername = request().getQueryString("username"); + String username; + if (valueusername != null) { + username = valueusername; + } else { + throw new IllegalArgumentException("'username' parameter is required"); + } + String valuepassword = request().getQueryString("password"); + String password; + if (valuepassword != null) { + password = valuepassword; + } else { + throw new IllegalArgumentException("'password' parameter is required"); + } + CompletionStage stage = imp.loginUser(username, password).thenApply(obj -> { + return obj; + }); + stage.thenApply(obj -> { + JsonNode result = mapper.valueToTree(obj); + return ok(result); + }); + } + + @ApiAction + public CompletionStage logoutUser() throws Exception { + return CompletableFuture.supplyAsync(() -> { + imp.logoutUser() + return ok(); + }); + } + + @ApiAction + public CompletionStage updateUser(String username) throws Exception { + JsonNode nodebody = request().body().asJson(); + User body; + if (nodebody != null) { + body = mapper.readValue(nodebody.toString(), User.class); + if (configuration.getBoolean("useInputBeanValidation")) { + SwaggerUtils.validate(body); + } + } else { + throw new IllegalArgumentException("'body' parameter is required"); + } + return CompletableFuture.supplyAsync(() -> { + imp.updateUser(username, body) + return ok(); + }); + } +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImp.java b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImp.java new file mode 100644 index 0000000000..fa6028517c --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImp.java @@ -0,0 +1,60 @@ +package controllers; + +import java.util.List; +import apimodels.User; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.io.FileInputStream; +import javax.validation.constraints.*; + +public class UserApiControllerImp implements UserApiControllerImpInterface { + @Override + public void createUser(User body) throws Exception { + //Do your magic!!! + } + + @Override + public void createUsersWithArrayInput(List body) throws Exception { + //Do your magic!!! + } + + @Override + public void createUsersWithListInput(List body) throws Exception { + //Do your magic!!! + } + + @Override + public void deleteUser(String username) throws Exception { + //Do your magic!!! + } + + @Override + public CompletionStage getUserByName(String username) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new User(); + }); + } + + @Override + public CompletionStage loginUser( @NotNull String username, @NotNull String password) throws Exception { + //Do your magic!!! + return CompletableFuture.supplyAsync(() -> { + return new String(); + }); + } + + @Override + public void logoutUser() throws Exception { + //Do your magic!!! + } + + @Override + public void updateUser(String username, User body) throws Exception { + //Do your magic!!! + } + +} diff --git a/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImpInterface.java b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImpInterface.java new file mode 100644 index 0000000000..09b1d5042f --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/controllers/UserApiControllerImpInterface.java @@ -0,0 +1,33 @@ +package controllers; + +import java.util.List; +import apimodels.User; + +import play.mvc.Http; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CompletableFuture; + +import javax.validation.constraints.*; + +@SuppressWarnings("RedundantThrows") +public interface UserApiControllerImpInterface { + void createUser(User body) throws Exception; + + void createUsersWithArrayInput(List body) throws Exception; + + void createUsersWithListInput(List body) throws Exception; + + void deleteUser(String username) throws Exception; + + CompletionStage getUserByName(String username) throws Exception; + + CompletionStage loginUser( @NotNull String username, @NotNull String password) throws Exception; + + void logoutUser() throws Exception; + + void updateUser(String username, User body) throws Exception; + +} diff --git a/samples/server/petstore/java-play-framework-async/app/swagger/ApiCall.java b/samples/server/petstore/java-play-framework-async/app/swagger/ApiCall.java new file mode 100644 index 0000000000..2ca308045b --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/swagger/ApiCall.java @@ -0,0 +1,27 @@ +package swagger; + +import com.google.inject.Inject; +import play.mvc.Action; +import play.mvc.Http; +import play.mvc.Result; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +public class ApiCall extends Action { + + @Inject + private ApiCall() {} + + public CompletionStage call(Http.Context ctx) { + try { + //TODO: Do stuff you want to handle with each API call (metrics, logging, etc..) + return delegate.call(ctx); + } catch (Throwable t) { + //TODO: log the error in your metric + + //We rethrow this error so it will be caught in the ErrorHandler + throw t; + } + } +} \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/app/swagger/ErrorHandler.java b/samples/server/petstore/java-play-framework-async/app/swagger/ErrorHandler.java new file mode 100644 index 0000000000..2c813411a5 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/swagger/ErrorHandler.java @@ -0,0 +1,49 @@ +package swagger; + + +import play.*; +import play.api.OptionalSourceMapper; +import play.api.UsefulException; +import play.api.routing.Router; +import play.http.DefaultHttpErrorHandler; +import play.mvc.Http.*; +import play.mvc.*; + +import javax.inject.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import static play.mvc.Results.*; + +@Singleton +public class ErrorHandler extends DefaultHttpErrorHandler { + + @Inject + public ErrorHandler(Configuration configuration, Environment environment, OptionalSourceMapper sourceMapper, Provider routes) { + super(configuration, environment, sourceMapper, routes); + } + + @Override + protected CompletionStage onDevServerError(RequestHeader request, UsefulException exception) { + return CompletableFuture.completedFuture( + handleExceptions(exception) + ); + } + + @Override + protected CompletionStage onProdServerError(RequestHeader request, UsefulException exception) { + return CompletableFuture.completedFuture( + handleExceptions(exception) + ); + } + + @Override + protected void logServerError(RequestHeader request, UsefulException usefulException) { + //Since the error is already handled, we don't want to print anything on the console + //But if you want to have the error printed in the console, just delete this override + } + + private Result handleExceptions(Throwable t) { + //TODO: Handle exception that need special response (return a special apimodel, notFound(), etc..) + return ok(); + } +} diff --git a/samples/server/petstore/java-play-framework-async/app/swagger/SwaggerUtils.java b/samples/server/petstore/java-play-framework-async/app/swagger/SwaggerUtils.java new file mode 100644 index 0000000000..d4900e0216 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/app/swagger/SwaggerUtils.java @@ -0,0 +1,103 @@ +package swagger; + +import play.mvc.With; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.text.SimpleDateFormat; +import java.util.*; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +public class SwaggerUtils { + + @With(ApiCall.class) + @Target({ ElementType.TYPE, ElementType.METHOD }) + @Retention(RetentionPolicy.RUNTIME) + public @interface ApiAction { + } + + public static void validate(T obj) { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + Validator validator = factory.getValidator(); + Set> constraintViolations = validator.validate(obj); + if (constraintViolations.size() > 0) { + StringBuilder errors = new StringBuilder(); + for (ConstraintViolation contraintes : constraintViolations) { + errors.append(String.format("%s.%s %s\n", + contraintes.getRootBeanClass().getSimpleName(), + contraintes.getPropertyPath(), + contraintes.getMessage())); + } + throw new RuntimeException("Bean validation : " + errors); + } + } + + public static List parametersToList(String collectionFormat, String[] values){ + List params = new ArrayList<>(); + + if (values == null) { + return params; + } + + if (values.length >= 1 && collectionFormat.equals("multi")) { + params.addAll(Arrays.asList(values)); + } else { + collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv + + String delimiter = ","; + + switch(collectionFormat) { + case "csv": { + delimiter = ","; + break; + } + case "ssv": { + delimiter = " "; + break; + } + case "tsv": { + delimiter = "\t"; + break; + } + case "pipes": { + delimiter = "|"; + break; + } + } + + params = Arrays.asList(values[0].split(delimiter)); + } + + return params; + } + + public static String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date) { + return formatDatetime((Date) param); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for (Object o : (Collection)param) { + if (b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + + return b.toString(); + } else { + return String.valueOf(param); + } + } + + public static String formatDatetime(Date date) { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").format(date); + } +} \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/build.sbt b/samples/server/petstore/java-play-framework-async/build.sbt new file mode 100644 index 0000000000..e425cf8cfe --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/build.sbt @@ -0,0 +1,11 @@ +name := """swagger-java-playframework""" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayJava) + +scalaVersion := "2.12.2" + +libraryDependencies += "org.webjars" % "swagger-ui" % "3.1.5" +libraryDependencies += "javax.validation" % "validation-api" % "1.1.0.Final" +libraryDependencies += guice diff --git a/samples/server/petstore/java-play-framework-async/conf/application.conf b/samples/server/petstore/java-play-framework-async/conf/application.conf new file mode 100644 index 0000000000..bcd07672dc --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/conf/application.conf @@ -0,0 +1,374 @@ +# This is the main configuration file for the application. +# https://www.playframework.com/documentation/latest/ConfigFile +# ~~~~~ +# Play uses HOCON as its configuration file format. HOCON has a number +# of advantages over other config formats, but there are two things that +# can be used when modifying settings. +# +# You can include other configuration files in this main application.conf file: +#include "extra-config.conf" +# +# You can declare variables and substitute for them: +#mykey = ${some.value} +# +# And if an environment variable exists when there is no other subsitution, then +# HOCON will fall back to substituting environment variable: +#mykey = ${JAVA_HOME} + +play.filters.headers.contentSecurityPolicy=null + +# When using bean validation with the swagger api, the validator will check that every constraint is respected +# This is very useful when testing but could add a lot of overhead if you return a lot of data. Benchmark have +# shown that the time it takes to validate is exponential. +# If this is a concern in your application, or if you don't want to validate the output coming from your API for +# respecting its contract, set the "output" property below to "false". Since there is not a lot of data as input for +# an endpoint, I highly suggest you let the "input" property set to true. +useInputBeanValidation=true +useOutputBeanValidation=true + +play.http.errorHandler="swagger.ErrorHandler" + +## Akka +# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration +# https://www.playframework.com/documentation/latest/JavaAkka#Configuration +# ~~~~~ +# Play uses Akka internally and exposes Akka Streams and actors in Websockets and +# other streaming HTTP responses. +akka { +# "akka.log-config-on-start" is extraordinarily useful because it log the complete +# configuration at INFO level, including defaults and overrides, so it s worth +# putting at the very top. +# +# Put the following in your conf/logback.xml file: +# +# +# +# And then uncomment this line to debug the configuration. +# +#log-config-on-start = true +} + +## Secret key +# http://www.playframework.com/documentation/latest/ApplicationSecret +# ~~~~~ +# The secret key is used to sign Play's session cookie. +# This must be changed for production, but we don't recommend you change it in this file. +play.http.secret.key = "changeme" + +## Modules +# https://www.playframework.com/documentation/latest/Modules +# ~~~~~ +# Control which modules are loaded when Play starts. Note that modules are +# the replacement for "GlobalSettings", which are deprecated in 2.5.x. +# Please see https://www.playframework.com/documentation/latest/GlobalSettings +# for more information. +# +# You can also extend Play functionality by using one of the publically available +# Play modules: https://playframework.com/documentation/latest/ModuleDirectory +play.modules { +# By default, Play will load any class called Module that is defined +# in the root package (the "app" directory), or you can define them +# explicitly below. +# If there are any built-in modules that you want to disable, you can list them here. +} + +play.assets { +path = "/public" +urlPrefix = "/assets" +} + +## IDE +# https://www.playframework.com/documentation/latest/IDE +# ~~~~~ +# Depending on your IDE, you can add a hyperlink for errors that will jump you +# directly to the code location in the IDE in dev mode. The following line makes +# use of the IntelliJ IDEA REST interface: +#play.editor="http://localhost:63342/api/file/?file=%s&line=%s" + +## Internationalisation +# https://www.playframework.com/documentation/latest/JavaI18N +# https://www.playframework.com/documentation/latest/ScalaI18N +# ~~~~~ +# Play comes with its own i18n settings, which allow the user's preferred language +# to map through to internal messages, or allow the language to be stored in a cookie. +play.i18n { +# The application languages +langs = [ "en" ] + +# Whether the language cookie should be secure or not +#langCookieSecure = true + +# Whether the HTTP only attribute of the cookie should be set to true +#langCookieHttpOnly = true +} + +## Play HTTP settings +# ~~~~~ +play.http { +## Router +# https://www.playframework.com/documentation/latest/JavaRouting +# https://www.playframework.com/documentation/latest/ScalaRouting +# ~~~~~ +# Define the Router object to use for this application. +# This router will be looked up first when the application is starting up, +# so make sure this is the entry point. +# Furthermore, it's assumed your route file is named properly. +# So for an application router like `my.application.Router`, +# you may need to define a router file `conf/my.application.routes`. +# Default to Routes in the root package (aka "apps" folder) (and conf/routes) +#router = my.application.Router + +## Action Creator +# https://www.playframework.com/documentation/latest/JavaActionCreator +# ~~~~~ +#actionCreator = null + +## ErrorHandler +# https://www.playframework.com/documentation/latest/JavaRouting +# https://www.playframework.com/documentation/latest/ScalaRouting +# ~~~~~ +# If null, will attempt to load a class called ErrorHandler in the root package, +#errorHandler = null + +## Filters +# https://www.playframework.com/documentation/latest/ScalaHttpFilters +# https://www.playframework.com/documentation/latest/JavaHttpFilters +# ~~~~~ +# Filters run code on every request. They can be used to perform +# common logic for all your actions, e.g. adding common headers. +# Defaults to "Filters" in the root package (aka "apps" folder) +# Alternatively you can explicitly register a class here. +#filters = my.application.Filters + +## Session & Flash +# https://www.playframework.com/documentation/latest/JavaSessionFlash +# https://www.playframework.com/documentation/latest/ScalaSessionFlash +# ~~~~~ +session { +# Sets the cookie to be sent only over HTTPS. +#secure = true + +# Sets the cookie to be accessed only by the server. +#httpOnly = true + +# Sets the max-age field of the cookie to 5 minutes. +# NOTE: this only sets when the browser will discard the cookie. Play will consider any +# cookie value with a valid signature to be a valid session forever. To implement a server side session timeout, +# you need to put a timestamp in the session and check it at regular intervals to possibly expire it. +#maxAge = 300 + +# Sets the domain on the session cookie. +#domain = "example.com" +} + +flash { +# Sets the cookie to be sent only over HTTPS. +#secure = true + +# Sets the cookie to be accessed only by the server. +#httpOnly = true +} +} + +## Netty Provider +# https://www.playframework.com/documentation/latest/SettingsNetty +# ~~~~~ +play.server.netty { +# Whether the Netty wire should be logged +#log.wire = true + +# If you run Play on Linux, you can use Netty's native socket transport +# for higher performance with less garbage. +#transport = "native" +} + +## WS (HTTP Client) +# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS +# ~~~~~ +# The HTTP client primarily used for REST APIs. The default client can be +# configured directly, but you can also create different client instances +# with customized settings. You must enable this by adding to build.sbt: +# +# libraryDependencies += ws // or javaWs if using java +# +play.ws { +# Sets HTTP requests not to follow 302 requests +#followRedirects = false + +# Sets the maximum number of open HTTP connections for the client. +#ahc.maxConnectionsTotal = 50 + +## WS SSL +# https://www.playframework.com/documentation/latest/WsSSL +# ~~~~~ +ssl { +# Configuring HTTPS with Play WS does not require programming. You can +# set up both trustManager and keyManager for mutual authentication, and +# turn on JSSE debugging in development with a reload. +#debug.handshake = true +#trustManager = { +# stores = [ +# { type = "JKS", path = "exampletrust.jks" } +# ] +#} +} +} + +## Cache +# https://www.playframework.com/documentation/latest/JavaCache +# https://www.playframework.com/documentation/latest/ScalaCache +# ~~~~~ +# Play comes with an integrated cache API that can reduce the operational +# overhead of repeated requests. You must enable this by adding to build.sbt: +# +# libraryDependencies += cache +# +play.cache { +# If you want to bind several caches, you can bind the individually +#bindCaches = ["db-cache", "user-cache", "session-cache"] +} + +## Filters +# https://www.playframework.com/documentation/latest/Filters +# ~~~~~ +# There are a number of built-in filters that can be enabled and configured +# to give Play greater security. You must enable this by adding to build.sbt: +# +# libraryDependencies += filters +# +play.filters { +## CORS filter configuration +# https://www.playframework.com/documentation/latest/CorsFilter +# ~~~~~ +# CORS is a protocol that allows web applications to make requests from the browser +# across different domains. +# NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has +# dependencies on CORS settings. +cors { +# Filter paths by a whitelist of path prefixes +#pathPrefixes = ["/some/path", ...] + +# The allowed origins. If null, all origins are allowed. +#allowedOrigins = ["http://www.example.com"] + +# The allowed HTTP methods. If null, all methods are allowed +#allowedHttpMethods = ["GET", "POST"] +} + +## CSRF Filter +# https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter +# https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter +# ~~~~~ +# Play supports multiple methods for verifying that a request is not a CSRF request. +# The primary mechanism is a CSRF token. This token gets placed either in the query string +# or body of every form submitted, and also gets placed in the users session. +# Play then verifies that both tokens are present and match. +csrf { +# Sets the cookie to be sent only over HTTPS +#cookie.secure = true + +# Defaults to CSRFErrorHandler in the root package. +#errorHandler = MyCSRFErrorHandler +} + +## Security headers filter configuration +# https://www.playframework.com/documentation/latest/SecurityHeaders +# ~~~~~ +# Defines security headers that prevent XSS attacks. +# If enabled, then all options are set to the below configuration by default: +play.filters.headers { + +# The X-Frame-Options header. If null, the header is not set. +#frameOptions = "DENY" + +# The X-XSS-Protection header. If null, the header is not set. +#xssProtection = "1; mode=block" + +# The X-Content-Type-Options header. If null, the header is not set. +#contentTypeOptions = "nosniff" + +# The X-Permitted-Cross-Domain-Policies header. If null, the header is not set. +#permittedCrossDomainPolicies = "master-only" + +# The Content-Security-Policy header. If null, the header is not set. +contentSecurityPolicy = "default-src 'self'" + +# The Referrer-Policy header. If null, the header is not set. +#referrerPolicy = "origin-when-cross-origin, strict-origin-when-cross-origin" + +# If true, allow an action to use .withHeaders to replace one or more of the above headers +#allowActionSpecificHeaders = false +} + +## Allowed hosts filter configuration +# https://www.playframework.com/documentation/latest/AllowedHostsFilter +# ~~~~~ +# Play provides a filter that lets you configure which hosts can access your application. +# This is useful to prevent cache poisoning attacks. +hosts { +# Allow requests to example.com, its subdomains, and localhost:9000. +#allowed = [".example.com", "localhost:9000"] +} +} + +## Evolutions +# https://www.playframework.com/documentation/latest/Evolutions +# ~~~~~ +# Evolutions allows database scripts to be automatically run on startup in dev mode +# for database migrations. You must enable this by adding to build.sbt: +# +# libraryDependencies += evolutions +# +play.evolutions { +# You can disable evolutions for a specific datasource if necessary +#db.default.enabled = false +} + +## Database Connection Pool +# https://www.playframework.com/documentation/latest/SettingsJDBC +# ~~~~~ +# Play doesn't require a JDBC database to run, but you can easily enable one. +# +# libraryDependencies += jdbc +# +play.db { +# The combination of these two settings results in "db.default" as the +# default JDBC pool: +#config = "db" +#default = "default" + +# Play uses HikariCP as the default connection pool. You can override +# settings by changing the prototype: +prototype { +# Sets a fixed JDBC connection pool size of 50 +#hikaricp.minimumIdle = 50 +#hikaricp.maximumPoolSize = 50 +} +} + +## JDBC Datasource +# https://www.playframework.com/documentation/latest/JavaDatabase +# https://www.playframework.com/documentation/latest/ScalaDatabase +# ~~~~~ +# Once JDBC datasource is set up, you can work with several different +# database options: +# +# Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick +# JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA +# EBean: https://playframework.com/documentation/latest/JavaEbean +# Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm +# +db { +# You can declare as many datasources as you want. +# By convention, the default datasource is named `default` + +# https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database +#default.driver = org.h2.Driver +#default.url = "jdbc:h2:mem:play" +#default.username = sa +#default.password = "" + +# You can turn on SQL logging for any datasource +# https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements +#default.logSql=true +} diff --git a/samples/server/petstore/java-play-framework-async/conf/logback.xml b/samples/server/petstore/java-play-framework-async/conf/logback.xml new file mode 100644 index 0000000000..01f301ab73 --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/conf/logback.xml @@ -0,0 +1,41 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/server/petstore/java-play-framework-async/conf/routes b/samples/server/petstore/java-play-framework-async/conf/routes new file mode 100644 index 0000000000..775497a59f --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/conf/routes @@ -0,0 +1,36 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# ~~~~ + +GET /api controllers.ApiDocController.api + + +#Functions for Pet API +POST /v2/pet controllers.PetApiController.addPet() +DELETE /v2/pet/:petId controllers.PetApiController.deletePet(petId: Long) +GET /v2/pet/findByStatus controllers.PetApiController.findPetsByStatus() +GET /v2/pet/findByTags controllers.PetApiController.findPetsByTags() +GET /v2/pet/:petId controllers.PetApiController.getPetById(petId: Long) +PUT /v2/pet controllers.PetApiController.updatePet() +POST /v2/pet/:petId controllers.PetApiController.updatePetWithForm(petId: Long) +POST /v2/pet/:petId/uploadImage controllers.PetApiController.uploadFile(petId: Long) + +#Functions for Store API +DELETE /v2/store/order/:orderId controllers.StoreApiController.deleteOrder(orderId: String) +GET /v2/store/inventory controllers.StoreApiController.getInventory() +GET /v2/store/order/:orderId controllers.StoreApiController.getOrderById(orderId: Long) +POST /v2/store/order controllers.StoreApiController.placeOrder() + +#Functions for User API +POST /v2/user controllers.UserApiController.createUser() +POST /v2/user/createWithArray controllers.UserApiController.createUsersWithArrayInput() +POST /v2/user/createWithList controllers.UserApiController.createUsersWithListInput() +DELETE /v2/user/:username controllers.UserApiController.deleteUser(username: String) +GET /v2/user/:username controllers.UserApiController.getUserByName(username: String) +GET /v2/user/login controllers.UserApiController.loginUser() +GET /v2/user/logout controllers.UserApiController.logoutUser() +PUT /v2/user/:username controllers.UserApiController.updateUser(username: String) + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.at(file) +GET /versionedAssets/*file controllers.Assets.versioned(file) \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/project/build.properties b/samples/server/petstore/java-play-framework-async/project/build.properties new file mode 100644 index 0000000000..cf19fd026f --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.15 \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-async/project/plugins.sbt b/samples/server/petstore/java-play-framework-async/project/plugins.sbt new file mode 100644 index 0000000000..66fbf368ae --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/project/plugins.sbt @@ -0,0 +1,2 @@ +// The Play plugin +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.3") diff --git a/samples/server/petstore/java-play-framework-async/public/swagger.json b/samples/server/petstore/java-play-framework-async/public/swagger.json new file mode 100644 index 0000000000..3ab9cda2ce --- /dev/null +++ b/samples/server/petstore/java-play-framework-async/public/swagger.json @@ -0,0 +1,907 @@ +{ + "swagger" : "2.0", + "info" : { + "description" : "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "version" : "1.0.0", + "title" : "Swagger Petstore", + "termsOfService" : "http://swagger.io/terms/", + "contact" : { + "email" : "apiteam@swagger.io" + }, + "license" : { + "name" : "Apache-2.0", + "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "basePath" : "/v2", + "tags" : [ { + "name" : "pet", + "description" : "Everything about your Pets", + "externalDocs" : { + "description" : "Find out more", + "url" : "http://swagger.io" + } + }, { + "name" : "store", + "description" : "Access to Petstore orders" + }, { + "name" : "user", + "description" : "Operations about user", + "externalDocs" : { + "description" : "Find out more about our store", + "url" : "http://swagger.io" + } + } ], + "schemes" : [ "http" ], + "paths" : { + "/pet" : { + "post" : { + "tags" : [ "pet" ], + "summary" : "Add a new pet to the store", + "description" : "", + "operationId" : "addPet", + "consumes" : [ "application/json", "application/xml" ], + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "Pet object that needs to be added to the store", + "required" : true, + "schema" : { + "$ref" : "#/definitions/Pet" + } + } ], + "responses" : { + "405" : { + "description" : "Invalid input" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-contentType" : "application/json", + "x-accepts" : "application/json" + }, + "put" : { + "tags" : [ "pet" ], + "summary" : "Update an existing pet", + "description" : "", + "operationId" : "updatePet", + "consumes" : [ "application/json", "application/xml" ], + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "Pet object that needs to be added to the store", + "required" : true, + "schema" : { + "$ref" : "#/definitions/Pet" + } + } ], + "responses" : { + "400" : { + "description" : "Invalid ID supplied" + }, + "404" : { + "description" : "Pet not found" + }, + "405" : { + "description" : "Validation exception" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-contentType" : "application/json", + "x-accepts" : "application/json" + } + }, + "/pet/findByStatus" : { + "get" : { + "tags" : [ "pet" ], + "summary" : "Finds Pets by status", + "description" : "Multiple status values can be provided with comma separated strings", + "operationId" : "findPetsByStatus", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "status", + "in" : "query", + "description" : "Status values that need to be considered for filter", + "required" : true, + "type" : "array", + "items" : { + "type" : "string", + "enum" : [ "available", "pending", "sold" ], + "default" : "available" + }, + "collectionFormat" : "csv" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Pet" + } + } + }, + "400" : { + "description" : "Invalid status value" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-accepts" : "application/json" + } + }, + "/pet/findByTags" : { + "get" : { + "tags" : [ "pet" ], + "summary" : "Finds Pets by tags", + "description" : "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "operationId" : "findPetsByTags", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "tags", + "in" : "query", + "description" : "Tags to filter by", + "required" : true, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "csv" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Pet" + } + } + }, + "400" : { + "description" : "Invalid tag value" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "deprecated" : true, + "x-accepts" : "application/json" + } + }, + "/pet/{petId}" : { + "get" : { + "tags" : [ "pet" ], + "summary" : "Find pet by ID", + "description" : "Returns a single pet", + "operationId" : "getPetById", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "petId", + "in" : "path", + "description" : "ID of pet to return", + "required" : true, + "type" : "integer", + "format" : "int64" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/Pet" + } + }, + "400" : { + "description" : "Invalid ID supplied" + }, + "404" : { + "description" : "Pet not found" + } + }, + "security" : [ { + "api_key" : [ ] + } ], + "x-accepts" : "application/json" + }, + "post" : { + "tags" : [ "pet" ], + "summary" : "Updates a pet in the store with form data", + "description" : "", + "operationId" : "updatePetWithForm", + "consumes" : [ "application/x-www-form-urlencoded" ], + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "petId", + "in" : "path", + "description" : "ID of pet that needs to be updated", + "required" : true, + "type" : "integer", + "format" : "int64" + }, { + "name" : "name", + "in" : "formData", + "description" : "Updated name of the pet", + "required" : false, + "type" : "string" + }, { + "name" : "status", + "in" : "formData", + "description" : "Updated status of the pet", + "required" : false, + "type" : "string" + } ], + "responses" : { + "405" : { + "description" : "Invalid input" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-contentType" : "application/x-www-form-urlencoded", + "x-accepts" : "application/json" + }, + "delete" : { + "tags" : [ "pet" ], + "summary" : "Deletes a pet", + "description" : "", + "operationId" : "deletePet", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "api_key", + "in" : "header", + "required" : false, + "type" : "string" + }, { + "name" : "petId", + "in" : "path", + "description" : "Pet id to delete", + "required" : true, + "type" : "integer", + "format" : "int64" + } ], + "responses" : { + "400" : { + "description" : "Invalid pet value" + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-accepts" : "application/json" + } + }, + "/pet/{petId}/uploadImage" : { + "post" : { + "tags" : [ "pet" ], + "summary" : "uploads an image", + "description" : "", + "operationId" : "uploadFile", + "consumes" : [ "multipart/form-data" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "petId", + "in" : "path", + "description" : "ID of pet to update", + "required" : true, + "type" : "integer", + "format" : "int64" + }, { + "name" : "additionalMetadata", + "in" : "formData", + "description" : "Additional data to pass to server", + "required" : false, + "type" : "string" + }, { + "name" : "file", + "in" : "formData", + "description" : "file to upload", + "required" : false, + "type" : "file" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/ApiResponse" + } + } + }, + "security" : [ { + "petstore_auth" : [ "write:pets", "read:pets" ] + } ], + "x-contentType" : "multipart/form-data", + "x-accepts" : "application/json" + } + }, + "/store/inventory" : { + "get" : { + "tags" : [ "store" ], + "summary" : "Returns pet inventories by status", + "description" : "Returns a map of status codes to quantities", + "operationId" : "getInventory", + "produces" : [ "application/json" ], + "parameters" : [ ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "type" : "object", + "additionalProperties" : { + "type" : "integer", + "format" : "int32" + } + } + } + }, + "security" : [ { + "api_key" : [ ] + } ], + "x-accepts" : "application/json" + } + }, + "/store/order" : { + "post" : { + "tags" : [ "store" ], + "summary" : "Place an order for a pet", + "description" : "", + "operationId" : "placeOrder", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "order placed for purchasing the pet", + "required" : true, + "schema" : { + "$ref" : "#/definitions/Order" + } + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/Order" + } + }, + "400" : { + "description" : "Invalid Order" + } + }, + "x-contentType" : "application/json", + "x-accepts" : "application/json" + } + }, + "/store/order/{orderId}" : { + "get" : { + "tags" : [ "store" ], + "summary" : "Find purchase order by ID", + "description" : "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", + "operationId" : "getOrderById", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "orderId", + "in" : "path", + "description" : "ID of pet that needs to be fetched", + "required" : true, + "type" : "integer", + "maximum" : 5, + "minimum" : 1, + "format" : "int64" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/Order" + } + }, + "400" : { + "description" : "Invalid ID supplied" + }, + "404" : { + "description" : "Order not found" + } + }, + "x-accepts" : "application/json" + }, + "delete" : { + "tags" : [ "store" ], + "summary" : "Delete purchase order by ID", + "description" : "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", + "operationId" : "deleteOrder", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "orderId", + "in" : "path", + "description" : "ID of the order that needs to be deleted", + "required" : true, + "type" : "string" + } ], + "responses" : { + "400" : { + "description" : "Invalid ID supplied" + }, + "404" : { + "description" : "Order not found" + } + }, + "x-accepts" : "application/json" + } + }, + "/user" : { + "post" : { + "tags" : [ "user" ], + "summary" : "Create user", + "description" : "This can only be done by the logged in user.", + "operationId" : "createUser", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "Created user object", + "required" : true, + "schema" : { + "$ref" : "#/definitions/User" + } + } ], + "responses" : { + "default" : { + "description" : "successful operation" + } + }, + "x-contentType" : "application/json", + "x-accepts" : "application/json" + } + }, + "/user/createWithArray" : { + "post" : { + "tags" : [ "user" ], + "summary" : "Creates list of users with given input array", + "description" : "", + "operationId" : "createUsersWithArrayInput", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "List of user object", + "required" : true, + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/User" + } + } + } ], + "responses" : { + "default" : { + "description" : "successful operation" + } + }, + "x-contentType" : "application/json", + "x-accepts" : "application/json" + } + }, + "/user/createWithList" : { + "post" : { + "tags" : [ "user" ], + "summary" : "Creates list of users with given input array", + "description" : "", + "operationId" : "createUsersWithListInput", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "description" : "List of user object", + "required" : true, + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/User" + } + } + } ], + "responses" : { + "default" : { + "description" : "successful operation" + } + }, + "x-contentType" : "application/json", + "x-accepts" : "application/json" + } + }, + "/user/login" : { + "get" : { + "tags" : [ "user" ], + "summary" : "Logs user into the system", + "description" : "", + "operationId" : "loginUser", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "username", + "in" : "query", + "description" : "The user name for login", + "required" : true, + "type" : "string" + }, { + "name" : "password", + "in" : "query", + "description" : "The password for login in clear text", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "type" : "string" + }, + "headers" : { + "X-Rate-Limit" : { + "type" : "integer", + "format" : "int32", + "description" : "calls per hour allowed by the user" + }, + "X-Expires-After" : { + "type" : "string", + "format" : "date-time", + "description" : "date in UTC when toekn expires" + } + } + }, + "400" : { + "description" : "Invalid username/password supplied" + } + }, + "x-accepts" : "application/json" + } + }, + "/user/logout" : { + "get" : { + "tags" : [ "user" ], + "summary" : "Logs out current logged in user session", + "description" : "", + "operationId" : "logoutUser", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ ], + "responses" : { + "default" : { + "description" : "successful operation" + } + }, + "x-accepts" : "application/json" + } + }, + "/user/{username}" : { + "get" : { + "tags" : [ "user" ], + "summary" : "Get user by user name", + "description" : "", + "operationId" : "getUserByName", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "username", + "in" : "path", + "description" : "The name that needs to be fetched. Use user1 for testing.", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "successful operation", + "schema" : { + "$ref" : "#/definitions/User" + } + }, + "400" : { + "description" : "Invalid username supplied" + }, + "404" : { + "description" : "User not found" + } + }, + "x-accepts" : "application/json" + }, + "put" : { + "tags" : [ "user" ], + "summary" : "Updated user", + "description" : "This can only be done by the logged in user.", + "operationId" : "updateUser", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "username", + "in" : "path", + "description" : "name that need to be deleted", + "required" : true, + "type" : "string" + }, { + "in" : "body", + "name" : "body", + "description" : "Updated user object", + "required" : true, + "schema" : { + "$ref" : "#/definitions/User" + } + } ], + "responses" : { + "400" : { + "description" : "Invalid user supplied" + }, + "404" : { + "description" : "User not found" + } + }, + "x-contentType" : "application/json", + "x-accepts" : "application/json" + }, + "delete" : { + "tags" : [ "user" ], + "summary" : "Delete user", + "description" : "This can only be done by the logged in user.", + "operationId" : "deleteUser", + "produces" : [ "application/xml", "application/json" ], + "parameters" : [ { + "name" : "username", + "in" : "path", + "description" : "The name that needs to be deleted", + "required" : true, + "type" : "string" + } ], + "responses" : { + "400" : { + "description" : "Invalid username supplied" + }, + "404" : { + "description" : "User not found" + } + }, + "x-accepts" : "application/json" + } + } + }, + "securityDefinitions" : { + "petstore_auth" : { + "type" : "oauth2", + "authorizationUrl" : "http://petstore.swagger.io/api/oauth/dialog", + "flow" : "implicit", + "scopes" : { + "write:pets" : "modify pets in your account", + "read:pets" : "read your pets" + } + }, + "api_key" : { + "type" : "apiKey", + "name" : "api_key", + "in" : "header" + } + }, + "definitions" : { + "Order" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "petId" : { + "type" : "integer", + "format" : "int64" + }, + "quantity" : { + "type" : "integer", + "format" : "int32" + }, + "shipDate" : { + "type" : "string", + "format" : "date-time" + }, + "status" : { + "type" : "string", + "description" : "Order Status", + "enum" : [ "placed", "approved", "delivered" ] + }, + "complete" : { + "type" : "boolean", + "default" : false + } + }, + "title" : "Pet Order", + "description" : "An order for a pets from the pet store", + "example" : { + "petId" : 6, + "quantity" : 1, + "id" : 0, + "shipDate" : "2000-01-23T04:56:07.000+00:00", + "complete" : false, + "status" : "placed" + }, + "xml" : { + "name" : "Order" + } + }, + "Category" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + } + }, + "title" : "Pet category", + "description" : "A category for a pet", + "example" : { + "name" : "name", + "id" : 6 + }, + "xml" : { + "name" : "Category" + } + }, + "User" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "username" : { + "type" : "string" + }, + "firstName" : { + "type" : "string" + }, + "lastName" : { + "type" : "string" + }, + "email" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "phone" : { + "type" : "string" + }, + "userStatus" : { + "type" : "integer", + "format" : "int32", + "description" : "User Status" + } + }, + "title" : "a User", + "description" : "A User who is purchasing from the pet store", + "example" : { + "firstName" : "firstName", + "lastName" : "lastName", + "password" : "password", + "userStatus" : 6, + "phone" : "phone", + "id" : 0, + "email" : "email", + "username" : "username" + }, + "xml" : { + "name" : "User" + } + }, + "Tag" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "name" : { + "type" : "string" + } + }, + "title" : "Pet Tag", + "description" : "A tag for a pet", + "example" : { + "name" : "name", + "id" : 1 + }, + "xml" : { + "name" : "Tag" + } + }, + "Pet" : { + "type" : "object", + "required" : [ "name", "photoUrls" ], + "properties" : { + "id" : { + "type" : "integer", + "format" : "int64" + }, + "category" : { + "$ref" : "#/definitions/Category" + }, + "name" : { + "type" : "string", + "example" : "doggie" + }, + "photoUrls" : { + "type" : "array", + "xml" : { + "name" : "photoUrl", + "wrapped" : true + }, + "items" : { + "type" : "string" + } + }, + "tags" : { + "type" : "array", + "xml" : { + "name" : "tag", + "wrapped" : true + }, + "items" : { + "$ref" : "#/definitions/Tag" + } + }, + "status" : { + "type" : "string", + "description" : "pet status in the store", + "enum" : [ "available", "pending", "sold" ] + } + }, + "title" : "a Pet", + "description" : "A pet for sale in the pet store", + "example" : { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }, + "xml" : { + "name" : "Pet" + } + }, + "ApiResponse" : { + "type" : "object", + "properties" : { + "code" : { + "type" : "integer", + "format" : "int32" + }, + "type" : { + "type" : "string" + }, + "message" : { + "type" : "string" + } + }, + "title" : "An uploaded response", + "description" : "Describes the result of uploading an image resource", + "example" : { + "code" : 0, + "type" : "type", + "message" : "message" + } + } + }, + "externalDocs" : { + "description" : "Find out more about Swagger", + "url" : "http://swagger.io" + } +} \ No newline at end of file diff --git a/samples/server/petstore/java-play-framework-controller-only/public/swagger.json b/samples/server/petstore/java-play-framework-controller-only/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework-controller-only/public/swagger.json +++ b/samples/server/petstore/java-play-framework-controller-only/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], diff --git a/samples/server/petstore/java-play-framework-fake-endpoints/public/swagger.json b/samples/server/petstore/java-play-framework-fake-endpoints/public/swagger.json index d23a601863..dca4e4b58a 100644 --- a/samples/server/petstore/java-play-framework-fake-endpoints/public/swagger.json +++ b/samples/server/petstore/java-play-framework-fake-endpoints/public/swagger.json @@ -112,8 +112,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +588,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], @@ -711,8 +711,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "$", - "enum" : [ ">", "$" ] + "enum" : [ ">", "$" ], + "default" : "$" } }, { "name" : "enum_form_string", @@ -730,8 +730,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "$", - "enum" : [ ">", "$" ] + "enum" : [ ">", "$" ], + "default" : "$" } }, { "name" : "enum_header_string", @@ -749,8 +749,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "$", - "enum" : [ ">", "$" ] + "enum" : [ ">", "$" ], + "default" : "$" } }, { "name" : "enum_query_string", diff --git a/samples/server/petstore/java-play-framework-no-bean-validation/public/swagger.json b/samples/server/petstore/java-play-framework-no-bean-validation/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework-no-bean-validation/public/swagger.json +++ b/samples/server/petstore/java-play-framework-no-bean-validation/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], diff --git a/samples/server/petstore/java-play-framework-no-exception-handling/public/swagger.json b/samples/server/petstore/java-play-framework-no-exception-handling/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework-no-exception-handling/public/swagger.json +++ b/samples/server/petstore/java-play-framework-no-exception-handling/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], diff --git a/samples/server/petstore/java-play-framework-no-interface/public/swagger.json b/samples/server/petstore/java-play-framework-no-interface/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework-no-interface/public/swagger.json +++ b/samples/server/petstore/java-play-framework-no-interface/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], diff --git a/samples/server/petstore/java-play-framework-no-wrap-calls/public/swagger.json b/samples/server/petstore/java-play-framework-no-wrap-calls/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework-no-wrap-calls/public/swagger.json +++ b/samples/server/petstore/java-play-framework-no-wrap-calls/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ], diff --git a/samples/server/petstore/java-play-framework/public/swagger.json b/samples/server/petstore/java-play-framework/public/swagger.json index 0f5defa602..3ab9cda2ce 100644 --- a/samples/server/petstore/java-play-framework/public/swagger.json +++ b/samples/server/petstore/java-play-framework/public/swagger.json @@ -13,7 +13,6 @@ "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, - "host" : "petstore.swagger.io", "basePath" : "/v2", "tags" : [ { "name" : "pet", @@ -112,8 +111,8 @@ "type" : "array", "items" : { "type" : "string", - "default" : "available", - "enum" : [ "available", "pending", "sold" ] + "enum" : [ "available", "pending", "sold" ], + "default" : "available" }, "collectionFormat" : "csv" } ], @@ -588,7 +587,7 @@ "parameters" : [ { "name" : "username", "in" : "path", - "description" : "The name that needs to be fetched. Use user1 for testing. ", + "description" : "The name that needs to be fetched. Use user1 for testing.", "required" : true, "type" : "string" } ],