From 47232eebc2a24f21b2f85330fd8a6939089ea3c0 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Sun, 5 Oct 2014 23:53:49 -0700 Subject: [PATCH] Added command line arguments parser and flag to start app in seed mode. Also added default properties loader, but not using it yet. --- .idea/copyright/Bitsquare_Affero_GPLv3.xml | 9 -- .idea/copyright/profiles_settings.xml | 2 +- build.gradle | 1 + src/main/java/io/bitsquare/BitSquare.java | 91 +++++++++++++------ .../java/io/bitsquare/gui/main/MainModel.java | 21 ----- .../java/io/bitsquare/msg/DHTSeedService.java | 4 +- .../io/bitsquare/msg/actor/DHTManager.java | 11 +-- .../msg/actor/event/PeerInitialized.java | 7 +- .../util/BitsquareArgumentParser.java | 56 ++++++++++++ .../java/io/bitsquare/util/ConfigLoader.java | 29 +++++- src/main/resources/bitsquare.properties | 7 ++ 11 files changed, 165 insertions(+), 73 deletions(-) delete mode 100644 .idea/copyright/Bitsquare_Affero_GPLv3.xml create mode 100644 src/main/java/io/bitsquare/util/BitsquareArgumentParser.java diff --git a/.idea/copyright/Bitsquare_Affero_GPLv3.xml b/.idea/copyright/Bitsquare_Affero_GPLv3.xml deleted file mode 100644 index 20bcc836bb..0000000000 --- a/.idea/copyright/Bitsquare_Affero_GPLv3.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index f6fb94b193..e7bedf3377 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 21a9af1e84..7857b19d63 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,7 @@ dependencies { compile 'com.google.code.findbugs:jsr305:2.0.3' compile 'net.jcip:jcip-annotations:1.0' compile 'org.jetbrains:annotations:13.0' + compile 'net.sourceforge.argparse4j:argparse4j:0.4.4' testCompile 'junit:junit:4.11' testCompile 'org.mockito:mockito-all:1.9.5' } diff --git a/src/main/java/io/bitsquare/BitSquare.java b/src/main/java/io/bitsquare/BitSquare.java index fcbb7f0115..56cb6697f2 100644 --- a/src/main/java/io/bitsquare/BitSquare.java +++ b/src/main/java/io/bitsquare/BitSquare.java @@ -24,11 +24,13 @@ import io.bitsquare.gui.Navigation; import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.Profiler; +import io.bitsquare.msg.DHTSeedService; import io.bitsquare.msg.MessageFacade; -import io.bitsquare.msg.SeedNodeAddress; +import io.bitsquare.msg.actor.event.PeerInitialized; import io.bitsquare.persistence.Persistence; import io.bitsquare.settings.Settings; import io.bitsquare.user.User; +import io.bitsquare.util.BitsquareArgumentParser; import io.bitsquare.util.ViewLoader; import com.google.common.base.Throwables; @@ -39,7 +41,6 @@ import com.google.inject.Injector; import java.io.IOException; import java.util.Arrays; -import java.util.List; import javafx.application.Application; import javafx.scene.*; @@ -52,6 +53,8 @@ import org.slf4j.LoggerFactory; import akka.actor.ActorSystem; import lighthouse.files.AppDirectory; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; public class BitSquare extends Application { private static final Logger log = LoggerFactory.getLogger(BitSquare.class); @@ -59,6 +62,7 @@ public class BitSquare extends Application { public static final boolean fillFormsWithDummyData = true; private static String APP_NAME = "Bitsquare"; + private static Injector injector; private static Stage primaryStage; private WalletFacade walletFacade; private MessageFacade messageFacade; @@ -67,37 +71,68 @@ public class BitSquare extends Application { Profiler.init(); Profiler.printMsgWithTime("BitSquare.main called with args " + Arrays.asList(args).toString()); - if (args.length > 0) - APP_NAME = APP_NAME + "-" + args[0]; - - /*Thread seedNodeThread = new Thread(new Runnable() { - @Override - public void run() { - startSeedNode(); - } - }); - seedNodeThread.start();*/ - - launch(args); - } - - private static void startSeedNode() { - List staticSedNodeAddresses = SeedNodeAddress - .StaticSeedNodeAddresses.getAllSeedNodeAddresses(); - SeedNode seedNode = new SeedNode(new SeedNodeAddress(staticSedNodeAddresses.get(0))); - seedNode.setDaemon(true); - seedNode.start(); + injector = Guice.createInjector(new BitSquareModule()); + BitsquareArgumentParser parser = new BitsquareArgumentParser(); + Namespace namespace = null; try { - // keep main thread up - Thread.sleep(Long.MAX_VALUE); - log.debug("Localhost seed node started"); - } catch (InterruptedException e) { - log.error(e.toString()); + //System.out.println(parser.parseArgs(args)); + namespace = parser.parseArgs(args); + } catch (ArgumentParserException e) { + parser.handleError(e); + System.exit(1); + } + if (namespace != null) { + + if (namespace.getString(BitsquareArgumentParser.NAME_FLAG) != null) { + APP_NAME = APP_NAME + "-" + namespace.getString(BitsquareArgumentParser.NAME_FLAG); + } + + Integer port = BitsquareArgumentParser.PORT_DEFAULT; + if (namespace.getString(BitsquareArgumentParser.PORT_FLAG) != null) { + port = Integer.valueOf(namespace.getString(BitsquareArgumentParser.PORT_FLAG)); + } + if (namespace.getBoolean(BitsquareArgumentParser.SEED_FLAG) == true) { + DHTSeedService dhtSeed = injector.getInstance(DHTSeedService.class); + dhtSeed.setHandler(m -> { + if (m instanceof PeerInitialized) { + System.out.println("Seed Peer Initialized on port " + ((PeerInitialized) m).getPort + ()); + } + }); + dhtSeed.initializePeer("localhost", port); + } + else { + launch(args); + } } +// Thread seedNodeThread = new Thread(new Runnable() { +// @Override +// public void run() { +// startSeedNode(); +// } +// }); +// seedNodeThread.start(); + } +// private static void startSeedNode() { +// List staticSedNodeAddresses = SeedNodeAddress +// .StaticSeedNodeAddresses.getAllSeedNodeAddresses(); +// SeedNode seedNode = new SeedNode(new SeedNodeAddress(staticSedNodeAddresses.get(0))); +// seedNode.setDaemon(true); +// seedNode.start(); +// +// try { +// // keep main thread up +// Thread.sleep(Long.MAX_VALUE); +// log.debug("Localhost seed node started"); +// } catch (InterruptedException e) { +// log.error(e.toString()); +// } +// } + public static Stage getPrimaryStage() { return primaryStage; @@ -121,7 +156,7 @@ public class BitSquare extends Application { log.error(e.getMessage()); } - final Injector injector = Guice.createInjector(new BitSquareModule()); +// final Injector injector = Guice.createInjector(new BitSquareModule()); // currently there is not SystemTray support for java fx (planned for version 3) so we use the old AWT AWTSystemTray.createSystemTray(primaryStage, injector.getInstance(ActorSystem.class)); diff --git a/src/main/java/io/bitsquare/gui/main/MainModel.java b/src/main/java/io/bitsquare/gui/main/MainModel.java index 2291611195..a49e223dd7 100644 --- a/src/main/java/io/bitsquare/gui/main/MainModel.java +++ b/src/main/java/io/bitsquare/gui/main/MainModel.java @@ -104,27 +104,6 @@ class MainModel extends UIModel { // For testing with the serverside seednode we need the BootstrappedPeerFactory which gets started form // messageFacade.init - - /*dhtSeedService.setHandler(m -> { - if (m instanceof PeerInitialized) { - log.debug("dht seed initialized. "); - // init messageFacade after seed node initialized - messageFacade.init(new BootstrapListener() { - @Override - public void onCompleted() { - messageFacadeInited = true; - if (walletFacadeInited) onFacadesInitialised(); - } - - @Override - public void onFailed(Throwable throwable) { - log.error(throwable.toString()); - } - }); - } - }); - - dhtSeedService.initializePeer();*/ messageFacade.init(new BootstrapListener() { @Override diff --git a/src/main/java/io/bitsquare/msg/DHTSeedService.java b/src/main/java/io/bitsquare/msg/DHTSeedService.java index c54d62d5a4..f13b223756 100644 --- a/src/main/java/io/bitsquare/msg/DHTSeedService.java +++ b/src/main/java/io/bitsquare/msg/DHTSeedService.java @@ -39,9 +39,9 @@ public class DHTSeedService extends ActorService { super(system, "/user/" + DHTManager.SEED_NAME); } - public void initializePeer() { + public void initializePeer(String id, Integer port) { // TODO hard coded seed peer config for now, should read from config properties file - send(new InitializePeer(new Number160(5001), 5001, null)); + send(new InitializePeer(Number160.createHash(id), port, null)); } } diff --git a/src/main/java/io/bitsquare/msg/actor/DHTManager.java b/src/main/java/io/bitsquare/msg/actor/DHTManager.java index 4495306242..2b97595f6f 100644 --- a/src/main/java/io/bitsquare/msg/actor/DHTManager.java +++ b/src/main/java/io/bitsquare/msg/actor/DHTManager.java @@ -67,12 +67,11 @@ public class DHTManager extends AbstractActor { .StaticSeedNodeAddresses.getAllSeedNodeAddresses(); SeedNodeAddress seedNodeAddress = new SeedNodeAddress(staticSedNodeAddresses.get(0)); - peer = new PeerBuilder( - Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort - ()).start(); + peer = new PeerBuilder(ip.getPeerId()).ports(ip.getPort()) + .start(); // Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID) - new PeerBuilderDHT(peer).start(); + peerDHT = new PeerBuilderDHT(peer).start(); PeerNAT nodeBehindNat = new PeerBuilderNAT(peer).start(); new RelayRPC(peer); //new PeerBuilderTracker(peer); @@ -92,11 +91,11 @@ public class DHTManager extends AbstractActor { .bootstrapTo(ip.getBootstrapPeers()).start(); futureBootstrap.awaitUninterruptibly(bootstrapTimeout); }*/ - sender().tell(new PeerInitialized(peer.peerID()), self()); + sender().tell(new PeerInitialized(peer.peerID(), ip.getPort()), self()); } catch (Throwable t) { log.info("The second instance has been started. If that happens at the first instance" + " we are in trouble... " + t.getMessage()); - sender().tell(new PeerInitialized(null), self()); + sender().tell(new PeerInitialized(null, null), self()); } }) .matchAny(o -> log.info("received unknown message")).build() diff --git a/src/main/java/io/bitsquare/msg/actor/event/PeerInitialized.java b/src/main/java/io/bitsquare/msg/actor/event/PeerInitialized.java index 8f27f1a535..82c4dd0cd0 100644 --- a/src/main/java/io/bitsquare/msg/actor/event/PeerInitialized.java +++ b/src/main/java/io/bitsquare/msg/actor/event/PeerInitialized.java @@ -26,13 +26,18 @@ import net.tomp2p.peers.Number160; public class PeerInitialized { private final Number160 peerId; + private final Integer port; - public PeerInitialized(Number160 peerId) { + public PeerInitialized(Number160 peerId, Integer port) { this.peerId = peerId; + this.port = port; } public Number160 getPeerId() { return peerId; } + public Integer getPort() { + return port; + } } diff --git a/src/main/java/io/bitsquare/util/BitsquareArgumentParser.java b/src/main/java/io/bitsquare/util/BitsquareArgumentParser.java new file mode 100644 index 0000000000..593e581fdb --- /dev/null +++ b/src/main/java/io/bitsquare/util/BitsquareArgumentParser.java @@ -0,0 +1,56 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.util; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.impl.Arguments; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; + +public class BitsquareArgumentParser { + + public static String SEED_FLAG = "seed"; + public static String PORT_FLAG = "port"; + public static Integer PORT_DEFAULT = 5000; + public static String NAME_FLAG = "name"; + + private final ArgumentParser parser; + + public BitsquareArgumentParser() { + parser = ArgumentParsers.newArgumentParser("BitSquare") + .defaultHelp(true) + .description("BitSquare decentralized bitcoin exchange."); + parser.addArgument("-s", "--" + SEED_FLAG) + .action(Arguments.storeTrue()) + .help("Start in DHT seed mode, no UI."); + parser.addArgument("-p", "--"+PORT_FLAG) + .setDefault(PORT_DEFAULT) + .help("IP port to listen on."); + parser.addArgument("-n", "--"+NAME_FLAG) + .help("Append name to application name."); + } + + public Namespace parseArgs(String... args) throws ArgumentParserException { + return parser.parseArgs(args); + } + + public void handleError(ArgumentParserException e) { + parser.handleError(e); + } +} diff --git a/src/main/java/io/bitsquare/util/ConfigLoader.java b/src/main/java/io/bitsquare/util/ConfigLoader.java index a4cc284790..0cde807aa3 100644 --- a/src/main/java/io/bitsquare/util/ConfigLoader.java +++ b/src/main/java/io/bitsquare/util/ConfigLoader.java @@ -34,20 +34,39 @@ public class ConfigLoader { private static final String configFilePath = AppDirectory.dir() + "/bitsquare.conf"; public static Properties loadConfig() { - Properties properties = new Properties(); InputStream inputStream = null; + + // load default properties from class path + Properties defaultProperties = new Properties(); + try { + InputStream is = ConfigLoader.class.getResourceAsStream("/bitsquare.properties"); + defaultProperties.load(is); + } catch (IOException ioe) { + ioe.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + + // load properties file from config file path + Properties properties = new Properties(defaultProperties); if (new File(configFilePath).exists()) { try { inputStream = new FileInputStream(configFilePath); properties.load(inputStream); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ioe) { + ioe.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); - } catch (IOException e2) { - e2.printStackTrace(); + } catch (IOException ioe) { + ioe.printStackTrace(); } } } diff --git a/src/main/resources/bitsquare.properties b/src/main/resources/bitsquare.properties index e69de29bb2..75bbb382d4 100644 --- a/src/main/resources/bitsquare.properties +++ b/src/main/resources/bitsquare.properties @@ -0,0 +1,7 @@ +seed.0.id=localhost +seed.0.address=127.0.0.1 +seed.0.port=5001 + +seed.1.id=digitalocean.bitsquare.io +seed.1.address=188.226.179.109 +seed.1.port=5000