diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2781a64..3f432ba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,11 @@ Proteus Changelog.
## Unreleased
### No issue
+**Reduce logging.**
+
+
+[f6a8f1986b6d0da](https://github.com/noboomu/proteus/commit/f6a8f1986b6d0da) Joshua Bauer *2022-07-19 20:15:26*
+
**Tweak parameters.**
diff --git a/pom.xml b/pom.xml
index 008d2f9..02f80bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
3.0.0-M4
1.6.8
2.2.1
- 2.21ea82
+ 2.23ea0
UTF-8
${project.version}
0.10.2
diff --git a/proteus-core/conf/logback-test.xml b/proteus-core/conf/logback-test.xml
index 2fb2167..f934c40 100644
--- a/proteus-core/conf/logback-test.xml
+++ b/proteus-core/conf/logback-test.xml
@@ -19,6 +19,8 @@
+
+
diff --git a/proteus-core/conf/logback.xml b/proteus-core/conf/logback.xml
index dd8243f..b9f5278 100644
--- a/proteus-core/conf/logback.xml
+++ b/proteus-core/conf/logback.xml
@@ -27,6 +27,7 @@
+
diff --git a/proteus-core/src/main/java/io/sinistral/proteus/ProteusApplication.java b/proteus-core/src/main/java/io/sinistral/proteus/ProteusApplication.java
index 354097c..9319f69 100644
--- a/proteus-core/src/main/java/io/sinistral/proteus/ProteusApplication.java
+++ b/proteus-core/src/main/java/io/sinistral/proteus/ProteusApplication.java
@@ -30,10 +30,10 @@
import io.undertow.server.session.SessionAttachmentHandler;
import io.undertow.util.Headers;
import io.undertow.util.Methods;
+import net.openhft.compiler.CachedCompiler;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.xnio.Options;
import org.xnio.Xnio;
import org.xnio.XnioWorker;
@@ -61,6 +61,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -71,11 +72,13 @@
* @author jbauer
*/
-@SuppressWarnings("UnusedReturnValue")
+@SuppressWarnings({"UnusedReturnValue", "unchecked"})
public class ProteusApplication {
private static Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ProteusApplication.class.getCanonicalName());
+ private static final String TMP_DIRECTORY_NAME = "proteus_generated_classes";
+
@Inject
@Named("registeredControllers")
public Set> registeredControllers;
@@ -118,6 +121,7 @@ public class ProteusApplication {
public ProteusApplication()
{
+
injector = Guice.createInjector(new ConfigModule());
injector.injectMembers(this);
}
@@ -138,7 +142,7 @@ public ProteusApplication(URL configURL)
}
- public ProteusApplication(Module ... modules)
+ public ProteusApplication(Module... modules)
{
injector = Guice.createInjector(modules);
@@ -146,7 +150,6 @@ public ProteusApplication(Module ... modules)
}
-
public void start()
{
@@ -158,7 +161,6 @@ public void start()
final Thread mainThread = Thread.currentThread();
-
log.info("Installing modules: {}", registeredModules.stream().map(Class::getSimpleName).collect(Collectors.joining(",")));
Set modules = registeredModules.stream().map(mc -> injector.getInstance(mc)).collect(Collectors.toSet());
@@ -182,6 +184,7 @@ public void start()
serviceManager.addListener(new Listener() {
public void stopped()
{
+
log.info("Services are stopped");
}
@@ -191,7 +194,7 @@ public void healthy()
log.info("Services are healthy");
- startupDuration = Duration.between(startTime,Instant.now());
+ startupDuration = Duration.between(startTime, Instant.now());
for (ListenerInfo info : undertow.getListenerInfo())
{
@@ -213,7 +216,7 @@ public void failure(Service service)
log.error("Service failure: " + service);
- startupDuration = Duration.between(startTime,Instant.now());
+ startupDuration = Duration.between(startTime, Instant.now());
for (ListenerInfo info : undertow.getListenerInfo())
{
@@ -256,7 +259,6 @@ public void failure(Service service)
buildServer();
-
undertow.start();
Duration timeout = config.getDuration("application.services.timeout");
@@ -264,16 +266,14 @@ public void failure(Service service)
try
{
serviceManager.startAsync().awaitHealthy(timeout);
- } catch( TimeoutException e )
+ } catch (TimeoutException e)
{
- log.error("Failed start to services within {} minutes",timeout,e);
+ log.error("Failed start to services within {} minutes", timeout, e);
} catch (Exception e)
{
- log.error("Failed to start services",e);
+ log.error("Failed to start services", e);
}
-
-
this.running.set(true);
// serviceManager.startAsync();
@@ -317,6 +317,8 @@ public void buildServer()
CopyOnWriteArrayList>> routerClasses = new CopyOnWriteArrayList<>();
+ ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
log.info("Compiling route handlers...");
for (Class> controllerClass : registeredControllers)
@@ -327,19 +329,27 @@ public void buildServer()
try
{
- // log.debug("Generating {}...", controllerClass);
+ // log.debug("Generating {}...", controllerClass);
HandlerGenerator generator = new HandlerGenerator("io.sinistral.proteus.controllers.handlers", controllerClass);
injector.injectMembers(generator);
- // log.debug("Compiling {}...", controllerClass);
+ // log.debug("Compiling {}...", controllerClass);
+
+ try (CachedCompiler cachedCompiler = new CachedCompiler(null, getTemporaryDirectoryPath().toFile()))
+ {
+ final String source = generator.generateClassSource();
+ var routerClass = cachedCompiler.loadFromJava(generator.getCanonicalName(), source);
- Class extends Supplier> routerClass = generator.compileClass();
+ lock.writeLock().lock();
+
+ routerClasses.add(routerClass);
+
+ lock.writeLock().unlock();
+ }
- routerClasses.add(routerClass);
- // log.debug("Compiled {}", controllerClass);
} catch (Exception e)
{
@@ -359,7 +369,7 @@ public void buildServer()
log.error("Failed waiting for handlers to generate", e);
}
- log.debug("Compilation completed in {}", DurationFormatUtils.formatDurationHMS(Duration.between(compilationStartTime,Instant.now()).toMillis()));
+ log.debug("Compilation completed in {}", DurationFormatUtils.formatDurationHMS(Duration.between(compilationStartTime, Instant.now()).toMillis()));
for (Class extends Supplier> clazz : routerClasses)
{
@@ -400,8 +410,7 @@ public void buildServer()
handler = sessionAttachmentHandler;
}
-
- if(config.hasPath("undertow.gracefulShutdown") && config.getBoolean("undertow.gracefulShutdown"))
+ if (config.hasPath("undertow.gracefulShutdown") && config.getBoolean("undertow.gracefulShutdown"))
{
handler = new GracefulShutdownHandler(handler);
}
@@ -433,7 +442,6 @@ public void buildServer()
.setServerOption(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, config.getInt("undertow.server.maxBufferedRequestSize"))
.setHandler(handler);
-
if (config.getBoolean("undertow.ssl.enabled"))
{
try
@@ -522,7 +530,7 @@ public ProteusApplication addDefaultRoutes(RoutingHandler router)
{
exchange.getResponseHeaders().add(Headers.CONTENT_TYPE, MediaType.TEXT_PLAIN);
- if(this.serviceManager.servicesByState().values().stream().allMatch(Service::isRunning))
+ if (this.serviceManager.servicesByState().values().stream().allMatch(Service::isRunning))
{
exchange.setStatusCode(200).getResponseSender().send("OK");
}
@@ -734,7 +742,7 @@ public void printStatus()
tableHeaders = Arrays.asList("Method", "Path", "Consumes", "Produces", "Controller");
tableRows = this.registeredEndpoints.stream().sorted().map(e ->
- Arrays.asList(e.getMethod().toString(), e.getPathTemplate(), String.format("[%s]", e.getConsumes()), String.format("[%s]", e.getProduces()), String.format("(%s.%s)", e.getControllerName(), e.getControllerMethod())))
+ Arrays.asList(e.getMethod().toString(), e.getPathTemplate(), String.format("[%s]", e.getConsumes()), String.format("[%s]", e.getProduces()), String.format("(%s.%s)", e.getControllerName(), e.getControllerMethod())))
.collect(Collectors.toList());
printer = new TablePrinter(tableHeaders, tableRows);
@@ -748,17 +756,33 @@ public void printStatus()
tableHeaders = Arrays.asList("Service", "State", "Startup Time");
tableRows = serviceStateMap.asMap().entrySet().stream().flatMap(e ->
- e.getValue().stream().map(s ->
- Arrays.asList(s.getClass().getSimpleName(), e.getKey().toString(), DurationFormatUtils.formatDurationHMS(serviceStartupTimeMap.get(s)))))
+ e.getValue().stream().map(s ->
+ Arrays.asList(s.getClass().getSimpleName(), e.getKey().toString(), DurationFormatUtils.formatDurationHMS(serviceStartupTimeMap.get(s)))))
.collect(Collectors.toList());
printer = new TablePrinter(tableHeaders, tableRows);
- sb.append(printer.toString()).append("\nListening On: " + this.ports).append("\nApplication Startup Time: ").append(DurationFormatUtils.formatDurationHMS(this.startupDuration.toMillis())).append( "\n");
+ sb.append(printer.toString()).append("\nListening On: " + this.ports).append("\nApplication Startup Time: ").append(DurationFormatUtils.formatDurationHMS(this.startupDuration.toMillis())).append("\n");
log.info(sb.toString());
}
+ protected java.nio.file.Path getTemporaryDirectoryPath() throws Exception
+ {
+
+ String tmpDirLocation = System.getProperty("java.io.tmpdir");
+ java.nio.file.Path tmpPath = Paths.get(tmpDirLocation);
+
+ try
+ {
+ return Files.createDirectory(tmpPath.resolve(TMP_DIRECTORY_NAME));
+
+ } catch (Exception e)
+ {
+ return tmpPath;
+ }
+
+ }
}
diff --git a/proteus-core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java b/proteus-core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java
index 10e59ef..d4f3ac7 100644
--- a/proteus-core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java
+++ b/proteus-core/src/main/java/io/sinistral/proteus/modules/JacksonModule.java
@@ -7,7 +7,9 @@
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+@Singleton
public class JacksonModule extends AbstractModule
{
@Override
diff --git a/proteus-core/src/main/java/io/sinistral/proteus/modules/XmlModule.java b/proteus-core/src/main/java/io/sinistral/proteus/modules/XmlModule.java
index 8381607..65df682 100644
--- a/proteus-core/src/main/java/io/sinistral/proteus/modules/XmlModule.java
+++ b/proteus-core/src/main/java/io/sinistral/proteus/modules/XmlModule.java
@@ -12,10 +12,12 @@
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
+@Singleton
public class XmlModule extends AbstractModule {
@Override
diff --git a/proteus-core/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java b/proteus-core/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
index 9ab0fa6..a899784 100644
--- a/proteus-core/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
+++ b/proteus-core/src/main/java/io/sinistral/proteus/server/handlers/HandlerGenerator.java
@@ -92,7 +92,6 @@ public class HandlerGenerator {
private static final Pattern CONCURRENT_TYPE_NAME_PATTERN = Pattern.compile("(java\\.util\\.concurrent\\.[A-Za-z]+)<([^>]+)", Pattern.DOTALL | Pattern.UNIX_LINES);
- private static final String TMP_DIRECTORY_NAME = "proteus_generated_classes";
private static java.nio.file.Path TMP_DIRECTORY = null;
@@ -109,6 +108,8 @@ public enum StatementParameterType {
protected String packageName;
+ protected String canonicalName;
+
protected String className;
protected String sourceString;
@@ -129,7 +130,7 @@ public enum StatementParameterType {
protected Map, String> typeLevelHandlerWrapperMap = new LinkedHashMap<>();
- final Map> typeTokenMap = new ConcurrentHashMap<>();
+ final Map> typeTokenMap = new ConcurrentHashMap<>();
/**
* Create a new {@code HandlerGenerator} instance used to generate a
@@ -144,48 +145,20 @@ public HandlerGenerator(String packageName, Class> controllerClass)
this.packageName = packageName;
this.controllerClass = controllerClass;
this.className = controllerClass.getSimpleName() + "RouteSupplier";
+ this.canonicalName = String.format("%s.%s", this.packageName, this.className);
}
- /**
- * Compiles the generated source into a new {@link Class}
- *
- * @return a new {@code Supplier} class
- */
- public Class compileClass() throws Exception
- {
-
- String source = null;
-
- try
- {
-
- if (TMP_DIRECTORY == null)
- {
- TMP_DIRECTORY = getTemporaryDirectoryPath();
- }
-
- source = this.generateClassSource();
-
- // log.debug("\n\nGenerated Class Source:\n\n{}", source);
-
- try (CachedCompiler cachedCompiler = new CachedCompiler(null, null))
- {
- return cachedCompiler.loadFromJava(packageName + "." + className, source);
- }
+ public String getCanonicalName() {
- } catch (Exception e)
- {
- log.error("Failed to compile {}\nSource:\n{}", packageName + "." + className, source, e);
- throw e;
- }
+ return canonicalName;
}
/**
* Generates the routing Java source code
*/
- protected String generateClassSource() throws Exception
+ public String generateClassSource() throws Exception
{
TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC)
@@ -239,27 +212,11 @@ protected String generateClassSource() throws Exception
javaFile.writeTo(sb);
- javaFile.writeToPath(TMP_DIRECTORY);
+ // javaFile.writeToPath(TMP_DIRECTORY);
- return sb.toString();
-
- }
-
- protected java.nio.file.Path getTemporaryDirectoryPath() throws Exception
- {
+ this.sourceString = sb.toString();
- String tmpDirLocation = System.getProperty("java.io.tmpdir");
-
- java.nio.file.Path tmpPath = Paths.get(tmpDirLocation);
-
- try
- {
- return Files.createDirectory(tmpPath.resolve(TMP_DIRECTORY_NAME));
-
- } catch (Exception e)
- {
- return tmpPath;
- }
+ return this.sourceString;
}
@@ -285,44 +242,40 @@ protected void addClassMethodHandlers(TypeSpec.Builder typeBuilder, Class> cla
.distinct().filter(t ->
{
-
TypeHandler handler = TypeHandler.forType(t);
return (handler.equals(TypeHandler.ModelType) || handler.equals(TypeHandler.OptionalModelType) || handler.equals(TypeHandler.NamedModelType) || handler.equals(TypeHandler.OptionalNamedModelType));
}).collect(Collectors.toMap(java.util.function.Function.identity(), ClassUtilities::typeReferenceNameForParameterizedType));
-
java.util.regex.Pattern internalTypesPattern = java.util.regex.Pattern.compile("concurrent|<");
- final Map> googleParameterTypeTokens = Arrays.stream(clazz.getDeclaredMethods())
- .filter(m -> m.getAnnotation(Path.class) != null)
- .flatMap(
- m -> Invokable.from(m).getParameters().stream())
- .filter(p -> internalTypesPattern.matcher(p.getType().getType().getTypeName()).find() )
- .distinct().collect(Collectors.toMap(p -> p.getType().toString(), com.google.common.reflect.Parameter::getType, (p1, p2) -> p1 ));
-
-
+ final Map> googleParameterTypeTokens = Arrays.stream(clazz.getDeclaredMethods())
+ .filter(m -> m.getAnnotation(Path.class) != null)
+ .flatMap(
+ m -> Invokable.from(m).getParameters().stream())
+ .filter(p -> internalTypesPattern.matcher(p.getType().getType().getTypeName()).find())
+ .distinct().collect(Collectors.toMap(p -> p.getType().toString(), com.google.common.reflect.Parameter::getType, (p1, p2) -> p1));
//log.info("googleParameterTypeTokens: {}",googleParameterTypeTokens);
- Arrays.stream(clazz.getDeclaredMethods())
+ Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> m.getAnnotation(Path.class) != null)
.forEach(m -> {
- Invokable,Object> invokable = Invokable.from(m);
+ Invokable, Object> invokable = Invokable.from(m);
List extends TypeToken>> parameterTokens = invokable.getParameters().stream().filter(p -> Objects.isNull(p.getAnnotation(BeanParam.class))).map(com.google.common.reflect.Parameter::getType).collect(Collectors.toList());
- // log.info("parameterTokens: {}",parameterTokens);
+ // log.info("parameterTokens: {}",parameterTokens);
parameterTokens.forEach(rt -> {
- // log.info("t:\n|{}|\n|{}|\n|{}|\ncached:\n|{}|",rt.getType(), rt.getRawType(), rt, typeTokenMap.get(rt.getType()));
- typeTokenMap.put(rt.getType(),rt);
+ // log.info("t:\n|{}|\n|{}|\n|{}|\ncached:\n|{}|",rt.getType(), rt.getRawType(), rt, typeTokenMap.get(rt.getType()));
+ typeTokenMap.put(rt.getType(), rt);
});
- // log.info("invokable: \ntype {}\n rawt {}\n hc {}\n params{}\n return type{}\n generic string {}\nog return type: {}",returnType.getType(),returnType.getRawType(),returnType.hashCode(),
+ // log.info("invokable: \ntype {}\n rawt {}\n hc {}\n params{}\n return type{}\n generic string {}\nog return type: {}",returnType.getType(),returnType.getRawType(),returnType.hashCode(),
// m.getParameters(),m.getReturnType(),m.getReturnType().toGenericString(),
// m.getReturnType());
- // typeTokenMap.put(m.getReturnType().getTypeName(),invokable.getReturnType());
+ // typeTokenMap.put(m.getReturnType().getTypeName(),invokable.getReturnType());
});
Arrays.stream(clazz.getDeclaredMethods())
@@ -483,7 +436,7 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
continue;
}
- // log.debug("\n\nScanning method: {}\n", m.getName());
+ // log.debug("\n\nScanning method: {}\n", m.getName());
EndpointInfo endpointInfo = new EndpointInfo();
@@ -631,9 +584,8 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
//
// TypeToken> token = invokable.getReturnType();
- // Object obj - MutableTypeToInstanceMap
- // log.error("parameterized: {} \ntoken: {}\ntoken type: {}", p.getParameterizedType(), token, token.getType());
-
+ // Object obj - MutableTypeToInstanceMap
+ // log.error("parameterized: {} \ntoken: {}\ntoken type: {}", p.getParameterizedType(), token, token.getType());
TypeHandler t = TypeHandler.forType(p.getParameterizedType(), isBeanParameter);
@@ -665,7 +617,7 @@ else if (t.equals(HttpServerExchange.class) || t.equals(ServerRequest.class))
List parameters = Arrays.stream(m.getParameters()).collect(Collectors.toList());
- // log.debug("parameterizedLiteralsNameMap: " + parameterizedLiteralsNameMap);
+ // log.debug("parameterizedLiteralsNameMap: " + parameterizedLiteralsNameMap);
for (Parameter p : parameters)
{
diff --git a/proteus-openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java b/proteus-openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
index dedec6c..c00a2a5 100644
--- a/proteus-openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
+++ b/proteus-openapi/src/main/java/io/sinistral/proteus/openapi/services/OpenAPIService.java
@@ -58,6 +58,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ForkJoinPool;
import java.util.function.Supplier;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
@@ -313,6 +314,21 @@ protected void generateSpec() throws Exception
}
+ public OpenAPI getOpenApi() {
+
+ return openApi;
+ }
+
+ public String getYamlSpec() {
+
+ return yamlSpec;
+ }
+
+ public String getJsonSpec() {
+
+ return jsonSpec;
+ }
+
@Override
protected void startUp() throws Exception
{
@@ -321,7 +337,7 @@ protected void startUp() throws Exception
generateHTML();
- CompletableFuture.runAsync(() ->
+ ForkJoinPool.commonPool().execute(() ->
{
try
{
@@ -360,9 +376,18 @@ public RoutingHandler get()
router.add(HttpMethod.GET, yamlTemplatePath, (HttpServerExchange exchange) ->
{
+
+ String spec = getYamlSpec();
+
+ if(spec == null)
+ {
+ exchange.setStatusCode(404).setReasonPhrase("Spec has not yet been generated").endExchange();
+ return;
+ }
+
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, io.sinistral.proteus.protocol.MediaType.TEXT_YAML.contentType());
- exchange.getResponseSender().send(yamlSpec);
+ exchange.getResponseSender().send(spec);
});
this.registeredEndpoints.add(EndpointInfo.builder()
@@ -385,9 +410,17 @@ public RoutingHandler get()
router.add(HttpMethod.GET, jsonTemplatePath, (HttpServerExchange exchange) ->
{
+ final String spec = this.getJsonSpec();
+
+ if(spec == null)
+ {
+ exchange.setStatusCode(404).setReasonPhrase("Spec has not yet been generated").endExchange();
+ return;
+ }
+
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, io.sinistral.proteus.protocol.MediaType.JSON.contentType());
- exchange.getResponseSender().send(jsonSpec);
+ exchange.getResponseSender().send(spec);
});
this.registeredEndpoints.add(EndpointInfo.builder()