Add web-api module with OpenAPI integration, enable chat logs forwarding to web backend, and update dependencies across modules.

This commit is contained in:
2026-07-18 20:21:25 +02:00
parent dc513ac2f0
commit 5a508fdf28
10 changed files with 356 additions and 24 deletions
@@ -1,6 +1,9 @@
package com.alttd.chat.objects.chat_log;
import com.alttd.altitudeweb.model.ChatMessageDto;
import com.alttd.chat.objects.BatchInsertable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.jetbrains.annotations.NotNull;
@@ -11,24 +14,21 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.util.UUID;
@AllArgsConstructor
public class ChatLog implements BatchInsertable {
@Getter
private final UUID uuid;
@Getter
private final Instant timestamp;
private final String server;
@Getter
private final String message;
@Getter
private final Component miniMessage;
@Getter
private final boolean blocked;
protected ChatLog(UUID uuid, Instant timestamp, String server, String message, Component miniMessage, boolean blocked) {
this.uuid = uuid;
this.timestamp = timestamp;
this.server = server;
this.message = message;
this.miniMessage = miniMessage;
this.blocked = blocked;
}
@Override
public void prepareStatement(@NotNull PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setString(1, uuid.toString());
@@ -41,19 +41,17 @@ public class ChatLog implements BatchInsertable {
preparedStatement.setInt(6, blocked ? 1 : 0);
}
public UUID getUuid() {
return uuid;
}
public Instant getTimestamp() {
return timestamp;
}
public String getMessage() {
return message;
}
public boolean isBlocked() {
return blocked;
public ChatMessageDto toDto() {
ChatMessageDto chatMessageDto = new ChatMessageDto();
if (miniMessage == null) {
throw new IllegalArgumentException("MiniMessage cannot be null");
}
chatMessageDto.setMessage(GsonComponentSerializer.gson().serialize(miniMessage));
chatMessageDto.setChannel(ChatMessageDto.ChannelEnum.CHAT);
chatMessageDto.setServer(server);
chatMessageDto.setTimestamp(timestamp);
chatMessageDto.setUuid(uuid);
chatMessageDto.setBlocked(blocked);
return chatMessageDto;
}
}
@@ -16,6 +16,7 @@ import java.util.concurrent.*;
public class ChatLogHandler {
private final ChatLogWebHandler chatLogWebHandler = new ChatLogWebHandler();
private static ChatLogHandler instance = null;
private ScheduledExecutorService executorService = null;
@@ -123,7 +124,9 @@ public class ChatLogHandler {
}
public void addChatLog(UUID uuid, String server, String message, Component miniMessage, boolean blocked) {
addLog(new ChatLog(uuid, Instant.now(), server, message, miniMessage, blocked));
ChatLog chatLog = new ChatLog(uuid, Instant.now(), server, message, miniMessage, blocked);
addLog(chatLog);
chatLogWebHandler.forwardChatLogToWeb(chatLog);
}
public CompletableFuture<List<ChatLog>> retrieveChatLogs(UUID uuid, Duration duration, String server) {
@@ -0,0 +1,96 @@
package com.alttd.chat.objects.chat_log;
import com.alttd.altitudeweb.api.ChatApi;
import com.alttd.altitudeweb.invoker.ApiClient;
import com.alttd.altitudeweb.invoker.ApiException;
import com.alttd.altitudeweb.model.ChatMessageDto;
import com.alttd.chat.util.ALogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ChatLogWebHandler {
private static final int MAX_QUEUE_SIZE = 100;
private static final Logger log = LoggerFactory.getLogger(ChatLogWebHandler.class);
private final Queue<ChatLog> queue = new ConcurrentLinkedQueue<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final ChatApi chatApi;
public ChatLogWebHandler() {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("http://10.0.0.109");
chatApi = new ChatApi(apiClient);
}
private volatile boolean sending;
public void forwardChatLogToWeb(ChatLog chatLog) {
if (queue.size() >= MAX_QUEUE_SIZE) {
queue.clear();
log.error("Chat log queue overflow, is the web backend still running?");
}
queue.add(chatLog);
triggerSend();
}
private void triggerSend() {
if (sending) {
return;
}
synchronized (this) {
if (sending || queue.isEmpty()) {
return;
}
sending = true;
}
executor.execute(this::sendBatch);
}
private void sendBatch() {
try {
ArrayList<ChatLog> chatLogList = new ArrayList<>();
ChatLog log;
while ((log = queue.poll()) != null) {
if (log.getMiniMessage() == null) {
ALogger.warn("No mini message for message, skipping");
continue;
}
chatLogList.add(log);
}
List<ChatMessageDto> batch = chatLogList.stream().map(ChatLog::toDto).toList();
if (!chatLogList.isEmpty()) {
try {
chatApi.sendChatMessages(batch);
} catch (ApiException e) {
ALogger.error("Failed to send chat messages to web backend, " +
"adding messages back to queue for another try", e
);
queue.addAll(chatLogList);
}
}
} finally {
synchronized (this) {
sending = false;
}
triggerSend();
}
}
}