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 String save_neighbor ;
86 private String lastSaveName ;
88 ComputingClient( ConnectedClient cl )
92 save_neighbor = "none" ;
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( String _sn )
104 if( _sn != null && ! _sn.isEmpty() )
106 save_neighbor = _sn ;
109 client.getStub().setSavingNeighbor( _sn ) ;
110 } catch( RemoteException e ) {
111 System.err.println( "Error while setting save neighbor on " +
112 client.getName() + "(" + client.getIP() + ")!" ) ;
113 e.printStackTrace() ;
118 protected String getSaveNeighbor() { return save_neighbor ; }
120 public void setLastSave( String _saveName )
122 lastSaveName = _saveName ;
125 public String getLastSave() { return lastSaveName ; }
130 private class IPAssociation
132 private String vmIP ;
133 private String hostIP ;
141 protected void setVmIP( String _vmIP )
146 protected void setHostIP( String _hostIP )
151 protected String getVmIP()
156 protected String getHostIP()
164 private static final long serialVersionUID = 1L ;
166 private ArrayList<ConnectedClient> clients ;
167 private ArrayList<ComputingClient> computingClients ;
168 private int max_timeout ;
169 private ConnectedMonitor monitor ;
170 private DiscCount counter ;
171 private ArrayList<IPAssociation> vmIPs ;
174 protected Server() throws RemoteException
182 public Integer register( ServicesClient _stub )
188 ip = _stub.getIPHost() ;
189 } catch (RemoteException e) {
190 e.printStackTrace() ;
194 boolean exists = false ;
197 for( i = 0 ; i < clients.size() ; i++ )
199 if( ip.equals( clients.get( i ).getIP() ) )
202 System.out.println( "Client already connected!" ) ;
209 System.out.println( "The client stub will be replaced." ) ;
210 clients.get( i ).setStub( _stub ) ;
211 System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ;
214 System.out.println( "New connection!" ) ;
215 clients.add( new ConnectedClient( _stub ) ) ;
216 System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ;
219 if( clients.size() == 0 )
221 System.out.println( "There is no client connected." ) ;
222 } else if( clients.size() == 1 ) {
223 System.out.println( "There is one client connected." ) ;
225 System.out.println( "There are " + clients.size() + " clients connected." ) ;
236 private void generateVmIP( String _ip )
238 if( _ip != null && ! _ip.equals( "" ) )
240 for( int i = 0 ; i < vmIPs.size() ; i++ )
242 if( vmIPs.get( i ).getHostIP() == null )
244 vmIPs.get( i ).setHostIP( _ip ) ;
254 public void ping( String _ip )
258 for( int i = 0 ; i < clients.size() ; i++ )
260 if( _ip.equals( clients.get( i ).getIP() ) )
262 clients.get( i ).resetTimeout() ;
271 public void changeStatus( String _ip, String _status )
273 if( _ip != null && _status != null )
275 for( int i = 0 ; i < clients.size() ; i++ )
277 if( _ip.equals( clients.get( i ).getIP() ) )
279 clients.get( i ).setStatus( _status ) ;
280 System.out.println( "Client " + clients.get( i ).getName() + " changed its status to: " + _status ) ;
288 public void init( int _port )
293 clients = new ArrayList<Server.ConnectedClient>() ;
294 computingClients = new ArrayList<Server.ComputingClient>() ;
299 vmIPs = new ArrayList<IPAssociation>() ;
300 // TODO initialisation of VM IPs
301 for( int i = 2 ; i < 101 ; i++ )
303 vmIPs.add( new IPAssociation() ) ;
304 vmIPs.get( vmIPs.size() - 1 ).setVmIP( "10.11.10." + i ) ;
307 clients = new ArrayList<Server.ConnectedClient>() ;
309 counter = new DiscCount() ;
311 monitor = new ConnectedMonitor() ;
318 if( monitor != null ) { monitor.stopMonitor() ; }
320 for( int i = 0 ; i < clients.size() ; i++ )
323 clients.get( i ).getStub().stop() ;
324 } catch (RemoteException e) {
335 private void exportObject()
337 ServicesServer ref = null ;
338 Registry reg = null ;
344 reg = LocateRegistry.getRegistry( port ) ;
346 String tab[] = reg.list() ;
348 System.out.println( "There is an existing RMI Registry on port " +
349 port + " with " + tab.length + " entries!" ) ;
350 for( int i = 0 ; i < tab.length ; i++ )
353 if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) )
355 System.out.println( "Register successfuly deleted!" ) ;
357 System.err.println( "Register undeleted !!!" ) ;
359 } catch( Exception e ) {
360 e.printStackTrace() ;
364 } catch( RemoteException e ) {
368 if ( System.getSecurityManager() == null )
370 System.setSecurityManager( new SecurityManager() ) ;
373 LocateRegistry.createRegistry( port ) ;
374 LocateRegistry.getRegistry( port ).rebind( "Server", this ) ;
375 ref = (ServicesServer) Naming.lookup( "rmi://"
376 + LocalHost.Instance().getIP() + ":" + port
378 } catch ( Exception e ) {
379 System.err.println( "Error in Server.exportObject() when creating local services:" + e ) ;
380 System.err.println( "Exit from Server.exportObject" ) ;
384 LocalHost.Instance().setServerStub( ref ) ;
386 System.out.println( "Server launched on IP " + LocalHost.Instance().getIP() +
387 " on port " + port + "." ) ;
390 /** Fault manager thread **/
391 private class FaultManager extends Thread
395 FaultManager( ConnectedClient _cl )
403 synchronized( counter ){
405 System.out.println("ici");
406 if( cl != null && cl.getStatus().equalsIgnoreCase( "running" ) ||
407 cl.getStatus().equalsIgnoreCase( "saving" ) )
409 System.out.println("ok");
410 ComputingClient cc = cl.getComputingClient() ;
411 String ipDead = cc.getClient().getIP() ;
415 for( int i = 0 ; i < clients.size() ; i++ )
417 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) )
421 // res = clients.get( i ).getStub().startVM() ;
422 // } catch( RemoteException e ) {
423 // e.printStackTrace();
428 //clients.get(i).setStatus( "running" ) ;
430 int pos = computingClients.indexOf( cc ) ;
433 System.err.println( "Dead client not found in the computing clients list!" ) ;
435 System.out.println( "Trying to replace " + cc.getClient().getName() + " with " +
436 clients.get(i).getName() + " ... " ) ;
438 ComputingClient ccl = new ComputingClient( clients.get(i) ) ;
439 clients.get( i ).setComputingClient( ccl ) ;
440 String sn = computingClients.get( pos ).getSaveNeighbor() ;
441 ccl.setSaveNeighbor( sn ) ;
442 computingClients.set( pos, ccl ) ;
443 // computingClients.get( pos ).setSaveNeighbor( sn ) ;
448 res = computingClients.get( pos ).getClient().getStub().
449 retrieveSave( computingClients.get(i).getLastSave() ) ;
450 } catch( RemoteException e ) {
451 System.err.println( "Unable to indicate to client to retrieve last save!" ) ;
452 e.printStackTrace() ;
459 // replace dead client in vmIPs
460 for( int j = 0 ; j < vmIPs.size() ; j++ )
462 if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( ipDead ) )
464 String vmIP = vmIPs.get( j ).getVmIP() ;
465 vmIPs.get( j ).setHostIP( computingClients.get( pos ).getClient().getIP() ) ;
468 computingClients.get( pos ).getClient().getStub().setIPVM( vmIP ) ;
469 } catch( RemoteException e ) {
470 System.err.println( "Unable to set the new VM IP on the replacing client!" ) ;
471 e.printStackTrace() ;
477 System.out.println( "Successful redeployment of the VM." ) ;
479 System.err.println( "Unable to deploy the save on the new computing client!" ) ;
483 // System.err.println( "Problem while launching the VM on "
484 // + clients.get(i).getName() + "!" ) ;
489 System.out.println( "Dead client successfully replaced." ) ;
493 System.err.println( "Dead client not replaced!!" ) ;
500 synchronized( counter ) {
502 counter.notifyAll() ;}
503 } catch( Exception e ) {}
508 /** Monitoring thread **/
509 private class ConnectedMonitor extends Thread
518 protected void stopMonitor() { run = false ; }
528 Iterator<ConnectedClient> it = clients.iterator() ;
529 int nb_disconnections = 0 ;
530 int nb_disconnections_computing = 0 ;
532 while( it.hasNext() )
534 ConnectedClient cl = it.next() ;
537 if( cl.getTimeout() > max_timeout )
539 System.out.println( "Disconnection of " + cl.getName() ) ;
540 if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) )
542 System.out.println( "A VM was running on it!!" ) ;
543 System.out.println( "I will redeploy a save and restart all VM ..." ) ;
545 // for( int i = 0 ; i < computingClients.size() ; i++ )
547 // if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) )
549 // computingClients.remove( i ) ;
554 new Server.FaultManager( cl ).start() ;
555 nb_disconnections_computing++ ;
557 System.out.println( "There was no VM running on it." ) ;
558 System.out.println( "Maybe it will come back later :)" ) ;
562 nb_disconnections++ ;
569 if( clients.size() == 0 )
571 System.out.println( "There is no client connected." ) ;
572 } else if( clients.size() == 1 ) {
573 System.out.println( "There is one client connected." ) ;
575 System.out.println( "There are " + clients.size() + " clients connected." ) ;
580 if( nb_disconnections_computing > 0 )
582 System.out.println( "I will redeploy save and restart VMs ..." ) ;
584 synchronized( counter )
586 if( counter.getNb() > 0 )
588 System.out.println( "... waiting all redeployments done ..." ) ;
591 while( counter.getNb() != 0 )
594 counter.wait() ; // !!!!! synchro
595 } catch( InterruptedException e ) {
596 e.printStackTrace() ;
601 for( int i = 0 ; i < computingClients.size() ; i++ )
603 final ServicesClient sc = computingClients.get( i ).getClient().getStub() ;
605 new Thread( new Runnable() {
611 sc.restartVMAfterCrash() ;
612 } catch( RemoteException e ) {
613 e.printStackTrace() ;
622 Thread.sleep( 2000 ) ;
623 } catch( InterruptedException e ) {
624 e.printStackTrace() ;
631 public Integer saveOk( String _ip, String _saveName )
634 for( i = 0 ; i < computingClients.size() ; i ++ )
636 if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
638 computingClients.get( i ).setLastSave( _saveName ) ;
639 computingClients.get( i ).setSaveStatus( true ) ;
645 boolean all_ok = true ;
648 while( all_ok && i < computingClients.size() )
650 all_ok = all_ok & computingClients.get( i ).getSaveStatus() ;
656 for( i = 0 ; i < computingClients.size() ; i++ )
659 computingClients.get( i ).getClient().getStub().saveOk() ;
660 } catch (RemoteException e) {
663 computingClients.get( i ).setSaveStatus( false ) ;
673 public ArrayList<ServicesClient> startApplication( int _nb )
675 int nb = clients.size() - computingClients.size() ;
679 ArrayList<ServicesClient> ac = new ArrayList<ServicesClient>() ;
680 ArrayList<ComputingClient> tmp = new ArrayList<Server.ComputingClient>() ;
684 while( i < clients.size() && ac.size() < _nb )
686 if( clients.get(i).getStatus().equalsIgnoreCase( "connected" ) )
690 res = clients.get( i ).getStub().startVM( 0 ) ;
691 } catch( RemoteException e ) {
697 ac.add( clients.get( i ).getStub() ) ;
698 clients.get( i ).setStatus( "running" ) ;
699 ComputingClient cl = new ComputingClient( clients.get( i ) ) ;
700 clients.get( i ).setComputingClient( cl ) ;
701 computingClients.add( cl ) ;
704 System.err.println( "Problem while launching the VM on "
705 + clients.get(i).getName() + "!" ) ;
712 if( ac.size() == _nb )
715 /* Choosing save neighbors */
716 for( i = 0 ; i < tmp.size() ; i++ )
718 if( i == tmp.size() - 1 )
720 index = computingClients.indexOf( tmp.get( i ) ) ;
721 index2 = computingClients.indexOf( tmp.get( 0 ) ) ;
723 if( index == -1 || index2 == -1 )
725 System.err.println( "Problem in ComputingClients list!" ) ;
727 computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ;
730 index = computingClients.indexOf( tmp.get( i ) ) ;
731 index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ;
733 if( index == -1 || index2 == -1 )
735 System.err.println( "Problem in ComputingClients list!" ) ;
737 computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ;
756 public void endApplication()
758 Iterator<ComputingClient> it = computingClients.iterator() ;
760 while( it.hasNext() )
762 ComputingClient cl = it.next() ;
765 cl.getClient().getStub().stopVM() ;
766 } catch (RemoteException e) {
770 cl.getClient().setStatus( "connected" ) ;
771 cl.getClient().setComputingClient( null ) ;
781 public String getAssociatedIP( String _ip ) throws RemoteException
785 for( int i = 0 ; i < vmIPs.size() ; i++ )
787 if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) )
789 ret = vmIPs.get( i ).getVmIP() ;
799 /** La programmation est un art, respectons ceux qui la pratiquent !! **/