Сервер: починить поиск сообщения в 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) { public Net_Response handle(Net_Request baseRequest, ConnectionContext ctx) {
Net_GetMessageThread_Request req = (Net_GetMessageThread_Request) baseRequest; Net_GetMessageThread_Request req = (Net_GetMessageThread_Request) baseRequest;
if (req.getMessage() == null || req.getMessage().getBlockchainName() == null || req.getMessage().getBlockNumber() == null) { 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()); 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()) { if (viewerLogin == null || viewerLogin.isBlank()) {
viewerLogin = ChannelsReadSupport.canonicalLogin(c, req.getLogin()); 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) { 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(); Net_GetMessageThread_Response resp = new Net_GetMessageThread_Response();
@@ -67,10 +67,31 @@ public class Net_GetMessageThread_Handler implements JsonMessageHandler {
return resp; return resp;
} catch (Exception e) { } catch (Exception e) {
log.error("GetMessageThread failed", 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 { 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(); if (depthDown <= 0) return List.of();
List<PostRow> replies = findReplies(c, parent.bchName, parent.blockNumber, parent.blockHash, childLimit); 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 { private PostRow mapRow(ResultSet rs) throws Exception {
PostRow row = new PostRow(); PostRow row = new PostRow();
row.login = rs.getString("login"); row.login = rs.getString("login");
@@ -57,11 +57,12 @@ public class IT_06_ChannelsApi {
JsonNode first = messages.get(0); JsonNode first = messages.get(0);
int blockNumber = first.path("messageRef").path("blockNumber").asInt(-1); int blockNumber = first.path("messageRef").path("blockNumber").asInt(-1);
String blockHash = first.path("messageRef").path("blockHash").asText(""); 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( String threadResp = ws.call(
"GetMessageThread", "GetMessageThread",
JsonBuilders.getMessageThread(bchName, blockNumber, blockHash, 20, 2, 50), JsonBuilders.getMessageThread(messageBlockchainName, blockNumber, blockHash, 20, 2, 50),
t t
); );
check200(r, threadResp, "GetMessageThread"); check200(r, threadResp, "GetMessageThread");
@@ -73,7 +74,7 @@ public class IT_06_ChannelsApi {
} }
r.ok("GetMessageThread: payload shape OK"); r.ok("GetMessageThread: payload shape OK");
} else { } else {
r.ok("GetMessageThread: пропущено, у первого сообщения нет корректного ref"); r.ok("GetMessageThread: пропущено, у первого сообщения нет полного messageRef/authorBlockchainName");
} }
} else { } else {
r.ok("GetMessageThread: пропущено, в канале нет сообщений"); r.ok("GetMessageThread: пропущено, в канале нет сообщений");
+1 -1
View File
@@ -1,2 +1,2 @@
client.version=1.2.354 client.version=1.2.354
server.version=1.2.327 server.version=1.2.328