update datastructures to 5.2.3, remove settings wherever possible

This commit is contained in:
Jörg Prante 2025-03-12 13:45:22 +01:00
parent d4a8beaf65
commit be870d64ea
49 changed files with 205 additions and 172 deletions

View file

@ -18,7 +18,8 @@ test {
'--add-opens=java.base/java.nio=ALL-UNNAMED',
'--add-opens=java.base/java.util=ALL-UNNAMED'
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
systemProperty 'java.net.preferIPv6Addresses', 'true'
// avoid network unreachable on IPv4-only environments
systemProperty 'java.net.preferIPv6Addresses', 'false'
systemProperty 'io.netty.tryReflectionSetAccessible', 'false'
systemProperty 'io.netty.allocator.typ', 'pooled'
systemProperty 'io.netty.noUnsafe', 'true'

View file

@ -25,6 +25,8 @@ import org.xbib.net.http.client.netty.NettyHttpClientConfig;
import org.xbib.net.http.client.netty.secure.HttpsResponse;
import org.xbib.net.http.client.netty.secure.NettyHttpsClientConfig;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class Https1Test {
@ -193,7 +195,6 @@ class Https1Test {
.join();
logger.info("got result = " + result);
}
// TODO 15 sec timeout on closing event loop group, why?
}
@Test
@ -217,10 +218,11 @@ class Https1Test {
.addParameter("query", content.substring(0, 15))
.build(), stringFunction);
} catch (IOException e) {
logger.log(Level.WARNING, e.getMessage(), e);
return null;
logger.log(Level.SEVERE, e.getMessage(), e);
return null; // never reached
}
});
assertNotNull(completableFuture);
String result = completableFuture.join();
logger.info("got result = " + result);
}

View file

@ -81,8 +81,8 @@ public abstract class BaseInteraction implements Interaction {
/**
* Method for executing the request and respond in a completable future.
*
* @param request request
* @param supplier supplier
* @param request request, must not be null
* @param supplier supplier, must not be null
* @param <T> supplier result
* @return completable future
*/
@ -99,7 +99,7 @@ public abstract class BaseInteraction implements Interaction {
} else {
completableFuture.cancel(true);
}
get();
get(request.getTimeoutMillis(), TimeUnit.MILLISECONDS);
cancel();
});
request.setTimeoutListener(req -> completableFuture.completeExceptionally(new TimeoutException()));
@ -110,9 +110,8 @@ public abstract class BaseInteraction implements Interaction {
@Override
public void close() throws IOException {
logger.log(Level.FINE, "closing interaction " + this);
get();
//cancel();
logger.log(Level.FINE, "closing interaction " + this + " within 15 seconds");
get(15000L, TimeUnit.MILLISECONDS);
releaseChannel(channel, true);
if (future != null) {
future.complete(null);

View file

@ -26,14 +26,14 @@ public class J2HtmlServiceBuilder extends BaseHttpServiceBuilder {
}
@Override
public J2HtmlServiceBuilder setMethod(HttpMethod... httpMethod) {
super.setMethod(httpMethod);
public J2HtmlServiceBuilder addMethod(HttpMethod httpMethod) {
super.addMethod(httpMethod);
return this;
}
@Override
public J2HtmlServiceBuilder setHandler(HttpHandler... handler) {
super.setHandler(handler);
public J2HtmlServiceBuilder addHandler(HttpHandler handler) {
super.addHandler(handler);
return this;
}
@ -60,9 +60,9 @@ public class J2HtmlServiceBuilder extends BaseHttpServiceBuilder {
}
public J2HtmlService build() {
if (handlers == null) {
if (this.handlers == null) {
HttpHandler httpHandler = new J2HtmlResourceHandler(prefix, suffix, "index.java");
setHandler(httpHandler);
addHandler(httpHandler);
}
return new J2HtmlService(this);
}

View file

@ -1,6 +1,5 @@
package org.xbib.net.http.server.application.config;
import java.util.logging.Logger;
import org.xbib.config.ConfigLoader;
import org.xbib.config.ConfigParams;
import org.xbib.net.http.server.HttpRequest;
@ -12,19 +11,17 @@ import org.xbib.settings.Settings;
public class ConfigApplicationModule extends BaseApplicationModule {
private static final Logger logger = Logger.getLogger(ConfigApplicationModule.class.getName());
private final ConfigParams configParams;
private final ConfigLoader configLoader;
private final Settings settings;
public ConfigApplicationModule(Application application, String name, Settings settings) {
super(application, name, settings);
String profile = System.getProperty("application.profile");
public ConfigApplicationModule(Application application, String name) {
super(application, name);
String profile = application.getProfile();
if (profile == null) {
profile = "developer";
profile = "dev";
}
this.configParams = new ConfigParams()
.withDirectoryName(name)

View file

@ -3,5 +3,4 @@ dependencies {
api libs.datastructures.json.tiny
api libs.jdbc.query
api libs.jdbc.pool
implementation libs.settings.api
}

View file

@ -5,7 +5,6 @@ module org.xbib.net.http.server.application.database {
requires org.xbib.net.http;
requires org.xbib.net.http.server;
requires org.xbib.datastructures.tiny;
requires org.xbib.settings.api;
requires org.xbib.jdbc.query;
requires org.xbib.jdbc.pool;
}

View file

@ -13,15 +13,14 @@ import org.xbib.net.http.server.application.BaseApplicationModule;
import org.xbib.net.http.server.HttpRequest;
import org.xbib.net.http.server.route.HttpRouterContext;
import org.xbib.net.http.server.service.HttpService;
import org.xbib.settings.Settings;
import javax.sql.DataSource;
import java.util.Properties;
public class DatabaseApplicationModule extends BaseApplicationModule {
public DatabaseApplicationModule(Application application, String name, Settings settings) {
super(application, name, settings);
public DatabaseApplicationModule(Application application, String name) {
super(application, name);
}
@Override

View file

@ -1,4 +1,3 @@
dependencies {
api project(':net-http-server')
implementation libs.settings.api
}

View file

@ -2,6 +2,5 @@ module org.xbib.net.http.server.application.journal {
requires org.xbib.net;
requires org.xbib.net.http;
requires org.xbib.net.http.server;
requires org.xbib.settings.api;
requires java.logging;
}

View file

@ -6,10 +6,10 @@ import org.xbib.net.http.server.application.Application;
import org.xbib.net.http.server.application.BaseApplicationModule;
import org.xbib.net.http.server.route.HttpRouterContext;
import org.xbib.net.http.server.service.HttpService;
import org.xbib.settings.Settings;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -19,9 +19,10 @@ public class JournalApplicationModule extends BaseApplicationModule {
private final Journal journal;
public JournalApplicationModule(Application application, String name, Settings settings) throws IOException {
super(application, name, settings);
this.journal = new Journal(settings.get("application.journal", "/var/tmp/application/journal"));
public JournalApplicationModule(Application application, String name) throws IOException {
super(application, name);
String journalPath = Objects.requireNonNull(application.getAttributes().get(String.class, "application.journal", "/var/tmp/application/journal"));
this.journal = new Journal(journalPath);
}
@Override

View file

@ -122,7 +122,7 @@ public final class Bootstrap {
HttpService httpService = BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -149,7 +149,7 @@ public final class Bootstrap {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, "image/x-icon")
.body(NettyDataBufferFactory.getInstance().wrap(fromHex(hexFavIcon)))
@ -158,14 +158,14 @@ public final class Bootstrap {
.build())
.addService(BaseHttpService.builder()
.setPath("/webjars/**")
.setHandler(new ClassLoaderResourceHandler(Bootstrap.class.getClassLoader(), "META-INF/resources/", 24 + 2600))
.addHandler(new ClassLoaderResourceHandler(Bootstrap.class.getClassLoader(), "META-INF/resources/", 24 + 2600))
.build())
.addService(httpService)
.addService(GroovyTemplateService.builder()
.setTemplateName("index.gtpl")
.setSecurityDomain(securityDomain)
.setPath("glob:**")
.setHandler(new GroovyTemplateResourceHandler())
.addHandler(new GroovyTemplateResourceHandler())
.build())
.build())
.build();

View file

@ -139,7 +139,7 @@ public final class Bootstrap {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, "image/x-icon")
.body(NettyDataBufferFactory.getInstance().wrap(fromHex(hexFavIcon)))
@ -148,11 +148,11 @@ public final class Bootstrap {
.build())
.addService(BaseHttpService.builder()
.setPath("/webjars/**")
.setHandler(new ClassLoaderResourceHandler(Bootstrap.class.getClassLoader(), "META-INF/resources/", 24 * 3600))
.addHandler(new ClassLoaderResourceHandler(Bootstrap.class.getClassLoader(), "META-INF/resources/", 24 * 3600))
.build())
.addService(BaseHttpService.builder()
.setPath("/insecure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -170,7 +170,7 @@ public final class Bootstrap {
.addService(J2HtmlService.builder()
.setPath("glob:**")
.setSecurityDomain(securityDomain)
.setHandler(new MyResourceHandler())
.addHandler(new MyResourceHandler())
.build())
.build())
.build();

View file

@ -3,7 +3,7 @@ dependencies {
api libs.net.security
testImplementation project(':net-http-client-netty-secure')
testImplementation project(':net-http-netty-boringssl')
testImplementation libs.settings.datastructures.json
testImplementation testLibs.settings.datastructures.json
testImplementation libs.net.bouncycastle
}

View file

@ -58,12 +58,12 @@ public class NettyHttps2ServerMultiRequestLoadTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx ->
.addHandler(ctx ->
ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -59,11 +59,11 @@ public class NettyHttps2ServerTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -60,11 +60,11 @@ public class NettyHttpsServerMultiRequestLoadTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
logger.log(Level.INFO, "executing /secure");
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
@ -148,11 +148,11 @@ public class NettyHttpsServerMultiRequestLoadTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -64,12 +64,12 @@ public class NettyHttpsServerTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx ->
.addHandler(ctx ->
ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx ->
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -80,8 +80,8 @@ public class NettyHttpsServerTest {
" parameter = " + ctx.getRequest().getParameter().toString() +
" attributes = " + ctx.getAttributes() +
" local address = " + ctx.getRequest().getLocalAddress() +
" remote address = " + ctx.getRequest().getRemoteAddress());
})
" remote address = " + ctx.getRequest().getRemoteAddress())
)
.build())
.build())
.build();
@ -143,11 +143,11 @@ public class NettyHttpsServerTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx ->
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -158,8 +158,8 @@ public class NettyHttpsServerTest {
" parameter = " + ctx.getRequest().getParameter().toString() +
" attributes = " + ctx.getAttributes() +
" local address = " + ctx.getRequest().getLocalAddress() +
" remote address = " + ctx.getRequest().getRemoteAddress());
})
" remote address = " + ctx.getRequest().getRemoteAddress())
)
.build())
.build())
.build();
@ -220,11 +220,11 @@ public class NettyHttpsServerTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx ->
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -234,8 +234,8 @@ public class NettyHttpsServerTest {
" base URL = " + ctx.getRequest().getBaseURL() + " " +
ctx.getRequest().getParameter() + " " +
ctx.getRequest().getLocalAddress() + " " +
ctx.getRequest().getRemoteAddress());
})
ctx.getRequest().getRemoteAddress())
)
.build())
.build())
.build();

View file

@ -3,7 +3,7 @@ dependencies {
api libs.netty.codec.http2
testImplementation project(':net-http-client-netty')
testImplementation project(':net-http-template-groovy')
testImplementation libs.settings.datastructures.json
testImplementation testLibs.settings.datastructures.json
testImplementation libs.datastructures.json.tiny
}

View file

@ -52,7 +52,7 @@ public class NettyHttp2ServerMultiRequestLoadTest {
.setHttpAddress(httpAddress)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -50,7 +50,7 @@ public class NettyHttp2ServerTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -48,7 +48,7 @@ public class NettyHttpServerBodyTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
String body = ctx.getRequestBuilder().getBodyAsChars(StandardCharsets.UTF_8).toString();
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)

View file

@ -52,8 +52,8 @@ class NettyHttpServerByteOrderMarkTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/")
.setMethod(HttpMethod.POST)
.setHandler(ctx -> {
.addMethod(HttpMethod.POST)
.addHandler(ctx -> {
logger.log(Level.FINEST, "handler starting");
String content = ctx.getRequestBuilder().getBodyAsChars(StandardCharsets.UTF_8).toString();
logger.log(Level.FINEST, "got content = " + content);

View file

@ -54,7 +54,7 @@ public class NettyHttpServerFailureTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -59,8 +59,8 @@ public class NettyHttpServerFileUploadTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/")
.setMethod(HttpMethod.POST)
.setHandler(ctx -> {
.addMethod(HttpMethod.POST)
.addHandler(ctx -> {
HttpResponseStatus httpResponseStatus = HttpResponseStatus.NOT_FOUND;
List<org.xbib.net.http.server.Message> messages = ctx.getRequest().getMessages();
logger.log(Level.INFO, "messages = " + messages.size());
@ -155,8 +155,8 @@ public class NettyHttpServerFileUploadTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/")
.setMethod(HttpMethod.POST)
.setHandler(ctx -> {
.addMethod(HttpMethod.POST)
.addHandler(ctx -> {
HttpResponseStatus httpResponseStatus = HttpResponseStatus.NOT_FOUND;
List<org.xbib.net.http.server.Message> messages = ctx.getRequest().getMessages();
logger.log(Level.INFO, "messages = " + messages.size());

View file

@ -52,7 +52,7 @@ public class NettyHttpServerMultiRequestLoadTest {
.setHttpAddress(httpAddress)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -53,8 +53,8 @@ public class NettyHttpServerRequestTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath(url.getPath())
.setMethod(HttpMethod.GET)
.setHandler(ctx -> {
.addMethod(HttpMethod.GET)
.addHandler(ctx -> {
try {
String value = ctx.getRequest().getParameter().getAsString("value", Parameter.Domain.QUERY);
ctx.status(HttpResponseStatus.OK)

View file

@ -53,7 +53,7 @@ public class NettyHttpServerTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -36,7 +36,7 @@ public class NioHttpServerTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain1")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -51,7 +51,7 @@ public class NioHttpServerTest {
.setHttpAddress(httpAddress2)
.addService(BaseHttpService.builder()
.setPath("/domain2")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -67,7 +67,7 @@ public class NioHttpServerTest {
Executor executor = BaseExecutor.builder()
.build();
try(NioHttpServer server = NioHttpServer.builder()
try (NioHttpServer server = NioHttpServer.builder()
.setHttpServerConfig(new HttpServerConfig()
.setServerName("NioHttpServer", NioHttpServer.class.getPackage().getImplementationVendor())
.setNetworkClass(NetworkClass.SITE))

View file

@ -1,7 +1,7 @@
dependencies {
api project(':net-http-server-simple')
api libs.net.security
testImplementation libs.settings.datastructures.json
testImplementation testLibs.settings.datastructures.json
testImplementation libs.net.bouncycastle
}

View file

@ -48,11 +48,11 @@ public class SimpleHttpsServerTest {
.setHttpAddress(httpsAddress)
.addService(BaseHttpService.builder()
.setPath("/favicon.ico")
.setHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.addHandler(ctx -> ctx.status(HttpResponseStatus.NOT_FOUND))
.build())
.addService(BaseHttpService.builder()
.setPath("/secure")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -1,6 +1,6 @@
dependencies {
api project(':net-http-server')
testImplementation libs.settings.datastructures.json
testImplementation testLibs.settings.datastructures.json
}
test {

View file

@ -39,9 +39,9 @@ public class HttpRouterTest {
.addDomain(BaseHttpDomain.builder()
.setHttpAddress(httpAddress)
.addService(BaseHttpService.builder()
.setMethod(HttpMethod.DELETE)
.addMethod(HttpMethod.DELETE)
.setPath("/demo")
.setHandler(ctx -> {
.addHandler(ctx -> {
Logger.getAnonymousLogger().log(Level.INFO, "got request: " + ctx.getRequestBuilder().getRequestURI());
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)

View file

@ -36,7 +36,7 @@ public class SimpleHttpServerTest {
.setHttpAddress(httpAddress1)
.addService(BaseHttpService.builder()
.setPath("/domain1")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)
@ -48,14 +48,14 @@ public class SimpleHttpServerTest {
.build())
.addService(BaseHttpService.builder()
.setPath("/file1/*")
.setHandler(new FileResourceHandler())
.addHandler(new FileResourceHandler())
.build())
.build())
.addDomain(BaseHttpDomain.builder()
.setHttpAddress(httpAddress2)
.addService(BaseHttpService.builder()
.setPath("/domain2")
.setHandler(ctx -> {
.addHandler(ctx -> {
ctx.status(HttpResponseStatus.OK)
.setHeader(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN)
.charset(StandardCharsets.UTF_8)

View file

@ -3,6 +3,7 @@ dependencies {
implementation libs.datastructures.tiny
implementation libs.datastructures.json.tiny
implementation libs.settings.api
testImplementation testLibs.settings.datastructures
}
def moduleName = 'org.xbib.net.http.server.test'

View file

@ -3,6 +3,7 @@ module org.xbib.net.http.server {
requires java.logging;
requires java.naming;
requires java.sql;
requires org.xbib.datastructures.api;
requires org.xbib.datastructures.common;
requires org.xbib.datastructures.tiny;
requires org.xbib.datastructures.json.tiny;

View file

@ -11,9 +11,9 @@ public interface HttpServiceBuilder {
HttpServiceBuilder setPath(String path);
HttpServiceBuilder setMethod(HttpMethod... method);
HttpServiceBuilder addMethod(HttpMethod method);
HttpServiceBuilder setHandler(HttpHandler... handler);
HttpServiceBuilder addHandler(HttpHandler handler);
HttpServiceBuilder setParameterDefinition(ParameterDefinition... parameterDefinition);

View file

@ -57,8 +57,8 @@ public class BaseApplication implements Application {
protected BaseApplication(BaseApplicationBuilder builder) {
this.builder = builder;
this.attributes = newAttributes();
this.applicationModuleList = new ArrayList<>();
this.attributes = newAttributes();
this.httpResponseRenderer = newResponseRenderer();
}
@ -168,7 +168,7 @@ public class BaseApplication implements Application {
}
public String getSessionName() {
return "SESS_" + getProfile().toLowerCase(Locale.ROOT);
return "SESS_" + getProfile().toUpperCase(Locale.ROOT);
}
public String getSecret() {

View file

@ -4,7 +4,6 @@ import org.xbib.net.http.server.HttpRequest;
import org.xbib.net.http.server.route.HttpRouterContext;
import org.xbib.net.http.server.service.HttpService;
import org.xbib.net.http.server.session.Session;
import org.xbib.settings.Settings;
public abstract class BaseApplicationModule implements ApplicationModule {
@ -12,17 +11,14 @@ public abstract class BaseApplicationModule implements ApplicationModule {
protected final String name;
protected final Settings settings;
public BaseApplicationModule(Application application, String name, Settings settings) {
public BaseApplicationModule(Application application, String name) {
this.application = application;
this.name = name;
this.settings = settings;
}
@Override
public String getName() {
return name != null ? name : settings.get("name", "undefined");
return name;
}
@Override

View file

@ -0,0 +1,23 @@
package org.xbib.net.http.server.handler;
import org.xbib.net.http.HttpResponseStatus;
import org.xbib.net.http.server.HttpErrorHandler;
import org.xbib.net.http.server.route.HttpRouterContext;
import java.io.IOException;
import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE;
public class OkHandler implements HttpErrorHandler {
public OkHandler() {
}
@Override
public void handle(HttpRouterContext context) throws IOException {
context.status(HttpResponseStatus.OK)
.setHeader(CONTENT_TYPE, "text/plain; charset=utf-8")
.body("Hello world")
.done();
}
}

View file

@ -48,7 +48,7 @@ public class BaseHttpRouter implements HttpRouter {
private static final String PATH_SEPARATOR = "/";
private final Logger logger = Logger.getLogger(BaseHttpRouter.class.getName());
private static final Logger logger = Logger.getLogger(BaseHttpRouter.class.getName());
private final BaseHttpRouterBuilder builder;

View file

@ -88,31 +88,6 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder {
return this;
}
@Override
public HttpRouterBuilder fromSettings(Settings settings) {
fromSettings(settings, null);
return this;
}
@Override
public HttpRouterBuilder fromSettings(Settings settings,
Map<String, HttpSecurityDomain> securityDomainMap) {
// global prefix
if (settings.containsSetting("prefix")) {
setPrefix(settings.get("prefix"));
}
// global handlers
for (Map.Entry<String, Settings> entry : settings.getGroups("handler").entrySet()) {
String codeString = entry.getKey();
Settings handlerSettings = entry.getValue();
setHandler(Integer.parseInt(codeString), createHttpHandler(handlerSettings));
}
// handler domains
for (Map.Entry<String, Settings> entry : settings.getGroups("domain").entrySet()) {
addDomain(createHttpDomain(entry.getValue(), securityDomainMap));
}
return this;
}
@Override
public BaseHttpRouter build() {
if (domains.isEmpty()) {
@ -138,6 +113,31 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder {
return new BaseHttpRouter(this);
}
public HttpRouterBuilder fromSettings(Settings settings) {
fromSettings(settings, null);
return this;
}
public HttpRouterBuilder fromSettings(Settings settings,
Map<String, HttpSecurityDomain> securityDomainMap) {
// global prefix
if (settings.containsSetting("prefix")) {
setPrefix(settings.get("prefix"));
}
// global handlers
for (Map.Entry<String, Settings> entry : settings.getGroups("handler").entrySet()) {
String codeString = entry.getKey();
Settings handlerSettings = entry.getValue();
setHandler(Integer.parseInt(codeString), createHttpHandler(handlerSettings));
}
// handler domains
for (Map.Entry<String, Settings> entry : settings.getGroups("domain").entrySet()) {
addDomain(createHttpDomain(entry.getValue(), securityDomainMap));
}
return this;
}
private HttpDomain createHttpDomain(Settings settings,
Map<String, HttpSecurityDomain> securityDomainMap) {
if (settings.getAsBoolean("enabled", true)) {
@ -156,7 +156,7 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder {
throw new IllegalArgumentException("class not found or not loadable: " + e.getMessage());
}
} else {
logger.log(Level.WARNING, "disabled: " + settings.getAsMap());
logger.log(Level.WARNING, "disabled domain: " + settings.getAsMap());
}
return null;
}
@ -174,7 +174,7 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder {
boolean isSecure = settings.getAsBoolean("secure", false);
httpAddressBuilder.setSecure(isSecure);
httpAddressBuilder.setPort(settings.getAsInt("port", isSecure ? 443 : 80));
httpAddressBuilder.setVersion(HttpVersion.valueOf(settings.get("version", "HTTP_1_1")));
httpAddressBuilder.setVersion(HttpVersion.valueOf(settings.get("version", "HTTP/1.1")));
}
return httpAddressBuilder.build();
}
@ -191,8 +191,13 @@ public class BaseHttpRouterBuilder implements HttpRouterBuilder {
}
httpServiceBuilder.setPrefix(prefix);
httpServiceBuilder.setPath(path);
httpServiceBuilder.setMethod(HttpMethod.valueOf(settings.get("method", "GET")));
httpServiceBuilder.setHandler(createHttpHandler(settings));
if (settings.containsSetting("method")) {
String[] methods = settings.getAsArray("method");
} else {
httpServiceBuilder.addMethod(HttpMethod.GET);
}
httpServiceBuilder.addHandler(createHttpHandler(settings));
return httpServiceBuilder.build();
}

View file

@ -1,6 +1,7 @@
package org.xbib.net.http.server.route;
import java.util.Collection;
import org.xbib.net.http.HttpResponseStatus;
import org.xbib.net.http.server.HttpException;
import org.xbib.net.http.server.HttpRequestBuilder;
@ -21,5 +22,4 @@ public interface HttpRouter {
void routeToErrorHandler(HttpRouterContext httpRouterContext, Throwable t);
void routeException(HttpException e);
}

View file

@ -18,10 +18,5 @@ public interface HttpRouterBuilder {
HttpRouterBuilder setRouteResolver(HttpRouteResolver<HttpService> httpRouteResolver);
HttpRouterBuilder fromSettings(Settings settings);
HttpRouterBuilder fromSettings(Settings settings,
Map<String, HttpSecurityDomain> securityDomainMap);
HttpRouter build();
}

View file

@ -1,9 +1,8 @@
package org.xbib.net.http.server.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import org.xbib.net.ParameterDefinition;
import org.xbib.net.PathNormalizer;
import org.xbib.net.http.HttpMethod;
@ -28,8 +27,8 @@ public class BaseHttpServiceBuilder implements HttpServiceBuilder {
protected BaseHttpServiceBuilder() {
this.prefix = "";
this.pathSpec = "/**";
this.methods = Set.of(HttpMethod.GET);
this.handlers = null;
this.methods = new ArrayList<>();
this.handlers = new ArrayList<>();
this.securityDomain = null;
}
@ -40,22 +39,22 @@ public class BaseHttpServiceBuilder implements HttpServiceBuilder {
}
@Override
public BaseHttpServiceBuilder setPath(String path) {
if (path != null) {
this.pathSpec = PathNormalizer.normalize(path);
public BaseHttpServiceBuilder setPath(String pathSpec) {
if (pathSpec != null) {
this.pathSpec = PathNormalizer.normalize(pathSpec);
}
return this;
}
@Override
public BaseHttpServiceBuilder setMethod(HttpMethod... methods) {
this.methods = Set.of(methods);
public BaseHttpServiceBuilder addMethod(HttpMethod method) {
this.methods.add(method);
return this;
}
@Override
public BaseHttpServiceBuilder setHandler(HttpHandler... handler) {
this.handlers = Arrays.asList(handler);
public BaseHttpServiceBuilder addHandler(HttpHandler handler) {
this.handlers.add(handler);
return this;
}
@ -72,7 +71,9 @@ public class BaseHttpServiceBuilder implements HttpServiceBuilder {
}
public BaseHttpService build() {
Objects.requireNonNull(handlers);
if (methods.isEmpty()) {
methods.add(HttpMethod.GET);
}
return new BaseHttpService(this);
}
}

View file

@ -1,10 +1,15 @@
package org.xbib.net.http.server.test.base;
import org.junit.jupiter.api.Test;
import org.xbib.net.http.server.domain.HttpDomain;
import org.xbib.net.http.server.route.BaseHttpRouter;
import org.xbib.net.http.server.route.HttpRouter;
import org.xbib.settings.Settings;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RouterBuilderTest {
public RouterBuilderTest() {
@ -12,10 +17,17 @@ public class RouterBuilderTest {
@Test
void buildFromSettings() {
// java.lang.NullPointerException: Cannot invoke "org.xbib.settings.SettingsBuilder.build()" because the return value of "org.xbib.settings.Settings$Holder.createBuilder()" is null
Settings settings = Settings.emptySettings();
// the simplest possible setup in settings
Settings settings = Settings.settingsBuilder()
.put("domain.domain1.name", "localhost")
.put("domain.domain1.service./demo1.method", "GET")
.put("domain.domain1.service./demo1.class", "org.xbib.net.http.server.handler.OkHandler")
.build();
HttpRouter httpRouter = BaseHttpRouter.builder()
.fromSettings(settings)
.build();
Optional<HttpDomain> httpDomain = httpRouter.getDomains().stream().findFirst();
assertTrue(httpDomain.isPresent());
assertTrue(httpDomain.get().getNames().contains("localhost"));
}
}

View file

@ -9,6 +9,7 @@ import org.xbib.net.http.server.route.HttpRouterContext;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -23,27 +24,28 @@ public class GroovyTemplateApplicationModule extends BaseApplicationModule {
private final GroovyTemplateRenderer groovyTemplateRenderer;
public GroovyTemplateApplicationModule(Application application, String name, Settings settings) {
super(application, name, settings);
ClassLoader classLoader = GroovyMarkupTemplateHandler.class.getClassLoader();
String defaultMarkupTemplate = settings.get("markup.templateClass",
public GroovyTemplateApplicationModule(Application application, String name) {
super(application, name);
ClassLoader classLoader = getClass().getClassLoader();
Settings settings = Objects.requireNonNull(application.getAttributes().get(Settings.class, "settings"));
String defaultMarkupTemplate = settings.get("groovy.markup.templateClass",
"org.xbib.net.http.template.DefaultMarkupTemplate");
try {
@SuppressWarnings("unchecked")
Class<? extends BaseTemplate> defaultMarkupTemplateClass =
(Class<? extends BaseTemplate>) Class.forName(defaultMarkupTemplate, true, classLoader);
logger.log(Level.INFO, "markup template class = " + defaultMarkupTemplateClass.getName());
logger.log(Level.INFO, "groovy markup template class = " + defaultMarkupTemplateClass.getName());
this.groovyMarkupTemplateHandler = new GroovyMarkupTemplateHandler(application,
classLoader, defaultMarkupTemplateClass, application.getLocale(),
settings.getAsBoolean("markup.autoEscape", true),
settings.getAsBoolean("markup.autoIndent", false),
settings.get("markup.autoIndentString", " "),
settings.getAsBoolean("markup.autoNewline", false),
settings.getAsBoolean("markup.cacheTemplates", true),
settings.get("markup.declarationEncoding", null),
settings.getAsBoolean("markup.expandEmptyElements", true),
settings.get("markup.newLine", System.getProperty("line.separator")),
settings.getAsBoolean("markup.useDoubleQuotes", true));
settings.getAsBoolean("groovy.markup.autoEscape", true),
settings.getAsBoolean("groovy.markup.autoIndent", false),
settings.get("groovy.markup.autoIndentString", " "),
settings.getAsBoolean("groovy.markup.autoNewline", false),
settings.getAsBoolean("groovy.markup.cacheTemplates", true),
settings.get("groovy.markup.declarationEncoding", null),
settings.getAsBoolean("groovy.markup.expandEmptyElements", true),
settings.get("groovy.markup.newLine", System.getProperty("line.separator")),
settings.getAsBoolean("groovy.markup.useDoubleQuotes", true));
this.groovyTemplateRenderer = new GroovyTemplateRenderer();
} catch (Exception e) {
throw new IllegalStateException(e);

View file

@ -32,14 +32,14 @@ public class GroovyTemplateServiceBuilder extends BaseHttpServiceBuilder {
}
@Override
public GroovyTemplateServiceBuilder setMethod(HttpMethod... httpMethod) {
super.setMethod(httpMethod);
public GroovyTemplateServiceBuilder addMethod(HttpMethod httpMethod) {
super.addMethod(httpMethod);
return this;
}
@Override
public GroovyTemplateServiceBuilder setHandler(HttpHandler... handler) {
super.setHandler(handler);
public GroovyTemplateServiceBuilder addHandler(HttpHandler handler) {
super.addHandler(handler);
return this;
}
@ -78,7 +78,7 @@ public class GroovyTemplateServiceBuilder extends BaseHttpServiceBuilder {
public GroovyTemplateService build() {
if (this.handlers == null) {
HttpHandler httpHandler = new GroovyTemplateResourceHandler(prefix, suffix, indexFileName);
setHandler(httpHandler);
addHandler(httpHandler);
}
return new GroovyTemplateService(this);
}

View file

@ -5,7 +5,7 @@ dependencyResolutionManagement {
version('groovy', '4.0.26')
version('netty', '4.1.119.Final')
version('netty-tcnative', '2.0.70.Final')
version('datastructures', '5.2.2')
version('datastructures', '5.2.3')
version('net', '4.8.0')
version('database', '2.3.2')
library('netty-codec-http2', 'io.netty', 'netty-codec-http2').versionRef('netty')
@ -27,19 +27,21 @@ dependencyResolutionManagement {
library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
library('settings-api', 'org.xbib', 'settings-api').versionRef('datastructures')
library('settings-datastructures-json', 'org.xbib', 'settings-datastructures-json').versionRef('datastructures')
library('settings-datastructures-yaml', 'org.xbib', 'settings-datastructures-yaml').versionRef('datastructures')
library('config', 'org.xbib', 'config').versionRef('datastructures')
library('jdbc-query', 'org.xbib', 'jdbc-query').versionRef('database')
library('jdbc-pool', 'org.xbib', 'jdbc-pool').versionRef('database')
}
testLibs {
version('junit', '5.12.0')
version('datastructures', '5.2.3')
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit')
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
library('junit-jupiter-platform-launcher', 'org.junit.platform', 'junit-platform-launcher').version('1.12.0')
library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('3.0')
library('settings-datastructures', 'org.xbib', 'settings-datastructures').versionRef('datastructures')
library('settings-datastructures-json', 'org.xbib', 'settings-datastructures-json').versionRef('datastructures')
library('settings-datastructures-yaml', 'org.xbib', 'settings-datastructures-yaml').versionRef('datastructures')
}
}
}