diff --git a/src/main/java/io/sinistral/proteus/ProteusApplication.java b/src/main/java/io/sinistral/proteus/ProteusApplication.java
index d6d5cfa..ef82725 100644
--- a/src/main/java/io/sinistral/proteus/ProteusApplication.java
+++ b/src/main/java/io/sinistral/proteus/ProteusApplication.java
@@ -307,14 +307,15 @@ public void buildServer()
.setBufferSize(Long.valueOf(config.getMemorySize("undertow.bufferSize").toBytes()).intValue())
.setIoThreads(Runtime.getRuntime().availableProcessors() * config.getInt("undertow.ioThreadsMultiplier"))
+ .setWorkerThreads(Runtime.getRuntime().availableProcessors() * config.getInt("undertow.workerThreadMultiplier"))
+ .setDirectBuffers(config.getBoolean("undertow.directBuffers"))
+ .setSocketOption(org.xnio.Options.BACKLOG, config.getInt("undertow.socket.backlog"))
+ .setSocketOption(org.xnio.Options.REUSE_ADDRESSES, config.getBoolean("undertow.socket.reuseAddresses"))
.setServerOption(UndertowOptions.ENABLE_HTTP2, config.getBoolean("undertow.server.enableHttp2"))
.setServerOption(UndertowOptions.ALWAYS_SET_DATE, config.getBoolean("undertow.server.alwaysSetDate"))
- .setSocketOption(org.xnio.Options.BACKLOG, config.getInt("undertow.socket.backlog"))
.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, config.getBoolean("undertow.server.alwaysSetKeepAlive"))
.setServerOption(UndertowOptions.RECORD_REQUEST_START_TIME, config.getBoolean("undertow.server.recordRequestStartTime"))
.setServerOption(UndertowOptions.MAX_ENTITY_SIZE, config.getBytes("undertow.server.maxEntitySize"))
- .setSocketOption(org.xnio.Options.REUSE_ADDRESSES, config.getBoolean("undertow.socket.reuseAddresses"))
- .setWorkerThreads(config.getInt("undertow.workerThreads"))
.setHandler(handler);
diff --git a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
index eb55153..518a1ca 100644
--- a/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
+++ b/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package io.sinistral.proteus.server.handlers;
@@ -74,87 +74,79 @@
* annotation (i.e. javax.ws.rs.GET
)
* @author jbauer
*/
-public class HandlerGenerator
-{
-
- static Logger log = LoggerFactory.getLogger(HandlerGenerator.class.getCanonicalName());
-
- private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
- private static final Pattern CONCURRENT_TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.concurrent\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
-
- public enum StatementParameterType
- {
- STRING, LITERAL, TYPE, RAW
- }
-
- @Inject
- @Named("application.path")
- protected String applicationPath;
-
- protected String packageName;
- protected String className;
- protected String sourceString;
-
- @Inject
- @Named("registeredEndpoints")
- protected Set registeredEndpoints;
-
- protected Class> controllerClass;
-
- protected Set injectedHandlerWrappers = new HashSet<>();
-
- @Inject
- @Named("registeredHandlerWrappers")
- protected Map registeredHandlerWrappers;
-
- protected Map, String> typeLevelHandlerWrapperMap = new LinkedHashMap, String>();
-
- protected Map, String> handlerWrapperMap = new LinkedHashMap, String>();
-
- /**
- * Create a new {@code HandlerGenerator} instance used to generate a
- * {@code Supplier} class
- * @param packageName
- * generated class package name
- * @param controllerClass
- * the class handlers will be generated from this class
- */
- public HandlerGenerator(String packageName, Class> controllerClass)
- {
- this.packageName = packageName;
- this.controllerClass = controllerClass;
- this.className = controllerClass.getSimpleName() + "RouteSupplier";
- }
-
- /**
- * Compiles the generated source into a new {@link Class}
- * @return a new {@code Supplier} class
- */
- public Class extends Supplier> compileClass()
- {
- try
- {
- this.generateRoutes();
-
- log.debug("\n\nGenerated Class Source:\n\n" + this.sourceString);
-
- return CompilerUtils.CACHED_COMPILER.loadFromJava(packageName + "." + className, this.sourceString);
-
- } catch (Exception e)
- {
- log.error(e.getMessage(), e);
- return null;
- }
- }
-
- /**
- * Generates the routing Java source code
- */
- protected void generateRoutes()
- {
- try
- {
-
+public class HandlerGenerator {
+
+ static Logger log = LoggerFactory.getLogger(HandlerGenerator.class.getCanonicalName());
+
+ private static final Pattern TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
+ private static final Pattern CONCURRENT_TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.concurrent\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
+
+ public enum StatementParameterType {
+ STRING, LITERAL, TYPE, RAW
+ }
+
+ @Inject
+ @Named("application.path")
+ protected String applicationPath;
+
+ protected String packageName;
+ protected String className;
+ protected String sourceString;
+
+ @Inject
+ @Named("registeredEndpoints")
+ protected Set registeredEndpoints;
+
+ protected Class> controllerClass;
+
+ protected Set injectedHandlerWrappers = new HashSet<>();
+
+ @Inject
+ @Named("registeredHandlerWrappers")
+ protected Map registeredHandlerWrappers;
+
+ protected Map, String> typeLevelHandlerWrapperMap = new LinkedHashMap, String>();
+
+ protected Map, String> handlerWrapperMap = new LinkedHashMap, String>();
+
+ /**
+ * Create a new {@code HandlerGenerator} instance used to generate a
+ * {@code Supplier} class
+ * @param packageName
+ * generated class package name
+ * @param controllerClass
+ * the class handlers will be generated from this class
+ */
+ public HandlerGenerator(String packageName, Class> controllerClass) {
+ this.packageName = packageName;
+ this.controllerClass = controllerClass;
+ this.className = controllerClass.getSimpleName() + "RouteSupplier";
+ }
+
+ /**
+ * Compiles the generated source into a new {@link Class}
+ * @return a new {@code Supplier} class
+ */
+ public Class extends Supplier> compileClass() {
+ try {
+ this.generateRoutes();
+
+ log.debug("\n\nGenerated Class Source:\n\n" + this.sourceString);
+
+ return CompilerUtils.CACHED_COMPILER.loadFromJava(packageName + "." + className, this.sourceString);
+
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * Generates the routing Java source code
+ */
+ protected void generateRoutes() {
+ try {
+
// Optional typeLevelWrapAnnotation = Optional.ofNullable(controllerClass.getAnnotation(io.sinistral.proteus.annotations.Chain.class));
//
// typeLevelWrapAnnotation.ifPresent( a -> {
@@ -200,327 +192,287 @@ protected void generateRoutes()
//
// log.info("handlerWrapperMap: " + handlerWrapperMap);
- TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC)
- .addSuperinterface(ParameterizedTypeName.get(Supplier.class, RoutingHandler.class));
+ TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC)
+ .addSuperinterface(ParameterizedTypeName.get(Supplier.class, RoutingHandler.class));
+
+ ClassName extractorClass = ClassName.get("io.sinistral.proteus.server", "Extractors");
+
+ ClassName injectClass = ClassName.get("com.google.inject", "Inject");
+
+
+ MethodSpec.Builder constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addAnnotation(injectClass);
+
+ String className = this.controllerClass.getSimpleName().toLowerCase() + "Controller";
+
+ typeBuilder.addField(this.controllerClass, className, Modifier.PROTECTED, Modifier.FINAL);
+
+ ClassName wrapperClass = ClassName.get("io.undertow.server", "HandlerWrapper");
+ ClassName stringClass = ClassName.get("java.lang", "String");
+ ClassName mapClass = ClassName.get("java.util", "Map");
+
+ TypeName mapOfWrappers = ParameterizedTypeName.get(mapClass, stringClass, wrapperClass);
+
+ TypeName annotatedMapOfWrappers = mapOfWrappers
+ .annotated(AnnotationSpec.builder(com.google.inject.name.Named.class).addMember("value", "$S", "registeredHandlerWrappers").build());
+
+ typeBuilder.addField(mapOfWrappers, "registeredHandlerWrappers", Modifier.PROTECTED, Modifier.FINAL);
+
+
+ constructor.addParameter(this.controllerClass, className);
+ constructor.addParameter(annotatedMapOfWrappers, "registeredHandlerWrappers");
+
+ constructor.addStatement("this.$N = $N", className, className);
+ constructor.addStatement("this.$N = $N", "registeredHandlerWrappers", "registeredHandlerWrappers");
+
+ addClassMethodHandlers(typeBuilder, this.controllerClass);
+
+ typeBuilder.addMethod(constructor.build());
+
+ JavaFile javaFile = JavaFile.builder(packageName, typeBuilder.build()).addStaticImport(extractorClass, "*").build();
+
+ StringBuilder sb = new StringBuilder();
+
+ javaFile.writeTo(sb);
+
+ this.sourceString = sb.toString();
+
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz) throws Exception {
+ ClassName httpHandlerClass = ClassName.get("io.undertow.server", "HttpHandler");
+
+ String controllerName = clazz.getSimpleName().toLowerCase() + "Controller";
+
+ int handlerWrapperIndex = 1;
+
+ HashSet handlerNameSet = new HashSet<>();
+
+ MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC).returns(RoutingHandler.class)
+ .addStatement("final $T router = new $T()", io.undertow.server.RoutingHandler.class, io.undertow.server.RoutingHandler.class);
+
+ final Map parameterizedLiteralsNameMap = Arrays.stream(clazz.getDeclaredMethods())
+ .filter(m -> m.getAnnotation(Path.class) != null)
+ .flatMap(
+ m -> Arrays.stream(m.getParameters()).map(Parameter::getParameterizedType)
+ .filter(t -> t.getTypeName().contains("<") && !t.getTypeName().contains("concurrent")))
+ .distinct().filter(t ->
+ {
+
+ TypeHandler handler = TypeHandler.forType(t);
+ return (handler.equals(TypeHandler.ModelType) || handler.equals(TypeHandler.OptionalModelType));
+
+ }).collect(Collectors.toMap(java.util.function.Function.identity(), HandlerGenerator::typeReferenceNameForParameterizedType));
+
+
+ Arrays.stream(clazz.getDeclaredMethods())
+ .filter(m -> m.getAnnotation(Path.class) != null)
+ .flatMap(m -> Arrays.stream(m.getParameters()))
+ .forEach(p ->
+ {
+
+ BeanParam beanParam = p.getAnnotation(BeanParam.class);
+
+ boolean isBeanParameter = beanParam != null;
+
+ if (isBeanParameter) {
+ TypeHandler handler = TypeHandler.forType(p.getParameterizedType(), true);
+
+ if (handler.equals(TypeHandler.BeanListValueOfType)
+ || handler.equals(TypeHandler.BeanListFromStringType)
+ || handler.equals(TypeHandler.OptionalBeanListValueOfType)
+ || handler.equals(TypeHandler.OptionalBeanListFromStringType)) {
+ parameterizedLiteralsNameMap.put(p.getParameterizedType(), HandlerGenerator.typeReferenceNameForParameterizedType(p.getParameterizedType()));
+ }
+ }
- ClassName extractorClass = ClassName.get("io.sinistral.proteus.server", "Extractors");
+ });
- ClassName injectClass = ClassName.get("com.google.inject", "Inject");
-
+ final Map literalsNameMap = Arrays.stream(clazz.getDeclaredMethods())
+ .filter(m -> m.getAnnotation(Path.class) != null)
+ .flatMap(m -> Arrays.stream(m.getParameters())
+ .map(Parameter::getParameterizedType)).filter(t ->
+ {
+ if (t.getTypeName().contains("java.util")) {
+ return false;
+ }
- MethodSpec.Builder constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addAnnotation(injectClass);
+ try {
+ Class> optionalType = (Class>) extractErasedType(t);
- String className = this.controllerClass.getSimpleName().toLowerCase() + "Controller";
+ if (optionalType != null) {
+ t = optionalType;
+ }
- typeBuilder.addField(this.controllerClass, className, Modifier.PROTECTED, Modifier.FINAL);
+ } catch (Exception e) {
- ClassName wrapperClass = ClassName.get("io.undertow.server", "HandlerWrapper");
- ClassName stringClass = ClassName.get("java.lang", "String");
- ClassName mapClass = ClassName.get("java.util", "Map");
+ }
- TypeName mapOfWrappers = ParameterizedTypeName.get(mapClass, stringClass, wrapperClass);
+ if (t.getTypeName().contains("java.lang")) {
+ return false;
+ } else if (t.getTypeName().contains("java.nio")) {
+ return false;
+ } else if (t.getTypeName().contains("java.io")) {
+ return false;
+ } else if (t.getTypeName().contains("java.util")) {
+ return false;
+ } else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class)) {
+ return false;
+ }
- TypeName annotatedMapOfWrappers = mapOfWrappers
- .annotated(AnnotationSpec.builder(com.google.inject.name.Named.class).addMember("value", "$S", "registeredHandlerWrappers").build());
+ if (t instanceof Class) {
+ Class> pClazz = (Class>) t;
+ if (pClazz.isPrimitive()) {
+ return false;
+ }
+ if (pClazz.isEnum()) {
+ return false;
+ }
- typeBuilder.addField(mapOfWrappers, "registeredHandlerWrappers", Modifier.PROTECTED, Modifier.FINAL);
-
+ }
- constructor.addParameter(this.controllerClass, className);
- constructor.addParameter(annotatedMapOfWrappers, "registeredHandlerWrappers");
-
- constructor.addStatement("this.$N = $N", className, className);
- constructor.addStatement("this.$N = $N", "registeredHandlerWrappers", "registeredHandlerWrappers");
+ return true;
- addClassMethodHandlers(typeBuilder, this.controllerClass);
-
- typeBuilder.addMethod(constructor.build());
-
- JavaFile javaFile = JavaFile.builder(packageName, typeBuilder.build()).addStaticImport(extractorClass, "*").build();
-
- StringBuilder sb = new StringBuilder();
-
- javaFile.writeTo(sb);
-
- this.sourceString = sb.toString();
-
- } catch (Exception e)
- {
- log.error(e.getMessage(), e);
- }
- }
-
- protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> clazz) throws Exception
- {
- ClassName httpHandlerClass = ClassName.get("io.undertow.server", "HttpHandler");
-
- String controllerName = clazz.getSimpleName().toLowerCase() + "Controller";
-
- int handlerWrapperIndex = 1;
-
- HashSet handlerNameSet = new HashSet<>();
-
- MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC).returns(RoutingHandler.class)
- .addStatement("final $T router = new $T()", io.undertow.server.RoutingHandler.class, io.undertow.server.RoutingHandler.class);
-
- final Map parameterizedLiteralsNameMap = Arrays.stream(clazz.getDeclaredMethods())
- .filter(m -> m.getAnnotation(Path.class) != null)
- .flatMap(
- m -> Arrays.stream(m.getParameters()).map(Parameter::getParameterizedType)
- .filter(t -> t.getTypeName().contains("<") && !t.getTypeName().contains("concurrent")))
- .distinct().filter(t ->
- {
-
- TypeHandler handler = TypeHandler.forType(t);
- return (handler.equals(TypeHandler.ModelType) || handler.equals(TypeHandler.OptionalModelType));
-
- }).collect(Collectors.toMap(java.util.function.Function.identity(), HandlerGenerator::typeReferenceNameForParameterizedType));
-
-
-
- Arrays.stream(clazz.getDeclaredMethods())
- .filter(m -> m.getAnnotation(Path.class) != null)
- .flatMap(m -> Arrays.stream(m.getParameters()))
- .forEach(p ->
- {
-
- BeanParam beanParam = p.getAnnotation(BeanParam.class);
-
- boolean isBeanParameter = beanParam != null;
-
- if (isBeanParameter)
- {
- TypeHandler handler = TypeHandler.forType(p.getParameterizedType(), true);
-
- if (handler.equals(TypeHandler.BeanListValueOfType)
- || handler.equals(TypeHandler.BeanListFromStringType)
- || handler.equals(TypeHandler.OptionalBeanListValueOfType)
- || handler.equals(TypeHandler.OptionalBeanListFromStringType))
- {
- parameterizedLiteralsNameMap.put(p.getParameterizedType(), HandlerGenerator.typeReferenceNameForParameterizedType(p.getParameterizedType()));
- }
- }
-
- });
-
- final Map literalsNameMap = Arrays.stream(clazz.getDeclaredMethods())
- .filter(m -> m.getAnnotation(Path.class) != null)
- .flatMap(m -> Arrays.stream(m.getParameters())
- .map(Parameter::getParameterizedType)).filter(t ->
- {
-
- if (t.getTypeName().contains("java.util"))
- {
- return false;
- }
-
- try
- {
- Class> optionalType = (Class>) extractErasedType(t);
-
- if (optionalType != null)
- {
- t = optionalType;
- }
-
- } catch (Exception e)
- {
-
- }
-
- if (t.getTypeName().contains("java.lang"))
- {
- return false;
- }
- else if (t.getTypeName().contains("java.nio"))
- {
- return false;
- }
- else if (t.getTypeName().contains("java.io"))
- {
- return false;
- }
- else if (t.getTypeName().contains("java.util"))
- {
- return false;
- }
- else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
- {
- return false;
- }
-
- if (t instanceof Class)
- {
- Class> pClazz = (Class>) t;
- if (pClazz.isPrimitive())
- {
- return false;
- }
- if (pClazz.isEnum())
- {
- return false;
- }
-
- }
-
- return true;
-
- })
- .distinct()
- .collect(Collectors.toMap(java.util.function.Function.identity(), HandlerGenerator::typeReferenceNameForType));
-
- parameterizedLiteralsNameMap
- .forEach((t, n) -> initBuilder.addStatement("final $T<$L> $LTypeReference = new $T<$L>(){}", TypeReference.class, t, n, TypeReference.class, t));
-
- literalsNameMap.forEach((t, n) -> initBuilder.addStatement("final $T<$T> $LTypeReference = new $T<$T>(){}", TypeReference.class, t, n, TypeReference.class, t));
-
- Optional typeLevelWrapAnnotation = Optional.ofNullable(clazz.getAnnotation(io.sinistral.proteus.annotations.Chain.class));
-
-
- if (typeLevelWrapAnnotation.isPresent())
- {
- io.sinistral.proteus.annotations.Chain w = typeLevelWrapAnnotation.get();
-
- Class extends HandlerWrapper> wrapperClasses[] = w.value();
-
- for (int i = 0; i < wrapperClasses.length; i++)
- {
- Class extends HandlerWrapper> wrapperClass = wrapperClasses[i];
-
- String wrapperName = generateFieldName(wrapperClass.getCanonicalName());
-
- initBuilder.addStatement("final $T $L = new $T()", wrapperClass, wrapperName, wrapperClass);
-
- typeLevelHandlerWrapperMap.put(wrapperClass, wrapperName);
- }
- }
-
- initBuilder.addStatement("$T currentHandler = $L", HttpHandler.class, "null");
-
- initBuilder.addCode("$L", "\n");
-
- List consumesContentTypes = new ArrayList<>();
- List producesContentTypes = new ArrayList<>();
+ })
+ .distinct()
+ .collect(Collectors.toMap(java.util.function.Function.identity(), HandlerGenerator::typeReferenceNameForType));
- /*
- * Controller Level Authorization
- */
+ parameterizedLiteralsNameMap
+ .forEach((t, n) -> initBuilder.addStatement("final $T<$L> $LTypeReference = new $T<$L>(){}", TypeReference.class, t, n, TypeReference.class, t));
- List typeLevelSecurityDefinitions = new ArrayList<>();
+ literalsNameMap.forEach((t, n) -> initBuilder.addStatement("final $T<$T> $LTypeReference = new $T<$T>(){}", TypeReference.class, t, n, TypeReference.class, t));
- if (Optional.ofNullable(clazz.getAnnotation(Path.class)).isPresent())
- {
- SecurityRequirement securityRequirementAnnotation = clazz.getAnnotation(SecurityRequirement.class);
+ Optional typeLevelWrapAnnotation = Optional.ofNullable(clazz.getAnnotation(io.sinistral.proteus.annotations.Chain.class));
- if(securityRequirementAnnotation != null)
- {
- String securityRequirement = securityRequirementAnnotation.name();
-
- typeLevelSecurityDefinitions.add(securityRequirement);
- }
- }
- log.debug("Scanning methods for class " + clazz.getName());
+ if (typeLevelWrapAnnotation.isPresent()) {
+ io.sinistral.proteus.annotations.Chain w = typeLevelWrapAnnotation.get();
- int nameIndex = 1;
+ Class extends HandlerWrapper> wrapperClasses[] = w.value();
- for (Method m : clazz.getDeclaredMethods())
- {
+ for (int i = 0; i < wrapperClasses.length; i++) {
+ Class extends HandlerWrapper> wrapperClass = wrapperClasses[i];
- if (!Optional.ofNullable(m.getAnnotation(javax.ws.rs.Path.class)).isPresent())
- {
- continue;
- }
+ String wrapperName = generateFieldName(wrapperClass.getCanonicalName());
- log.debug("Scanning method " + m.getName() + "\n");
+ initBuilder.addStatement("final $T $L = new $T()", wrapperClass, wrapperName, wrapperClass);
- EndpointInfo endpointInfo = new EndpointInfo();
+ typeLevelHandlerWrapperMap.put(wrapperClass, wrapperName);
+ }
+ }
+
+ initBuilder.addStatement("$T currentHandler = $L", HttpHandler.class, "null");
+
+ initBuilder.addCode("$L", "\n");
+
+ List consumesContentTypes = new ArrayList<>();
+ List producesContentTypes = new ArrayList<>();
+
+ /*
+ * Controller Level Authorization
+ */
+
+ List typeLevelSecurityDefinitions = new ArrayList<>();
+
+ if (Optional.ofNullable(clazz.getAnnotation(Path.class)).isPresent()) {
+ SecurityRequirement securityRequirementAnnotation = clazz.getAnnotation(SecurityRequirement.class);
+
+ if (securityRequirementAnnotation != null) {
+ String securityRequirement = securityRequirementAnnotation.name();
+
+ typeLevelSecurityDefinitions.add(securityRequirement);
+ }
+ }
+
+ log.debug("Scanning methods for class " + clazz.getName());
+
+ int nameIndex = 1;
+
+ for (Method m : clazz.getDeclaredMethods()) {
- String producesContentType = "*/*";
- String consumesContentType = "*/*";
+ if (!Optional.ofNullable(m.getAnnotation(javax.ws.rs.Path.class)).isPresent()) {
+ continue;
+ }
- Boolean isBlocking = false;
- Boolean isDebug = false;
+ log.debug("Scanning method " + m.getName() + "\n");
- Optional blockingAnnotation = Optional.ofNullable(m.getAnnotation(Blocking.class));
+ EndpointInfo endpointInfo = new EndpointInfo();
- if (blockingAnnotation.isPresent())
- {
- isBlocking = blockingAnnotation.get().value();
- }
-
- Optional debugAnnotation = Optional.ofNullable(m.getAnnotation(Debug.class));
+ String producesContentType = "*/*";
+ String consumesContentType = "*/*";
- if (debugAnnotation.isPresent())
- {
- isDebug = debugAnnotation.get().value();
- }
+ Boolean isBlocking = false;
+ Boolean isDebug = false;
- Optional producesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Produces.class));
+ Optional blockingAnnotation = Optional.ofNullable(m.getAnnotation(Blocking.class));
- if (!producesAnnotation.isPresent())
- {
- producesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Produces.class));
+ if (blockingAnnotation.isPresent()) {
+ isBlocking = blockingAnnotation.get().value();
+ }
- if (producesAnnotation.isPresent())
- {
+ Optional debugAnnotation = Optional.ofNullable(m.getAnnotation(Debug.class));
- producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+ if (debugAnnotation.isPresent()) {
+ isDebug = debugAnnotation.get().value();
+ }
- producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
- }
+ Optional producesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Produces.class));
- }
- else
- {
- producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+ if (!producesAnnotation.isPresent()) {
+ producesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Produces.class));
- producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
- }
+ if (producesAnnotation.isPresent()) {
- endpointInfo.setProduces(producesContentType);
+ producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
- Optional consumesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Consumes.class));
+ producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
+ }
- if (!consumesAnnotation.isPresent())
- {
- consumesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Consumes.class));
+ } else {
+ producesContentTypes = Arrays.stream(producesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
- if (consumesAnnotation.isPresent())
- {
- consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+ producesContentType = producesContentTypes.stream().collect(Collectors.joining(","));
+ }
- consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
- }
- }
- else
- {
- consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
+ endpointInfo.setProduces(producesContentType);
- consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
- }
+ Optional consumesAnnotation = Optional.ofNullable(m.getAnnotation(javax.ws.rs.Consumes.class));
- endpointInfo.setControllerName(clazz.getSimpleName());
+ if (!consumesAnnotation.isPresent()) {
+ consumesAnnotation = Optional.ofNullable(clazz.getAnnotation(javax.ws.rs.Consumes.class));
- String methodPath = null;
+ if (consumesAnnotation.isPresent()) {
+ consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
- try
- {
- methodPath = Extractors.pathTemplateFromMethod.apply(m).replaceAll("\\/\\/", "\\/");
- } catch (Exception e)
- {
- log.error(e.getMessage() + " for " + m, e);
- continue;
- }
+ consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
+ }
+ } else {
+ consumesContentTypes = Arrays.stream(consumesAnnotation.get().value()).flatMap(v -> Arrays.stream((v.split(",")))).collect(Collectors.toList());
- methodPath = applicationPath + methodPath;
+ consumesContentType = consumesContentTypes.stream().collect(Collectors.joining(","));
+ }
+
+ endpointInfo.setControllerName(clazz.getSimpleName());
- HttpString httpMethod = Extractors.httpMethodFromMethod.apply(m);
+ String methodPath = null;
- endpointInfo.setMethod(httpMethod);
+ try {
+ methodPath = Extractors.pathTemplateFromMethod.apply(m).replaceAll("\\/\\/", "\\/");
+ } catch (Exception e) {
+ log.error(e.getMessage() + " for " + m, e);
+ continue;
+ }
- endpointInfo.setConsumes(consumesContentType);
+ methodPath = applicationPath + methodPath;
+
+ HttpString httpMethod = Extractors.httpMethodFromMethod.apply(m);
+
+ endpointInfo.setMethod(httpMethod);
+
+ endpointInfo.setConsumes(consumesContentType);
//The handler for these two inputs types is blocking, so we set the flag
if (endpointInfo.getConsumes().contains(FormEncodedDataDefinition.APPLICATION_X_WWW_FORM_URLENCODED)
@@ -528,741 +480,625 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
isBlocking = true;
}
- endpointInfo.setPathTemplate(methodPath);
-
- endpointInfo.setControllerMethod(m.getName());
-
- String handlerName = String.format("%c%s%sHandler_%s", Character.toLowerCase(clazz.getSimpleName().charAt(0)), clazz.getSimpleName()
- .substring(1), StringUtils.capitalize(m.getName()), String.valueOf(nameIndex++));
-
- handlerNameSet.add(handlerName);
-
- TypeSpec.Builder handlerClassBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(httpHandlerClass);
-
- MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("handleRequest").addModifiers(Modifier.PUBLIC).addException(ClassName.get("java.lang", "Exception"))
- .addAnnotation(Override.class)
- .addParameter(ParameterSpec.builder(HttpServerExchange.class, "exchange", Modifier.FINAL).build());
-
- for (Parameter p : m.getParameters())
- {
-
- if (p.getParameterizedType().equals(ServerRequest.class)
- || p.getParameterizedType().equals(HttpServerExchange.class)
- || p.getParameterizedType().equals(HttpHandler.class))
- {
- continue;
- }
-
- try
- {
- BeanParam beanParam = p.getAnnotation(BeanParam.class);
-
- boolean isBeanParameter = beanParam != null;
-
- TypeHandler t = TypeHandler.forType(p.getParameterizedType(), isBeanParameter);
-
- if (t.isBlocking())
- {
- isBlocking = true;
- break;
- }
-
- } catch (Exception e)
- {
- log.error(e.getMessage(), e);
- }
- }
-
- log.debug("parameterizedLiteralsNameMap: " + parameterizedLiteralsNameMap);
-
- if(isBlocking)
- {
-
- methodBuilder.addCode(
- "$L.dispatch( () -> ",
- "exchange");
-
- methodBuilder.beginControlFlow("", "");
-
- methodBuilder.beginControlFlow("try");
-
- }
-
- Arrays.stream(m.getParameters()).forEachOrdered(p ->
- {
-
- Type type = p.getParameterizedType();
-
- try
- {
-
- log.debug("Parameter " + p.getName() + " of type " + type);
-
- if (p.getType().equals(ServerRequest.class))
- {
- methodBuilder.addStatement("$T $L = new $T(exchange)", ServerRequest.class, p.getName(), ServerRequest.class);
-
- }
- else if (p.getType().equals(HttpHandler.class))
- {
- methodBuilder.addStatement("$T $L = this", HttpHandler.class, p.getName());
- }
- else if(!p.getType().equals(HttpServerExchange.class))
- {
- if (p.isAnnotationPresent(HeaderParam.class))
- {
-
- TypeHandler handler = TypeHandler.forType(type);
-
- if (handler.equals(TypeHandler.OptionalStringType))
- {
- handler = TypeHandler.OptionalHeaderStringType;
-
- TypeHandler.addStatement(methodBuilder, p, handler);
-
- }
- else if (handler.equals(TypeHandler.OptionalValueOfType))
- {
- handler = TypeHandler.OptionalHeaderValueOfType;
-
- TypeHandler.addStatement(methodBuilder, p, handler);
-
- }
- else if (handler.equals(TypeHandler.OptionalFromStringType))
- {
- handler = TypeHandler.OptionalHeaderFromStringType;
- TypeHandler.addStatement(methodBuilder, p, handler);
-
- }
- else if (handler.equals(TypeHandler.StringType))
- {
- handler = TypeHandler.HeaderStringType;
- TypeHandler.addStatement(methodBuilder, p, handler);
-
- }
- else if (handler.equals(TypeHandler.ValueOfType))
- {
- handler = TypeHandler.HeaderValueOfType;
- TypeHandler.addStatement(methodBuilder, p, handler);
-
- }
- else if (handler.equals(TypeHandler.FromStringType))
- {
- handler = TypeHandler.HeaderFromStringType;
- TypeHandler.addStatement(methodBuilder, p, handler);
- }
- else
- {
- handler = TypeHandler.HeaderStringType;
-
- TypeHandler.addStatement(methodBuilder, p, handler);
- }
-
- }
- else
- {
- BeanParam beanParam = p.getAnnotation(BeanParam.class);
-
- boolean isBeanParameter = beanParam != null;
-
- TypeHandler t = TypeHandler.forType(type, isBeanParameter);
-
- log.debug("beanParam handler: " + t);
-
- if (t.equals(TypeHandler.OptionalModelType) || t.equals(TypeHandler.ModelType))
- {
- String interfaceType = parameterizedLiteralsNameMap.get(type);
-
- String typeName = type.getTypeName();
-
- if (typeName.contains("$"))
- {
- typeName = typeName.replace("$", ".");
- }
-
- String pType = interfaceType != null ? interfaceType + "TypeReference" : typeName + ".class";
-
- methodBuilder.addStatement(t.statement, type, p.getName(), pType);
-
- }
- else if (t.equals(TypeHandler.BeanListFromStringType) || t.equals(TypeHandler.BeanListValueOfType))
- {
- String interfaceType = parameterizedLiteralsNameMap.get(type);
+ endpointInfo.setPathTemplate(methodPath);
+
+ endpointInfo.setControllerMethod(m.getName());
+
+ String handlerName = String.format("%c%s%sHandler_%s", Character.toLowerCase(clazz.getSimpleName().charAt(0)), clazz.getSimpleName()
+ .substring(1), StringUtils.capitalize(m.getName()), String.valueOf(nameIndex++));
+
+ handlerNameSet.add(handlerName);
+
+ TypeSpec.Builder handlerClassBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(httpHandlerClass);
+
+ /**
+ * @TODO
+ * Rewrite with lambdas or method references.
+ *
+ * final io.undertow.server.HttpHandler benchmarksDbPostgresHandler = (final HttpServerExchange exchange) ->
+ * {
+ * benchmarksController.dbPostgres;
+ * });
+ *
+ * OR
+ *
+ * final io.undertow.server.HttpHandler benchmarksDbPostgresHandler = benchmarksController::dbPostgres;
+ **/
+
+ MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("handleRequest").addModifiers(Modifier.PUBLIC).addException(ClassName.get("java.lang", "Exception"))
+ .addAnnotation(Override.class)
+ .addParameter(ParameterSpec.builder(HttpServerExchange.class, "exchange", Modifier.FINAL).build());
+
+ for (Parameter p : m.getParameters()) {
+
+ if (p.getParameterizedType().equals(ServerRequest.class)
+ || p.getParameterizedType().equals(HttpServerExchange.class)
+ || p.getParameterizedType().equals(HttpHandler.class)) {
+ continue;
+ }
+
+ try {
+ BeanParam beanParam = p.getAnnotation(BeanParam.class);
+
+ boolean isBeanParameter = beanParam != null;
+
+ TypeHandler t = TypeHandler.forType(p.getParameterizedType(), isBeanParameter);
+
+ if (t.isBlocking()) {
+ isBlocking = true;
+ break;
+ }
+
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ log.debug("parameterizedLiteralsNameMap: " + parameterizedLiteralsNameMap);
+
+ if (isBlocking) {
+
+ methodBuilder.addCode(
+ "$L.dispatch( () -> ",
+ "exchange");
+
+ methodBuilder.beginControlFlow("", "");
+
+ methodBuilder.beginControlFlow("try");
+
+ }
+
+ Arrays.stream(m.getParameters()).forEachOrdered(p ->
+ {
+
+ Type type = p.getParameterizedType();
+
+ try {
+
+ log.debug("Parameter " + p.getName() + " of type " + type);
+
+ if (p.getType().equals(ServerRequest.class)) {
+ methodBuilder.addStatement("$T $L = new $T(exchange)", ServerRequest.class, p.getName(), ServerRequest.class);
+
+ } else if (p.getType().equals(HttpHandler.class)) {
+ methodBuilder.addStatement("$T $L = this", HttpHandler.class, p.getName());
+ } else if (!p.getType().equals(HttpServerExchange.class)) {
+ if (p.isAnnotationPresent(HeaderParam.class)) {
+
+ TypeHandler handler = TypeHandler.forType(type);
+
+ if (handler.equals(TypeHandler.OptionalStringType)) {
+ handler = TypeHandler.OptionalHeaderStringType;
+
+ TypeHandler.addStatement(methodBuilder, p, handler);
+
+ } else if (handler.equals(TypeHandler.OptionalValueOfType)) {
+ handler = TypeHandler.OptionalHeaderValueOfType;
+
+ TypeHandler.addStatement(methodBuilder, p, handler);
+
+ } else if (handler.equals(TypeHandler.OptionalFromStringType)) {
+ handler = TypeHandler.OptionalHeaderFromStringType;
+ TypeHandler.addStatement(methodBuilder, p, handler);
+
+ } else if (handler.equals(TypeHandler.StringType)) {
+ handler = TypeHandler.HeaderStringType;
+ TypeHandler.addStatement(methodBuilder, p, handler);
+
+ } else if (handler.equals(TypeHandler.ValueOfType)) {
+ handler = TypeHandler.HeaderValueOfType;
+ TypeHandler.addStatement(methodBuilder, p, handler);
+
+ } else if (handler.equals(TypeHandler.FromStringType)) {
+ handler = TypeHandler.HeaderFromStringType;
+ TypeHandler.addStatement(methodBuilder, p, handler);
+ } else {
+ handler = TypeHandler.HeaderStringType;
+
+ TypeHandler.addStatement(methodBuilder, p, handler);
+ }
+
+ } else {
+ BeanParam beanParam = p.getAnnotation(BeanParam.class);
+
+ boolean isBeanParameter = beanParam != null;
+
+ TypeHandler t = TypeHandler.forType(type, isBeanParameter);
+
+ log.debug("beanParam handler: " + t);
+
+ if (t.equals(TypeHandler.OptionalModelType) || t.equals(TypeHandler.ModelType)) {
+ String interfaceType = parameterizedLiteralsNameMap.get(type);
+
+ String typeName = type.getTypeName();
+
+ if (typeName.contains("$")) {
+ typeName = typeName.replace("$", ".");
+ }
+
+ String pType = interfaceType != null ? interfaceType + "TypeReference" : typeName + ".class";
+
+ methodBuilder.addStatement(t.statement, type, p.getName(), pType);
+
+ } else if (t.equals(TypeHandler.BeanListFromStringType) || t.equals(TypeHandler.BeanListValueOfType)) {
+ String interfaceType = parameterizedLiteralsNameMap.get(type);
+
+ String typeName = type.getTypeName();
+
+ if (typeName.contains("$")) {
+ typeName = typeName.replace("$", ".");
+ }
+
+ String pType = interfaceType != null ? interfaceType + "TypeReference" : typeName + ".class";
+
+ methodBuilder.addStatement(t.statement, type, p.getName(), pType);
+
+ } else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.OptionalValueOfType)) {
+
+ TypeHandler.addStatement(methodBuilder, p);
+ } else if (t.equals(TypeHandler.QueryOptionalListFromStringType)
+ || t.equals(TypeHandler.QueryOptionalListValueOfType)
+ || t.equals(TypeHandler.QueryOptionalSetValueOfType)
+ || t.equals(TypeHandler.QueryOptionalSetFromStringType)) {
+ ParameterizedType pType = (ParameterizedType) type;
+
+ if (type instanceof ParameterizedType) {
+ pType = (ParameterizedType) type;
+ type = pType.getActualTypeArguments()[0];
+ }
+
+ Class> erasedType = (Class>) extractErasedType(type);
+
+ methodBuilder.addStatement(t.statement, pType, p.getName(), p.getName(), erasedType);
+
+ } else if (t.equals(TypeHandler.OptionalBeanListFromStringType) || t.equals(TypeHandler.OptionalBeanListValueOfType)) {
+ ParameterizedType pType = (ParameterizedType) type;
+
+ if (type instanceof ParameterizedType) {
+ pType = (ParameterizedType) type;
+ type = pType.getActualTypeArguments()[0];
+ }
+
+ Class> erasedType = (Class>) extractErasedType(type);
+
+ try {
+
+ methodBuilder.addStatement(t.statement, pType, p.getName(), p.getName(), erasedType);
+
+ } catch (Exception e) {
+ log.error("method builder: \nstatement: " + t.statement + "\npType: " + pType + "\np.name(): " + p.getName() + "\nerasedType: " + erasedType);
+ }
+
+ } else {
+ TypeHandler.addStatement(methodBuilder, p);
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+
+ });
+
+ methodBuilder.addCode("$L", "\n");
+
+ CodeBlock.Builder functionBlockBuilder = CodeBlock.builder();
+
+ String controllerMethodArgs = Arrays.stream(m.getParameters()).map(Parameter::getName).collect(Collectors.joining(","));
+
+ if (!m.getReturnType().toString().equalsIgnoreCase("void")) {
+ if (m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage")
+ || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture")) {
+ Type futureType = m.getGenericReturnType();
+
+ functionBlockBuilder.add("$T $L = $L.$L($L);", futureType, "response", controllerName, m.getName(), controllerMethodArgs);
+
+ } else {
+ functionBlockBuilder.add("$T $L = $L.$L($L);", m.getGenericReturnType(), "response", controllerName, m.getName(), controllerMethodArgs);
+ }
+
+ methodBuilder.addCode(functionBlockBuilder.build());
+
+ methodBuilder.addCode("$L", "\n");
+
+ if (m.getReturnType().equals(ServerResponse.class)) {
+ methodBuilder.addStatement("$L.send(this,$L)", "response", "exchange");
+
+ } else if (m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage")
+ || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture")) {
+ String postProcess = ".";
+
+ if (!producesContentType.contains(",")) {
+ if (producesContentType.contains(MediaType.APPLICATION_JSON)) {
+ postProcess = ".applicationJson().";
+ } else if (producesContentType.contains(MediaType.APPLICATION_XML)) {
+ postProcess = ".applicationXml().";
+ } else if (producesContentType.contains(MediaType.TEXT_HTML)) {
+ postProcess = ".textHtml().";
+ }
+ }
+
+ methodBuilder.addCode(
+ "$L.thenAcceptAsync( r -> r" + postProcess + "send(this,$L), io.undertow.util.SameThreadExecutor.INSTANCE )\n\t.exceptionally( ex -> ",
+ "response", "exchange");
+ methodBuilder.beginControlFlow("", "");
+ methodBuilder.addCode("\t\tthrow new java.util.concurrent.CompletionException(ex);\n\t");
+ methodBuilder.endControlFlow(")", "");
+ } else {
+
+ methodBuilder.addStatement("exchange.getResponseHeaders().put($T.CONTENT_TYPE, $S)", Headers.class, producesContentType);
+
+ if (m.getReturnType().equals(String.class)) {
+ methodBuilder.addStatement("exchange.getResponseHeaders().send($L)", "response");
+ } else {
+ methodBuilder.addStatement("exchange.getResponseSender().send($L.toString())", "response");
+ }
+
+ }
+
+
+ } else {
+
+ functionBlockBuilder.add("$L.$L($L);", controllerName, m.getName(), controllerMethodArgs);
+
+ methodBuilder.addCode(functionBlockBuilder.build());
+
+ methodBuilder.addCode("$L", "\n");
+
+
+ }
+
+ if (isBlocking) {
+ methodBuilder.endControlFlow("catch ($T e) { \n\texchange.putAttachment(io.sinistral.proteus.server.handlers.ServerDefaultResponseListener.EXCEPTION, e);\n\texchange.endExchange();\n}", Exception.class);
+ methodBuilder.endControlFlow(")", "");
+
+ }
+
+ handlerClassBuilder.addMethod(methodBuilder.build());
+
+
+ FieldSpec handlerField = FieldSpec.builder(httpHandlerClass, handlerName, Modifier.FINAL).initializer("$L", handlerClassBuilder.build()).build();
+
+ initBuilder.addCode("$L\n", handlerField.toString());
+
+ Optional wrapAnnotation = Optional.ofNullable(m.getAnnotation(io.sinistral.proteus.annotations.Chain.class));
+
+ /*
+ * Authorization
+ */
+
+ List securityDefinitions = new ArrayList<>();
+
+ /*
+ * @TODO wrap blocking in BlockingHandler
+ */
+
+ if (Optional.ofNullable(m.getAnnotation(Path.class)).isPresent()) {
+ SecurityRequirement securityRequirementAnnotation = m.getAnnotation(SecurityRequirement.class);
+
+ if (securityRequirementAnnotation != null) {
+ String securityRequirement = securityRequirementAnnotation.name();
+
+ securityDefinitions.add(securityRequirement);
+ }
+
+ }
+
+ if (securityDefinitions.isEmpty()) {
+ securityDefinitions.addAll(typeLevelSecurityDefinitions);
+ }
+
+ if (isBlocking && isDebug) {
+ handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + ")))";
+ } else if (isBlocking) {
+ handlerName = "new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + "))";
- String typeName = type.getTypeName();
+ } else if (isDebug) {
+ handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(" + handlerName + ")";
- if (typeName.contains("$"))
- {
- typeName = typeName.replace("$", ".");
- }
+ }
+
+ if (wrapAnnotation.isPresent() || typeLevelHandlerWrapperMap.size() > 0 || securityDefinitions.size() > 0) {
+ initBuilder.addStatement("currentHandler = $L", handlerName);
+
+ if (wrapAnnotation.isPresent()) {
+ io.sinistral.proteus.annotations.Chain w = wrapAnnotation.get();
+
+ Class extends HandlerWrapper>[] wrapperClasses = w.value();
+
+ for (Class extends HandlerWrapper> wrapperClass : wrapperClasses) {
+ String wrapperName = typeLevelHandlerWrapperMap.get(wrapperClass);
+
+ if (wrapperName == null) {
+ wrapperName = String.format("%s_%d", generateFieldName(wrapperClass.getCanonicalName()), handlerWrapperIndex++);
+
+ initBuilder.addStatement("final $T $L = new $T()", wrapperClass, wrapperName, wrapperClass);
+ }
+
+ initBuilder.addStatement("currentHandler = $L.wrap($L)", wrapperName, "currentHandler");
+ }
+ }
+
+ for (Class extends HandlerWrapper> wrapperClass : typeLevelHandlerWrapperMap.keySet()) {
+ String wrapperName = typeLevelHandlerWrapperMap.get(wrapperClass);
+ initBuilder.addStatement("currentHandler = $L.wrap($L)", wrapperName, "currentHandler");
+ }
+
+ for (String securityDefinitionName : securityDefinitions) {
+ initBuilder.addStatement("currentHandler = registeredHandlerWrappers.get($S).wrap($L)", securityDefinitionName, "currentHandler");
+ }
+
+ initBuilder.addStatement("$L.add(io.undertow.util.Methods.$L,$S,$L)", "router", httpMethod, methodPath, "currentHandler");
+ } else {
+ initBuilder.addStatement("$L.add(io.undertow.util.Methods.$L,$S,$L)", "router", httpMethod, methodPath, handlerName);
+ }
+
+ initBuilder.addCode("$L", "\n");
+
+ registeredEndpoints.add(endpointInfo);
+
+ }
+
+ initBuilder.addCode("$Lreturn router;\n", "\n");
+
+ typeBuilder.addMethod(initBuilder.build());
+
+ }
+
+ /**
+ * @return the packageName
+ */
+ public String getPackageName() {
+ return packageName;
+ }
+
+ /**
+ * @param packageName
+ * the packageName to set
+ */
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ /**
+ * @return the className
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * @param className
+ * the className to set
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ protected static ArrayList getClassNamesFromPackage(String packageName) throws Exception {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ URL packageURL;
+ ArrayList names = new ArrayList<>();
+
+ packageName = packageName.replace(".", "/");
+ packageURL = classLoader.getResource(packageName);
+
+ assert packageURL != null;
+ URI uri = new URI(packageURL.toString());
+ File folder = new File(uri.getPath());
+ // won't work with path which contains blank (%20)
+ // File folder = new File(packageURL.getFile());
+ File[] contenuti = folder.listFiles();
+ String entryName;
+ assert contenuti != null;
+ for (File actual : contenuti) {
+ if (actual.isDirectory()) {
+ continue;
+ }
+
+ entryName = actual.getName();
+ entryName = entryName.substring(0, entryName.lastIndexOf('.'));
+ names.add(entryName);
+ }
- String pType = interfaceType != null ? interfaceType + "TypeReference" : typeName + ".class";
+ return names;
+ }
- methodBuilder.addStatement(t.statement, type, p.getName(), pType);
-
- }
- else if (t.equals(TypeHandler.OptionalFromStringType) || t.equals(TypeHandler.OptionalValueOfType))
- {
-
- TypeHandler.addStatement(methodBuilder, p);
- }
- else if (t.equals(TypeHandler.QueryOptionalListFromStringType)
- || t.equals(TypeHandler.QueryOptionalListValueOfType)
- || t.equals(TypeHandler.QueryOptionalSetValueOfType)
- || t.equals(TypeHandler.QueryOptionalSetFromStringType))
- {
- ParameterizedType pType = (ParameterizedType) type;
-
- if (type instanceof ParameterizedType)
- {
- pType = (ParameterizedType) type;
- type = pType.getActualTypeArguments()[0];
- }
-
- Class> erasedType = (Class>) extractErasedType(type);
-
- methodBuilder.addStatement(t.statement, pType, p.getName(), p.getName(), erasedType);
-
- }
- else if (t.equals(TypeHandler.OptionalBeanListFromStringType) || t.equals(TypeHandler.OptionalBeanListValueOfType))
- {
- ParameterizedType pType = (ParameterizedType) type;
-
- if (type instanceof ParameterizedType)
- {
- pType = (ParameterizedType) type;
- type = pType.getActualTypeArguments()[0];
- }
-
- Class> erasedType = (Class>) extractErasedType(type);
-
- try
- {
-
- methodBuilder.addStatement(t.statement, pType, p.getName(), p.getName(), erasedType);
-
- } catch (Exception e)
- {
- log.error("method builder: \nstatement: " + t.statement + "\npType: " + pType + "\np.name(): " + p.getName() + "\nerasedType: " + erasedType);
- }
-
- }
- else
- {
- TypeHandler.addStatement(methodBuilder, p);
- }
- }
- }
-
- } catch (Exception e)
- {
- log.error(e.getMessage(), e);
- }
-
- });
+ protected static Set> getApiClasses(String basePath, Predicate pathPredicate) throws Exception {
- methodBuilder.addCode("$L", "\n");
+ Reflections ref = new Reflections(basePath);
+ Stream> stream = ref.getTypesAnnotatedWith(Path.class).stream();
- CodeBlock.Builder functionBlockBuilder = CodeBlock.builder();
+ if (pathPredicate != null) {
+ stream = stream.filter(clazz ->
+ {
- String controllerMethodArgs = Arrays.stream(m.getParameters()).map(Parameter::getName).collect(Collectors.joining(","));
+ Path annotation = clazz.getDeclaredAnnotation(Path.class);
- if (!m.getReturnType().toString().equalsIgnoreCase("void"))
- {
- if (m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage")
- || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture"))
- {
- Type futureType = m.getGenericReturnType();
+ return annotation != null && pathPredicate.test(annotation.value());
- functionBlockBuilder.add("$T $L = $L.$L($L);", futureType, "response", controllerName, m.getName(), controllerMethodArgs);
+ });
+ }
- }
- else
- {
- functionBlockBuilder.add("$T $L = $L.$L($L);", m.getGenericReturnType(), "response", controllerName, m.getName(), controllerMethodArgs);
- }
-
- methodBuilder.addCode(functionBlockBuilder.build());
-
- methodBuilder.addCode("$L", "\n");
-
- if (m.getReturnType().equals(ServerResponse.class))
- {
- methodBuilder.addStatement("$L.send(this,$L)", "response", "exchange");
-
- }
- else if (m.getReturnType().getTypeName().contains("java.util.concurrent.CompletionStage")
- || m.getReturnType().getTypeName().contains("java.util.concurrent.CompletableFuture"))
- {
- String postProcess = ".";
-
- if (!producesContentType.contains(","))
- {
- if (producesContentType.contains(MediaType.APPLICATION_JSON))
- {
- postProcess = ".applicationJson().";
- }
- else if (producesContentType.contains(MediaType.APPLICATION_XML))
- {
- postProcess = ".applicationXml().";
- }
- else if (producesContentType.contains(MediaType.TEXT_HTML))
- {
- postProcess = ".textHtml().";
- }
- }
-
- methodBuilder.addCode(
- "$L.thenAcceptAsync( r -> r" + postProcess + "send(this,$L), io.undertow.util.SameThreadExecutor.INSTANCE )\n\t.exceptionally( ex -> ",
- "response", "exchange");
- methodBuilder.beginControlFlow("", "");
- methodBuilder.addCode("\t\tthrow new java.util.concurrent.CompletionException(ex);\n\t");
- methodBuilder.endControlFlow(")", "");
- }
- else
- {
-
- methodBuilder.addStatement("exchange.getResponseHeaders().put($T.CONTENT_TYPE, $S)", Headers.class, producesContentType);
-
- if (m.getReturnType().equals(String.class))
- {
- methodBuilder.addStatement("exchange.getResponseHeaders().send($L)", "response");
- }
- else
- {
- methodBuilder.addStatement("exchange.getResponseSender().send($L.toString())", "response");
- }
-
- }
-
-
- }
- else
- {
-
- functionBlockBuilder.add("$L.$L($L);", controllerName, m.getName(), controllerMethodArgs);
-
- methodBuilder.addCode(functionBlockBuilder.build());
-
- methodBuilder.addCode("$L", "\n");
-
-
- }
-
- if(isBlocking)
- {
- methodBuilder.endControlFlow("catch ($T e) { \n\texchange.putAttachment(io.sinistral.proteus.server.handlers.ServerDefaultResponseListener.EXCEPTION, e);\n\texchange.endExchange();\n}", Exception.class);
- methodBuilder.endControlFlow(")", "");
-
- }
-
- handlerClassBuilder.addMethod(methodBuilder.build());
+ return stream.collect(Collectors.toSet());
+ }
- FieldSpec handlerField = FieldSpec.builder(httpHandlerClass, handlerName, Modifier.FINAL).initializer("$L", handlerClassBuilder.build()).build();
+ protected static Type extractErasedType(Type type) {
+ String typeName = type.getTypeName();
- initBuilder.addCode("$L\n", handlerField.toString());
+ Matcher matcher = TYPE_NAME_PATTERN.matcher(typeName);
- Optional wrapAnnotation = Optional.ofNullable(m.getAnnotation(io.sinistral.proteus.annotations.Chain.class));
-
- /*
- * Authorization
- */
-
- List securityDefinitions = new ArrayList<>();
-
- /*
- * @TODO wrap blocking in BlockingHandler
- */
-
- if (Optional.ofNullable(m.getAnnotation(Path.class)).isPresent())
- {
- SecurityRequirement securityRequirementAnnotation = m.getAnnotation(SecurityRequirement.class);
-
- if(securityRequirementAnnotation != null)
- {
- String securityRequirement = securityRequirementAnnotation.name();
-
- securityDefinitions.add(securityRequirement);
- }
-
- }
-
- if (securityDefinitions.isEmpty())
- {
- securityDefinitions.addAll(typeLevelSecurityDefinitions);
- }
-
- if (isBlocking && isDebug)
- {
- handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + ")))";
- }
- else if( isBlocking )
- {
- handlerName = "new io.undertow.server.handlers.BlockingHandler(new io.undertow.server.handlers.RequestBufferingHandler.Wrapper(8).wrap(" + handlerName + "))";
-
- }
- else if( isDebug )
- {
- handlerName = "new io.undertow.server.handlers.RequestDumpingHandler(" + handlerName + ")";
-
- }
-
- if (wrapAnnotation.isPresent() || typeLevelHandlerWrapperMap.size() > 0 || securityDefinitions.size() > 0)
- {
- initBuilder.addStatement("currentHandler = $L", handlerName);
-
- if (wrapAnnotation.isPresent())
- {
- io.sinistral.proteus.annotations.Chain w = wrapAnnotation.get();
-
- Class extends HandlerWrapper>[] wrapperClasses = w.value();
-
- for(Class extends HandlerWrapper> wrapperClass : wrapperClasses)
- {
- String wrapperName = typeLevelHandlerWrapperMap.get(wrapperClass);
-
- if (wrapperName == null)
- {
- wrapperName = String.format("%s_%d",generateFieldName(wrapperClass.getCanonicalName()),handlerWrapperIndex++) ;
-
- initBuilder.addStatement("final $T $L = new $T()", wrapperClass, wrapperName, wrapperClass);
- }
-
- initBuilder.addStatement("currentHandler = $L.wrap($L)", wrapperName, "currentHandler");
- }
- }
-
- for (Class extends HandlerWrapper> wrapperClass : typeLevelHandlerWrapperMap.keySet())
- {
- String wrapperName = typeLevelHandlerWrapperMap.get(wrapperClass);
- initBuilder.addStatement("currentHandler = $L.wrap($L)", wrapperName, "currentHandler");
- }
-
- for (String securityDefinitionName : securityDefinitions)
- {
- initBuilder.addStatement("currentHandler = registeredHandlerWrappers.get($S).wrap($L)", securityDefinitionName, "currentHandler");
- }
-
- initBuilder.addStatement("$L.add(io.undertow.util.Methods.$L,$S,$L)", "router", httpMethod, methodPath, "currentHandler");
- }
- else
- {
- initBuilder.addStatement("$L.add(io.undertow.util.Methods.$L,$S,$L)", "router", httpMethod, methodPath, handlerName);
- }
-
- initBuilder.addCode("$L", "\n");
-
- registeredEndpoints.add(endpointInfo);
-
- }
-
- initBuilder.addCode("$Lreturn router;\n", "\n");
-
- typeBuilder.addMethod(initBuilder.build());
-
- }
-
- /**
- * @return the packageName
- */
- public String getPackageName()
- {
- return packageName;
- }
-
- /**
- * @param packageName
- * the packageName to set
- */
- public void setPackageName(String packageName)
- {
- this.packageName = packageName;
- }
-
- /**
- * @return the className
- */
- public String getClassName()
- {
- return className;
- }
-
- /**
- * @param className
- * the className to set
- */
- public void setClassName(String className)
- {
- this.className = className;
- }
-
- protected static ArrayList getClassNamesFromPackage(String packageName) throws Exception
- {
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- URL packageURL;
- ArrayList names = new ArrayList<>();
-
- packageName = packageName.replace(".", "/");
- packageURL = classLoader.getResource(packageName);
-
- assert packageURL != null;
- URI uri = new URI(packageURL.toString());
- File folder = new File(uri.getPath());
- // won't work with path which contains blank (%20)
- // File folder = new File(packageURL.getFile());
- File[] contenuti = folder.listFiles();
- String entryName;
- assert contenuti != null;
- for (File actual : contenuti)
- {
- if (actual.isDirectory())
- {
- continue;
- }
-
- entryName = actual.getName();
- entryName = entryName.substring(0, entryName.lastIndexOf('.'));
- names.add(entryName);
- }
-
- return names;
- }
-
- protected static Set> getApiClasses(String basePath, Predicate pathPredicate) throws Exception
- {
-
- Reflections ref = new Reflections(basePath);
- Stream> stream = ref.getTypesAnnotatedWith(Path.class).stream();
-
- if (pathPredicate != null)
- {
- stream = stream.filter(clazz ->
- {
-
- Path annotation = clazz.getDeclaredAnnotation(Path.class);
-
- return annotation != null && pathPredicate.test(annotation.value());
-
- });
- }
-
- return stream.collect(Collectors.toSet());
-
- }
-
- protected static Type extractErasedType(Type type)
- {
- String typeName = type.getTypeName();
-
- Matcher matcher = TYPE_NAME_PATTERN.matcher(typeName);
-
- if (matcher.find())
- {
-
- int matches = matcher.groupCount();
-
- if (matches == 2)
- {
-
- String erasedType = matcher.group(2);
-
- String clearDollarType = erasedType.replaceAll("\\$", ".");
-
- try
- {
- Class> clazz = Class.forName(clearDollarType);
- return clazz;
-
- } catch (Exception e1)
- {
- try
- {
- Class> clazz = Class.forName(erasedType);
+ if (matcher.find()) {
- return clazz;
-
- } catch (Exception e2)
- {
- return type;
- }
- }
+ int matches = matcher.groupCount();
- }
- else if (matches > 2)
- {
- String erasedType = matcher.group(3);
+ if (matches == 2) {
- String clearDollarType = erasedType.replaceAll("\\$", ".");
+ String erasedType = matcher.group(2);
- try
- {
- return Class.forName(clearDollarType);
- } catch (Exception e1)
- {
- try
- {
- return Class.forName(erasedType);
- } catch (Exception e2)
- {
- return type;
- }
- }
- }
- }
+ String clearDollarType = erasedType.replaceAll("\\$", ".");
- return null;
- }
+ try {
+ Class> clazz = Class.forName(clearDollarType);
+ return clazz;
- protected static String typeReferenceNameForParameterizedType(Type type)
- {
+ } catch (Exception e1) {
+ try {
+ Class> clazz = Class.forName(erasedType);
- String typeName = type.getTypeName();
+ return clazz;
- if (typeName.contains("Optional"))
- {
- log.warn("For an optional named: " + typeName);
- }
+ } catch (Exception e2) {
+ return type;
+ }
+ }
- Matcher matcher = TYPE_NAME_PATTERN.matcher(typeName);
+ } else if (matches > 2) {
+ String erasedType = matcher.group(3);
- if (matcher.find())
- {
+ String clearDollarType = erasedType.replaceAll("\\$", ".");
- int matches = matcher.groupCount();
+ try {
+ return Class.forName(clearDollarType);
+ } catch (Exception e1) {
+ try {
+ return Class.forName(erasedType);
+ } catch (Exception e2) {
+ return type;
+ }
+ }
+ }
+ }
- if (matches == 2)
- {
- String genericInterface = matcher.group(1);
- String erasedType = matcher.group(2).replaceAll("\\$", ".");
+ return null;
+ }
- String[] genericParts = genericInterface.split("\\.");
- String[] erasedParts = erasedType.split("\\.");
+ protected static String typeReferenceNameForParameterizedType(Type type) {
- String genericTypeName = genericParts[genericParts.length - 1];
- String erasedTypeName;
+ String typeName = type.getTypeName();
- if (erasedParts.length > 1)
- {
- erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
- }
- else
- {
- erasedTypeName = erasedParts[0];
- }
+ if (typeName.contains("Optional")) {
+ log.warn("For an optional named: " + typeName);
+ }
- typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName);
+ Matcher matcher = TYPE_NAME_PATTERN.matcher(typeName);
- return typeName;
- }
+ if (matcher.find()) {
- }
+ int matches = matcher.groupCount();
- matcher = CONCURRENT_TYPE_NAME_PATTERN.matcher(typeName);
+ if (matches == 2) {
+ String genericInterface = matcher.group(1);
+ String erasedType = matcher.group(2).replaceAll("\\$", ".");
- if (matcher.find())
- {
+ String[] genericParts = genericInterface.split("\\.");
+ String[] erasedParts = erasedType.split("\\.");
- int matches = matcher.groupCount();
+ String genericTypeName = genericParts[genericParts.length - 1];
+ String erasedTypeName;
- if (matches == 2)
- {
- String genericInterface = matcher.group(1);
- String erasedType = matcher.group(2).replaceAll("\\$", ".");
+ if (erasedParts.length > 1) {
+ erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
+ } else {
+ erasedTypeName = erasedParts[0];
+ }
- String[] genericParts = genericInterface.split("\\.");
- String[] erasedParts = erasedType.split("\\.");
+ typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName);
- String genericTypeName = genericParts[genericParts.length - 1];
- String erasedTypeName;
+ return typeName;
+ }
- if (erasedParts.length > 1)
- {
- erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
- }
- else
- {
- erasedTypeName = erasedParts[0];
- }
+ }
- typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName);
- return typeName;
- }
+ matcher = CONCURRENT_TYPE_NAME_PATTERN.matcher(typeName);
- }
+ if (matcher.find()) {
- return typeName;
- }
+ int matches = matcher.groupCount();
- protected static String typeReferenceNameForType(Type type)
- {
- String typeName = type.getTypeName();
+ if (matches == 2) {
+ String genericInterface = matcher.group(1);
+ String erasedType = matcher.group(2).replaceAll("\\$", ".");
- String[] erasedParts = typeName.split("\\.");
+ String[] genericParts = genericInterface.split("\\.");
+ String[] erasedParts = erasedType.split("\\.");
- String erasedTypeName;
+ String genericTypeName = genericParts[genericParts.length - 1];
+ String erasedTypeName;
+
+ if (erasedParts.length > 1) {
+ erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
+ } else {
+ erasedTypeName = erasedParts[0];
+ }
+
+ typeName = String.format("%s%s%s", Character.toLowerCase(erasedTypeName.charAt(0)), erasedTypeName.substring(1, erasedTypeName.length()), genericTypeName);
+ return typeName;
+ }
- if (erasedParts.length > 1)
- {
- erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
- }
- else
- {
- erasedTypeName = erasedParts[0];
- }
+ }
- typeName = generateFieldName(erasedTypeName);
+ return typeName;
+ }
- return typeName;
- }
+ protected static String typeReferenceNameForType(Type type) {
+ String typeName = type.getTypeName();
- protected static String generateFieldName(String name)
- {
- String[] parts = name.split("\\.");
+ String[] erasedParts = typeName.split("\\.");
- StringBuilder sb = new StringBuilder();
+ String erasedTypeName;
- for (int i = 0; i < parts.length; i++)
- {
- String part = parts[i];
+ if (erasedParts.length > 1) {
+ erasedTypeName = erasedParts[erasedParts.length - 2] + erasedParts[erasedParts.length - 1];
+ } else {
+ erasedTypeName = erasedParts[0];
+ }
- if (i == 0)
- {
- sb.append(String.format("%s%s", Character.toLowerCase(part.charAt(0)), part.substring(1, part.length())));
- }
- else
- {
- sb.append(String.format("%s%s", Character.toUpperCase(part.charAt(0)), part.substring(1, part.length())));
- }
- }
+ typeName = generateFieldName(erasedTypeName);
+
+ return typeName;
+ }
+
+ protected static String generateFieldName(String name) {
+ String[] parts = name.split("\\.");
+
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < parts.length; i++) {
+ String part = parts[i];
+
+ if (i == 0) {
+ sb.append(String.format("%s%s", Character.toLowerCase(part.charAt(0)), part.substring(1, part.length())));
+ } else {
+ sb.append(String.format("%s%s", Character.toUpperCase(part.charAt(0)), part.substring(1, part.length())));
+ }
+ }
- return sb.toString();
- }
+ return sb.toString();
+ }
- protected static void generateTypeReference(MethodSpec.Builder builder, Type type, String name)
- {
+ protected static void generateTypeReference(MethodSpec.Builder builder, Type type, String name) {
- builder.addCode(
- CodeBlock
- .of("\n\ncom.fasterxml.jackson.core.type.TypeReference<$T> $L = new com.fasterxml.jackson.core.type.TypeReference<$L>(){};\n\n", type, name, type));
+ builder.addCode(
+ CodeBlock
+ .of("\n\ncom.fasterxml.jackson.core.type.TypeReference<$T> $L = new com.fasterxml.jackson.core.type.TypeReference<$L>(){};\n\n", type, name, type));
- }
+ }
- protected static void generateParameterReference(MethodSpec.Builder builder, Class> clazz)
- {
+ protected static void generateParameterReference(MethodSpec.Builder builder, Class> clazz) {
- builder.addCode(CodeBlock.of("\n\nType $LType = $T.", clazz, clazz));
+ builder.addCode(CodeBlock.of("\n\nType $LType = $T.", clazz, clazz));
- }
+ }
- protected static boolean hasValueOfMethod(Class> clazz)
- {
- return Arrays.stream(clazz.getMethods()).anyMatch(m -> m.getName().equals("valueOf"));
- }
+ protected static boolean hasValueOfMethod(Class> clazz) {
+ return Arrays.stream(clazz.getMethods()).anyMatch(m -> m.getName().equals("valueOf"));
+ }
- protected static boolean hasFromStringMethod(Class> clazz)
- {
- return Arrays.stream(clazz.getMethods()).anyMatch(m -> m.getName().equals("fromString"));
- }
+ protected static boolean hasFromStringMethod(Class> clazz) {
+ return Arrays.stream(clazz.getMethods()).anyMatch(m -> m.getName().equals("fromString"));
+ }
}
diff --git a/src/main/java/io/sinistral/proteus/services/SwaggerService.java b/src/main/java/io/sinistral/proteus/services/SwaggerService.java
index 9933522..d27032e 100644
--- a/src/main/java/io/sinistral/proteus/services/SwaggerService.java
+++ b/src/main/java/io/sinistral/proteus/services/SwaggerService.java
@@ -620,10 +620,4 @@ protected void startUp() throws Exception
router.addAll(this.get());
}
- @Override
- protected void shutDown() throws Exception
- {
-
- }
-
}
diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf
index 32c068d..2ae43f3 100644
--- a/src/main/resources/reference.conf
+++ b/src/main/resources/reference.conf
@@ -185,7 +185,7 @@ undertow
# x AvailableProcessors
ioThreadsMultiplier = 2
- workerThreads = 200
+ workerThreadMultiplier = 8
bufferSize = 16k
directBuffers = true
}
diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf
index 22c446a..401fe14 100644
--- a/src/test/resources/application.conf
+++ b/src/test/resources/application.conf
@@ -176,7 +176,7 @@ undertow
enableHttp2=false
# x AvailableProcessors
ioThreadsMultiplier = 2
- workerThreads = 200
+ workerThreadMultiplier = 8
bufferSize = 16K
directBuffers = true
}