Сервер: починить поиск сообщения в GetMessageThread

This commit is contained in:
AidarKC
2026-07-25 20:31:06 +04:00
parent 59a1117ed3
commit 8ddf592ffc
3 changed files with 72 additions and 8 deletions
@@ -28,7 +28,7 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) {
Net_GetMessageThread_Request req = (Net_GetMessageThread_Request) baseRequest;
if (req.getMessage() == null || req.getMessage().getBlockchainName() == null || req.getMessage().getBlockNumber() == null) {
return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "bad_fields", "Некорректные поля message");
return NetExceptionResponseFactory.error(req, WireCodes.Status.BAD_REQUEST, "bad_fields", "Некорректные поля message");
}
int depthUp = req.getDepthUp() == null ? 20 : Math.max(0, req.getDepthUp());
@@ -40,9 +40,9 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
if (viewerLogin == null || viewerLogin.isBlank()) {
viewerLogin = ChannelsReadSupport.canonicalLogin(c, req.getLogin());
}
PostRow focusRow = findByNumber(c, req.getMessage().getBlockchainName(), req.getMessage().getBlockNumber());
PostRow focusRow = findFocusRow(c, req.getMessage());
if (focusRow == null) {
return NetExceptionResponseFactory.error(req, 404, "message_not_found", "Сообщение не найдено");
return NetExceptionResponseFactory.error(req, 404, "message_not_found", "Сообщение не найдено");
}
Net_GetMessageThread_Response resp = new Net_GetMessageThread_Response();
@@ -67,10 +67,31 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
return resp;
} catch (Exception e) {
log.error("GetMessageThread failed", e);
return NetExceptionResponseFactory.error(req, WireCodes.Status.INTERNAL_ERROR, "internal_error", "Внутренняя ошибка сервера");
return NetExceptionResponseFactory.error(req, WireCodes.Status.INTERNAL_ERROR, "internal_error", "Внутренняя ошибка сервера");
}
}
private PostRow findFocusRow(Connection c, Net_GetMessageThread_Request.MessageSelector selector) throws Exception {
String blockchainName = String.valueOf(selector.getBlockchainName() == null ? "" : selector.getBlockchainName()).trim();
int blockNumber = selector.getBlockNumber();
byte[] blockHash = parseOptionalHash(selector.getBlockHash());
if (blockHash != null) {
PostRow exact = findByNumberAndHash(c, blockchainName, blockNumber, blockHash);
if (exact != null) return exact;
}
PostRow byNumber = findByNumber(c, blockchainName, blockNumber);
if (byNumber != null) return byNumber;
if (blockHash != null) {
PostRow byHash = findByHash(c, blockHash);
if (byHash != null) return byHash;
}
return null;
}
private List<Net_GetMessageThread_Response.MessageNodeTree> loadChildren(Connection c, PostRow parent, int depthDown, int childLimit, String viewerLogin) throws Exception {
if (depthDown <= 0) return List.of();
List<PostRow> replies = findReplies(c, parent.bchName, parent.blockNumber, parent.blockHash, childLimit);
@@ -123,6 +144,48 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
}
}
private PostRow findByNumberAndHash(Connection c, String bchName, int blockNumber, byte[] blockHash) throws Exception {
String sql = """
SELECT login,bch_name,block_number,block_hash,block_bytes,to_bch_name,to_block_number,to_block_hash,line_code,msg_sub_type,this_line_number
FROM blocks
WHERE bch_name=? AND block_number=? AND block_hash=?
LIMIT 1
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, bchName);
ps.setInt(2, blockNumber);
ps.setBytes(3, blockHash);
try (ResultSet rs = ps.executeQuery()) {
return rs.next() ? mapRow(rs) : null;
}
}
}
private PostRow findByHash(Connection c, byte[] blockHash) throws Exception {
String sql = """
SELECT login,bch_name,block_number,block_hash,block_bytes,to_bch_name,to_block_number,to_block_hash,line_code,msg_sub_type,this_line_number
FROM blocks
WHERE block_hash=?
LIMIT 1
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setBytes(1, blockHash);
try (ResultSet rs = ps.executeQuery()) {
return rs.next() ? mapRow(rs) : null;
}
}
}
private byte[] parseOptionalHash(String hex) {
String value = String.valueOf(hex == null ? "" : hex).trim();
if (value.isEmpty()) return null;
try {
return ChannelsReadSupport.hexToBytes(value);
} catch (Exception ignored) {
return null;
}
}
private PostRow mapRow(ResultSet rs) throws Exception {
PostRow row = new PostRow();
row.login = rs.getString("login");
@@ -57,11 +57,12 @@ public class IT_06_ChannelsApi {
JsonNode first = messages.get(0);
int blockNumber = first.path("messageRef").path("blockNumber").asInt(-1);
String blockHash = first.path("messageRef").path("blockHash").asText("");
String messageBlockchainName = first.path("authorBlockchainName").asText("");
if (blockNumber > 0 && !blockHash.isBlank()) {
if (!messageBlockchainName.isBlank() && blockNumber >= 0 && !blockHash.isBlank()) {
String threadResp = ws.call(
"GetMessageThread",
JsonBuilders.getMessageThread(bchName, blockNumber, blockHash, 20, 2, 50),
JsonBuilders.getMessageThread(messageBlockchainName, blockNumber, blockHash, 20, 2, 50),
t
);
check200(r, threadResp, "GetMessageThread");
@@ -73,7 +74,7 @@ public class IT_06_ChannelsApi {
}
r.ok("GetMessageThread: payload shape OK");
} else {
r.ok("GetMessageThread: пропущено, у первого сообщения нет корректного ref");
r.ok("GetMessageThread: пропущено, у первого сообщения нет полного messageRef/authorBlockchainName");
}
} else {
r.ok("GetMessageThread: пропущено, в канале нет сообщений");
+1 -1
View File
@@ -1,2 +1,2 @@
client.version=1.2.354
server.version=1.2.327
server.version=1.2.328