removed unused file

This commit is contained in:
Radek Davidek 2026-03-27 22:22:47 +01:00
parent 212216b101
commit 3a14e79738

View File

@ -1,212 +0,0 @@
package local.processmonitor.api;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
public class Main {
private static final Gson GSON = new Gson();
public static void main(String[] args) throws Exception {
AppConfig config = AppConfig.load();
Database database = new Database(config);
HttpServer server = HttpServer.create(new InetSocketAddress(config.listenHost, config.listenPort), 0);
server.createContext(config.apiPath, new HeartbeatHandler(database));
server.setExecutor(null);
server.start();
log("Listening on http://" + config.listenHost + ":" + config.listenPort + config.apiPath);
}
private static final class HeartbeatHandler implements HttpHandler {
private final Database database;
private HeartbeatHandler(Database database) {
this.database = database;
}
@Override
public void handle(HttpExchange exchange) throws IOException {
try {
if (!"POST".equalsIgnoreCase(exchange.getRequestMethod())) {
sendJson(exchange, 405, "{\"error\":\"method_not_allowed\"}");
return;
}
Headers headers = exchange.getRequestHeaders();
String contentType = headers.getFirst("Content-Type");
if (contentType == null || !contentType.toLowerCase().contains("application/json")) {
sendJson(exchange, 415, "{\"error\":\"unsupported_media_type\"}");
return;
}
String body = readBody(exchange.getRequestBody());
log("Incoming heartbeat request: " + body);
HeartbeatRequest request = HeartbeatRequest.parse(body);
int insertedRows = database.saveHeartbeat(request);
log("Stored heartbeat for machine " + request.machineName + ", inserted rows: " + insertedRows);
sendJson(exchange, 200, String.format("{\"ok\":true,\"inserted\":%d}", insertedRows));
} catch (IllegalArgumentException ex) {
log("Request validation failed: " + ex.getMessage());
sendJson(exchange, 400, "{\"error\":\"" + escapeJson(ex.getMessage()) + "\"}");
} catch (Exception ex) {
ex.printStackTrace();
log("Internal server error: " + ex.getMessage());
sendJson(exchange, 500, "{\"error\":\"internal_error\"}");
}
}
private static String readBody(InputStream inputStream) throws IOException {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
private static void sendJson(HttpExchange exchange, int statusCode, String body) throws IOException {
byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8");
exchange.sendResponseHeaders(statusCode, bytes.length);
try (OutputStream outputStream = exchange.getResponseBody()) {
outputStream.write(bytes);
}
}
}
private static final class AppConfig {
private final String listenHost;
private final int listenPort;
private final String apiPath;
private final String jdbcUrl;
private final String dbUser;
private final String dbPassword;
private AppConfig(String listenHost, int listenPort, String apiPath, String jdbcUrl, String dbUser, String dbPassword) {
this.listenHost = listenHost;
this.listenPort = listenPort;
this.apiPath = apiPath;
this.jdbcUrl = jdbcUrl;
this.dbUser = dbUser;
this.dbPassword = dbPassword;
}
private static AppConfig load() throws IOException {
Properties properties = new Properties();
try (InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("application.properties")) {
if (inputStream == null) {
throw new IOException("Missing application.properties");
}
properties.load(inputStream);
}
String listenHost = properties.getProperty("server.host", "0.0.0.0");
int listenPort = Integer.parseInt(properties.getProperty("server.port", "8080"));
String apiPath = properties.getProperty("server.path", "/hb/api");
String jdbcUrl = required(properties, "db.url");
String dbUser = required(properties, "db.user");
String dbPassword = required(properties, "db.password");
return new AppConfig(listenHost, listenPort, apiPath, jdbcUrl, dbUser, dbPassword);
}
private static String required(Properties properties, String key) {
String value = properties.getProperty(key);
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("Missing config key: " + key);
}
return value.trim();
}
}
private static final class Database {
private final AppConfig config;
private Database(AppConfig config) {
this.config = config;
}
private int saveHeartbeat(HeartbeatRequest request) throws SQLException {
List<String> processes = request.processes.isEmpty() ? Collections.singletonList(null) : request.processes;
String sql = "INSERT INTO process_heartbeat (machine_name, status, detected_at, process_name) VALUES (?, ?, ?, ?)";
try (Connection connection = DriverManager.getConnection(config.jdbcUrl, config.dbUser, config.dbPassword);
PreparedStatement statement = connection.prepareStatement(sql)) {
int inserted = 0;
for (String processName : processes) {
statement.setString(1, request.machineName);
statement.setString(2, request.status);
statement.setTimestamp(3, Timestamp.from(request.detectedAt));
statement.setString(4, processName);
inserted += statement.executeUpdate();
}
return inserted;
}
}
}
private static final class HeartbeatRequest {
private String machine_name;
private String status;
private String detected_at;
private List<String> processes;
private transient String machineName;
private transient Instant detectedAt;
private static HeartbeatRequest parse(String json) {
try {
HeartbeatRequest request = GSON.fromJson(json, HeartbeatRequest.class);
if (request == null) {
throw new IllegalArgumentException("Empty request body");
}
request.validate();
return request;
} catch (JsonSyntaxException ex) {
throw new IllegalArgumentException("Invalid JSON");
}
}
private void validate() {
machineName = required(machine_name, "machine_name");
status = required(status, "status");
try {
detectedAt = Instant.parse(required(detected_at, "detected_at"));
} catch (DateTimeParseException ex) {
throw new IllegalArgumentException("Invalid detected_at");
}
if (processes == null) {
processes = Collections.emptyList();
}
}
private static String required(String value, String fieldName) {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("Missing field: " + fieldName);
}
return value.trim();
}
}
private static void log(String message) {
System.out.printf("[%s] %s%n", Instant.now(), message);
}
private static String escapeJson(String value) {
return value.replace("\\", "\\\\").replace("\"", "\\\"");
}
}