Migrated core and extension modules to Kotlin
(Except BitmessageContext and Bytes)
This commit is contained in:
@ -97,10 +97,10 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
private List<BitmessageAddress> find(String where) {
|
||||
List<BitmessageAddress> result = new LinkedList<>();
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT address, alias, public_key, private_key, subscribed, chan " +
|
||||
"FROM Address WHERE " + where)
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT address, alias, public_key, private_key, subscribed, chan " +
|
||||
"FROM Address WHERE " + where)
|
||||
) {
|
||||
while (rs.next()) {
|
||||
BitmessageAddress address;
|
||||
@ -111,7 +111,7 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
Blob publicKeyBlob = rs.getBlob("public_key");
|
||||
if (publicKeyBlob != null) {
|
||||
Pubkey pubkey = Factory.readPubkey(address.getVersion(), address.getStream(),
|
||||
publicKeyBlob.getBinaryStream(), (int) publicKeyBlob.length(), false);
|
||||
publicKeyBlob.getBinaryStream(), (int) publicKeyBlob.length(), false);
|
||||
if (address.getVersion() == 4 && pubkey instanceof V3Pubkey) {
|
||||
pubkey = new V4Pubkey((V3Pubkey) pubkey);
|
||||
}
|
||||
@ -127,7 +127,7 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
|
||||
result.add(address);
|
||||
}
|
||||
} catch (IOException | SQLException e) {
|
||||
} catch (SQLException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
@ -135,10 +135,10 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
|
||||
private boolean exists(BitmessageAddress address) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM Address " +
|
||||
"WHERE address='" + address.getAddress() + "'")
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM Address " +
|
||||
"WHERE address='" + address.getAddress() + "'")
|
||||
) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1) > 0;
|
||||
@ -172,8 +172,8 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
}
|
||||
statement.append(", subscribed=?, chan=? WHERE address=?");
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement(statement.toString())
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement(statement.toString())
|
||||
) {
|
||||
int i = 0;
|
||||
ps.setString(++i, address.getAlias());
|
||||
@ -192,10 +192,10 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
|
||||
private void insert(BitmessageAddress address) throws IOException, SQLException {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement(
|
||||
"INSERT INTO Address (address, version, alias, public_key, private_key, subscribed, chan) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?)")
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement(
|
||||
"INSERT INTO Address (address, version, alias, public_key, private_key, subscribed, chan) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?)")
|
||||
) {
|
||||
ps.setString(1, address.getAddress());
|
||||
ps.setLong(2, address.getVersion());
|
||||
@ -221,8 +221,8 @@ public class JdbcAddressRepository extends JdbcHelper implements AddressReposito
|
||||
@Override
|
||||
public void remove(BitmessageAddress address) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement()
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement()
|
||||
) {
|
||||
stmt.executeUpdate("DELETE FROM Address WHERE address = '" + address.getAddress() + "'");
|
||||
} catch (SQLException e) {
|
||||
|
@ -17,24 +17,16 @@
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.Streamable;
|
||||
import ch.dissem.bitmessage.entity.payload.ObjectType;
|
||||
import ch.dissem.bitmessage.exception.ApplicationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.Strings.hex;
|
||||
|
||||
/**
|
||||
* Helper class that does Flyway migration, provides JDBC connections and some helper methods.
|
||||
*/
|
||||
public abstract class JdbcHelper {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JdbcHelper.class);
|
||||
|
||||
protected final JdbcConfig config;
|
||||
|
||||
|
@ -49,8 +49,8 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
List<InventoryVector> result = new LinkedList<>();
|
||||
for (long stream : streams) {
|
||||
getCache(stream).entrySet().stream()
|
||||
.filter(e -> e.getValue() > now())
|
||||
.forEach(e -> result.add(e.getKey()));
|
||||
.filter(e -> e.getValue() > now())
|
||||
.forEach(e -> result.add(e.getKey()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -63,10 +63,10 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
result = new ConcurrentHashMap<>();
|
||||
cache.put(stream, result);
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT hash, expires FROM Inventory " +
|
||||
"WHERE expires > " + now(-5 * MINUTE) + " AND stream = " + stream)
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT hash, expires FROM Inventory " +
|
||||
"WHERE expires > " + (now() - 5 * MINUTE) + " AND stream = " + stream)
|
||||
) {
|
||||
while (rs.next()) {
|
||||
result.put(InventoryVector.fromHash(rs.getBytes("hash")), rs.getLong("expires"));
|
||||
@ -91,9 +91,9 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
@Override
|
||||
public ObjectMessage getObject(InventoryVector vector) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT data, version FROM Inventory WHERE hash = X'" + vector + "'")
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT data, version FROM Inventory WHERE hash = X'" + vector + "'")
|
||||
) {
|
||||
if (rs.next()) {
|
||||
Blob data = rs.getBlob("data");
|
||||
@ -121,9 +121,9 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
query.append(" AND type IN (").append(join(types)).append(')');
|
||||
}
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(query.toString())
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(query.toString())
|
||||
) {
|
||||
List<ObjectMessage> result = new LinkedList<>();
|
||||
while (rs.next()) {
|
||||
@ -143,9 +143,9 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
return;
|
||||
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("INSERT INTO Inventory " +
|
||||
"(hash, stream, expires, data, type, version) VALUES (?, ?, ?, ?, ?, ?)")
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("INSERT INTO Inventory " +
|
||||
"(hash, stream, expires, data, type, version) VALUES (?, ?, ?, ?, ?, ?)")
|
||||
) {
|
||||
InventoryVector iv = object.getInventoryVector();
|
||||
LOG.trace("Storing object " + iv);
|
||||
@ -167,21 +167,21 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
||||
@Override
|
||||
public boolean contains(ObjectMessage object) {
|
||||
return getCache(object.getStream()).entrySet().stream()
|
||||
.anyMatch(x -> x.getKey().equals(object.getInventoryVector()));
|
||||
.anyMatch(x -> x.getKey().equals(object.getInventoryVector()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement()
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement()
|
||||
) {
|
||||
stmt.executeUpdate("DELETE FROM Inventory WHERE expires < " + now(-5 * MINUTE));
|
||||
stmt.executeUpdate("DELETE FROM Inventory WHERE expires < " + (now() - 5 * MINUTE));
|
||||
} catch (SQLException e) {
|
||||
LOG.debug(e.getMessage(), e);
|
||||
}
|
||||
for (Map<InventoryVector, Long> c : cache.values()) {
|
||||
c.entrySet().removeIf(e -> e.getValue() < now(-5 * MINUTE));
|
||||
c.entrySet().removeIf(e -> e.getValue() < (now() - 5 * MINUTE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,8 +111,8 @@ public class JdbcMessageRepository extends AbstractMessageRepository implements
|
||||
long id = rs.getLong("id");
|
||||
builder.id(id);
|
||||
builder.IV(InventoryVector.fromHash(iv));
|
||||
builder.from(ctx.getAddressRepository().getAddress(rs.getString("sender")));
|
||||
builder.to(ctx.getAddressRepository().getAddress(rs.getString("recipient")));
|
||||
builder.from(getCtx().getAddressRepository().getAddress(rs.getString("sender")));
|
||||
builder.to(getCtx().getAddressRepository().getAddress(rs.getString("recipient")));
|
||||
builder.ackData(rs.getBytes("ack_data"));
|
||||
builder.sent(rs.getObject("sent", Long.class));
|
||||
builder.received(rs.getObject("received", Long.class));
|
||||
@ -127,7 +127,7 @@ public class JdbcMessageRepository extends AbstractMessageRepository implements
|
||||
message.setInitialHash(rs.getBytes("initial_hash"));
|
||||
result.add(message);
|
||||
}
|
||||
} catch (IOException | SQLException e) {
|
||||
} catch (SQLException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
@ -33,7 +49,7 @@ public class JdbcNodeRegistry extends JdbcHelper implements NodeRegistry {
|
||||
PreparedStatement ps = connection.prepareStatement(
|
||||
"DELETE FROM Node WHERE time<?")
|
||||
) {
|
||||
ps.setLong(1, now(-28 * DAY));
|
||||
ps.setLong(1, now() - 28 * DAY);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
@ -135,7 +151,7 @@ public class JdbcNodeRegistry extends JdbcHelper implements NodeRegistry {
|
||||
public void offerAddresses(List<NetworkAddress> nodes) {
|
||||
cleanUp();
|
||||
nodes.stream()
|
||||
.filter(node -> node.getTime() < now(+2 * MINUTE) && node.getTime() > now(-28 * DAY))
|
||||
.filter(node -> node.getTime() < now() + 2 * MINUTE && node.getTime() > now() - 28 * DAY)
|
||||
.forEach(node -> {
|
||||
synchronized (this) {
|
||||
NetworkAddress existing = loadExisting(node);
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.InternalContext;
|
||||
@ -30,9 +46,9 @@ public class JdbcProofOfWorkRepository extends JdbcHelper implements ProofOfWork
|
||||
@Override
|
||||
public Item getItem(byte[] initialHash) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT data, version, nonce_trials_per_byte, " +
|
||||
"extra_bytes, expiration_time, message_id FROM POW WHERE initial_hash=?")
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("SELECT data, version, nonce_trials_per_byte, " +
|
||||
"extra_bytes, expiration_time, message_id FROM POW WHERE initial_hash=?")
|
||||
) {
|
||||
ps.setBytes(1, initialHash);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
@ -40,17 +56,17 @@ public class JdbcProofOfWorkRepository extends JdbcHelper implements ProofOfWork
|
||||
Blob data = rs.getBlob("data");
|
||||
if (rs.getObject("message_id") == null) {
|
||||
return new Item(
|
||||
Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()),
|
||||
rs.getLong("nonce_trials_per_byte"),
|
||||
rs.getLong("extra_bytes")
|
||||
Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()),
|
||||
rs.getLong("nonce_trials_per_byte"),
|
||||
rs.getLong("extra_bytes")
|
||||
);
|
||||
} else {
|
||||
return new Item(
|
||||
Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()),
|
||||
rs.getLong("nonce_trials_per_byte"),
|
||||
rs.getLong("extra_bytes"),
|
||||
rs.getLong("expiration_time"),
|
||||
ctx.getMessageRepository().getMessage(rs.getLong("message_id"))
|
||||
Factory.getObjectMessage(rs.getInt("version"), data.getBinaryStream(), (int) data.length()),
|
||||
rs.getLong("nonce_trials_per_byte"),
|
||||
rs.getLong("extra_bytes"),
|
||||
rs.getLong("expiration_time"),
|
||||
ctx.getMessageRepository().getMessage(rs.getLong("message_id"))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -66,9 +82,9 @@ public class JdbcProofOfWorkRepository extends JdbcHelper implements ProofOfWork
|
||||
@Override
|
||||
public List<byte[]> getItems() {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT initial_hash FROM POW")
|
||||
Connection connection = config.getConnection();
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT initial_hash FROM POW")
|
||||
) {
|
||||
List<byte[]> result = new LinkedList<>();
|
||||
while (rs.next()) {
|
||||
@ -84,27 +100,27 @@ public class JdbcProofOfWorkRepository extends JdbcHelper implements ProofOfWork
|
||||
@Override
|
||||
public void putObject(Item item) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("INSERT INTO POW (initial_hash, data, version, " +
|
||||
"nonce_trials_per_byte, extra_bytes, expiration_time, message_id) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?)")
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("INSERT INTO POW (initial_hash, data, version, " +
|
||||
"nonce_trials_per_byte, extra_bytes, expiration_time, message_id) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?)")
|
||||
) {
|
||||
ps.setBytes(1, cryptography().getInitialHash(item.object));
|
||||
writeBlob(ps, 2, item.object);
|
||||
ps.setLong(3, item.object.getVersion());
|
||||
ps.setLong(4, item.nonceTrialsPerByte);
|
||||
ps.setLong(5, item.extraBytes);
|
||||
ps.setBytes(1, cryptography().getInitialHash(item.getObject()));
|
||||
writeBlob(ps, 2, item.getObject());
|
||||
ps.setLong(3, item.getObject().getVersion());
|
||||
ps.setLong(4, item.getNonceTrialsPerByte());
|
||||
ps.setLong(5, item.getExtraBytes());
|
||||
|
||||
if (item.message == null) {
|
||||
if (item.getMessage() == null) {
|
||||
ps.setObject(6, null);
|
||||
ps.setObject(7, null);
|
||||
} else {
|
||||
ps.setLong(6, item.expirationTime);
|
||||
ps.setLong(7, (Long) item.message.getId());
|
||||
ps.setLong(6, item.getExpirationTime());
|
||||
ps.setLong(7, (Long) item.getMessage().getId());
|
||||
}
|
||||
ps.executeUpdate();
|
||||
} catch (IOException | SQLException e) {
|
||||
LOG.debug("Error storing object of type " + item.object.getPayload().getClass().getSimpleName(), e);
|
||||
LOG.debug("Error storing object of type " + item.getObject().getPayload().getClass().getSimpleName(), e);
|
||||
throw new ApplicationException(e);
|
||||
}
|
||||
}
|
||||
@ -117,8 +133,8 @@ public class JdbcProofOfWorkRepository extends JdbcHelper implements ProofOfWork
|
||||
@Override
|
||||
public void removeObject(byte[] initialHash) {
|
||||
try (
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("DELETE FROM POW WHERE initial_hash=?")
|
||||
Connection connection = config.getConnection();
|
||||
PreparedStatement ps = connection.prepareStatement("DELETE FROM POW WHERE initial_hash=?")
|
||||
) {
|
||||
ps.setBytes(1, initialHash);
|
||||
ps.executeUpdate();
|
||||
|
@ -17,7 +17,6 @@
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey;
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -72,7 +71,7 @@ public class JdbcAddressRepositoryTest extends TestBase {
|
||||
|
||||
BitmessageAddress storedIdentity = repo.findIdentity(identity.getTag());
|
||||
assertEquals(identity, storedIdentity);
|
||||
assertTrue(storedIdentity.has(Pubkey.Feature.DOES_ACK));
|
||||
assertTrue(storedIdentity.has(DOES_ACK));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -181,4 +180,4 @@ public class JdbcAddressRepositoryTest extends TestBase {
|
||||
subscription.setSubscribed(true);
|
||||
repo.save(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,7 @@ import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding;
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||
import ch.dissem.bitmessage.entity.valueobject.extended.Message;
|
||||
import ch.dissem.bitmessage.ports.AddressRepository;
|
||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||
import ch.dissem.bitmessage.ports.*;
|
||||
import ch.dissem.bitmessage.utils.TestUtils;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.hamcrest.BaseMatcher;
|
||||
@ -45,6 +44,7 @@ import static ch.dissem.bitmessage.utils.Singleton.cryptography;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class JdbcMessageRepositoryTest extends TestBase {
|
||||
private BitmessageAddress contactA;
|
||||
@ -64,12 +64,21 @@ public class JdbcMessageRepositoryTest extends TestBase {
|
||||
config.reset();
|
||||
AddressRepository addressRepo = new JdbcAddressRepository(config);
|
||||
repo = new JdbcMessageRepository(config);
|
||||
new InternalContext(new BitmessageContext.Builder()
|
||||
.cryptography(cryptography())
|
||||
.addressRepo(addressRepo)
|
||||
.messageRepo(repo)
|
||||
new InternalContext(
|
||||
cryptography(),
|
||||
mock(Inventory.class),
|
||||
mock(NodeRegistry.class),
|
||||
mock(NetworkHandler.class),
|
||||
addressRepo,
|
||||
repo,
|
||||
mock(ProofOfWorkRepository.class),
|
||||
mock(ProofOfWorkEngine.class),
|
||||
mock(CustomCommandHandler.class),
|
||||
mock(BitmessageContext.Listener.class),
|
||||
mock(Labeler.class),
|
||||
12345,
|
||||
10, 10
|
||||
);
|
||||
|
||||
BitmessageAddress tmp = new BitmessageAddress(new PrivateKey(false, 1, 1000, 1000, DOES_ACK));
|
||||
contactA = new BitmessageAddress(tmp.getAddress());
|
||||
contactA.setPubkey(tmp.getPubkey());
|
||||
@ -225,7 +234,7 @@ public class JdbcMessageRepositoryTest extends TestBase {
|
||||
message.updateNextTry();
|
||||
assertThat(message.getRetries(), is(1));
|
||||
assertThat(message.getNextTry(), greaterThan(UnixTime.now()));
|
||||
assertThat(message.getNextTry(), lessThanOrEqualTo(UnixTime.now(+2)));
|
||||
assertThat(message.getNextTry(), lessThanOrEqualTo(UnixTime.now() + 2));
|
||||
repo.save(message);
|
||||
Thread.sleep(4100); // somewhat longer than 2*TTL
|
||||
List<Plaintext> messagesToResend = repo.findMessagesToResend();
|
||||
|
@ -18,7 +18,6 @@ package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
|
||||
import ch.dissem.bitmessage.ports.NodeRegistry;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -28,7 +27,6 @@ import java.util.List;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.UnixTime.now;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
|
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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.payload.GenericPayload;
|
||||
import ch.dissem.bitmessage.entity.payload.GetPubkey;
|
||||
import ch.dissem.bitmessage.ports.AddressRepository;
|
||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository.Item;
|
||||
import ch.dissem.bitmessage.utils.TestUtils;
|
||||
import ch.dissem.bitmessage.utils.UnixTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
|
||||
import static ch.dissem.bitmessage.utils.Singleton.cryptography;
|
||||
import static ch.dissem.bitmessage.utils.UnixTime.MINUTE;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
public class JdbcProofOfWorkRepositoryTest extends TestBase {
|
||||
private TestJdbcConfig config;
|
||||
private JdbcProofOfWorkRepository repo;
|
||||
private AddressRepository addressRepo;
|
||||
private MessageRepository messageRepo;
|
||||
|
||||
private byte[] initialHash1;
|
||||
private byte[] initialHash2;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
config = new TestJdbcConfig();
|
||||
config.reset();
|
||||
|
||||
addressRepo = new JdbcAddressRepository(config);
|
||||
messageRepo = new JdbcMessageRepository(config);
|
||||
repo = new JdbcProofOfWorkRepository(config);
|
||||
InternalContext ctx = new InternalContext(new BitmessageContext.Builder()
|
||||
.addressRepo(addressRepo)
|
||||
.messageRepo(messageRepo)
|
||||
.powRepo(repo)
|
||||
.cryptography(cryptography())
|
||||
);
|
||||
|
||||
repo.putObject(new ObjectMessage.Builder()
|
||||
.payload(new GetPubkey(new BitmessageAddress("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn"))).build(),
|
||||
1000, 1000);
|
||||
initialHash1 = repo.getItems().get(0);
|
||||
|
||||
BitmessageAddress sender = TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8");
|
||||
BitmessageAddress recipient = TestUtils.loadContact();
|
||||
addressRepo.save(sender);
|
||||
addressRepo.save(recipient);
|
||||
Plaintext plaintext = new Plaintext.Builder(MSG)
|
||||
.ackData(cryptography().randomBytes(32))
|
||||
.from(sender)
|
||||
.to(recipient)
|
||||
.message("Subject", "Message")
|
||||
.status(Plaintext.Status.DOING_PROOF_OF_WORK)
|
||||
.build();
|
||||
messageRepo.save(plaintext);
|
||||
initialHash2 = cryptography().getInitialHash(plaintext.getAckMessage());
|
||||
repo.putObject(new Item(
|
||||
plaintext.getAckMessage(),
|
||||
1000, 1000,
|
||||
UnixTime.now(+10 * MINUTE),
|
||||
plaintext
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureObjectIsStored() throws Exception {
|
||||
int sizeBefore = repo.getItems().size();
|
||||
repo.putObject(new ObjectMessage.Builder()
|
||||
.payload(new GetPubkey(new BitmessageAddress("BM-2D9U2hv3YBMHM1zERP32anKfVKohyPN9x2"))).build(),
|
||||
1000, 1000);
|
||||
assertThat(repo.getItems().size(), is(sizeBefore + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAckObjectsAreStored() throws Exception {
|
||||
int sizeBefore = repo.getItems().size();
|
||||
BitmessageAddress sender = TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8");
|
||||
BitmessageAddress recipient = TestUtils.loadContact();
|
||||
addressRepo.save(sender);
|
||||
addressRepo.save(recipient);
|
||||
Plaintext plaintext = new Plaintext.Builder(MSG)
|
||||
.ackData(cryptography().randomBytes(32))
|
||||
.from(sender)
|
||||
.to(recipient)
|
||||
.message("Subject", "Message")
|
||||
.status(Plaintext.Status.DOING_PROOF_OF_WORK)
|
||||
.build();
|
||||
messageRepo.save(plaintext);
|
||||
repo.putObject(new Item(
|
||||
plaintext.getAckMessage(),
|
||||
1000, 1000,
|
||||
UnixTime.now(+10 * MINUTE),
|
||||
plaintext
|
||||
));
|
||||
assertThat(repo.getItems().size(), is(sizeBefore + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureItemCanBeRetrieved() {
|
||||
Item item = repo.getItem(initialHash1);
|
||||
assertThat(item, notNullValue());
|
||||
assertThat(item.object.getPayload(), instanceOf(GetPubkey.class));
|
||||
assertThat(item.nonceTrialsPerByte, is(1000L));
|
||||
assertThat(item.extraBytes, is(1000L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAckItemCanBeRetrieved() {
|
||||
Item item = repo.getItem(initialHash2);
|
||||
assertThat(item, notNullValue());
|
||||
assertThat(item.object.getPayload(), instanceOf(GenericPayload.class));
|
||||
assertThat(item.nonceTrialsPerByte, is(1000L));
|
||||
assertThat(item.extraBytes, is(1000L));
|
||||
assertThat(item.expirationTime, not(0));
|
||||
assertThat(item.message, notNullValue());
|
||||
assertThat(item.message.getFrom().getPrivateKey(), notNullValue());
|
||||
assertThat(item.message.getTo().getPubkey(), notNullValue());
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void ensureRetrievingNonexistingItemThrowsException() {
|
||||
repo.getItem(new byte[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureItemCanBeDeleted() {
|
||||
repo.removeObject(initialHash1);
|
||||
repo.removeObject(initialHash2);
|
||||
assertTrue(repo.getItems().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureDeletionOfNonexistingItemIsHandledSilently() {
|
||||
repo.removeObject(new byte[0]);
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2017 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository
|
||||
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import ch.dissem.bitmessage.entity.ObjectMessage
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
import ch.dissem.bitmessage.entity.Plaintext.Type.MSG
|
||||
import ch.dissem.bitmessage.entity.payload.GenericPayload
|
||||
import ch.dissem.bitmessage.entity.payload.GetPubkey
|
||||
import ch.dissem.bitmessage.entity.payload.ObjectPayload
|
||||
import ch.dissem.bitmessage.entity.payload.Pubkey
|
||||
import ch.dissem.bitmessage.entity.valueobject.PrivateKey
|
||||
import ch.dissem.bitmessage.ports.AddressRepository
|
||||
import ch.dissem.bitmessage.ports.MessageRepository
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository.Item
|
||||
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
||||
import ch.dissem.bitmessage.utils.TestUtils
|
||||
import ch.dissem.bitmessage.utils.UnixTime
|
||||
import ch.dissem.bitmessage.utils.UnixTime.MINUTE
|
||||
import org.hamcrest.CoreMatchers.*
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* @author Christian Basler
|
||||
*/
|
||||
class JdbcProofOfWorkRepositoryTest : TestBase() {
|
||||
private var config: TestJdbcConfig by Delegates.notNull<TestJdbcConfig>()
|
||||
private var repo: JdbcProofOfWorkRepository by Delegates.notNull<JdbcProofOfWorkRepository>()
|
||||
private var addressRepo: AddressRepository by Delegates.notNull<AddressRepository>()
|
||||
private var messageRepo: MessageRepository by Delegates.notNull<MessageRepository>()
|
||||
|
||||
private var initialHash1: ByteArray by Delegates.notNull<ByteArray>()
|
||||
private var initialHash2: ByteArray by Delegates.notNull<ByteArray>()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
config = TestJdbcConfig()
|
||||
config.reset()
|
||||
|
||||
addressRepo = JdbcAddressRepository(config)
|
||||
messageRepo = JdbcMessageRepository(config)
|
||||
repo = JdbcProofOfWorkRepository(config)
|
||||
TestUtils.mockedInternalContext(
|
||||
addressRepository = addressRepo,
|
||||
messageRepository = messageRepo,
|
||||
proofOfWorkRepository = repo,
|
||||
cryptography = cryptography()
|
||||
)
|
||||
|
||||
repo.putObject(ObjectMessage.Builder()
|
||||
.payload(GetPubkey(BitmessageAddress("BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn"))).build(),
|
||||
1000, 1000)
|
||||
initialHash1 = repo.getItems()[0]
|
||||
|
||||
val sender = TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8")
|
||||
val recipient = TestUtils.loadContact()
|
||||
addressRepo.save(sender)
|
||||
addressRepo.save(recipient)
|
||||
val plaintext = Plaintext.Builder(MSG)
|
||||
.ackData(cryptography().randomBytes(32))
|
||||
.from(sender)
|
||||
.to(recipient)
|
||||
.message("Subject", "Message")
|
||||
.status(Plaintext.Status.DOING_PROOF_OF_WORK)
|
||||
.build()
|
||||
messageRepo.save(plaintext)
|
||||
initialHash2 = cryptography().getInitialHash(plaintext.ackMessage!!)
|
||||
repo.putObject(Item(
|
||||
plaintext.ackMessage!!,
|
||||
1000, 1000,
|
||||
UnixTime.now + 10 * MINUTE,
|
||||
plaintext
|
||||
))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure object is stored`() {
|
||||
val sizeBefore = repo.getItems().size
|
||||
repo.putObject(ObjectMessage.Builder()
|
||||
.payload(GetPubkey(BitmessageAddress("BM-2D9U2hv3YBMHM1zERP32anKfVKohyPN9x2"))).build(),
|
||||
1000, 1000)
|
||||
assertThat(repo.getItems().size, `is`(sizeBefore + 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure ack objects are stored`() {
|
||||
val sizeBefore = repo.getItems().size
|
||||
val sender = TestUtils.loadIdentity("BM-2cSqjfJ8xK6UUn5Rw3RpdGQ9RsDkBhWnS8")
|
||||
val recipient = TestUtils.loadContact()
|
||||
addressRepo.save(sender)
|
||||
addressRepo.save(recipient)
|
||||
val plaintext = Plaintext.Builder(MSG)
|
||||
.ackData(cryptography().randomBytes(32))
|
||||
.from(sender)
|
||||
.to(recipient)
|
||||
.message("Subject", "Message")
|
||||
.status(Plaintext.Status.DOING_PROOF_OF_WORK)
|
||||
.build()
|
||||
messageRepo.save(plaintext)
|
||||
repo.putObject(Item(
|
||||
plaintext.ackMessage!!,
|
||||
1000, 1000,
|
||||
UnixTime.now + 10 * MINUTE,
|
||||
plaintext
|
||||
))
|
||||
assertThat(repo.getItems().size, `is`(sizeBefore + 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure item can be retrieved`() {
|
||||
val item = repo.getItem(initialHash1)
|
||||
assertThat(item, notNullValue())
|
||||
assertThat<ObjectPayload>(item.`object`.payload, instanceOf<ObjectPayload>(GetPubkey::class.java))
|
||||
assertThat(item.nonceTrialsPerByte, `is`(1000L))
|
||||
assertThat(item.extraBytes, `is`(1000L))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure ack item can be retrieved`() {
|
||||
val item = repo.getItem(initialHash2)
|
||||
assertThat(item, notNullValue())
|
||||
assertThat<ObjectPayload>(item.`object`.payload, instanceOf<ObjectPayload>(GenericPayload::class.java))
|
||||
assertThat(item.nonceTrialsPerByte, `is`(1000L))
|
||||
assertThat(item.extraBytes, `is`(1000L))
|
||||
assertThat(item.expirationTime, not<Number>(0))
|
||||
assertThat(item.message, notNullValue())
|
||||
assertThat<PrivateKey>(item.message?.from?.privateKey, notNullValue())
|
||||
assertThat<Pubkey>(item.message?.to?.pubkey, notNullValue())
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException::class)
|
||||
fun `ensure retrieving nonexisting item causes exception`() {
|
||||
repo.getItem(ByteArray(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure item can be deleted`() {
|
||||
repo.removeObject(initialHash1)
|
||||
repo.removeObject(initialHash2)
|
||||
assertTrue(repo.getItems().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ensure deletion of nonexisting item is handled silently`() {
|
||||
repo.removeObject(ByteArray(0))
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository;
|
||||
|
||||
import ch.dissem.bitmessage.InternalContext;
|
||||
import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine;
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
|
||||
import ch.dissem.bitmessage.utils.Singleton;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Created by chris on 20.07.15.
|
||||
*/
|
||||
public class TestBase {
|
||||
static {
|
||||
BouncyCryptography security = new BouncyCryptography();
|
||||
Singleton.initialize(security);
|
||||
InternalContext ctx = mock(InternalContext.class);
|
||||
when(ctx.getProofOfWorkEngine()).thenReturn(new MultiThreadedPOWEngine());
|
||||
security.setContext(ctx);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017 Christian Basler
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ch.dissem.bitmessage.repository
|
||||
|
||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||
import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine
|
||||
import ch.dissem.bitmessage.utils.Singleton
|
||||
import ch.dissem.bitmessage.utils.TestUtils.mockedInternalContext
|
||||
|
||||
/**
|
||||
* Created by chris on 20.07.15.
|
||||
*/
|
||||
open class TestBase {
|
||||
companion object {
|
||||
init {
|
||||
val security = BouncyCryptography()
|
||||
Singleton.initialize(security)
|
||||
mockedInternalContext(
|
||||
cryptography = security,
|
||||
proofOfWorkEngine = MultiThreadedPOWEngine()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user