3 import java.rmi.Naming;
4 import java.rmi.RemoteException;
5 import java.rmi.registry.LocateRegistry;
6 import java.rmi.registry.Registry;
7 import java.rmi.server.UnicastRemoteObject;
8 import java.util.ArrayList;
9 import java.util.Iterator;
12 public class Server extends UnicastRemoteObject implements ServicesServer
14 private class DiscCount
18 DiscCount() { nb = 0 ; }
20 protected void inc() { nb++ ; }
22 protected void dec() {
29 protected int getNb() { return nb ; }
33 private class ConnectedClient
35 private ServicesClient stub ;
37 private Status state ;
40 private ComputingClient cl ;
42 ConnectedClient( ServicesClient _stub )
46 state = new Status() ;
47 state.setStatus( "connected" ) ;
49 ip = stub.getIPHost() ;
50 name = stub.getName() ;
51 } catch (RemoteException e) {
57 protected ServicesClient getStub() { return stub ; }
59 protected void setStub( ServicesClient _stub ) { stub = _stub ; }
61 protected int getTimeout() { return timeout ; }
63 protected void incTimeout() { timeout++ ; }
65 protected void resetTimeout() { timeout = 0 ; }
67 protected String getStatus() { return state.getStatus() ; }
69 protected void setStatus( String _state ) { state.setStatus( _state ) ; }
71 protected String getIP() { return ip ; }
73 protected String getName() { return name ; } ;
75 protected void setComputingClient( ComputingClient _cl ) { cl = _cl ; }
77 protected ComputingClient getComputingClient() { return cl ; }
81 private class ComputingClient
83 private ConnectedClient client ;
84 private boolean save_status ;
85 private ArrayList<ServicesClient> save_neighbor ;
86 private String lastSaveName ;
88 ComputingClient( ConnectedClient cl )
92 save_neighbor = new ArrayList<ServicesClient>() ;
93 lastSaveName = "none" ;
96 protected ConnectedClient getClient() { return client ; }
98 protected boolean getSaveStatus(){ return save_status ; }
100 protected void setSaveStatus( boolean _status ) { save_status = _status ; }
102 protected void setSaveNeighbor( ServicesClient _sn )
106 save_neighbor.set( 0, _sn ) ;
108 System.out.println( "My save neighbor is " + _sn ) ;
111 client.getStub().setSavingNeighbor( _sn ) ;
112 } catch( RemoteException e ) {
113 System.err.println( "Error while setting save neighbor on " +
114 client.getName() + "(" + client.getIP() + ")!" ) ;
115 e.printStackTrace() ;
120 protected ServicesClient getSaveNeighbor()
122 if( save_neighbor.isEmpty() )
126 return save_neighbor.get( 0 ) ;
130 public void setLastSave( String _saveName )
132 lastSaveName = _saveName ;
135 public String getLastSave() { return lastSaveName ; }
140 private class IPAssociation
142 private String vmIP ;
143 private String hostIP ;
151 protected void setVmIP( String _vmIP )
156 protected void setHostIP( String _hostIP )
161 protected String getVmIP()
166 protected String getHostIP()
174 private static final long serialVersionUID = 1L ;
176 private ArrayList<ConnectedClient> clients ;
177 private ArrayList<ComputingClient> computingClients ;
178 private int max_timeout ;
179 private ConnectedMonitor monitor ;
180 private DiscCount counter ;
181 private ArrayList<IPAssociation> vmIPs ;
184 protected Server() throws RemoteException
192 public Integer register( ServicesClient _stub )
198 ip = _stub.getIPHost() ;
199 } catch (RemoteException e) {
200 e.printStackTrace() ;
204 boolean exists = false ;
207 for( i = 0 ; i < clients.size() ; i++ )
209 if( ip.equals( clients.get( i ).getIP() ) )
212 System.out.println( "Client already connected!" ) ;
219 System.out.println( "The client stub will be replaced." ) ;
220 clients.get( i ).setStub( _stub ) ;
221 System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ;
224 System.out.println( "New connection!" ) ;
225 clients.add( new ConnectedClient( _stub ) ) ;
226 System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ;
229 if( clients.size() == 0 )
231 System.out.println( "There is no client connected." ) ;
232 } else if( clients.size() == 1 ) {
233 System.out.println( "There is one client connected." ) ;
235 System.out.println( "There are " + clients.size() + " clients connected." ) ;
246 private void generateVmIP( String _ip )
248 if( _ip != null && ! _ip.equals( "" ) )
250 for( int i = 0 ; i < vmIPs.size() ; i++ )
252 if( vmIPs.get( i ).getHostIP() == null )
254 vmIPs.get( i ).setHostIP( _ip ) ;
264 public void ping( String _ip )
268 for( int i = 0 ; i < clients.size() ; i++ )
270 if( _ip.equals( clients.get( i ).getIP() ) )
272 clients.get( i ).resetTimeout() ;
281 public void changeStatus( String _ip, String _status )
283 if( _ip != null && _status != null )
285 for( int i = 0 ; i < clients.size() ; i++ )
287 if( _ip.equals( clients.get( i ).getIP() ) )
289 clients.get( i ).setStatus( _status ) ;
290 System.out.println( "Client " + clients.get( i ).getName() + " changed its status to: " + _status ) ;
298 public void init( int _port )
303 clients = new ArrayList<Server.ConnectedClient>() ;
304 computingClients = new ArrayList<Server.ComputingClient>() ;
309 vmIPs = new ArrayList<IPAssociation>() ;
310 // TODO initialisation of VM IPs
311 for( int i = 2 ; i < 101 ; i++ )
313 vmIPs.add( new IPAssociation() ) ;
314 vmIPs.get( vmIPs.size() - 1 ).setVmIP( "10.11.10." + i ) ;
317 clients = new ArrayList<Server.ConnectedClient>() ;
319 counter = new DiscCount() ;
321 monitor = new ConnectedMonitor() ;
328 if( monitor != null ) { monitor.stopMonitor() ; }
330 for( int i = 0 ; i < clients.size() ; i++ )
333 clients.get( i ).getStub().stop() ;
334 } catch (RemoteException e) {
345 private void exportObject()
347 ServicesServer ref = null ;
348 Registry reg = null ;
354 reg = LocateRegistry.getRegistry( port ) ;
356 String tab[] = reg.list() ;
358 System.out.println( "There is an existing RMI Registry on port " +
359 port + " with " + tab.length + " entries!" ) ;
360 for( int i = 0 ; i < tab.length ; i++ )
363 if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) )
365 System.out.println( "Register successfuly deleted!" ) ;
367 System.err.println( "Register undeleted !!!" ) ;
369 } catch( Exception e ) {
370 e.printStackTrace() ;
374 } catch( RemoteException e ) {
378 if ( System.getSecurityManager() == null )
380 System.setSecurityManager( new SecurityManager() ) ;
383 LocateRegistry.createRegistry( port ) ;
384 LocateRegistry.getRegistry( port ).rebind( "Server", this ) ;
385 ref = (ServicesServer) Naming.lookup( "rmi://"
386 + LocalHost.Instance().getIP() + ":" + port
388 } catch ( Exception e ) {
389 System.err.println( "Error in Server.exportObject() when creating local services:" + e ) ;
390 System.err.println( "Exit from Server.exportObject" ) ;
394 LocalHost.Instance().setServerStub( ref ) ;
396 System.out.println( "Server launched on IP " + LocalHost.Instance().getIP() +
397 " on port " + port + "." ) ;
400 /** Fault manager thread **/
401 private class FaultManager extends Thread
405 FaultManager( ConnectedClient _cl )
413 if( cl != null && cl.getStatus().equalsIgnoreCase( "running" ) ||
414 cl.getStatus().equalsIgnoreCase( "saving" ) )
416 ComputingClient cc = cl.getComputingClient() ;
417 ServicesClient dead = cc.getClient().getStub() ;
418 String ipDead = cc.getClient().getIP() ;
422 for( int i = 0 ; i < clients.size() ; i++ )
424 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) )
428 // res = clients.get( i ).getStub().startVM() ;
429 // } catch( RemoteException e ) {
430 // e.printStackTrace();
435 //clients.get(i).setStatus( "running" ) ;
437 int pos = computingClients.indexOf( cc ) ;
440 System.err.println( "Dead client not found in the computing clients list!" ) ;
442 System.out.println( "Trying to replace " + cc.getClient().getName() + " with " +
443 clients.get(i).getName() + " ... " ) ;
445 String save_name = computingClients.get( pos ).getLastSave() ;
447 ComputingClient ccl = new ComputingClient( clients.get(i) ) ;
448 clients.get( i ).setComputingClient( ccl ) ;
449 ServicesClient sn = computingClients.get( pos ).getSaveNeighbor() ;
450 ccl.setSaveNeighbor( sn ) ;
451 computingClients.set( pos, ccl ) ;
456 res = computingClients.get( pos ).getClient().getStub().
457 retrieveSave( save_name ) ;
458 } catch( RemoteException e ) {
459 System.err.println( "Unable to indicate to client to retrieve last save!" ) ;
460 e.printStackTrace() ;
467 // replace dead client in vmIPs
468 for( int j = 0 ; j < vmIPs.size() ; j++ )
470 if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( ipDead ) )
472 String vmIP = vmIPs.get( j ).getVmIP() ;
473 vmIPs.get( j ).setHostIP( computingClients.get( pos ).getClient().getIP() ) ;
476 computingClients.get( pos ).getClient().getStub().setIPVM( vmIP ) ;
477 } catch( RemoteException e ) {
478 System.err.println( "Unable to set the new VM IP on the replacing client!" ) ;
479 e.printStackTrace() ;
485 System.out.println( "Successful redeployment of the VM." ) ;
487 System.err.println( "Unable to deploy the save on the new computing client!" ) ;
491 // System.err.println( "Problem while launching the VM on "
492 // + clients.get(i).getName() + "!" ) ;
497 for( int k = 0 ; k < computingClients.size() ; k++ )
500 computingClients.get( i ).getClient().getStub().
501 replaceSavingNeighbor( dead, clients.get( i ).getStub() ) ;
502 } catch( RemoteException e ) {
503 System.err.println( "Unable to inform " + computingClients.get( k ).getClient().getName() +
504 " of the replacement of a save neighbor!" ) ;
505 e.printStackTrace() ;
510 System.out.println( "Dead client successfully replaced." ) ;
514 System.err.println( "Dead client not replaced!!" ) ;
521 synchronized( counter ) {
523 counter.notifyAll() ;}
524 } catch( Exception e ) {}
529 /** Monitoring thread **/
530 private class ConnectedMonitor extends Thread
539 protected void stopMonitor() { run = false ; }
549 Iterator<ConnectedClient> it = clients.iterator() ;
550 int nb_disconnections = 0 ;
551 int nb_disconnections_computing = 0 ;
553 while( it.hasNext() )
555 ConnectedClient cl = it.next() ;
558 if( cl.getTimeout() > max_timeout )
560 System.out.println( "Disconnection of " + cl.getName() ) ;
561 if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) )
563 System.out.println( "A VM was running on it!!" ) ;
564 System.out.println( "I will redeploy a save and restart all VM ..." ) ;
566 // for( int i = 0 ; i < computingClients.size() ; i++ )
568 // if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) )
570 // computingClients.remove( i ) ;
574 synchronized( counter ){
578 new Server.FaultManager( cl ).start() ;
579 nb_disconnections_computing++ ;
581 System.out.println( "There was no VM running on it." ) ;
582 System.out.println( "Maybe it will come back later :)" ) ;
586 nb_disconnections++ ;
593 if( clients.size() == 0 )
595 System.out.println( "There is no client connected." ) ;
596 } else if( clients.size() == 1 ) {
597 System.out.println( "There is one client connected." ) ;
599 System.out.println( "There are " + clients.size() + " clients connected." ) ;
604 if( nb_disconnections_computing > 0 )
606 System.out.println( "Sending emergency stop signal to all computing nodes ... " ) ;
608 for( int i = 0 ; i < clients.size() ; i++ )
610 if( clients.get( i ).getStatus().equalsIgnoreCase( "running" )
611 || clients.get( i ).getStatus().equalsIgnoreCase( "saving" ) )
614 clients.get( i ).getStub().emergencyStop() ;
615 } catch( RemoteException e ) {
616 System.err.println( "Unable to invoke emergency stop signal on " + clients.get( i ).getName() ) ;
617 e.printStackTrace() ;
622 System.out.println( "I will redeploy save and restart VMs ... " ) ;
624 synchronized( counter )
626 if( counter.getNb() > 0 )
628 System.out.println( "... waiting all redeployments done ..." ) ;
631 while( counter.getNb() != 0 )
634 System.out.println( "### WAITING counter ###" ) ;
635 counter.wait() ; // !!!!! synchro
636 } catch( InterruptedException e ) {
637 e.printStackTrace() ;
642 for( int i = 0 ; i < computingClients.size() ; i++ )
644 final ServicesClient sc = computingClients.get( i ).getClient().getStub() ;
646 new Thread( new Runnable() {
652 sc.restartVMAfterCrash() ;
653 } catch( RemoteException e ) {
654 e.printStackTrace() ;
663 Thread.sleep( 2000 ) ;
664 } catch( InterruptedException e ) {
665 e.printStackTrace() ;
672 public Integer saveOk( String _ip, String _saveName )
675 for( i = 0 ; i < computingClients.size() ; i ++ )
677 if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
679 computingClients.get( i ).setLastSave( _saveName ) ;
680 computingClients.get( i ).setSaveStatus( true ) ;
686 boolean all_ok = true ;
689 while( all_ok && i < computingClients.size() )
691 all_ok = all_ok & computingClients.get( i ).getSaveStatus() ;
697 for( i = 0 ; i < computingClients.size() ; i++ )
700 computingClients.get( i ).getClient().getStub().saveOk() ;
701 } catch (RemoteException e) {
704 computingClients.get( i ).setSaveStatus( false ) ;
714 public ArrayList<ServicesClient> startApplication( int _nb )
716 int nb = clients.size() - computingClients.size() ;
720 ArrayList<ServicesClient> ac = new ArrayList<ServicesClient>() ;
721 ArrayList<ComputingClient> tmp = new ArrayList<Server.ComputingClient>() ;
725 while( i < clients.size() && ac.size() < _nb )
727 if( clients.get(i).getStatus().equalsIgnoreCase( "connected" ) )
731 res = clients.get( i ).getStub().startVM( 0 ) ;
732 } catch( RemoteException e ) {
738 ac.add( clients.get( i ).getStub() ) ;
739 clients.get( i ).setStatus( "running" ) ;
740 ComputingClient cl = new ComputingClient( clients.get( i ) ) ;
741 clients.get( i ).setComputingClient( cl ) ;
742 computingClients.add( cl ) ;
745 System.err.println( "Problem while launching the VM on "
746 + clients.get(i).getName() + "!" ) ;
753 if( ac.size() == _nb )
756 /* Choosing save neighbors */
757 for( i = 0 ; i < tmp.size() ; i++ )
759 if( i == tmp.size() - 1 )
761 index = computingClients.indexOf( tmp.get( i ) ) ;
762 index2 = computingClients.indexOf( tmp.get( 0 ) ) ;
764 if( index == -1 || index2 == -1 )
766 System.err.println( "Problem in ComputingClients list!" ) ;
768 computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ;
771 index = computingClients.indexOf( tmp.get( i ) ) ;
772 index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ;
774 if( index == -1 || index2 == -1 )
776 System.err.println( "Problem in ComputingClients list!" ) ;
778 computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ;
797 public void endApplication()
799 Iterator<ComputingClient> it = computingClients.iterator() ;
801 while( it.hasNext() )
803 ComputingClient cl = it.next() ;
806 cl.getClient().getStub().stopVM() ;
807 } catch (RemoteException e) {
811 cl.getClient().setStatus( "connected" ) ;
812 cl.getClient().setComputingClient( null ) ;
822 public String getAssociatedIP( String _ip ) throws RemoteException
826 for( int i = 0 ; i < vmIPs.size() ; i++ )
828 if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) )
830 ret = vmIPs.get( i ).getVmIP() ;
840 /** La programmation est un art, respectons ceux qui la pratiquent !! **/