diff options
Diffstat (limited to 'dozentenmodulserver/src/main/java/org')
4 files changed, 132 insertions, 20 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java index e98f4d23..3b1a8de6 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java @@ -6,6 +6,9 @@ import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; @@ -25,6 +28,7 @@ import org.openslx.bwlp.sat.maintenance.DeleteOldUsers; import org.openslx.bwlp.sat.maintenance.MailFlusher; import org.openslx.bwlp.sat.maintenance.SendExpireWarning; import org.openslx.bwlp.sat.thrift.BinaryListener; +import org.openslx.bwlp.sat.thrift.JsonHttpListener; import org.openslx.bwlp.sat.thrift.cache.OperatingSystemList; import org.openslx.bwlp.sat.thrift.cache.OrganizationList; import org.openslx.bwlp.sat.thrift.cache.VirtualizerList; @@ -36,6 +40,8 @@ import org.openslx.sat.thrift.version.Version; import org.openslx.thrifthelper.ThriftManager; import org.openslx.thrifthelper.ThriftManager.ErrorCallback; import org.openslx.util.AppUtil; +import org.openslx.util.GrowingThreadPoolExecutor; +import org.openslx.util.PrioThreadFactory; import org.openslx.util.QuickTimer; public class App { @@ -46,12 +52,13 @@ public class App { private static final Set<String> failFastMethods = new HashSet<>(); - public static void main(String[] args) throws TTransportException, NoSuchAlgorithmException, IOException, - KeyManagementException - { + public static void main(String[] args) + throws TTransportException, NoSuchAlgorithmException, IOException, KeyManagementException { System.setProperty("mariadb.logging.disable", "true"); // setup basic logging appender to log output on console if no external appender (log4j.properties) is configured - if (org.apache.logging.log4j.core.Logger.class.cast(LogManager.getRootLogger()).getAppenders().isEmpty()) { + if (org.apache.logging.log4j.core.Logger.class.cast(LogManager.getRootLogger()) + .getAppenders() + .isEmpty()) { Configurator.initialize(new DefaultConfiguration()); } @@ -100,11 +107,10 @@ public class App { if (t instanceof TInvalidTokenException) return false; if (((TException) t).getCause() == null) { - LOGGER.info("Thrift error " + t.toString() + " for " - + method + ", retrying..."); + LOGGER.info("Thrift error " + t.toString() + " for " + method + ", retrying..."); } else { - LOGGER.info("Thrift error " + ((TException) t).getCause().toString() + " for " - + method + ", retrying..."); + LOGGER.info("Thrift error " + ((TException) t).getCause().toString() + " for " + method + + ", retrying..."); } try { Thread.sleep(failCount * 250); @@ -157,20 +163,29 @@ public class App { DeleteOldLectures.init(); DeleteOldUsers.init(); + // Shared executor for SSL thrift and HTTP thrift + ExecutorService es = new GrowingThreadPoolExecutor(3, 128, 1, TimeUnit.MINUTES, + new ArrayBlockingQueue<Runnable>(4), new PrioThreadFactory("SSL")); + // Start Thrift Server Thread t; // Plain - t = new Thread(new BinaryListener(9090, false)); + t = new Thread(new BinaryListener(9090, false, null)); t.setDaemon(true); t.start(); // SSL - t = new Thread(new BinaryListener(9091, true)); + t = new Thread(new BinaryListener(9091, true, es)); t.start(); - // Start httpd + // Start RPC httpd t = new Thread(new WebServer(9080)); t.setDaemon(true); t.start(); + // Start RPC httpd + t = new Thread(new JsonHttpListener(9081, es)); + t.setDaemon(true); + t.start(); + Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java index 7cb6ef19..d730eace 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.security.NoSuchAlgorithmException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; @@ -38,10 +39,10 @@ public class BinaryListener implements Runnable { private final TServer server; - public BinaryListener(int port, boolean secure) throws TTransportException, NoSuchAlgorithmException, - IOException { + public BinaryListener(int port, boolean secure, ExecutorService es) + throws TTransportException, NoSuchAlgorithmException, IOException { if (secure) - server = initSecure(port); + server = initSecure(port, es); else server = initNormal(port); } @@ -54,7 +55,7 @@ public class BinaryListener implements Runnable { // TODO: Restart listener; if it fails, quit server so it will be restarted by the OS } - private TServer initSecure(int port) throws NoSuchAlgorithmException, TTransportException, IOException { + private TServer initSecure(int port, ExecutorService es) throws NoSuchAlgorithmException, TTransportException, IOException { SSLContext context = Identity.getSSLContext(); if (context == null) return null; @@ -73,6 +74,7 @@ public class BinaryListener implements Runnable { TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport); args.protocolFactory(protFactory); args.processor(processor); + args.executorService(es); args.minWorkerThreads(MINWORKERTHREADS).maxWorkerThreads(MAXWORKERTHREADS); args.stopTimeoutVal(2).stopTimeoutUnit(TimeUnit.MINUTES); args.transportFactory(new TFastFramedTransport.Factory(MAX_MSG_LEN)); diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/JsonHttpListener.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/JsonHttpListener.java new file mode 100644 index 00000000..55c09756 --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/JsonHttpListener.java @@ -0,0 +1,95 @@ +package org.openslx.bwlp.sat.thrift; + +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.thrift.protocol.TJSONProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.TMemoryBuffer; +import org.openslx.bwlp.thrift.iface.SatelliteServer; +import org.openslx.util.Util; + +import fi.iki.elonen.NanoHTTPD; + +public class JsonHttpListener extends NanoHTTPD { + + private static final Logger LOGGER = LogManager.getLogger(JsonHttpListener.class); + + private final SatelliteServer.Processor<ServerHandler> processor = new SatelliteServer.Processor<ServerHandler>( + new ServerHandler()); + + public JsonHttpListener(int port, ExecutorService es) throws IOException { + super("127.0.0.1", port, es); + this.maxRequestSize = 1_000_000; + } + + @Override + public Response serve(IHTTPSession session) { + Response res = serveInternal(session); + if (res != null) { + addCorsHeaders(res); + } + return res; + } + + private Response serveInternal(IHTTPSession session) { + Method method = session.getMethod(); + if (Method.OPTIONS.equals(method)) + return new Response(Response.Status.NO_CONTENT, "application/json", ""); + if (!Method.PUT.equals(method) && !Method.POST.equals(method)) + return new Response(Response.Status.BAD_REQUEST, "text/plain; charset=UTF-8", + "Method not supported"); + + try { + //Input + String str = session.getHeaders().get("content-length"); + int len = 0; + if (str != null) { + len = Util.parseInt(str, 0); + } + if (len <= 0) { + len = session.getInputStream().available(); + } + if (len <= 0) + return new Response(Response.Status.BAD_REQUEST, "text/plain; charset=UTF-8", + "No Content-Length provided"); + + byte[] buffer = session.getInputStream().readNBytes(len); + TMemoryBuffer inbuffer = new TMemoryBuffer(buffer.length); + inbuffer.write(buffer); + TProtocol inprotocol = new TJSONProtocol(inbuffer); + + //Output + TMemoryBuffer outbuffer = new TMemoryBuffer(900); + TProtocol outprotocol = new TJSONProtocol(outbuffer); + + processor.process(inprotocol, outprotocol); + + buffer = Arrays.copyOf(outbuffer.getArray(), outbuffer.length()); + + return new Response(Response.Status.OK, "application/json", buffer); + } catch (Throwable t) { + if (!t.getMessage().contains("Remote side has closed")) { + LOGGER.warn("Error handling HTTP thrift", t); + } + return new Response(Response.Status.INTERNAL_ERROR, "text/plain; charset=UTF-8", t.getMessage()); + } + } + + @Override + public void serverStopped() { + System.exit(1); + } + + private static void addCorsHeaders(Response response) { + response.addHeader("Allow", "OPTIONS, GET, HEAD, POST, PUT"); + response.addHeader("Access-Control-Allow-Methods", "*"); + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Allow-Headers", "*, Content-Type"); + response.addHeader("Access-Control-Max-Age", "86400"); + } + +} diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java index f90a246a..85a824ae 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/web/WebServer.java @@ -8,7 +8,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -28,8 +28,8 @@ import org.openslx.bwlp.thrift.iface.NetShareAuth; import org.openslx.bwlp.thrift.iface.TNotFoundException; import org.openslx.util.GrowingThreadPoolExecutor; import org.openslx.util.Json; -import org.openslx.util.Util; import org.openslx.util.TarArchiveUtil.TarArchiveWriter; +import org.openslx.util.Util; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; @@ -40,12 +40,12 @@ public class WebServer extends NanoHTTPD { private static final Logger LOGGER = LogManager.getLogger(WebServer.class); private static final ThreadPoolExecutor tpe = new GrowingThreadPoolExecutor(1, 8, 1, TimeUnit.MINUTES, - new LinkedBlockingQueue<Runnable>(16)); + new ArrayBlockingQueue<Runnable>(16)); private static final Serializer serializer = new Persister(); - public WebServer(int port) { - super(Configuration.getWebServerBindAddressLocal(), port); + public WebServer(int port) throws IOException { + super(Configuration.getWebServerBindAddressLocal(), port, 16, 2); super.maxRequestSize = 65535; } |