Skip to content

Commit f5c4960

Browse files
authored
Javadoc + operations interface + provider for state(ful/less) handlers (#8346)
* Added Javadoc + meta-data about request/response + abstract class. * Added one more method to set base path. * Updated Javadoc for each endpoint. * Shorten the method name displayed in Javadoc. * Fix README grammar. * Separate imports based on type. * Put operations into their own interface class. * Update Javadoc. * Adjust Mustache template to support Java 1.5. * Add import for HttpServerExchange, suppress warning about using a Lambda. * Remove @OverRide from a mgetStatefulHandler(). * Regenrate the samples.
1 parent ede2a23 commit f5c4960

28 files changed

Lines changed: 1239 additions & 233 deletions

bin/configs/other/java-undertow-server-java-undertow.yaml renamed to bin/configs/java-undertow-server-java-undertow.yaml

File renamed without changes.

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaUndertowServerCodegen.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public void processOpts() {
106106

107107
// keep the yaml in config folder for framework validation.
108108
supportingFiles.add(new SupportingFile("openapi.mustache", ("src.main.resources.config").replace(".", java.io.File.separator), "openapi.json"));
109+
supportingFiles.add(new SupportingFile("interface.mustache", (String.format(Locale.ROOT, "src.main.java.%s", apiPackage)).replace(".", java.io.File.separator), "PathHandlerInterface.java"));
109110
supportingFiles.add(new SupportingFile("handler.mustache", (String.format(Locale.ROOT, "src.main.java.%s", apiPackage)).replace(".", java.io.File.separator), "PathHandlerProvider.java"));
110111
supportingFiles.add(new SupportingFile("service.mustache", ("src.main.resources.META-INF.services").replace(".", java.io.File.separator), "com.networknt.server.HandlerProvider"));
111112

modules/openapi-generator/src/main/resources/java-undertow-server/README.mustache

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@ mvn package exec:exec
1010

1111
## Test
1212

13-
By default, all endpoints are protected by OAuth jwt token verifier. It can be turned off with config change through for development.
14-
13+
By default, all endpoints are protected by the OAuth JWT token verifier. It can be turned off with a config change, when required.
1514

1615
In order to access the server, there is a long lived token below issued by my
17-
oauth2 server [undertow-server-oauth2](https://github.com/networknt/undertow-server-oauth2)
16+
OAuth2 server [undertow-server-oauth2](https://github.com/networknt/undertow-server-oauth2).
1817

1918
```
2019
Bearer eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJ1cm46Y29tOm5ldHdvcmtudDpvYXV0aDI6djEiLCJhdWQiOiJ1cm46Y29tLm5ldHdvcmtudCIsImV4cCI6MTc4ODEzMjczNSwianRpIjoiNWtyM2ZWOHJaelBZNEJrSnNYZzFpQSIsImlhdCI6MTQ3Mjc3MjczNSwibmJmIjoxNDcyNzcyNjE1LCJ2ZXJzaW9uIjoiMS4wIiwidXNlcl9pZCI6InN0ZXZlIiwidXNlcl90eXBlIjoiRU1QTE9ZRUUiLCJjbGllbnRfaWQiOiJkZGNhZjBiYS0xMTMxLTIyMzItMzMxMy1kNmYyNzUzZjI1ZGMiLCJzY29wZSI6WyJhcGkuciIsImFwaS53Il19.gteJiy1uao8HLeWRljpZxHWUgQfofwmnFP-zv3EPUyXjyCOy3xclnfeTnTE39j8PgBwdFASPcDLLk1YfZJbsU6pLlmYXLtdpHDBsVmIRuch6LFPCVQ3JdqSQVci59OhSK0bBThGWqCD3UzDI_OnX4IVCAahcT9Bu94m5u_H_JNmwDf1XaP3Lt4I34buYMuRD9stchsnZi-tuIRkL13FARm1XA9aPZUMUXFdedBWDXo1zMREQ_qCJXOpaZDJM9Im0rIkq9wTEVU00pbRp_Vcdya3dfkFteBMHiwFVt6VNQaco5BXURDAIzXidwQxNEbX1ek03wra8AIani65ZK7fy_w
2120
```
2221

2322
Add "Authorization" header with value as above token and a dummy message will return from the generated stub.
24-
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isBodyParam}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
1+
{{#isBodyParam}}{{{dataType}}} {{{paramName}}}{{/isBodyParam}}

modules/openapi-generator/src/main/resources/java-undertow-server/enumOuterClass.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
{{/jackson}}
44

55
/**
6-
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
7-
*/
6+
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
7+
*/
88
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
99
{{#gson}}
1010
{{#allowableValues}}{{#enumVars}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
@javax.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
1+
@javax.annotation.Generated(value = "{{{generatorClass}}}"{{^hideGenerationTimestamp}}, date = "{{{generatedDate}}}"{{/hideGenerationTimestamp}})
Lines changed: 146 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,161 @@
1+
{{>licenseInfo}}
12
package org.openapitools.handler;
23

3-
import com.networknt.config.Config;
44
import com.networknt.server.HandlerProvider;
55
import io.undertow.Handlers;
66
import io.undertow.server.HttpHandler;
77
import io.undertow.server.HttpServerExchange;
8+
import io.undertow.server.RoutingHandler;
9+
import io.undertow.server.handlers.PathHandler;
810
import io.undertow.util.Methods;
911

10-
public class PathHandlerProvider implements HandlerProvider {
12+
/**
13+
* The default implementation for {@link HandlerProvider} and {@link PathHandlerInterface}.
14+
*
15+
* <p>There are two flavors of {@link HttpHandler}s to choose from, depending on your needs:</p>
16+
*
17+
* <ul>
18+
* <li>
19+
* <b>Stateless</b>: if a specific endpoint is called more than once from multiple sessions,
20+
* its state is not retained – a different {@link HttpHandler} is instantiated for every new
21+
* session. This is the default behavior.
22+
* </li>
23+
* <li>
24+
* <b>Stateful</b>: if a specific endpoint is called more than once from multiple sessions,
25+
* its state is retained properly. For example, if you want to keep a class property that counts
26+
* the number of requests or the last time a request was received.
27+
* </li>
28+
* </ul>
29+
* <p>Note: <b>Stateful</b> flavor is more performant than <b>Stateless</b>.</p>
30+
*/
31+
@SuppressWarnings("TooManyFunctions")
32+
abstract public class PathHandlerProvider implements HandlerProvider, PathHandlerInterface {
33+
/**
34+
* Returns the default base path to access this server.
35+
*/
36+
@javax.annotation.Nonnull
37+
public String getBasePath() {
38+
return "{{{basePathWithoutHost}}}";
39+
}
1140

41+
/**
42+
* Returns a stateless {@link HttpHandler} that configures all endpoints in this server.
43+
*
44+
* <p>Endpoints bound in this method do NOT start with "{{{basePathWithoutHost}}}", and
45+
* it's your responsibility to configure a {@link PathHandler} with a prefix path
46+
* by calling {@link PathHandler#addPrefixPath} like so:</p>
47+
*
48+
* <code>pathHandler.addPrefixPath("{{{basePathWithoutHost}}}", handler)</code>
49+
*
50+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateless and won't
51+
* retain any state between multiple sessions.</p>
52+
*
53+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
54+
*/
55+
@javax.annotation.Nonnull
56+
@Override
1257
public HttpHandler getHandler() {
13-
HttpHandler handler = Handlers.routing()
58+
return getHandler(false);
59+
}
60+
61+
/**
62+
* Returns a stateless {@link HttpHandler} that configures all endpoints in this server.
63+
*
64+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateless and won't
65+
* retain any state between multiple sessions.</p>
66+
*
67+
* @param withBasePath if true, all endpoints would start with "{{{basePathWithoutHost}}}"
68+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
69+
*/
70+
@javax.annotation.Nonnull
71+
public HttpHandler getHandler(final boolean withBasePath) {
72+
return getHandler(withBasePath ? getBasePath() : "");
73+
}
1474

75+
/**
76+
* Returns a stateless {@link HttpHandler} that configures all endpoints in this server.
77+
*
78+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateless and won't
79+
* retain any state between multiple sessions.</p>
80+
*
81+
* @param basePath base path to set for all endpoints
82+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
83+
*/
84+
@SuppressWarnings("Convert2Lambda")
85+
@javax.annotation.Nonnull
86+
public HttpHandler getHandler(final String basePath) {
87+
return Handlers.routing()
1588
{{#apiInfo}}
16-
{{#apis}}
17-
{{#operations}}
18-
{{#operation}}
19-
20-
.add(Methods.{{httpMethod}}, "{{{basePathWithoutHost}}}{{{path}}}", new HttpHandler() {
21-
public void handleRequest(HttpServerExchange exchange) throws Exception {
22-
exchange.getResponseSender().send("{{operationId}}");
23-
}
24-
})
25-
26-
{{/operation}}
27-
{{/operations}}
28-
{{/apis}}
89+
{{#apis}}
90+
{{#operations}}
91+
{{#operation}}
92+
.add(Methods.{{{httpMethod}}}, basePath + "{{{path}}}", new HttpHandler() {
93+
@Override
94+
public void handleRequest(HttpServerExchange exchange) throws Exception {
95+
{{{operationId}}}().handleRequest(exchange);
96+
}
97+
})
98+
{{/operation}}
99+
{{/operations}}
100+
{{/apis}}
101+
;
29102
{{/apiInfo}}
30-
;
31-
return handler;
32103
}
33-
}
34104

105+
/**
106+
* Returns a stateful {@link HttpHandler} that configures all endpoints in this server.
107+
*
108+
* <p>Endpoints bound in this method do NOT start with "{{{basePathWithoutHost}}}", and
109+
* it's your responsibility to configure a {@link PathHandler} with a prefix path
110+
* by calling {@link PathHandler#addPrefixPath} like so:</p>
111+
*
112+
* <code>pathHandler.addPrefixPath("{{{basePathWithoutHost}}}", handler)</code>
113+
*
114+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateful and will
115+
* retain any state between multiple sessions.</p>
116+
*
117+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
118+
*/
119+
@javax.annotation.Nonnull
120+
public HttpHandler getStatefulHandler() {
121+
return getStatefulHandler(false);
122+
}
123+
124+
/**
125+
* Returns a stateful {@link HttpHandler} that configures all endpoints in this server.
126+
*
127+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateful and will
128+
* retain any state between multiple sessions.</p>
129+
*
130+
* @param withBasePath if true, all endpoints would start with "{{{basePathWithoutHost}}}"
131+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
132+
*/
133+
@javax.annotation.Nonnull
134+
public HttpHandler getStatefulHandler(final boolean withBasePath) {
135+
return getStatefulHandler(withBasePath ? getBasePath() : "");
136+
}
137+
138+
/**
139+
* Returns a stateful {@link HttpHandler} that configures all endpoints in this server.
140+
*
141+
* <p>Note: the endpoints bound to the returned {@link HttpHandler} are stateful and will
142+
* retain any state between multiple sessions.</p>
143+
*
144+
* @param basePath base path to set for all endpoints
145+
* @return an {@link HttpHandler} of type {@link RoutingHandler}
146+
*/
147+
@javax.annotation.Nonnull
148+
public HttpHandler getStatefulHandler(final String basePath) {
149+
return Handlers.routing()
150+
{{#apiInfo}}
151+
{{#apis}}
152+
{{#operations}}
153+
{{#operation}}
154+
.add(Methods.{{{httpMethod}}}, basePath + "{{{path}}}", {{{operationId}}}())
155+
{{/operation}}
156+
{{/operations}}
157+
{{/apis}}
158+
;
159+
{{/apiInfo}}
160+
}
161+
}

modules/openapi-generator/src/main/resources/java-undertow-server/inflector.mustache

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
controllerPackage: {{invokerPackage}}
2-
modelPackage: {{modelPackage}}
1+
controllerPackage: {{{invokerPackage}}}
2+
modelPackage: {{{modelPackage}}}
33
swaggerUrl: ./src/main/swagger/swagger.yaml
44
modelMappings:
55
# to enable explicit mappings, use this syntax:
66
DefinitionFromSwaggerSpecification: fully.qualified.path.to.Model
7-
{{#models}}{{#model}}{{classname}} : {{modelPackage}}.{{classname}}{{/model}}
7+
{{#models}}{{#model}}{{{classname}}} : {{{modelPackage}}}.{{{classname}}}{{/model}}
88
{{/models}}
99

1010
entityProcessors:
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{{>licenseInfo}}
2+
package org.openapitools.handler;
3+
4+
import io.undertow.server.*;
5+
import io.undertow.util.*;
6+
7+
import {{modelPackage}}.*;
8+
9+
@SuppressWarnings("TooManyFunctions")
10+
public interface PathHandlerInterface {
11+
{{#apiInfo}}
12+
{{#apis}}
13+
{{#operations}}
14+
{{#operation}}
15+
16+
/**
17+
{{#summary}} * <p>{{{summary}}}</p>
18+
*
19+
{{/summary}}
20+
{{#notes}} * <p>{{{notes}}}</p>
21+
*
22+
{{/notes}}
23+
* <p><b>Endpoint</b>: {@link Methods#{{{httpMethod}}} {{{httpMethod}}}} "{{{basePathWithoutHost}}}{{{path}}}" (<i>privileged: {{{hasAuthMethods}}}</i>)</p>
24+
{{#hasParams}}
25+
*
26+
* <p><b>Request parameters</b>:</p>
27+
* <ul>
28+
{{#allParams}}
29+
{{^isBodyParam}}
30+
* <li>
31+
* <p>"<b>{{{baseName}}}</b>"
32+
{{#description}} * <p>{{{description}}}</p>
33+
{{/description}}
34+
* <p>
35+
* - Parameter type: <b>{{>isContainerDoc}}{{#isModel}}{@link {{{dataType}}}}{{/isModel}}{{^isModel}}{{#isFile}}{{#isBinary}}Binary{{/isBinary}}File{{/isFile}}{{^isFile}}{@link {{dataType}}}{{/isFile}}{{/isModel}}</b><br/>
36+
* - Appears in: <b>{{#isFormParam}}{@link io.undertow.server.handlers.form.FormDataParser Form}{{/isFormParam}}{{#isQueryParam}}{@link HttpServerExchange#getQueryParameters Query}{{/isQueryParam}}{{#isPathParam}}{@link HttpServerExchange#getPathParameters Path}{{/isPathParam}}{{#isHeaderParam}}{@link Headers Header}{{/isHeaderParam}}{{#isCookieParam}}{@link HttpServerExchange#getRequestCookie Cookie}{{/isCookieParam}}{{#isBodyParam}}{@link HttpServerExchange#getRequestChannel Body}{{/isBodyParam}}</b><br/>
37+
{{#defaultValue}} * - Default value: <b>{{{defaultValue}}}</b><br/>
38+
{{/defaultValue}}
39+
* - Required: <b>{{{required}}}</b>
40+
* </p>
41+
* </li>
42+
{{/isBodyParam}}
43+
{{/allParams}}
44+
* </ul>
45+
{{/hasParams}}
46+
{{#hasResponseHeaders}}
47+
* <p><b>Response headers</b>: [{{#responseHeaders}}{{{.}}}{{^-last}}, {{/-last}}{{/responseHeaders}}]</p>
48+
{{/hasResponseHeaders}}
49+
{{#hasConsumes}}
50+
*
51+
* <p><b>Consumes</b>: {{{consumes}}}</p>
52+
{{#hasBodyParam}}{{#bodyParam}} * <p><b>Payload</b>: {{>isContainerDoc}}{{#isModel}}{@link {{{dataType}}}}{{/isModel}}{{^isModel}}{{#isFile}}{{#isBinary}}Binary {{/isBinary}}File{{/isFile}}{{^isFile}}{@link {{baseType}}}{{/isFile}}{{/isModel}} (<i>required: {{{required}}}</i>{{/bodyParam}})</p>
53+
{{/hasBodyParam}}
54+
{{/hasConsumes}}
55+
*
56+
{{#hasProduces}} * <p><b>Produces</b>: {{{produces}}}</p>
57+
{{/hasProduces}}
58+
{{#returnBaseType}} * <p><b>Returns</b>: {{>isContainerDoc}}{@link {{{returnBaseType}}}}</p>
59+
{{/returnBaseType}}
60+
*
61+
* <p><b>Responses</b>:</p>
62+
* <ul>
63+
{{#responses}}
64+
* <li><b>{{#isDefault}}Default{{/isDefault}}{{^isDefault}}{{{code}}} ({{#is1xx}}informative{{/is1xx}}{{#is2xx}}success{{/is2xx}}{{#is3xx}}redirection{{/is3xx}}{{#is4xx}}client error{{/is4xx}}{{#is5xx}}server error{{/is5xx}}){{/isDefault}}</b>{{#message}}: {{{message}}}{{/message}}</li>
65+
{{/responses}}
66+
* </ul>
67+
*/
68+
@javax.annotation.Nonnull
69+
{{#isDeprecated}} @Deprecated
70+
{{/isDeprecated}}
71+
HttpHandler {{{operationId}}}();
72+
{{/operation}}
73+
{{/operations}}
74+
{{/apis}}
75+
{{/apiInfo}}
76+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#isArray}}{@link java.util.List List} of {{/isArray}}{{#isMap}}{@link java.util.Map Map} of {{/isMap}}

0 commit comments

Comments
 (0)