diff --git a/src/main/java/fucoin/MainRemote.java b/src/main/java/fucoin/MainRemote.java index 291987533abdb5f8532fa39b3dd9d902a61915bf..e148dc8bed2c26f584a1ed41f05d9013c41150ce 100644 --- a/src/main/java/fucoin/MainRemote.java +++ b/src/main/java/fucoin/MainRemote.java @@ -3,22 +3,28 @@ package fucoin; import akka.actor.ActorRef; import akka.actor.ActorSelection; import akka.actor.ActorSystem; +import akka.japi.Pair; import akka.util.Timeout; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; +import fucoin.setup.SelectableNetworkInterface; import fucoin.wallet.WalletImpl; import scala.concurrent.Await; +import scala.concurrent.duration.FiniteDuration; import javax.swing.*; +import java.awt.*; import java.io.File; -import java.net.InetAddress; -import java.net.UnknownHostException; +import java.net.*; +import java.util.*; +import java.util.List; import java.util.concurrent.TimeUnit; public class MainRemote { - private static JTextField walletNameField = new JTextField(5); - private static JTextField pathField = new JTextField(5); + private static JTextField walletNameField = new JTextField(10); + private static JTextField pathField = new JTextField(10); + private static JComboBox<SelectableNetworkInterface> hostnameField = new JComboBox<>(); public static void main(String[] args) throws InterruptedException { @@ -43,7 +49,7 @@ public class MainRemote { //Init System Actor System ActorSystem system = ActorSystem.create("Remote", ConfigFactory.parseString("akka.remote.netty.tcp.hostname=" + hostname).withFallback(config)); - JPanel dialogPanel = createDialogPanel(); + JPanel dialogPanel = createDialogPanel(hostname); Timeout timeout = new Timeout(5, TimeUnit.SECONDS); ActorRef preknownNeighbour = null; @@ -55,20 +61,35 @@ public class MainRemote { int result = JOptionPane.showConfirmDialog(null, dialogPanel, "Connect to wallet network", JOptionPane.OK_CANCEL_OPTION); - if (result == JOptionPane.OK_OPTION) { - walletName = walletNameField.getText(); - path = pathField.getText(); + // terminate if user clicked cancel + if (result == JOptionPane.CANCEL_OPTION) { + if (system != null) { + system.terminate(); + } + return; } - // check input - if(result == JOptionPane.OK_OPTION && (path.equals("") || walletName.equals(""))){ - continue; + SelectableNetworkInterface selectedHostname = (SelectableNetworkInterface) hostnameField.getSelectedItem(); + + if (!selectedHostname.getHostName().equals(hostname)) { + if (system != null) { + try { + Await.result(system.terminate(), new FiniteDuration(5, TimeUnit.SECONDS)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + hostname = selectedHostname.getHostName(); + system = ActorSystem.create("Remote", ConfigFactory.parseString("akka.remote.netty.tcp.hostname=" + hostname).withFallback(config)); } - // terminate if user clicked cancel - if (result == JOptionPane.CANCEL_OPTION) { - system.terminate(); - return; + walletName = walletNameField.getText(); + path = pathField.getText(); + + // check input + if (path.equals("") || walletName.equals("")) { + continue; } // resolve the given address @@ -86,13 +107,46 @@ public class MainRemote { } - private static JPanel createDialogPanel() { + private static JPanel createDialogPanel(String defaultHostname) { JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BoxLayout(dialogPanel, BoxLayout.PAGE_AXIS)); - dialogPanel.add(new JLabel("Pick your wallet name: ")); + dialogPanel.setLayout(new GridLayout(3, 1)); + JLabel walletLabel = new JLabel("Pick your wallet name: ", SwingConstants.LEFT); + dialogPanel.add(walletLabel); dialogPanel.add(walletNameField); - dialogPanel.add(new JLabel("Enter a neighbour node address: ")); + dialogPanel.add(new JLabel("Enter a neighbour node address: ", SwingConstants.LEFT)); dialogPanel.add(pathField); + dialogPanel.add(new JLabel("Select your reachable IP address: ", SwingConstants.LEFT)); + + List<SelectableNetworkInterface> interfaces = fetchNetworkInterfaces(); + + for (SelectableNetworkInterface netint : interfaces) { + hostnameField.addItem(netint); + } + + hostnameField.setSelectedItem(new SelectableNetworkInterface(defaultHostname, "default")); + dialogPanel.add(hostnameField); return dialogPanel; } + + private static List<SelectableNetworkInterface> fetchNetworkInterfaces() { + List<SelectableNetworkInterface> map = new ArrayList<>(); + + try { + Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); + + for (NetworkInterface networkInterface : Collections.list(nets)) { + Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses(); + // To ease the setup, currently only IPv4 addresses are supported + Optional<InetAddress> picked = Collections.list(inetAddresses).stream().filter(inetAddress -> !(inetAddress instanceof Inet6Address)).findFirst(); + if (picked.isPresent()) { + String hostAddress = picked.get().getHostAddress(); + map.add(new SelectableNetworkInterface(hostAddress, networkInterface.getDisplayName())); + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + + return map; + } } diff --git a/src/main/java/fucoin/setup/SelectableNetworkInterface.java b/src/main/java/fucoin/setup/SelectableNetworkInterface.java new file mode 100644 index 0000000000000000000000000000000000000000..0e023c0ebb1f23261244e03c54c84521678e294e --- /dev/null +++ b/src/main/java/fucoin/setup/SelectableNetworkInterface.java @@ -0,0 +1,36 @@ +package fucoin.setup; + +/** + * @author davidbohn + */ +public class SelectableNetworkInterface { + + String hostName; + String interfaceName; + + public SelectableNetworkInterface(String hostName, String interfaceName) { + this.hostName = hostName; + this.interfaceName = interfaceName; + } + + public String getHostName() { + return hostName; + } + + public String getInterfaceName() { + return interfaceName; + } + + @Override + public String toString() { + return getInterfaceName() + " (" + getHostName() + ")"; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SelectableNetworkInterface) { + return ((SelectableNetworkInterface) obj).getHostName().equals(this.getHostName()); + } + return super.equals(obj); + } +} diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index b264199e3edbfecf65e5c1e2cd476388ec86d70a..b2e7193860f00eee523b79ad7c3898eb69f328d1 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -2,6 +2,7 @@ akka { actor { provider = "akka.remote.RemoteActorRefProvider" + warn-about-java-serializer-usage = false } remote {