Added option to connect to local Bitmessage client

(This makes it easier to debug some problem or make some tests)
This commit is contained in:
Christian Basler 2016-08-08 18:00:50 +02:00
parent 92229151a5
commit 505818a712
3 changed files with 109 additions and 87 deletions

View File

@ -17,14 +17,10 @@
package ch.dissem.bitmessage.demo; package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.payload.Pubkey; import ch.dissem.bitmessage.entity.payload.Pubkey;
import ch.dissem.bitmessage.entity.valueobject.Label; import ch.dissem.bitmessage.entity.valueobject.Label;
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler;
import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
import ch.dissem.bitmessage.repository.*;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -45,19 +41,10 @@ public class Application {
private BitmessageContext ctx; private BitmessageContext ctx;
public Application(InetAddress syncServer, int syncPort) { public Application(BitmessageContext.Builder ctxBuilder, InetAddress syncServer, int syncPort) {
JdbcConfig jdbcConfig = new JdbcConfig(); ctx = ctxBuilder
ctx = new BitmessageContext.Builder() .listener(plaintext -> System.out.println("New Message from " + plaintext.getFrom() + ": " + plaintext.getSubject()))
.addressRepo(new JdbcAddressRepository(jdbcConfig)) .build();
.inventory(new JdbcInventory(jdbcConfig))
.nodeRegistry(new MemoryNodeRegistry())
.messageRepo(new JdbcMessageRepository(jdbcConfig))
.powRepo(new JdbcProofOfWorkRepository(jdbcConfig))
.networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography())
.port(48444)
.listener(plaintext -> System.out.println("New Message from " + plaintext.getFrom() + ": " + plaintext.getSubject()))
.build();
if (syncServer == null) { if (syncServer == null) {
ctx.startup(); ctx.startup();
@ -392,7 +379,7 @@ public class Application {
System.out.println(WordUtils.wrap(message.getText(), 120)); System.out.println(WordUtils.wrap(message.getText(), 120));
System.out.println(); System.out.println();
System.out.println(message.getLabels().stream().map(Label::toString).collect( System.out.println(message.getLabels().stream().map(Label::toString).collect(
Collectors.joining(", ", "Labels: ", ""))); Collectors.joining(", ", "Labels: ", "")));
System.out.println(); System.out.println();
ctx.labeler().markAsRead(message); ctx.labeler().markAsRead(message);
ctx.messages().save(message); ctx.messages().save(message);

View File

@ -18,20 +18,29 @@ package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography; import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler; import ch.dissem.bitmessage.networking.nio.NioNetworkHandler;
import ch.dissem.bitmessage.ports.MemoryNodeRegistry; import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
import ch.dissem.bitmessage.ports.NodeRegistry;
import ch.dissem.bitmessage.repository.*; import ch.dissem.bitmessage.repository.*;
import ch.dissem.bitmessage.wif.WifExporter; import ch.dissem.bitmessage.wif.WifExporter;
import ch.dissem.bitmessage.wif.WifImporter; import ch.dissem.bitmessage.wif.WifImporter;
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main { public class Main {
private static final Logger LOG = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
if (System.getProperty("org.slf4j.simpleLogger.defaultLogLevel") == null) if (System.getProperty("org.slf4j.simpleLogger.defaultLogLevel") == null)
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "ERROR"); System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "ERROR");
@ -45,18 +54,39 @@ public class Main {
} catch (CmdLineException e) { } catch (CmdLineException e) {
parser.printUsage(System.err); parser.printUsage(System.err);
} }
JdbcConfig jdbcConfig = new JdbcConfig();
BitmessageContext.Builder ctxBuilder = new BitmessageContext.Builder()
.addressRepo(new JdbcAddressRepository(jdbcConfig))
.inventory(new JdbcInventory(jdbcConfig))
.messageRepo(new JdbcMessageRepository(jdbcConfig))
.powRepo(new JdbcProofOfWorkRepository(jdbcConfig))
.networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography())
.port(48444);
if (options.localPort != null) {
ctxBuilder.nodeRegistry(new NodeRegistry() {
@Override
public List<NetworkAddress> getKnownAddresses(int limit, long... streams) {
return Arrays.stream(streams)
.mapToObj(s -> new NetworkAddress.Builder()
.ipv4(127, 0, 0, 1)
.port(options.localPort)
.stream(s).build())
.collect(Collectors.toList());
}
@Override
public void offerAddresses(List<NetworkAddress> addresses) {
LOG.info("Local node registry ignored offered addresses: " + addresses);
}
});
} else {
ctxBuilder.nodeRegistry(new MemoryNodeRegistry());
}
if (options.exportWIF != null || options.importWIF != null) { if (options.exportWIF != null || options.importWIF != null) {
JdbcConfig jdbcConfig = new JdbcConfig(); BitmessageContext ctx = ctxBuilder.build();
BitmessageContext ctx = new BitmessageContext.Builder()
.addressRepo(new JdbcAddressRepository(jdbcConfig))
.inventory(new JdbcInventory(jdbcConfig))
.nodeRegistry(new MemoryNodeRegistry())
.messageRepo(new JdbcMessageRepository(jdbcConfig))
.powRepo(new JdbcProofOfWorkRepository(jdbcConfig))
.networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography())
.port(48444)
.build();
if (options.exportWIF != null) { if (options.exportWIF != null) {
new WifExporter(ctx).addAll().write(options.exportWIF); new WifExporter(ctx).addAll().write(options.exportWIF);
@ -66,11 +96,14 @@ public class Main {
} }
} else { } else {
InetAddress syncServer = options.syncServer == null ? null : InetAddress.getByName(options.syncServer); InetAddress syncServer = options.syncServer == null ? null : InetAddress.getByName(options.syncServer);
new Application(syncServer, options.syncPort); new Application(ctxBuilder, syncServer, options.syncPort);
} }
} }
private static class CmdLineOptions { private static class CmdLineOptions {
@Option(name = "-local", usage = "Connect to local Bitmessage client on given port, instead of the usual connections from node.txt")
private Integer localPort;
@Option(name = "-import", usage = "Import from keys.dat or other WIF file.") @Option(name = "-import", usage = "Import from keys.dat or other WIF file.")
private File importWIF; private File importWIF;

View File

@ -49,7 +49,9 @@ import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
/** /**
* FIXME: there really should be sensible tests for the network handler * Tests network handlers. This test is parametrized, so it can test both the nio and classic implementation
* as well as their combinations. It might be slightly over the top and will most probably be cleaned up once
* the nio implementation is deemed stable.
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class NetworkHandlerTest { public class NetworkHandlerTest {
@ -76,10 +78,10 @@ public class NetworkHandlerTest {
@Parameterized.Parameters @Parameterized.Parameters
public static List<Object[]> parameters() { public static List<Object[]> parameters() {
return Arrays.asList(new Object[][]{ return Arrays.asList(new Object[][]{
{new DefaultNetworkHandler(), new DefaultNetworkHandler()}, {new DefaultNetworkHandler(), new DefaultNetworkHandler()},
{new DefaultNetworkHandler(), new NioNetworkHandler()}, {new DefaultNetworkHandler(), new NioNetworkHandler()},
{new NioNetworkHandler(), new DefaultNetworkHandler()}, {new NioNetworkHandler(), new DefaultNetworkHandler()},
{new NioNetworkHandler(), new NioNetworkHandler()} {new NioNetworkHandler(), new NioNetworkHandler()}
}); });
} }
@ -87,50 +89,50 @@ public class NetworkHandlerTest {
public void setUp() { public void setUp() {
peerInventory = new TestInventory(); peerInventory = new TestInventory();
peer = new BitmessageContext.Builder() peer = new BitmessageContext.Builder()
.addressRepo(mock(AddressRepository.class)) .addressRepo(mock(AddressRepository.class))
.inventory(peerInventory) .inventory(peerInventory)
.messageRepo(mock(MessageRepository.class)) .messageRepo(mock(MessageRepository.class))
.powRepo(mock(ProofOfWorkRepository.class)) .powRepo(mock(ProofOfWorkRepository.class))
.port(peerAddress.getPort()) .port(peerAddress.getPort())
.nodeRegistry(new TestNodeRegistry()) .nodeRegistry(new TestNodeRegistry())
.networkHandler(peerNetworkHandler) .networkHandler(peerNetworkHandler)
.cryptography(new BouncyCryptography()) .cryptography(new BouncyCryptography())
.listener(mock(BitmessageContext.Listener.class)) .listener(mock(BitmessageContext.Listener.class))
.customCommandHandler(new CustomCommandHandler() { .customCommandHandler(new CustomCommandHandler() {
@Override @Override
public MessagePayload handle(CustomMessage request) { public MessagePayload handle(CustomMessage request) {
byte[] data = request.getData(); byte[] data = request.getData();
if (data.length > 0) { if (data.length > 0) {
switch (data[0]) { switch (data[0]) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
case 3: case 3:
data[0] = 0; data[0] = 0;
break; break;
default: default:
break; break;
}
} }
return new CustomMessage("test response", request.getData());
} }
}) return new CustomMessage("test response", request.getData());
.build(); }
})
.build();
peer.startup(); peer.startup();
nodeInventory = new TestInventory(); nodeInventory = new TestInventory();
node = new BitmessageContext.Builder() node = new BitmessageContext.Builder()
.addressRepo(mock(AddressRepository.class)) .addressRepo(mock(AddressRepository.class))
.inventory(nodeInventory) .inventory(nodeInventory)
.messageRepo(mock(MessageRepository.class)) .messageRepo(mock(MessageRepository.class))
.powRepo(mock(ProofOfWorkRepository.class)) .powRepo(mock(ProofOfWorkRepository.class))
.port(6002) .port(6002)
.nodeRegistry(new TestNodeRegistry(peerAddress)) .nodeRegistry(new TestNodeRegistry(peerAddress))
.networkHandler(nodeNetworkHandler) .networkHandler(nodeNetworkHandler)
.cryptography(new BouncyCryptography()) .cryptography(new BouncyCryptography())
.listener(mock(BitmessageContext.Listener.class)) .listener(mock(BitmessageContext.Listener.class))
.build(); .build();
} }
@After @After
@ -162,7 +164,7 @@ public class NetworkHandlerTest {
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
if (networkHandler.isRunning()) { if (networkHandler.isRunning()) {
LOG.warn("Thread interrupted while waiting for network shutdown - " + LOG.warn("Thread interrupted while waiting for network shutdown - " +
"this could cause problems in subsequent tests."); "this could cause problems in subsequent tests.");
} }
return; return;
} }
@ -219,18 +221,18 @@ public class NetworkHandlerTest {
@Test @Test
public void ensureObjectsAreSynchronizedIfBothHaveObjects() throws Exception { public void ensureObjectsAreSynchronizedIfBothHaveObjects() throws Exception {
peerInventory.init( peerInventory.init(
"V4Pubkey.payload", "V4Pubkey.payload",
"V5Broadcast.payload" "V5Broadcast.payload"
); );
nodeInventory.init( nodeInventory.init(
"V1Msg.payload", "V1Msg.payload",
"V4Pubkey.payload" "V4Pubkey.payload"
); );
Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(), Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(),
mock(NetworkHandler.MessageListener.class), mock(NetworkHandler.MessageListener.class),
10); 10);
future.get(); future.get();
assertInventorySize(3, nodeInventory); assertInventorySize(3, nodeInventory);
assertInventorySize(3, peerInventory); assertInventorySize(3, peerInventory);
@ -239,15 +241,15 @@ public class NetworkHandlerTest {
@Test @Test
public void ensureObjectsAreSynchronizedIfOnlyPeerHasObjects() throws Exception { public void ensureObjectsAreSynchronizedIfOnlyPeerHasObjects() throws Exception {
peerInventory.init( peerInventory.init(
"V4Pubkey.payload", "V4Pubkey.payload",
"V5Broadcast.payload" "V5Broadcast.payload"
); );
nodeInventory.init(); nodeInventory.init();
Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(), Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(),
mock(NetworkHandler.MessageListener.class), mock(NetworkHandler.MessageListener.class),
10); 10);
future.get(); future.get();
assertInventorySize(2, nodeInventory); assertInventorySize(2, nodeInventory);
assertInventorySize(2, peerInventory); assertInventorySize(2, peerInventory);
@ -258,12 +260,12 @@ public class NetworkHandlerTest {
peerInventory.init(); peerInventory.init();
nodeInventory.init( nodeInventory.init(
"V1Msg.payload" "V1Msg.payload"
); );
Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(), Future<?> future = nodeNetworkHandler.synchronize(peerAddress.toInetAddress(), peerAddress.getPort(),
mock(NetworkHandler.MessageListener.class), mock(NetworkHandler.MessageListener.class),
10); 10);
future.get(); future.get();
assertInventorySize(1, nodeInventory); assertInventorySize(1, nodeInventory);
assertInventorySize(1, peerInventory); assertInventorySize(1, peerInventory);