This breaks a lot of things, but it seems necessary. Implemented the resending mechanism and fixed many problems on the way, but tests and triggers are still to do.
This commit is contained in:
@ -24,6 +24,8 @@ import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||
import ch.dissem.bitmessage.exception.ApplicationException;
|
||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||
import ch.dissem.bitmessage.utils.Strings;
|
||||
import ch.dissem.bitmessage.utils.TTL;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -165,13 +167,20 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
return find("sender='" + sender.getAddress() + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Plaintext> findMessagesToResend() {
|
||||
return find("status='" + Plaintext.Status.SENT.name() + "'" +
|
||||
" AND next_try < " + UnixTime.now());
|
||||
}
|
||||
|
||||
private List<Plaintext> find(String where) {
|
||||
List<Plaintext> result = new LinkedList<>();
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, iv, type, sender, recipient, data, ack_data, sent, received, status " +
|
||||
"FROM Message WHERE " + where)
|
||||
ResultSet rs = stmt.executeQuery(
|
||||
"SELECT id, iv, type, sender, recipient, data, ack_data, sent, received, initial_hash, status, ttl, retries, next_try " +
|
||||
"FROM Message WHERE " + where)
|
||||
) {
|
||||
while (rs.next()) {
|
||||
byte[] iv = rs.getBytes("iv");
|
||||
@ -187,8 +196,13 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
builder.sent(rs.getLong("sent"));
|
||||
builder.received(rs.getLong("received"));
|
||||
builder.status(Plaintext.Status.valueOf(rs.getString("status")));
|
||||
builder.ttl(rs.getLong("ttl"));
|
||||
builder.retries(rs.getInt("retries"));
|
||||
builder.nextTry(rs.getLong("next_try"));
|
||||
builder.labels(findLabels(connection, id));
|
||||
result.add(builder.build());
|
||||
Plaintext message = builder.build();
|
||||
message.setInitialHash(rs.getBytes("initial_hash"));
|
||||
result.add(message);
|
||||
}
|
||||
} catch (IOException | SQLException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
@ -265,8 +279,9 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
|
||||
private void insert(Connection connection, Plaintext message) throws SQLException, IOException {
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"INSERT INTO Message (iv, type, sender, recipient, data, ack_data, sent, received, status, initial_hash) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
"INSERT INTO Message (iv, type, sender, recipient, data, ack_data, sent, received, " +
|
||||
"status, initial_hash, ttl, retries, next_try) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
Statement.RETURN_GENERATED_KEYS)
|
||||
) {
|
||||
ps.setBytes(1, message.getInventoryVector() == null ? null : message.getInventoryVector().getHash());
|
||||
@ -279,6 +294,9 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
ps.setLong(8, message.getReceived());
|
||||
ps.setString(9, message.getStatus() == null ? null : message.getStatus().name());
|
||||
ps.setBytes(10, message.getInitialHash());
|
||||
ps.setLong(11, message.getTTL());
|
||||
ps.setInt(12, message.getRetries());
|
||||
ps.setObject(13, message.getNextTry());
|
||||
|
||||
ps.executeUpdate();
|
||||
// get generated id
|
||||
@ -291,13 +309,23 @@ public class JdbcMessageRepository extends JdbcHelper implements MessageReposito
|
||||
|
||||
private void update(Connection connection, Plaintext message) throws SQLException, IOException {
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"UPDATE Message SET iv=?, sent=?, received=?, status=?, initial_hash=? WHERE id=?")) {
|
||||
"UPDATE Message SET iv=?, type=?, sender=?, recipient=?, data=?, ack_data=?, sent=?, received=?, " +
|
||||
"status=?, initial_hash=?, ttl=?, retries=?, next_try=? " +
|
||||
"WHERE id=?")) {
|
||||
ps.setBytes(1, message.getInventoryVector() == null ? null : message.getInventoryVector().getHash());
|
||||
ps.setLong(2, message.getSent());
|
||||
ps.setLong(3, message.getReceived());
|
||||
ps.setString(4, message.getStatus() == null ? null : message.getStatus().name());
|
||||
ps.setBytes(5, message.getInitialHash());
|
||||
ps.setLong(6, (Long) message.getId());
|
||||
ps.setString(2, message.getType().name());
|
||||
ps.setString(3, message.getFrom().getAddress());
|
||||
ps.setString(4, message.getTo() == null ? null : message.getTo().getAddress());
|
||||
writeBlob(ps, 5, message);
|
||||
ps.setBytes(6, message.getAckData());
|
||||
ps.setLong(7, message.getSent());
|
||||
ps.setLong(8, message.getReceived());
|
||||
ps.setString(9, message.getStatus() == null ? null : message.getStatus().name());
|
||||
ps.setBytes(10, message.getInitialHash());
|
||||
ps.setLong(11, message.getTTL());
|
||||
ps.setInt(12, message.getRetries());
|
||||
ps.setObject(13, message.getNextTry());
|
||||
ps.setLong(14, (Long) message.getId());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,4 @@
|
||||
ALTER TABLE Message ADD COLUMN ack_data BINARY(32);
|
||||
ALTER TABLE Message ADD COLUMN ttl BIGINT NOT NULL;
|
||||
ALTER TABLE Message ADD COLUMN retries INT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE Message ADD COLUMN next_try BIGINT;
|
||||
|
@ -19,6 +19,7 @@ package ch.dissem.bitmessage.repository;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.InternalContext;
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||
import ch.dissem.bitmessage.entity.Plaintext;
|
||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||
@ -32,6 +33,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
|
||||
import static ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK;
|
||||
import static ch.dissem.bitmessage.utils.Singleton.cryptography;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
@ -59,14 +61,14 @@ public class JdbcMessageRepositoryTest extends TestBase {
|
||||
.messageRepo(repo)
|
||||
);
|
||||
|
||||
BitmessageAddress tmp = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000));
|
||||
BitmessageAddress tmp = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000, DOES_ACK));
|
||||
contactA = new BitmessageAddress(tmp.getAddress());
|
||||
contactA.setPubkey(tmp.getPubkey());
|
||||
addressRepo.save(contactA);
|
||||
contactB = new BitmessageAddress("BM-2cTtkBnb4BUYDndTKun6D9PjtueP2h1bQj");
|
||||
addressRepo.save(contactB);
|
||||
|
||||
identity = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000));
|
||||
identity = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000, DOES_ACK));
|
||||
addressRepo.save(identity);
|
||||
|
||||
inbox = repo.getLabels(Label.Type.INBOX).get(0);
|
||||
@ -123,6 +125,18 @@ public class JdbcMessageRepositoryTest extends TestBase {
|
||||
assertThat(other, is(message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAckMessageCanBeUpdatedAndRetrieved() {
|
||||
byte[] initialHash = new byte[64];
|
||||
Plaintext message = repo.findMessages(contactA).get(0);
|
||||
message.setInitialHash(initialHash);
|
||||
ObjectMessage ackMessage = message.getAckMessage();
|
||||
repo.save(message);
|
||||
Plaintext other = repo.getMessage(initialHash);
|
||||
assertThat(other, is(message));
|
||||
assertThat(other.getAckMessage(), is(ackMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMessagesByStatus() throws Exception {
|
||||
List<Plaintext> messages = repo.findMessages(Plaintext.Status.RECEIVED);
|
||||
|
Reference in New Issue
Block a user