import java.net.*; import java.io.*; class Master { private int basePort; private static boolean reelection; public static void main(String argv[]) { if (argv.length<1 || argv.length>2) { System.out.println("\n java Master client_listen_port [rieletto]\n"); System.exit(1); } if (argv.length==2 && argv[1].equals("rieletto")) { Master.reelection=true; System.out.println("Avvio master rieletto ..."); } else Master.reelection=false; Master m=new Master((new Integer(argv[0])).intValue()); } Master(int p) { super(); basePort=p; ConstantsM.sv=new SlaveVivi(); if (Master.reelection) { initSlaveLst(); try { ConstantsM.cm=new CacheMaster(basePort+1,"cachem.txt"); } catch(IOException ex) { System.out.println("Master$CacheMaster: "+ex.toString()); } // aggiorna il name server nameServerUpdate(); // avvisa tutti gli slaves della nuova rielezione slaveUpdate(); } else { ConstantsM.cm=new CacheMaster(basePort+1); getSlaves(); } if (Master.reelection){ int maxInd=0; CacheElem[] ce = ConstantsM.cm.getAll(); for (int i=0; i<ce.length; i++){ if (ce[i].index>maxInd){ maxInd=ce[i].index; } int indice1 = ce[i].richiesta.indexOf('\n'); String mitt = ce[i].richiesta.substring(0,indice1); if (mitt.indexOf(':')>0){ ConstantsM.numRichiesteSlave++; inoltraQuerySlave iqs = new inoltraQuerySlave(ce[i].index, ce[i].richiesta, "SLAVE", ce[i].numVivi); iqs.start(); } else{ ConstantsM.numRichiesteClient++; inoltraQuerySlave iqs = new inoltraQuerySlave(ce[i].index, ce[i].richiesta, mitt, ce[i].numVivi); iqs.start(); } } ConstantsM.index=++maxInd; } AliveThread at=new AliveThread(basePort+3); at.start(); ConstantsM.contactSlaveUDP=basePort+4; ConstantsM.contactSlaveVivi=basePort+1000; AcceptClient ac =new AcceptClient(basePort); ac.start(); AcceptSlave as =new AcceptSlave(basePort+2); as.start(); } // inizializzazione della lista degli slaves da file private void initSlaveLst() { try { System.out.println("Master.initSlaveLst: lettura file slavelst.txt ..."); BufferedReader inb=new BufferedReader(new FileReader("slavelst.txt")); String l; boolean deadLst=false; int pos,p; while ((l=inb.readLine())!=null) { if (l.equals("*** lista slaves morti ***")) { deadLst=true; continue; } pos=l.indexOf(':'); p=(new Integer(l.substring(pos+1,l.length()))).intValue(); if (deadLst) ConstantsM.sv.putDeadSlave(l.substring(0,pos),p); else ConstantsM.sv.putSlave(l.substring(0,pos),p); } inb.close(); System.out.println("Master.initSlaveLst, slaves vivi:\n"+ConstantsM.sv.aliveToString()); System.out.println("Master.initSlaveLst, slaves morti:\n"+ConstantsM.sv.deadToString()); } catch(IOException ex) { System.out.println("Master.initSlaveLst: "+ex.toString()); } } // fine initSlaveLst // aggiorna il name server private void nameServerUpdate() { try { System.out.println("Master.nameServerUpdate: aggiorno il name server ... "); // legge il vecchio ip del master morto (salvato nel file // ip_old.txt) BufferedReader buf=new BufferedReader(new FileReader("ip_old.txt")); String oldIp=buf.readLine(); buf.close(); if (oldIp==null) { System.out.println("Master.nameServerUpdate: impossibile determinare il vecchio ip !"); return; } Socket soc=new Socket(Constants.nsIP,Constants.nsPort); DataInputStream inb=new DataInputStream(soc.getInputStream()); DataOutputStream outb=new DataOutputStream(soc.getOutputStream()); // invia i comandi al name sever byte[] outmsg=("unset "+ConstantsM.ambito+" "+oldIp).getBytes(); outb.writeInt(outmsg.length); outb.write(outmsg); outmsg=("set "+ConstantsM.ambito+" "+(soc.getLocalAddress()).getHostAddress()).getBytes(); outb.writeInt(outmsg.length); outb.write(outmsg); // raccoglie le risposte del name server for (int j=0;j<2;j++) { int n=inb.readInt(); byte[] b=new byte[n]; inb.read(b); } inb.close();outb.close();soc.close(); System.out.println("Master.nameServerUpdate: name server aggiornato."); } catch(UnknownHostException ex) { System.out.println("Master.nameServerUpdate: "+ex.toString()); } catch(SecurityException ex) { System.out.println("Master.nameServerUpdate: "+ex.toString()); } catch(IOException ex) { System.out.println("Master.nameServerUpdate: "+ex.toString()); } } // fine nameServerUpdate // avvisa gli slaves della rielezione private void slaveUpdate() { try { System.out.println("Master.slaveUpdate: avviso gli slaves ... "); DatagramSocket soc=new DatagramSocket(basePort); byte[] outb=("nuovo master attivato").getBytes(); DatagramPacket outpac=new DatagramPacket(outb,outb.length); transmit(soc,ConstantsM.sv.getSlave(),outpac); soc.close(); System.out.println("Master.slaveUpdate: slaves avvisati."); } catch(SocketException ex) { System.out.println("Master.slaveUpdate: "+ex.toString()); } catch(SecurityException ex) { System.out.println("Master.slaveUpdate: "+ex.toString()); } catch(IOException ex) { System.out.println("Master.slaveUpdate: "+ex.toString()); } } // fine slaveUpdate // trasmette a tutti i destinatari in dest il msg pac private void transmit(DatagramSocket soc,KeySlave[] dest,DatagramPacket pac) { int i; try { for (i=0;i<dest.length;i++) { pac.setAddress(InetAddress.getByName(dest[i].ipSlave)); if (Master.reelection) pac.setPort(dest[i].portaSlave+3); else pac.setPort(dest[i].portaSlave); soc.send(pac); } } catch(IOException ex) { System.out.println("Master.transmit: "+ex.toString()); } } // fine transmit /* riceve le porte su cui gli slaves rimangono in ascolto per le richieste del Master. Il msg degli slaves e' una stringa che indica il numero della porta (l'ip dello slave e' ricavato dall' indirizzo del pacchetto udp). */ private void getSlaves() { try { System.out.println("\nInizio acquisizione slaves ... "); DatagramSocket soc=new DatagramSocket(basePort); StringBuffer slaveBuf=new StringBuffer(); for (int i=0;i<ConstantsM.numSlaves;i++) { byte[] inb=new byte[10]; DatagramPacket inpac=new DatagramPacket(inb,inb.length); soc.receive(inpac); // aggiunge lo slave nell'oggetto SlaveVivi String porta=(new String(inpac.getData())).trim(); String slaveAddr=(inpac.getAddress()).getHostAddress(); ConstantsM.sv.putSlave(slaveAddr,(new Integer(porta)).intValue()); slaveBuf.append(slaveAddr+":"+porta+"\n"); System.out.println(slaveAddr+":"+porta+" aggiunto."); } // invia gli ack che contengono la lista di tutti gli slaves byte[] outb=(slaveBuf.toString()).getBytes(); DatagramPacket outpac=new DatagramPacket(outb,outb.length); transmit(soc,ConstantsM.sv.getSlave(),outpac); soc.close(); System.out.println("lista slaves impostata.\n"); } catch(SocketException ex) { System.out.println("Master.getSlaves: "+ex.toString()); System.exit(2); } catch(SecurityException ex) { System.out.println("Master.getSlaves: "+ex.toString()); System.exit(3); } catch(IOException ex) { System.out.println("Master.getSlaves: "+ex.toString()); System.exit(4); } } // fine getSlaves } // fine Master