add session name, fix netty request body retain, fix static suffixes, log throwables in the router dispatch
This commit is contained in:
parent
2f17616f1d
commit
1df5f884b1
13 changed files with 108 additions and 73 deletions
|
@ -10,15 +10,11 @@ import org.xbib.net.http.server.session.IncomingSessionHandler;
|
||||||
import org.xbib.net.http.server.session.OutgoingSessionHandler;
|
import org.xbib.net.http.server.session.OutgoingSessionHandler;
|
||||||
import org.xbib.net.http.server.session.Session;
|
import org.xbib.net.http.server.session.Session;
|
||||||
import org.xbib.net.http.server.session.file.FileJsonSessionCodec;
|
import org.xbib.net.http.server.session.file.FileJsonSessionCodec;
|
||||||
import org.xbib.settings.Settings;
|
|
||||||
|
|
||||||
public class WebApplication extends BaseApplication {
|
public class WebApplication extends BaseApplication {
|
||||||
|
|
||||||
private final WebApplicationBuilder builder;
|
|
||||||
|
|
||||||
protected WebApplication(WebApplicationBuilder builder) {
|
protected WebApplication(WebApplicationBuilder builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
this.builder = builder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WebApplicationBuilder builder() {
|
public static WebApplicationBuilder builder() {
|
||||||
|
@ -30,7 +26,7 @@ public class WebApplication extends BaseApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Codec<Session> buildSessionCodec(HttpServerContext httpServerContext) {
|
protected Codec<Session> buildSessionCodec(HttpServerContext httpServerContext) {
|
||||||
return new FileJsonSessionCodec(this, 1024, Duration.ofDays(1),
|
return new FileJsonSessionCodec(sessionName, this, 1024, Duration.ofDays(1),
|
||||||
Paths.get("/var/tmp/session"));
|
Paths.get("/var/tmp/session"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +36,7 @@ public class WebApplication extends BaseApplication {
|
||||||
return new IncomingSessionHandler(
|
return new IncomingSessionHandler(
|
||||||
getSecret(),
|
getSecret(),
|
||||||
"HmacSHA1",
|
"HmacSHA1",
|
||||||
"SESSION",
|
sessionName,
|
||||||
sessionCodec,
|
sessionCodec,
|
||||||
getStaticFileSuffixes(),
|
getStaticFileSuffixes(),
|
||||||
"user_id",
|
"user_id",
|
||||||
|
@ -53,7 +49,7 @@ public class WebApplication extends BaseApplication {
|
||||||
return new OutgoingSessionHandler(
|
return new OutgoingSessionHandler(
|
||||||
getSecret(),
|
getSecret(),
|
||||||
"HmacSHA1",
|
"HmacSHA1",
|
||||||
"SESSION",
|
sessionName,
|
||||||
Duration.ofDays(1),
|
Duration.ofDays(1),
|
||||||
sessionCodec,
|
sessionCodec,
|
||||||
getStaticFileSuffixes(),
|
getStaticFileSuffixes(),
|
||||||
|
|
|
@ -15,16 +15,17 @@ import java.nio.charset.Charset;
|
||||||
|
|
||||||
public class HttpRequestBuilder extends BaseHttpRequestBuilder {
|
public class HttpRequestBuilder extends BaseHttpRequestBuilder {
|
||||||
|
|
||||||
FullHttpRequest fullHttpRequest;
|
protected FullHttpRequest fullHttpRequest;
|
||||||
|
|
||||||
ByteBuffer byteBuffer;
|
protected ByteBuffer byteBuffer;
|
||||||
|
|
||||||
protected HttpRequestBuilder() {
|
protected HttpRequestBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRequestBuilder setFullHttpRequest(FullHttpRequest fullHttpRequest) {
|
public HttpRequestBuilder setFullHttpRequest(FullHttpRequest fullHttpRequest) {
|
||||||
if (fullHttpRequest != null) {
|
if (fullHttpRequest != null) {
|
||||||
this.fullHttpRequest = fullHttpRequest;
|
// retain request so we can read the body later without refCnt=0 error
|
||||||
|
this.fullHttpRequest = fullHttpRequest.retain();
|
||||||
setVersion(HttpVersion.valueOf(fullHttpRequest.protocolVersion().text()));
|
setVersion(HttpVersion.valueOf(fullHttpRequest.protocolVersion().text()));
|
||||||
setMethod(HttpMethod.valueOf(fullHttpRequest.method().name()));
|
setMethod(HttpMethod.valueOf(fullHttpRequest.method().name()));
|
||||||
setRequestURI(fullHttpRequest.uri());
|
setRequestURI(fullHttpRequest.uri());
|
||||||
|
|
|
@ -41,6 +41,8 @@ public class BaseApplication implements Application {
|
||||||
|
|
||||||
private final HttpRequestValidator httpRequestValidator;
|
private final HttpRequestValidator httpRequestValidator;
|
||||||
|
|
||||||
|
protected final String sessionName;
|
||||||
|
|
||||||
private final HttpHandler incomingCookieHandler;
|
private final HttpHandler incomingCookieHandler;
|
||||||
|
|
||||||
private final HttpHandler outgoingCookieHandler;
|
private final HttpHandler outgoingCookieHandler;
|
||||||
|
@ -59,6 +61,7 @@ public class BaseApplication implements Application {
|
||||||
new NamedThreadFactory("org-xbib-net-http-server-application"));
|
new NamedThreadFactory("org-xbib-net-http-server-application"));
|
||||||
this.executor.setRejectedExecutionHandler((runnable, threadPoolExecutor) ->
|
this.executor.setRejectedExecutionHandler((runnable, threadPoolExecutor) ->
|
||||||
logger.log(Level.SEVERE, "rejected " + runnable + " for thread pool executor = " + threadPoolExecutor));
|
logger.log(Level.SEVERE, "rejected " + runnable + " for thread pool executor = " + threadPoolExecutor));
|
||||||
|
this.sessionName = getSettings().get("session.name", "SESS");
|
||||||
this.httpRequestValidator = buildRequestValidator();
|
this.httpRequestValidator = buildRequestValidator();
|
||||||
this.incomingCookieHandler = buildIncomingCookieHandler();
|
this.incomingCookieHandler = buildIncomingCookieHandler();
|
||||||
this.outgoingCookieHandler = buildOutgoingCookieHandler();
|
this.outgoingCookieHandler = buildOutgoingCookieHandler();
|
||||||
|
@ -121,7 +124,14 @@ public class BaseApplication implements Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispatch(HttpRequestBuilder requestBuilder, HttpResponseBuilder responseBuilder) {
|
public void dispatch(HttpRequestBuilder requestBuilder, HttpResponseBuilder responseBuilder) {
|
||||||
Future<?> future = executor.submit(() -> getRouter().route(requestBuilder, responseBuilder));
|
Future<?> future = executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
getRouter().route(requestBuilder, responseBuilder);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
logger.log(Level.SEVERE, t.getMessage(), t);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
});
|
||||||
logger.log(Level.FINE, "dispatching " + future);
|
logger.log(Level.FINE, "dispatching " + future);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +142,12 @@ public class BaseApplication implements Application {
|
||||||
Future<?> future = executor.submit(() -> {
|
Future<?> future = executor.submit(() -> {
|
||||||
HttpServerContext httpServerContext = createContext(null, httpRequestBuilder, httpResponseBuilder);
|
HttpServerContext httpServerContext = createContext(null, httpRequestBuilder, httpResponseBuilder);
|
||||||
httpServerContext.attributes().put("responsebuilder", httpResponseBuilder);
|
httpServerContext.attributes().put("responsebuilder", httpResponseBuilder);
|
||||||
|
try {
|
||||||
getRouter().routeStatus(httpResponseStatus, httpServerContext);
|
getRouter().routeStatus(httpResponseStatus, httpServerContext);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
logger.log(Level.SEVERE, t.getMessage(), t);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
logger.log(Level.FINE, "dispatching status " + future);
|
logger.log(Level.FINE, "dispatching status " + future);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +181,7 @@ public class BaseApplication implements Application {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Codec<Session> buildSessionCodec(HttpServerContext httpServerContext) {
|
protected Codec<Session> buildSessionCodec(HttpServerContext httpServerContext) {
|
||||||
return new MemoryPropertiesSessionCodec(this, 1024, Duration.ofDays(1));
|
return new MemoryPropertiesSessionCodec(sessionName,this, 1024, Duration.ofDays(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpHandler buildIncomingSessionHandler(HttpServerContext httpServerContext) {
|
protected HttpHandler buildIncomingSessionHandler(HttpServerContext httpServerContext) {
|
||||||
|
@ -175,7 +190,7 @@ public class BaseApplication implements Application {
|
||||||
return new IncomingSessionHandler(
|
return new IncomingSessionHandler(
|
||||||
getSecret(),
|
getSecret(),
|
||||||
"HmacSHA1",
|
"HmacSHA1",
|
||||||
"SESS",
|
sessionName,
|
||||||
sessionCodec,
|
sessionCodec,
|
||||||
getStaticFileSuffixes(),
|
getStaticFileSuffixes(),
|
||||||
"user_id",
|
"user_id",
|
||||||
|
@ -188,7 +203,7 @@ public class BaseApplication implements Application {
|
||||||
return new OutgoingSessionHandler(
|
return new OutgoingSessionHandler(
|
||||||
getSecret(),
|
getSecret(),
|
||||||
"HmacSHA1",
|
"HmacSHA1",
|
||||||
"SESS",
|
sessionName,
|
||||||
Duration.ofDays(1),
|
Duration.ofDays(1),
|
||||||
sessionCodec,
|
sessionCodec,
|
||||||
getStaticFileSuffixes(),
|
getStaticFileSuffixes(),
|
||||||
|
@ -202,13 +217,13 @@ public class BaseApplication implements Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreated(Session session) {
|
public void onCreated(Session session) {
|
||||||
logger.log(Level.INFO, "session created = " + session);
|
logger.log(Level.FINE, "session name = " + sessionName + " created = " + session);
|
||||||
builder.applicationModuleList.forEach(module -> module.onOpen(this, session));
|
builder.applicationModuleList.forEach(module -> module.onOpen(this, session));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy(Session session) {
|
public void onDestroy(Session session) {
|
||||||
logger.log(Level.INFO, "session destroyed = " + session);
|
logger.log(Level.FINE, "session name = " + sessionName + " destroyed = " + session);
|
||||||
builder.applicationModuleList.forEach(module -> module.onClose(this, session));
|
builder.applicationModuleList.forEach(module -> module.onClose(this, session));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.xbib.config.ConfigLoader;
|
||||||
import org.xbib.config.ConfigLogger;
|
import org.xbib.config.ConfigLogger;
|
||||||
import org.xbib.config.ConfigParams;
|
import org.xbib.config.ConfigParams;
|
||||||
import org.xbib.config.SystemConfigLogger;
|
import org.xbib.config.SystemConfigLogger;
|
||||||
import org.xbib.datastructures.common.ImmutableSet;
|
|
||||||
import org.xbib.net.http.server.route.HttpRouter;
|
import org.xbib.net.http.server.route.HttpRouter;
|
||||||
import org.xbib.settings.Settings;
|
import org.xbib.settings.Settings;
|
||||||
|
|
||||||
|
@ -136,12 +135,8 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationBuilder addStaticSuffixes(String... suffixes) {
|
public ApplicationBuilder setStaticSuffixes(String... suffixes) {
|
||||||
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
this.staticFileSuffixes = Set.of(suffixes);
|
||||||
for (String suffix : suffixes) {
|
|
||||||
builder.add(suffix);
|
|
||||||
}
|
|
||||||
this.staticFileSuffixes = builder.build(new String[]{});
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,12 +147,13 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Application build() {
|
public Application build() {
|
||||||
|
prepareApplication();
|
||||||
Application application = new BaseApplication(this);
|
Application application = new BaseApplication(this);
|
||||||
setupApplication(application);
|
setupApplication(application);
|
||||||
return application;
|
return application;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupApplication(Application application) {
|
protected void prepareApplication() {
|
||||||
String name = System.getProperty("application.name");
|
String name = System.getProperty("application.name");
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = "application";
|
name = "application";
|
||||||
|
@ -176,6 +172,15 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
|
||||||
this.configLoader = ConfigLoader.getInstance()
|
this.configLoader = ConfigLoader.getInstance()
|
||||||
.withLogger(bootLogger);
|
.withLogger(bootLogger);
|
||||||
this.settings = configLoader.load(configParams);
|
this.settings = configLoader.load(configParams);
|
||||||
|
if (staticFileSuffixes == null) {
|
||||||
|
staticFileSuffixes = DEFAULT_SUFFIXES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupApplication(Application application) {
|
||||||
|
if (router != null) {
|
||||||
|
router.setApplication(application);
|
||||||
|
}
|
||||||
for (Map.Entry<String, Settings> entry : settings.getGroups("module").entrySet()) {
|
for (Map.Entry<String, Settings> entry : settings.getGroups("module").entrySet()) {
|
||||||
String moduleName = entry.getKey();
|
String moduleName = entry.getKey();
|
||||||
Settings moduleSettings = entry.getValue();
|
Settings moduleSettings = entry.getValue();
|
||||||
|
@ -197,22 +202,8 @@ public class BaseApplicationBuilder implements ApplicationBuilder {
|
||||||
logger.log(Level.WARNING, "disabled module: " + moduleName);
|
logger.log(Level.WARNING, "disabled module: " + moduleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (router != null) {
|
|
||||||
router.setApplication(application);
|
|
||||||
}
|
|
||||||
if (staticFileSuffixes == null) {
|
|
||||||
staticFileSuffixes = DEFAULT_SUFFIXES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<String> DEFAULT_SUFFIXES = ImmutableSet.<String>builder()
|
private static final Set<String> DEFAULT_SUFFIXES =
|
||||||
.add("css")
|
Set.of("css", "js", "ico", "png", "jpg", "jpeg", "gif", "woff2");
|
||||||
.add("js")
|
|
||||||
.add("ico")
|
|
||||||
.add("png")
|
|
||||||
.add("jpg")
|
|
||||||
.add("jpeg")
|
|
||||||
.add("gif")
|
|
||||||
.add("woff2")
|
|
||||||
.build(new String[]{});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,7 @@ public abstract class AbstractResourceHandler implements HttpHandler {
|
||||||
Resource resource = createResource(context);
|
Resource resource = createResource(context);
|
||||||
logger.log(Level.FINE, "handle: resource = " + (resource != null ? resource.getClass().getName() + " " + resource : null));
|
logger.log(Level.FINE, "handle: resource = " + (resource != null ? resource.getClass().getName() + " " + resource : null));
|
||||||
if (resource instanceof HtmlTemplateResource) {
|
if (resource instanceof HtmlTemplateResource) {
|
||||||
logger.log(Level.FINE, "handle: HTML template resource, generate cacheable resource, parameter = " +
|
logger.log(Level.FINE, "handle: HTML template resource, generate cacheable resource");
|
||||||
context.httpRequest().getParameter());
|
|
||||||
generateCacheableResource(context, resource);
|
generateCacheableResource(context, resource);
|
||||||
logger.log(Level.FINE, "handle: done");
|
logger.log(Level.FINE, "handle: done");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -49,23 +49,24 @@ public class HtmlTemplateResource implements HttpServerResource {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
throw new IllegalArgumentException("no home path set for template resource resolving");
|
throw new IllegalArgumentException("no home path set for template resource resolving");
|
||||||
}
|
}
|
||||||
|
logger.log(Level.FINE, "class = " + getClass().getName());
|
||||||
logger.log(Level.FINE, "root = " + root);
|
logger.log(Level.FINE, "root = " + root);
|
||||||
this.resourcePath = httpServerContext.request().getRequestPath().substring(1);
|
this.resourcePath = httpServerContext.request().getRequestPath().substring(1);
|
||||||
logger.log(Level.FINE, "resource path = " + resourcePath);
|
logger.log(Level.FINE, "resource path = " + resourcePath);
|
||||||
this.path = resourcePath.length() > 0 ? root.resolve(resourcePath) : root;
|
this.path = resourcePath.length() > 0 ? root.resolve(resourcePath) : root;
|
||||||
logger.log(Level.FINE, "path = " + path);
|
logger.log(Level.FINE, "path = " + path);
|
||||||
logger.log(Level.FINE, "index file name = " + indexFileName);
|
logger.log(Level.FINE, "index file name = " + indexFileName);
|
||||||
this.url = URL.create(path.toUri().toString());
|
|
||||||
logger.log(Level.FINE, "uri = " + url);
|
|
||||||
this.name = path.getFileName().toString();
|
this.name = path.getFileName().toString();
|
||||||
this.baseName = AbstractResourceHandler.basename(name);
|
this.baseName = AbstractResourceHandler.basename(name);
|
||||||
this.suffix = AbstractResourceHandler.suffix(name);
|
this.suffix = AbstractResourceHandler.suffix(name);
|
||||||
if (Files.isDirectory(path)) {
|
if (Files.isDirectory(path)) {
|
||||||
if (getIndexFileName() != null) {
|
if (getIndexFileName() != null) {
|
||||||
Path indexPath = path.resolve(indexFileName);
|
Path indexPath = path.resolve(indexFileName);
|
||||||
|
logger.log(Level.FINE, "index path = " + indexPath);
|
||||||
if (Files.exists(indexPath)) {
|
if (Files.exists(indexPath)) {
|
||||||
this.isExistsIndexFile = true;
|
this.isExistsIndexFile = true;
|
||||||
this.path = indexPath;
|
this.path = indexPath;
|
||||||
|
logger.log(Level.FINE, "index file path found = " + path);
|
||||||
this.isDirectory = false;
|
this.isDirectory = false;
|
||||||
} else {
|
} else {
|
||||||
this.isExistsIndexFile = false;
|
this.isExistsIndexFile = false;
|
||||||
|
@ -82,6 +83,8 @@ public class HtmlTemplateResource implements HttpServerResource {
|
||||||
this.isExists = Files.exists(path);
|
this.isExists = Files.exists(path);
|
||||||
logger.log(Level.FINE, "exists = " + isExists);
|
logger.log(Level.FINE, "exists = " + isExists);
|
||||||
logger.log(Level.FINE, "isDirectory = " + isDirectory);
|
logger.log(Level.FINE, "isDirectory = " + isDirectory);
|
||||||
|
this.url = URL.create(path.toUri().toString());
|
||||||
|
logger.log(Level.FINE, "url = " + url);
|
||||||
if (isExists) {
|
if (isExists) {
|
||||||
this.lastModified = Files.getLastModifiedTime(path).toInstant();
|
this.lastModified = Files.getLastModifiedTime(path).toInstant();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,8 @@ public class BaseSession implements Session {
|
||||||
|
|
||||||
private final SessionListener sessionListener;
|
private final SessionListener sessionListener;
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
||||||
private final Duration lifetime;
|
private final Duration lifetime;
|
||||||
|
@ -30,11 +32,13 @@ public class BaseSession implements Session {
|
||||||
|
|
||||||
public BaseSession(SessionListener sessionListener,
|
public BaseSession(SessionListener sessionListener,
|
||||||
int cacheSize,
|
int cacheSize,
|
||||||
|
String name,
|
||||||
String id,
|
String id,
|
||||||
boolean create,
|
boolean create,
|
||||||
Duration lifetime) {
|
Duration lifetime) {
|
||||||
this.cacheSize = cacheSize;
|
this.cacheSize = cacheSize;
|
||||||
this.sessionListener = sessionListener;
|
this.sessionListener = sessionListener;
|
||||||
|
this.name = name;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.lifetime = lifetime;
|
this.lifetime = lifetime;
|
||||||
this.map = new LinkedHashMap<>();
|
this.map = new LinkedHashMap<>();
|
||||||
|
@ -47,6 +51,12 @@ public class BaseSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String id() {
|
public String id() {
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.util.Map;
|
||||||
|
|
||||||
public interface Session extends Map<String, Object> {
|
public interface Session extends Map<String, Object> {
|
||||||
|
|
||||||
|
String name();
|
||||||
|
|
||||||
String id();
|
String id();
|
||||||
|
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
|
@ -27,6 +27,8 @@ public class FileJsonSessionCodec implements Codec<Session> {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(FileJsonSessionCodec.class.getName());
|
private static final Logger logger = Logger.getLogger(FileJsonSessionCodec.class.getName());
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
private final ReentrantReadWriteLock lock;
|
private final ReentrantReadWriteLock lock;
|
||||||
|
|
||||||
private final SessionListener sessionListener;
|
private final SessionListener sessionListener;
|
||||||
|
@ -37,10 +39,13 @@ public class FileJsonSessionCodec implements Codec<Session> {
|
||||||
|
|
||||||
private final Duration sessionDuration;
|
private final Duration sessionDuration;
|
||||||
|
|
||||||
public FileJsonSessionCodec(SessionListener sessionListener,
|
public FileJsonSessionCodec(String name,
|
||||||
|
SessionListener sessionListener,
|
||||||
int sessionCacheSize,
|
int sessionCacheSize,
|
||||||
Duration sessionDuration,
|
Duration sessionDuration,
|
||||||
Path path) {
|
Path path
|
||||||
|
) {
|
||||||
|
this.name = name;
|
||||||
this.sessionListener = sessionListener;
|
this.sessionListener = sessionListener;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.sessionCacheSize = sessionCacheSize;
|
this.sessionCacheSize = sessionCacheSize;
|
||||||
|
@ -56,7 +61,7 @@ public class FileJsonSessionCodec implements Codec<Session> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Session create(String key) throws IOException {
|
public Session create(String key) throws IOException {
|
||||||
return new BaseSession(sessionListener, sessionCacheSize, key, true, sessionDuration);
|
return new BaseSession(sessionListener, sessionCacheSize, name, key, true, sessionDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,7 +71,7 @@ public class FileJsonSessionCodec implements Codec<Session> {
|
||||||
try {
|
try {
|
||||||
readLock.lock();
|
readLock.lock();
|
||||||
PercentEncoder percentEncoder = PercentEncoders.getUnreservedEncoder(StandardCharsets.UTF_8);
|
PercentEncoder percentEncoder = PercentEncoders.getUnreservedEncoder(StandardCharsets.UTF_8);
|
||||||
session = new BaseSession(sessionListener, sessionCacheSize, key, false, sessionDuration);
|
session = new BaseSession(sessionListener, sessionCacheSize, name, key, false, sessionDuration);
|
||||||
Map<String, Object> map = JsonUtil.toMap(Files.readString(path.resolve(percentEncoder.encode(key))));
|
Map<String, Object> map = JsonUtil.toMap(Files.readString(path.resolve(percentEncoder.encode(key))));
|
||||||
session.putAll(map);
|
session.putAll(map);
|
||||||
return session;
|
return session;
|
||||||
|
|
|
@ -17,7 +17,6 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import org.xbib.net.http.server.HttpServerContext;
|
|
||||||
import org.xbib.net.http.server.persist.Codec;
|
import org.xbib.net.http.server.persist.Codec;
|
||||||
import org.xbib.net.http.server.session.BaseSession;
|
import org.xbib.net.http.server.session.BaseSession;
|
||||||
import org.xbib.net.http.server.session.Session;
|
import org.xbib.net.http.server.session.Session;
|
||||||
|
@ -26,6 +25,8 @@ import org.xbib.net.util.JsonUtil;
|
||||||
|
|
||||||
public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
private final SessionListener sessionListener;
|
private final SessionListener sessionListener;
|
||||||
|
|
||||||
private final int sessionCacheSize;
|
private final int sessionCacheSize;
|
||||||
|
@ -44,7 +45,7 @@ public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
||||||
|
|
||||||
private final ScheduledExecutorService scheduledExecutorService;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
|
|
||||||
public JdbcSessionCodec(HttpServerContext httpServerContext,
|
public JdbcSessionCodec(String name,
|
||||||
SessionListener sessionListener,
|
SessionListener sessionListener,
|
||||||
int sessionCacheSize,
|
int sessionCacheSize,
|
||||||
Duration sessionDuration,
|
Duration sessionDuration,
|
||||||
|
@ -53,6 +54,7 @@ public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
||||||
String writeSessionStringStatement,
|
String writeSessionStringStatement,
|
||||||
String deleteSessionStringStatement,
|
String deleteSessionStringStatement,
|
||||||
String purgeSessionStringStatement) {
|
String purgeSessionStringStatement) {
|
||||||
|
this.name = name;
|
||||||
this.sessionListener = sessionListener;
|
this.sessionListener = sessionListener;
|
||||||
this.sessionCacheSize = sessionCacheSize;
|
this.sessionCacheSize = sessionCacheSize;
|
||||||
this.sessionDuration = sessionDuration;
|
this.sessionDuration = sessionDuration;
|
||||||
|
@ -67,7 +69,7 @@ public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Session create(String key) throws IOException {
|
public Session create(String key) throws IOException {
|
||||||
return new BaseSession(sessionListener, sessionCacheSize, key, true, sessionDuration);
|
return new BaseSession(sessionListener, sessionCacheSize, name, key, true, sessionDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,7 +78,7 @@ public class JdbcSessionCodec implements Codec<Session>, Closeable {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> map = JsonUtil.toMap(readString(key));
|
Map<String, Object> map = JsonUtil.toMap(readString(key));
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
session = new BaseSession(sessionListener, sessionCacheSize, key, false, sessionDuration);
|
session = new BaseSession(sessionListener, sessionCacheSize, name, key, false, sessionDuration);
|
||||||
session.putAll(map);
|
session.putAll(map);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,28 +14,32 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
public class MemoryPropertiesSessionCodec implements Codec<Session> {
|
public class MemoryPropertiesSessionCodec implements Codec<Session> {
|
||||||
|
|
||||||
private final ReentrantReadWriteLock lock;
|
|
||||||
|
|
||||||
private static final Map<String, Object> store = new HashMap<>();
|
private static final Map<String, Object> store = new HashMap<>();
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final ReentrantReadWriteLock lock;
|
||||||
|
|
||||||
private final SessionListener sessionListener;
|
private final SessionListener sessionListener;
|
||||||
|
|
||||||
private final int sessionCacheSize;
|
private final int sessionCacheSize;
|
||||||
|
|
||||||
private final Duration sessionDuration;
|
private final Duration sessionDuration;
|
||||||
|
|
||||||
public MemoryPropertiesSessionCodec(SessionListener sessionListener,
|
public MemoryPropertiesSessionCodec(String name,
|
||||||
|
SessionListener sessionListener,
|
||||||
int sessionCacheSize,
|
int sessionCacheSize,
|
||||||
Duration sessionDuration) {
|
Duration sessionDuration) {
|
||||||
this.lock = new ReentrantReadWriteLock();
|
this.name = name;
|
||||||
this.sessionListener = sessionListener;
|
this.sessionListener = sessionListener;
|
||||||
this.sessionCacheSize = sessionCacheSize;
|
this.sessionCacheSize = sessionCacheSize;
|
||||||
this.sessionDuration = sessionDuration;
|
this.sessionDuration = sessionDuration;
|
||||||
|
this.lock = new ReentrantReadWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Session create(String key) throws IOException {
|
public Session create(String key) throws IOException {
|
||||||
return new BaseSession(sessionListener, sessionCacheSize, key, true, sessionDuration);
|
return new BaseSession(sessionListener, sessionCacheSize, name, key, true, sessionDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,7 +70,7 @@ public class MemoryPropertiesSessionCodec implements Codec<Session> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Session toSession(String key, Properties properties) {
|
private Session toSession(String key, Properties properties) {
|
||||||
Session session = new BaseSession(sessionListener, sessionCacheSize, key, false, sessionDuration);
|
Session session = new BaseSession(sessionListener, sessionCacheSize, name, key, false, sessionDuration);
|
||||||
properties.forEach((k, v) -> session.put(k.toString(), v));
|
properties.forEach((k, v) -> session.put(k.toString(), v));
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
@ -26,7 +27,7 @@ public class BlockingThreadPoolExecutor extends ThreadPoolExecutor {
|
||||||
ThreadFactory threadFactory) {
|
ThreadFactory threadFactory) {
|
||||||
super(nThreads, nThreads, keepAliveTime, timeUnit, createBlockingQueue(maxQueue), threadFactory);
|
super(nThreads, nThreads, keepAliveTime, timeUnit, createBlockingQueue(maxQueue), threadFactory);
|
||||||
logger.log(Level.INFO, "blocking threadpool executor up with nThreads = " + nThreads +
|
logger.log(Level.INFO, "blocking threadpool executor up with nThreads = " + nThreads +
|
||||||
" keepALiveTime = " + keepAliveTime +
|
" keepAliveTime = " + keepAliveTime +
|
||||||
" time unit = " + timeUnit +
|
" time unit = " + timeUnit +
|
||||||
" maxQueue = " + maxQueue +
|
" maxQueue = " + maxQueue +
|
||||||
" thread factory = " + threadFactory);
|
" thread factory = " + threadFactory);
|
||||||
|
@ -42,7 +43,7 @@ public class BlockingThreadPoolExecutor extends ThreadPoolExecutor {
|
||||||
@Override
|
@Override
|
||||||
protected void afterExecute(Runnable runnable, Throwable terminationCause) {
|
protected void afterExecute(Runnable runnable, Throwable terminationCause) {
|
||||||
super.afterExecute(runnable, terminationCause);
|
super.afterExecute(runnable, terminationCause);
|
||||||
logger.log(Level.FINE, "after dispatching " + runnable);
|
logger.log(Level.FINE, "after dispatching " + runnable + " terminationCause = " + terminationCause);
|
||||||
Throwable throwable = terminationCause;
|
Throwable throwable = terminationCause;
|
||||||
if (throwable == null && runnable instanceof Future<?>) {
|
if (throwable == null && runnable instanceof Future<?>) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package org.xbib.net.http.template.groovy;
|
||||||
import groovy.text.markup.BaseTemplate;
|
import groovy.text.markup.BaseTemplate;
|
||||||
import groovy.text.markup.MarkupTemplateEngine;
|
import groovy.text.markup.MarkupTemplateEngine;
|
||||||
import groovy.text.markup.TemplateConfiguration;
|
import groovy.text.markup.TemplateConfiguration;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.xbib.net.URL;
|
import org.xbib.net.URL;
|
||||||
|
@ -27,13 +29,13 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DefaultMarkupTemplate.class.getName());
|
private static final Logger logger = Logger.getLogger(DefaultMarkupTemplate.class.getName());
|
||||||
|
|
||||||
private final Application application;
|
protected final Application application;
|
||||||
|
|
||||||
private final HttpRequest request;
|
protected final Session session;
|
||||||
|
|
||||||
private final HttpResponseBuilder responseBuilder;
|
protected final HttpRequest request;
|
||||||
|
|
||||||
private final Session session;
|
protected final HttpResponseBuilder responseBuilder;
|
||||||
|
|
||||||
public DefaultMarkupTemplate(MarkupTemplateEngine templateEngine,
|
public DefaultMarkupTemplate(MarkupTemplateEngine templateEngine,
|
||||||
Map<String,?> model,
|
Map<String,?> model,
|
||||||
|
@ -41,9 +43,13 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate {
|
||||||
TemplateConfiguration configuration) {
|
TemplateConfiguration configuration) {
|
||||||
super(templateEngine, model, modelTypes, configuration);
|
super(templateEngine, model, modelTypes, configuration);
|
||||||
this.application = (Application) model.get("application");
|
this.application = (Application) model.get("application");
|
||||||
this.request = (HttpRequest) model.get("request");
|
Objects.requireNonNull(this.application, "application must not be null");
|
||||||
this.responseBuilder = (HttpResponseBuilder) model.get("responsebuilder");
|
|
||||||
this.session = (Session) model.get("session");
|
this.session = (Session) model.get("session");
|
||||||
|
Objects.requireNonNull(this.session, "session must not be null");
|
||||||
|
this.request = (HttpRequest) model.get("request");
|
||||||
|
Objects.requireNonNull(this.request, "request must not be null");
|
||||||
|
this.responseBuilder = (HttpResponseBuilder) model.get("responsebuilder");
|
||||||
|
Objects.requireNonNull(this.responseBuilder, "response must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void responseStatus(HttpResponseStatus responseStatus) {
|
public void responseStatus(HttpResponseStatus responseStatus) {
|
||||||
|
@ -67,23 +73,23 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate {
|
||||||
responseBuilder.setHeader(HttpHeaderNames.CONTENT_LENGTH, Integer.toString(contentLength));
|
responseBuilder.setHeader(HttpHeaderNames.CONTENT_LENGTH, Integer.toString(contentLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPermanentRedirect(String url) {
|
public void movedPermanently(String url) {
|
||||||
responseBuilder.setResponseStatus(HttpResponseStatus.MOVED_PERMANENTLY);
|
responseBuilder.setResponseStatus(HttpResponseStatus.MOVED_PERMANENTLY); // 301
|
||||||
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRedirect(String url) {
|
public void found(String url) {
|
||||||
responseBuilder.setResponseStatus(HttpResponseStatus.FOUND);
|
responseBuilder.setResponseStatus(HttpResponseStatus.FOUND); // 302
|
||||||
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seeOther(String url) {
|
public void seeOther(String url) {
|
||||||
responseBuilder.setResponseStatus(HttpResponseStatus.SEE_OTHER);
|
responseBuilder.setResponseStatus(HttpResponseStatus.SEE_OTHER); // 303
|
||||||
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void temporaryRedirect(String url) {
|
public void temporaryRedirect(String url) {
|
||||||
responseBuilder.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT);
|
responseBuilder.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT); // 307
|
||||||
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue