From 59cf29c2ceaa7fe47791d7d790842119eac86cf6 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Sun, 3 Nov 2024 00:07:03 +0200 Subject: [PATCH] begin working on HTTP tracker server. parse config.json for tracker endpoints and create appropriate protocol servers --- .../com/mykola2312/retracker/Application.java | 80 +++++++++++++++++++ .../java/com/mykola2312/retracker/Main.java | 4 + .../mykola2312/retracker/config/Config.java | 7 ++ .../retracker/tracker/TrackerHTTPServer.java | 77 ++++++++++++++++++ .../retracker/tracker/TrackerJob.java | 7 ++ .../retracker/tracker/TrackerProtocol.java | 9 +++ .../retracker/tracker/TrackerServer.java | 5 ++ 7 files changed, 189 insertions(+) create mode 100644 src/main/java/com/mykola2312/retracker/tracker/TrackerHTTPServer.java create mode 100644 src/main/java/com/mykola2312/retracker/tracker/TrackerJob.java create mode 100644 src/main/java/com/mykola2312/retracker/tracker/TrackerServer.java diff --git a/src/main/java/com/mykola2312/retracker/Application.java b/src/main/java/com/mykola2312/retracker/Application.java index 4543a7c..3830779 100644 --- a/src/main/java/com/mykola2312/retracker/Application.java +++ b/src/main/java/com/mykola2312/retracker/Application.java @@ -1,9 +1,15 @@ package com.mykola2312.retracker; +import java.util.LinkedList; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mykola2312.retracker.config.Config; +import com.mykola2312.retracker.tracker.Tracker; +import com.mykola2312.retracker.tracker.TrackerEndpoint; +import com.mykola2312.retracker.tracker.TrackerHTTPServer; +import com.mykola2312.retracker.tracker.TrackerServer; /* Class responsible for managing running server threads * and repeating timer-based tasks @@ -13,7 +19,81 @@ public class Application { private Config config; + private Tracker tracker; + private LinkedList servers; + public Application(Config config) { this.config = config; } + + private class TrackerServerFactory { + private Tracker tracker; + private String endpointUrl; + + public TrackerServerFactory(Tracker tracker, String endpointUrl) { + this.tracker = tracker; + this.endpointUrl = endpointUrl; + } + + public TrackerServer create() throws Exception { + TrackerEndpoint endpoint = TrackerEndpoint.parseEndpoint(endpointUrl); + switch (endpoint.getProtocol()) { + case HTTP: return new TrackerHTTPServer(tracker, endpoint); + default: + throw new UnsupportedOperationException("protocol not implemented yet " + endpoint.getProtocol().toString()); + } + } + } + + public void init() { + // create tracker + tracker = new Tracker(); + // create endpoint servers + servers = new LinkedList(); + for (String endpointUrl : config.tracker.endpoints) { + try { + TrackerServer server = new TrackerServerFactory(tracker, endpointUrl) + .create(); + + servers.add(server); + } catch (Exception e) { + logger.error("failed to create endpoint {}: {}", endpointUrl, e.toString()); + } + } + } + + public void start() { + // start servers + for (TrackerServer server : servers) { + try { + server.start(); + } catch (Exception e) { + final String endpointString = server.getEndpoint().getAddress().toString(); + logger.error("failed to start server {}: {}", endpointString, e.toString()); + } + } + } + + public void stop() { + // stop servers + for (TrackerServer server : servers) { + try { + server.stop(); + } catch (Exception e) { + final String endpointString = server.getEndpoint().getAddress().toString(); + logger.error("failed to stop server {}: {}", endpointString, e.toString()); + } + } + } + + public void mainLoop() { + // TODO: only for debugging purposes + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.error("main thread interrupted: {}", e.toString()); + } + } + } } diff --git a/src/main/java/com/mykola2312/retracker/Main.java b/src/main/java/com/mykola2312/retracker/Main.java index e976def..6f9f463 100644 --- a/src/main/java/com/mykola2312/retracker/Main.java +++ b/src/main/java/com/mykola2312/retracker/Main.java @@ -85,7 +85,11 @@ public class Main { } Application app = new Application(config); + app.init(); + app.start(); log.info("retracker started!"); + + app.mainLoop(); } } diff --git a/src/main/java/com/mykola2312/retracker/config/Config.java b/src/main/java/com/mykola2312/retracker/config/Config.java index a076fae..f66c28a 100644 --- a/src/main/java/com/mykola2312/retracker/config/Config.java +++ b/src/main/java/com/mykola2312/retracker/config/Config.java @@ -2,10 +2,17 @@ package com.mykola2312.retracker.config; import java.io.File; import java.io.IOException; +import java.util.List; import com.fasterxml.jackson.databind.ObjectMapper; public class Config { + public static class TrackerConfig { + public List endpoints; + } + + public TrackerConfig tracker; + public static Config loadConfig(String configPath) throws IOException { return new ObjectMapper() .readerFor(Config.class) diff --git a/src/main/java/com/mykola2312/retracker/tracker/TrackerHTTPServer.java b/src/main/java/com/mykola2312/retracker/tracker/TrackerHTTPServer.java new file mode 100644 index 0000000..be4b4e0 --- /dev/null +++ b/src/main/java/com/mykola2312/retracker/tracker/TrackerHTTPServer.java @@ -0,0 +1,77 @@ +package com.mykola2312.retracker.tracker; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class TrackerHTTPServer implements TrackerServer { + private static final Logger logger = LoggerFactory.getLogger(TrackerHTTPServer.class); + + private Tracker tracker; + private TrackerEndpoint endpoint; + private HttpServer httpServer = null; + + public TrackerHTTPServer(Tracker tracker, TrackerEndpoint endpoint) { + this.tracker = tracker; + this.endpoint = endpoint; + } + + private class AnnounceHTTPHandler implements HttpHandler { + private static final Logger logger = LoggerFactory.getLogger(AnnounceHTTPHandler.class); + + private Tracker tracker; + + public AnnounceHTTPHandler(Tracker tracker) { + this.tracker = tracker; + } + + @Override + public void handle(HttpExchange exchange) throws IOException { + if (exchange.getRequestMethod().equals("GET")) { + handleAnnounce(exchange); + } + } + + private void handleAnnounce(HttpExchange exchange) throws IOException { + // here we need parse URI parameters and pass them to PeerLocalData + logger.info(exchange.getRequestURI().toString()); + } + } + + @Override + public void start() { + try { + httpServer = HttpServer.create(endpoint.getAddress(), 0); + + AnnounceHTTPHandler handler = new AnnounceHTTPHandler(getTracker()); + httpServer.createContext("/", handler); + + httpServer.start(); + } catch (IOException e) { + logger.error("HttpServer: {}", e.toString()); + } + } + + @Override + public void stop() { + if (httpServer != null) { + httpServer.stop(0); + httpServer = null; + } + } + + @Override + public Tracker getTracker() { + return tracker; + } + + @Override + public TrackerEndpoint getEndpoint() { + return endpoint; + } +} diff --git a/src/main/java/com/mykola2312/retracker/tracker/TrackerJob.java b/src/main/java/com/mykola2312/retracker/tracker/TrackerJob.java new file mode 100644 index 0000000..835b7ed --- /dev/null +++ b/src/main/java/com/mykola2312/retracker/tracker/TrackerJob.java @@ -0,0 +1,7 @@ +package com.mykola2312.retracker.tracker; + +public interface TrackerJob { + void start(); + void stop(); + Tracker getTracker(); +} diff --git a/src/main/java/com/mykola2312/retracker/tracker/TrackerProtocol.java b/src/main/java/com/mykola2312/retracker/tracker/TrackerProtocol.java index 6a3d0ff..1ee0f2d 100644 --- a/src/main/java/com/mykola2312/retracker/tracker/TrackerProtocol.java +++ b/src/main/java/com/mykola2312/retracker/tracker/TrackerProtocol.java @@ -11,4 +11,13 @@ public enum TrackerProtocol { default: return 0; } } + + @Override + public String toString() { + switch (this) { + case HTTP: return "http"; + case UDP: return "udp"; + default: return ""; + } + } } diff --git a/src/main/java/com/mykola2312/retracker/tracker/TrackerServer.java b/src/main/java/com/mykola2312/retracker/tracker/TrackerServer.java new file mode 100644 index 0000000..5c668ca --- /dev/null +++ b/src/main/java/com/mykola2312/retracker/tracker/TrackerServer.java @@ -0,0 +1,5 @@ +package com.mykola2312.retracker.tracker; + +public interface TrackerServer extends TrackerJob { + TrackerEndpoint getEndpoint(); +}