removed unused file
This commit is contained in:
parent
212216b101
commit
3a14e79738
@ -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("\"", "\\\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user