/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package bftsmart.reconfiguration; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.LinkedList; import java.util.List; import java.util.Scanner; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import bftsmart.communication.server.ServerConnection; import bftsmart.reconfiguration.views.View; /** * * @author eduardo */ public class TTP { private int id; private Reconfiguration rec = null; //private Hashtable<Integer, ServerConnection> connections = new Hashtable<Integer, ServerConnection>(); private ServerViewManager manager; //Need only inform those that are entering the systems, as those already //in the system will execute the reconfiguration request private List<Integer> addIds = new LinkedList<Integer>(); public TTP() { this(""); } public TTP(String configHome) { this.id = loadID(configHome); this.manager = new ServerViewManager(id, configHome); this.rec = new Reconfiguration(id); } public void connect(){ this.rec.connect(); } private int loadID(String configHome) { try { String path = ""; String sep = System.getProperty("file.separator"); if (configHome == null || configHome.equals("")) { path = "config" + sep + "system.config"; } else { path = configHome + sep + "system.config"; } FileReader fr = new FileReader(path); BufferedReader rd = new BufferedReader(fr); String line = null; while ((line = rd.readLine()) != null) { if (!line.startsWith("#")) { StringTokenizer str = new StringTokenizer(line, "="); if (str.countTokens() > 1 && str.nextToken().trim().equals("system.ttp.id")) { fr.close(); rd.close(); return Integer.parseInt(str.nextToken().trim()); } } } fr.close(); rd.close(); return -1; } catch (Exception e) { e.printStackTrace(System.out); return -1; } } public void addServer(int id, String ip, int port) { this.manager.getStaticConf().addHostInfo(id, ip, port); rec.addServer(id, ip, port); addIds.add(id); } public void removeServer(int id) { rec.removeServer(id); } public void setF(int f) { rec.setF(f); } public void executeUpdates() { connect(); ReconfigureReply r = rec.execute(); View v = r.getView(); System.out.println("New view f: " + v.getF()); TTPMessage msg = new TTPMessage(id, r); if (addIds.size() > 0) { sendResponse(addIds.toArray(new Integer[1]), msg); addIds.clear(); } } private ServerConnection getConnection(int remoteId) { return new ServerConnection(manager, null, remoteId, null, null); } public void sendResponse(Integer[] targets, TTPMessage sm) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try { new ObjectOutputStream(bOut).writeObject(sm); } catch (IOException ex) { Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex); } byte[] data = bOut.toByteArray(); for (Integer i : targets) { //br.ufsc.das.tom.util.Logger.println("(ServersCommunicationLayer.send) Sending msg to replica "+i); try { if (i.intValue() != id) { getConnection(i.intValue()).send(data, true); } } catch (InterruptedException ex) { // ex.printStackTrace(); System.err.println(ex); } } //br.ufsc.das.tom.util.Logger.println("(ServersCommunicationLayer.send) Finished sending messages to replicas"); } public void close() { rec.close(); } public static void main(String[] args) { TTP ttp = null; if (args.length > 0) { ttp = new TTP(args[0]); } else { ttp = new TTP(""); } Scanner scan = new Scanner(System.in); String str = null; do { str = scan.nextLine(); String cmd = ""; int arg = -1; try { StringTokenizer token = new StringTokenizer(str); cmd = token.nextToken(); arg = Integer.parseInt(token.nextToken()); } catch (Exception e) { } if (arg >= 0) { if (cmd.equals("add")) { int port = (arg * 10) + 11000; ttp.addServer(arg, "127.0.0.1", port); } else if (cmd.equals("rem")) { ttp.removeServer(arg); } ttp.executeUpdates(); } } while (!str.equals("exit")); ttp.close(); System.exit(0); } public StatusReply askStatus(int id) { connect(); StatusReply reply = rec.askStatus(id); close(); return reply; } }