package org.limewire.mojito; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.ArrayList; import java.util.List; import org.limewire.io.SimpleNetworkInstanceUtils; import org.limewire.mojito.db.Database; import org.limewire.mojito.result.BootstrapResult; import org.limewire.mojito.result.BootstrapResult.ResultType; import org.limewire.mojito.settings.BucketRefresherSettings; import org.limewire.mojito.settings.NetworkSettings; import org.limewire.mojito.settings.RouteTableSettings; import org.limewire.mojito.util.ContactUtils; import org.limewire.mojito.util.MojitoUtils; public class Main { /** * Creates a localhost Mojito DHT. Once the localhost Mojito DHT's * nodes are bootstrapped, you can execute various Mojito commands, * like adding values to the DHT using a key, looking up keys, getting * values using the key, etc. * * @param args 'count port [host port]' either two or four arguments to * setup a localhost Mojito DHT. * <ul> * <li>count: number of nodes in the example DHT; excludes the bootstrapped * node. * <li>port: the base port for nodes added to the DHT. Each additional node (if * count is greater than one) uses a port number which is an increment of the * base port. * <li>host: host name/host number for the bootstrapped node. * <li>port: the port for the bootstrap node's port. * </ul> * @throws Exception * <p> * See <a href="http://wiki.limewire.org/index.php?title=Mojito_Main"> * Mojito Main</a> for more information on using this example code. */ public static void main(String[] args) throws Exception { int count = 0; int port = 0; //Allows for running locally ContactUtils.setNetworkInstanceUtils(new SimpleNetworkInstanceUtils(false)); InetSocketAddress bootstrapHost = null; if (args.length != 2 && args.length != 4) { System.out.println("java Main count port"); System.out.println("java Main count port host port"); System.exit(-1); } else { count = Integer.parseInt(args[0]); port = Integer.parseInt(args[1]); if (args.length >= 4) { bootstrapHost = new InetSocketAddress(args[2], Integer.parseInt(args[3])); } } RouteTableSettings.MAX_CONTACTS_PER_NETWORK_CLASS_RATIO.setValue(1.0f); NetworkSettings.LOCAL_IS_PRIVATE.setValue(false); NetworkSettings.FILTER_CLASS_C.setValue(false); List<MojitoDHT> dhts = standalone(null, port, count); if (dhts.isEmpty()) { System.out.println("No Nodes to run"); System.exit(0); } if (!NetworkSettings.LOCAL_IS_PRIVATE.getValue()) { System.out.println("WARNING: LOCAL_IS_PRIVATE is set to false!"); } if (!NetworkSettings.FILTER_CLASS_C.getValue()) { System.out.println("WARNING: FILTER_CLASS_C is set to false!"); } if (RouteTableSettings.MAX_CONTACTS_PER_NETWORK_CLASS_RATIO.getValue() >= 1.0f) { System.out.println("WARNING: MAX_CONTACTS_PER_NETWORK_CLASS_RATIO is set to >= 1.0f!"); } run(port, dhts, bootstrapHost); } private static List<MojitoDHT> standalone(InetAddress addr, int port, int count) { if (count > 1) { BucketRefresherSettings.UNIFORM_BUCKET_REFRESH_DISTRIBUTION.setValue(true); } List<MojitoDHT> dhts = new ArrayList<MojitoDHT>(count); for(int i = 0; i < count; i++) { try { MojitoDHT dht = MojitoFactory.createDHT("DHT" + i); if (addr != null) { dht.bind(new InetSocketAddress(addr, port+i)); } else { dht.bind(new InetSocketAddress(port+i)); } dhts.add(dht); System.out.println(i + ": " + ((Context)dhts.get(dhts.size()-1)).getLocalNode()); } catch (IOException err) { System.err.println("Failed to start/connect DHT #" + i); err.printStackTrace(); } } return dhts; } private static void run(int port, List<MojitoDHT> dhts, SocketAddress bootstrapHost) throws Exception { long time = 0L; int start = 0; if (bootstrapHost == null) { dhts.get(0).start(); start = 1; bootstrapHost = new InetSocketAddress("localhost", port); } for(int i = start; i < dhts.size(); i++) { try { MojitoDHT dht = dhts.get(i); dht.start(); BootstrapResult result = dht.bootstrap(bootstrapHost).get(); time += result.getTime(); if (result.getResultType().equals(ResultType.BOOTSTRAP_SUCCEEDED)) { System.out.println("Node #" + i + " finished bootstrapping from " + bootstrapHost + " in " + result.getTime() + "ms"); } else { System.out.println("Node #" + i + " failed to bootstrap from " + bootstrapHost + "\n" + result); } } catch (Exception err) { System.out.println("Node #" + i + " failed to bootstrap from " + bootstrapHost); err.printStackTrace(); } } if (dhts.size() > 1) { BootstrapResult result = MojitoUtils.bootstrap( dhts.get(0), dhts.get(1).getContactAddress()).get(); time += result.getTime(); if (result.getResultType().equals(ResultType.BOOTSTRAP_SUCCEEDED)) { System.out.println("Node #0 finished bootstrapping from " + dhts.get(1).getContactAddress() + " in " + result.getTime() + "ms"); } else { System.out.println("Node #0 failed to bootstrap from " + dhts.get(1).getContactAddress() + "\n" + result); } } System.out.println("All Nodes finished bootstrapping in " + time + "ms"); int current = 0; MojitoDHT dht = dhts.get(current); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); while(true) { System.out.print("[" + current + "] $ "); String line = in.readLine(); // Null if app gets interrupted by Eclipse if (line == null) { break; } line = line.trim(); if (line.equals("")) { continue; } try { if (line.indexOf("quit") >= 0) { for(int i = 0; i < dhts.size(); i++) { dhts.get(i).close(); } System.exit(0); } else if (line.indexOf("switch") >= 0) { int index = Integer.parseInt(line.split(" ")[1]); dht = dhts.get(index); current = index; CommandHandler.info(dht, null, out); } else if (line.indexOf("help") >= 0) { out.println("quit"); out.println("switch <index>"); CommandHandler.handle(dht, line, out); } else if (line.indexOf("load") >= 0) { MojitoDHT d = CommandHandler.load(dht, line.split(" "), out); dht.close(); dhts.set(current, d); d.getDHTExecutorService().setThreadFactory( dht.getDHTExecutorService().getThreadFactory()); d.bind(dht.getLocalAddress()); d.start(); dht = d; CommandHandler.info(dht, null, out); } else if (line.indexOf("keycount") >= 0) { int keycount = 0; for (MojitoDHT mojito : dhts) { Database db = ((Context)mojito).getDatabase(); keycount += db.getKeyCount(); } System.out.println("Key count: " + keycount); } else { if(!CommandHandler.handle(dht, line, out)) System.out.println("Could not execute command: " + line); } } catch (Throwable t) { t.printStackTrace(); } finally { out.flush(); } } } }