Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Refunding the restart mechanism.
[hpcvm.git] / src / and / hpcvm / Server.java
1 package and.hpcvm ;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.rmi.Naming;
8 import java.rmi.RemoteException;
9 import java.rmi.registry.LocateRegistry;
10 import java.rmi.registry.Registry;
11 import java.rmi.server.UnicastRemoteObject;
12 import java.util.ArrayList;
13 import java.util.Iterator;
14 import java.util.concurrent.Semaphore;
15
16
17 public class Server extends UnicastRemoteObject implements ServicesServer
18 {
19         private class DiscCount
20         {
21                 private int nb ;
22                 
23                 DiscCount() { nb = 0 ; }
24                 
25                 protected void inc() { nb++ ; }
26                 
27                 protected void dec() { 
28                         if( nb > 0 )
29                         {
30                                 nb-- ;
31                         }
32                 }
33                 
34                 protected int getNb() { return nb ; }
35         }       
36         
37         
38         private class IPAssociation
39         {
40                 private String vmIP ;
41                 private String hostIP ;
42                 
43                 IPAssociation()
44                 {
45                         vmIP = "" ;
46                         hostIP = "" ;
47                 }
48                 
49                 protected void setVmIP( String _vmIP )
50                 {
51                         vmIP = _vmIP ;
52                 }
53                 
54                 protected void setHostIP( String _hostIP )
55                 {
56                         hostIP = _hostIP ;
57                 }
58                 
59                 protected String getVmIP()
60                 {
61                         return vmIP ;
62                 }
63                 
64                 protected String getHostIP()
65                 {
66                         return hostIP ;
67                 }
68         }
69         
70         
71         
72         private static final long serialVersionUID = 1L ;
73         private int port ;
74         private ArrayList<ConnectedClient> clients ;
75         private ArrayList<ComputingClient> computingClients ;
76         private ArrayList<RunningApplication> applications ;
77         private int max_timeout ;
78         private ConnectedMonitor monitor ;
79         private DiscCount counter ;
80         private ArrayList<IPAssociation> vmIPs ;
81         private String working_directory ;
82         private long save_interleave ;
83         private Semaphore semaSave ;
84         
85         
86         protected Server() throws RemoteException 
87         {
88                 super() ;
89         }
90
91
92
93         @Override
94         public Integer register( ServicesClient _stub ) 
95         {
96                 if( _stub != null )
97                 {
98                         String ip = "" ;
99                         try {
100                                 ip = _stub.getIPHost() ;
101                         } catch (RemoteException e) {
102                                 e.printStackTrace() ;
103                                 return 1 ;
104                         }
105                         
106                         boolean exists = false ;
107                         int i ;
108                         
109                         for( i = 0 ; i < clients.size() ; i++ )
110                         {
111                                 if( ip.equals( clients.get( i ).getIP() ) )
112                                 {
113                                         exists = true ;
114                                         System.out.println( "Client already connected!" ) ;
115                                         break ;
116                                 }
117                         }
118                         
119                         if( exists )
120                         {
121                                 System.out.println( "The client stub will be replaced." ) ;
122                                 clients.get( i ).setStub( _stub ) ;
123                                 System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ;
124                                 return 2 ;
125                         } else {
126                                 System.out.println( "New connection!" ) ;
127                                 clients.add( new ConnectedClient( _stub ) ) ;
128                                 System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ;
129                                 generateVmIP( ip ) ;
130                                 
131                                 if( clients.size() == 0 )
132                                 {
133                                         System.out.println( "There is no client connected." ) ;
134                                 } else if( clients.size() == 1 ) {
135                                         System.out.println( "There is one client connected." ) ;
136                                 } else {
137                                         System.out.println( "There are " + clients.size() + " clients connected." ) ;
138                                 }
139
140                                 return 0 ;
141                         }
142                 }
143                 
144                 return 1 ;
145         }
146
147         
148         private void generateVmIP( String _ip ) 
149         {
150                 if( _ip != null && ! _ip.equals( "" ) ) 
151                 {       
152                         for( int i = 0 ; i < vmIPs.size() ; i++ )
153                         {
154                                 if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( "" ) )
155                                 {
156                                         vmIPs.get( i ).setHostIP( _ip ) ;
157                                         
158                                         break ;
159                                 }
160                         }
161                 }
162         }
163         
164
165         @Override
166         public void ping( String _ip ) 
167         {
168                 if( _ip != null )
169                 {
170                         for( int i = 0 ; i < clients.size() ; i++ )
171                         {
172                                 if( _ip.equals( clients.get( i ).getIP() ) ) 
173                                 {
174                                         clients.get( i ).resetTimeout() ;
175                                         break ;
176                                 }
177                         }
178                 }               
179         }
180
181         
182         @Override
183         public void changeStatus( String _ip, String _status ) 
184         {
185                 if( _ip != null && _status != null )
186                 {
187                         for( int i = 0 ; i < clients.size() ; i++ )
188                         {
189                                 if( _ip.equals( clients.get( i ).getIP() ) ) 
190                                 {
191                                         clients.get( i ).setStatus( _status ) ;
192                                         System.out.println( "Client " + clients.get( i ).getName() + " changed its status to: " + _status ) ;
193                                         break ;
194                                 }
195                         }
196                 }
197         }
198         
199
200         public void init( int _port ) 
201         {       
202                 port = _port ;
203                 max_timeout = 4 ;
204                 
205                 clients = new ArrayList<ConnectedClient>() ;
206                 computingClients = new ArrayList<ComputingClient>() ;
207                 applications = new ArrayList<RunningApplication>() ;
208                 monitor = null ;
209                 
210                 working_directory = "/localhome/vmware" ;
211                 
212                 save_interleave  = 30 * 60 * 1000 ;
213                 
214                 semaSave = new Semaphore( 1 ) ;
215                 
216                 exportObject() ;
217
218                 vmIPs = new ArrayList<IPAssociation>() ;
219                 // TODO initialisation of VM IPs
220                 for( int i = 2 ; i < 101 ; i++ )
221                 {
222                         vmIPs.add( new IPAssociation() ) ;
223                         vmIPs.get( vmIPs.size() - 1 ).setVmIP( "10.11.10." + i ) ;
224                 }
225                 
226                 clients = new ArrayList<ConnectedClient>() ;
227                 
228                 counter = new DiscCount() ;
229                 
230                 monitor = new ConnectedMonitor() ;
231                 monitor.start() ;
232                 
233                 // TODO
234                 // Check if there are running applications ... and restart them :)
235         }
236         
237         
238         public void stop()
239         {
240                 if( monitor != null ) { monitor.stopMonitor() ; }
241                 
242                 for( int i = 0 ; i < clients.size() ; i++ )
243                 {
244                         try {
245                                 clients.get( i ).getStub().emergencyStop() ;
246                                 clients.get( i ).getStub().stop() ;
247                         } catch (RemoteException e) {
248                                 e.printStackTrace();
249                         }
250                 }
251                 
252                 // unexportObject ?
253                 
254                 System.exit( 0 ) ;
255         }
256
257         
258         private void exportObject() 
259         {
260                 ServicesServer ref = null ;
261                 Registry reg = null ;
262                 
263                 try 
264                 {       
265                         while( true )
266                         {
267                                 reg = LocateRegistry.getRegistry( port ) ;
268
269                                 String tab[] = reg.list() ;
270                         
271                                 System.out.println( "There is an existing RMI Registry on port " +
272                                                 port + " with " + tab.length + " entries!" ) ;
273                                 for( int i = 0 ; i < tab.length ; i++ )
274                                 {
275                                         try {
276                                                 if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) )
277                                                 {
278                                                         System.out.println( "Register successfuly deleted!" ) ;
279                                                 } else {
280                                                         System.err.println( "Register undeleted !!!" ) ;
281                                                 }
282                                         } catch( Exception e ) {
283                                                 e.printStackTrace() ;
284                                         }
285                                 } 
286                         }
287                 } catch( RemoteException e ) {
288                 }       
289                                 
290                 try {
291                         if ( System.getSecurityManager() == null ) 
292                         {
293                     System.setSecurityManager( new SecurityManager() ) ;
294                 }
295                         
296                         LocateRegistry.createRegistry( port ) ;
297                         LocateRegistry.getRegistry( port ).rebind( "Server", this ) ;
298                         ref = (ServicesServer) Naming.lookup( "rmi://"
299                                         + LocalHost.Instance().getIP() + ":" + port
300                                         + "/Server" ) ;
301                 } catch ( Exception e ) {
302                         System.err.println( "Error in Server.exportObject() when creating local services:" + e ) ;
303                         System.err.println( "Exit from Server.exportObject" ) ;
304                         System.exit( 1 ) ;
305                 }
306
307                 LocalHost.Instance().setServerStub( ref ) ;
308                 
309                 System.out.println( "Server launched on IP " + LocalHost.Instance().getIP() + 
310                                 " on port " + port + "." ) ;
311         }
312         
313         /** Fault manager thread **/
314         private class FaultManager extends Thread
315         {
316                 ConnectedClient cl ;
317                 
318                 FaultManager( ConnectedClient _cl )
319                 {
320                         cl = _cl ;
321                 }
322                 
323                 @Override
324                 public void run() 
325                 {
326                         if( cl != null && cl.getStatus().equalsIgnoreCase( "running" ) ||
327                                         cl.getStatus().equalsIgnoreCase( "saving" ) )
328                         {
329                                 ComputingClient cc = cl.getComputingClient() ;
330 //                              ServicesClient dead = cc.getClient().getStub() ;
331                                 String ipDead = cc.getClient().getIP() ;
332                                 SaveNeighbor snDead = null ;
333                                 for( int i = 0 ; i < computingClients.size() ; i++ )
334                                 {
335                                         if( computingClients.get( i ).getSaveNeighbor().getIPHost().equalsIgnoreCase( ipDead ) ) 
336                                         {
337                                                 snDead = computingClients.get( i ).getSaveNeighbor() ;
338                                                 break ;
339                                         }
340                                 }
341                                                                 
342                                 boolean ok = false ;
343                                 
344                                 for( int i = 0 ; i < clients.size() ; i++ )
345                                 {
346                                         if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) 
347                                         {
348 //                                              int res = 1 ;
349 //                                              try {
350 //                                                      res = clients.get( i ).getStub().startVM() ;
351 //                                              } catch( RemoteException e ) {
352 //                                                      e.printStackTrace();
353 //                                              }
354 //                                              
355 //                                              if( res == 0 )
356 //                                              {
357                                                         //clients.get(i).setStatus( "running" ) ;
358                                                 
359                                                 int pos = computingClients.indexOf( cc )  ;
360                                                 if( pos == -1 )
361                                                 {
362                                                         System.err.println( "Dead client not found in the computing clients list!" ) ;
363                                                 } else {
364                                                         System.out.println( "Trying to replace " + cc.getClient().getName() + " with " +
365                                                                         clients.get(i).getName() + " ... " ) ;
366                                                         
367                                                         String save_name = computingClients.get( pos ).getLastSave() ;
368                                                         
369                                                         ComputingClient ccl = new ComputingClient( clients.get(i) ) ;
370                                                         clients.get( i ).setComputingClient( ccl ) ;
371                                                         SaveNeighbor sn = computingClients.get( pos ).getSaveNeighbor() ;
372                                                         ccl.setSaveNeighbor( sn ) ;
373                                                         computingClients.set( pos, ccl ) ;
374
375                                                                 
376                                                         int res = 1 ;
377                                                         try {
378                                                                 res = computingClients.get( pos ).getClient().getStub().
379                                                                       retrieveSave( save_name ) ;
380                                                         } catch( RemoteException e ) {
381                                                                 System.err.println( "Unable to indicate to client to retrieve last save!" ) ;
382                                                                 e.printStackTrace() ;
383                                                         }
384                                                                 
385                                                         if( res == 0 )
386                                                         {
387                                                                 ok = true ;
388                                                                 
389                                                                 boolean ok_new = false, ok_old = false ;
390                                                                         
391                                                                 // replace dead client in vmIPs
392                                                                 for( int j = 0 ; j < vmIPs.size() ; j++ )
393                                                                 {
394                                                                         if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( computingClients.get( pos ).getClient().getIP() ) )
395                                                                         {
396                                                                                 vmIPs.get( j ).setHostIP( "" ) ;
397                                                                                 ok_new = true ;
398                                                                         }
399                                                                         if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( ipDead ) )
400                                                                         {
401                                                                                 String vmIP = vmIPs.get( j ).getVmIP() ;
402                                                                                 vmIPs.get( j ).setHostIP( computingClients.get( pos ).getClient().getIP() ) ;
403                                                                                 ok_old = true ;
404                                                                                 
405                                                                                 try {
406                                                                                         computingClients.get( pos ).getClient().getStub().setIPVM( vmIP ) ;
407                                                                                 } catch( RemoteException e ) {
408                                                                                         System.err.println( "Unable to set the new VM IP on the replacing client!" ) ;
409                                                                                         e.printStackTrace() ;
410                                                                                 }
411                                                                                 
412                                                                                 if( ok_new && ok_old )
413                                                                                 {
414                                                                                         break ;
415                                                                                 }
416                                                                         }
417                                                                 }
418                                                                 
419                                                                 // Replacing in RunningApplication
420                                                                 applications.get( 0 ).replaceComputingClient( cc, ccl ) ;
421                                                                 
422                                                                 for( int l = 0 ; l < applications.get(0).getComputingClients().size() ; l++ )
423                                                                 {
424                                                                         applications.get(0).getComputingClients().get( l ).setSaveRequest( false ) ;
425                                                                 }
426                                                                 
427                                                                         
428                                                                 System.out.println( "Successful redeployment of the VM." ) ;
429                                                         } else {
430                                                                 System.err.println( "Unable to deploy the save on the new computing client!" ) ;
431                                                         }
432                                                 }
433 //                                              } else {
434 //                                                      System.err.println( "Problem while launching the VM on " 
435 //                                                                      + clients.get(i).getName() + "!" ) ;
436 //                                              }
437                                                         
438                                                 if( ok )
439                                                 {
440                                                         for( int k = 0 ; k < computingClients.size() ; k++ )
441                                                         {
442                                                                 try {
443                                                                         computingClients.get( k ).getClient().getStub().
444                                                                                 replaceSaveNeighbor( snDead, new SaveNeighbor( clients.get( i ).getStub() ) ) ;
445                                                                 } catch( RemoteException e ) {
446                                                                         System.err.println( "Unable to inform " + computingClients.get( k ).getClient().getName() +
447                                                                                         " of the replacement of a save neighbor!" ) ;
448                                                                         e.printStackTrace() ;
449                                                                 }
450                                                         }
451                                                         
452                                                         System.out.println( "Dead client successfully replaced." ) ;
453
454                                                         break ;
455                                                 } else {
456                                                         System.err.println( "Dead client not replaced!!" ) ;
457                                                 }
458                                         }
459                                 }
460                         }
461                         
462                         try {
463                                 synchronized( counter ) {
464                                         counter.dec() ;
465                                         counter.notifyAll() ;}
466                         } catch( Exception e ) {}
467                 }
468         }
469         
470         
471         /** Monitoring thread **/
472         private class ConnectedMonitor extends Thread
473         {
474                 boolean run ;
475                 
476                 ConnectedMonitor()
477                 {
478                         run = true ;
479                 }
480                 
481                 protected void stopMonitor() { run = false ; }
482                 
483                 @Override
484                 public void run() 
485                 {
486                         boolean change ;
487                         
488                         while( run )
489                         {
490                                 change = false ;
491                                 Iterator<ConnectedClient> it = clients.iterator() ;
492                                 int nb_disconnections = 0 ;
493                                 int nb_disconnections_computing = 0 ;
494                                 
495                                 while( it.hasNext() )
496                                 {
497                                         ConnectedClient cl = it.next() ;
498                                         cl.incTimeout() ;
499                                         
500                                         if( cl.getTimeout() > max_timeout )
501                                         {
502                                                 System.out.println( "Disconnection of " + cl.getName() ) ;
503                                                 if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) )
504                                                 {
505                                                         System.out.println( "A VM was running on it!!" ) ;
506                                                         System.out.println( "I will redeploy a save and restart all VM ..." ) ;
507                                 
508 //                                                      for( int i = 0 ; i < computingClients.size() ; i++ )
509 //                                                      {
510 //                                                              if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) )
511 //                                                              {
512 //                                                                      computingClients.remove( i ) ;
513 //                                                                      break ;
514 //                                                              }
515 //                                                      }
516                                                         synchronized( counter ){
517                                                                 counter.inc() ;}
518                                                                 
519                                                         
520                                                         new Server.FaultManager( cl ).start() ;
521                                                         nb_disconnections_computing++ ;
522                                                 } else {
523                                                         System.out.println( "There was no VM running on it." ) ;
524                                                         System.out.println( "Maybe it will come back later :)" ) ;
525                                                 }
526                                                 
527                                                 it.remove() ;
528                                                 nb_disconnections++ ;
529                                                 change = true ;
530                                         }
531                                 }
532                                 
533                                 if( change )
534                                 {
535                                         if( clients.size() == 0 )
536                                         {
537                                                 System.out.println( "There is no client connected." ) ;
538                                         } else if( clients.size() == 1 ) {
539                                                 System.out.println( "There is one client connected." ) ;
540                                         } else {
541                                                 System.out.println( "There are " + clients.size() + " clients connected." ) ;
542                                         }
543                                 }
544                                 
545                                 
546                                 if( nb_disconnections_computing > 0 )
547                                 {
548                                         System.out.println( "Sending emergency stop signal to all computing nodes ... " ) ;
549                                         
550                                         for( int i = 0 ; i < clients.size() ; i++ )
551                                         {
552                                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "running" ) 
553                                                         || clients.get( i ).getStatus().equalsIgnoreCase( "saving" ) )
554                                                 {
555                                                         try {
556                                                                 clients.get( i ).getStub().emergencyStop() ;
557                                                         } catch( RemoteException e ) {
558                                                                 System.err.println( "Unable to invoke emergency stop signal on " + clients.get( i ).getName() ) ;
559                                                                 e.printStackTrace() ;
560                                                         }
561                                                 }
562                                         }
563                                         
564                                         System.out.println( "I will redeploy save and restart VMs ... " ) ;
565                                         
566                                         synchronized( counter ) 
567                                         {
568                                                 if( counter.getNb() > 0 )
569                                                 {
570                                                         System.out.println( "... waiting all redeployments done ..." ) ;
571                                                 }
572                                         
573                                                 while( counter.getNb() != 0 )
574                                                 {
575                                                         try {
576                                                                 counter.wait() ;
577                                                         } catch( InterruptedException e ) {
578                                                                 e.printStackTrace() ;
579                                                         }
580                                                 }
581                                         }
582                                         
583                                         for( int  i = 0 ; i < applications.get(0).getComputingClients().size() ; i++ )
584                                         {
585                                                 final ServicesClient sc = applications.get(0).getComputingClients().get( i ).getClient().getStub() ;
586                                                 
587                                                 applications.get( 0 ).getComputingClients().get( i ).setRestartOk( false ) ;
588                                                 
589                                                 new Thread( new Runnable() {
590                                                         
591                                                         @Override
592                                                         public void run() 
593                                                         {
594                                                                 try {
595                                                                         sc.restartVMAfterCrash() ;
596                                                                 } catch( RemoteException e ) {
597                                                                         e.printStackTrace() ;
598                                                                 }
599                                                         }
600                                                 } ).start() ;
601                                         }
602                                 }
603                                 
604                                 try 
605                                 {
606                                         Thread.sleep( 2000 ) ;
607                                 } catch( InterruptedException e ) {
608                                         e.printStackTrace() ;
609                                 }
610                         }
611                 }
612         }
613
614         @Override
615         public Integer saveOk( String _ip, String _saveName ) 
616         {
617                 int i ;
618                 for( i = 0 ; i < computingClients.size() ; i ++ )
619                 {
620                         if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) 
621                         {
622                                 computingClients.get( i ).setLastSave( _saveName ) ;
623                                 computingClients.get( i ).setSaveStatus( true ) ;
624                                 break ;
625                         }
626                 }
627                 
628                 
629                 boolean all_ok = true ;
630                 i = 0 ;
631                 
632                 while( all_ok && i < computingClients.size() )
633                 {
634                         all_ok = all_ok & computingClients.get( i ).getSaveStatus() ;
635                         i++ ;
636                 }
637                 
638                 if( all_ok )
639                 {
640                         for( i = 0 ; i < computingClients.size() ; i++ )
641                         {
642                                 try {
643                                         computingClients.get( i ).getClient().getStub().saveOk() ;
644                                 } catch (RemoteException e) {
645                                         e.printStackTrace();
646                                 }
647                                 computingClients.get( i ).setSaveStatus( false ) ;
648                         }
649                         
650                         applications.get( 0 ).setLastSaveDate( System.currentTimeMillis() ) ;
651                 }
652                 
653                 return 0 ;
654         }
655         
656         
657         public Integer changeSaveName( String _ip, String _saveName )
658         {
659                 if( _ip != null && _ip.length() > 0 && _saveName != null && _saveName.length() > 0 )
660                 {
661                         for( int i = 0 ; i < computingClients.size() ; i ++ )
662                         {
663                                 if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) 
664                                 {
665                                         computingClients.get( i ).setLastSave( _saveName ) ;
666                                         System.out.println( "Save name successfully change for " + _ip ) ;
667                                         return 0 ;
668                                 }
669                         }
670                 }
671                 
672                 return 1 ;
673         }
674
675         @Override
676         public ArrayList<ServicesClient> startApplication( int _nb ) 
677         {
678                 int nb = clients.size() - computingClients.size() ;
679                 
680                 if( nb > _nb )
681                 {
682                         ArrayList<ServicesClient> ac = new ArrayList<ServicesClient>() ;
683                         ArrayList<ComputingClient> tmp = new ArrayList<ComputingClient>() ;
684                         
685                         RunningApplication app = new RunningApplication( "Test" ) ;
686                         
687                         int i = 0 ;
688                         
689                         while( i < clients.size() && ac.size() < _nb )
690                         {
691                                 if( clients.get(i).getStatus().equalsIgnoreCase( "connected" ) ) 
692                                 {
693                                         int res = 1 ;
694                                         try {
695                                                 res = clients.get( i ).getStub().startVM( 0 ) ;
696                                         } catch( RemoteException e ) {
697                                                 e.printStackTrace();
698                                         }
699                                         
700                                         if( res == 0 )
701                                         {
702                                                 ac.add( clients.get( i ).getStub() ) ;
703                                                 clients.get( i ).setStatus( "running" ) ;
704                                                 ComputingClient cl = new ComputingClient( clients.get( i ) ) ;
705                                                 clients.get( i ).setComputingClient( cl ) ;
706                                                 computingClients.add( cl ) ;
707                                                 tmp.add( cl ) ;
708                                         } else {
709                                                 System.err.println( "Problem while launching the VM on " 
710                                                                 + clients.get(i).getName() + "!" ) ;
711                                         }
712                                 }
713                                 
714                                 i++ ;
715                         }
716                         
717                         if( ac.size() == _nb )
718                         {
719                                 app.setComputingClients( tmp ) ;
720                                 app.setRunning( true ) ;
721                                 app.setStartTime( System.currentTimeMillis() ) ;
722                                 
723                                 int index, index2 ;
724                                 /* Choosing save neighbors */
725                                 for( i = 0 ; i < tmp.size() ; i++ )
726                                 {
727                                         if( i == tmp.size() - 1 )
728                                         {
729                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
730                                                 index2 = computingClients.indexOf( tmp.get( 0 ) ) ;
731                                                 
732                                                 if( index == -1 || index2 == -1 )
733                                                 {
734                                                         System.err.println( "Problem in ComputingClients list!" ) ;
735                                                 } else {
736                                                         try {
737                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() )) ;
738                                                         } catch( RemoteException e ) {
739                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
740                                                                 e.printStackTrace() ;
741                                                         }
742                                                 }
743                                         } else {
744                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
745                                                 index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ;
746                                                 
747                                                 if( index == -1 || index2 == -1 )
748                                                 {
749                                                         System.err.println( "Problem in ComputingClients list!" ) ;
750                                                 } else {
751                                                         try {
752                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ) ;
753                                                         } catch( RemoteException e ) {
754                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
755                                                                 e.printStackTrace() ;
756                                                         }
757                                                 }
758                                         }
759                                 }
760                         }
761                         
762                         applications.add( app ) ;
763                         
764                         return ac ;
765                 }
766                 
767                 return null ;
768         }
769         
770         
771         @Override
772         public void requestSave( String _ip )
773         {
774                 try {
775                         semaSave.acquire() ;
776                 } catch( InterruptedException e ) {
777                         System.err.println( "Unable to obtain the semaphore for semaSave!" ) ;
778                         e.printStackTrace() ;
779                 }
780                 
781                 final String ip = _ip ;
782                 
783                 new Thread( new Runnable() {
784                         
785                         @Override
786                         public void run() 
787                         {
788                                 treatRequestSave( ip ) ;
789                         }
790                 } ).start() ;
791         }
792
793         
794         public void treatRequestSave( String _ip )
795         {
796                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
797                 {
798                         if( (System.currentTimeMillis() - applications.get( 0 ).getLastSaveDate()) > save_interleave )
799                         {
800                                 // Mark it as a requester
801                                 for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
802                                 {
803                                         if( applications.get( 0 ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
804                                         {
805                                                 applications.get( 0 ).getComputingClients().get( i ).setSaveRequest( true ) ;
806                                                                                                 
807                                                 break ;
808                                         }
809                                 }
810                                 
811                                 semaSave.release() ;
812                                 
813                                 // Is every body ok?
814                                 boolean ok = false ;
815                                 for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
816                                 {
817                                         if( i == 0 )
818                                         {
819                                                 ok = applications.get( 0 ).getComputingClients().get( i ).getSaveRequest() ;
820                                         } else {
821                                                 ok = ok & applications.get( 0 ).getComputingClients().get( i ).getSaveRequest() ;       
822                                         }
823                                         
824                                         if( ! ok )
825                                         {
826                                                 break ;
827                                         }
828                                 }
829                                 
830                                 if( ok )
831                                 {
832 //                                      try {
833 //                                              Thread.sleep( 5000 ) ;
834 //                                      } catch( InterruptedException e1 ) {
835 //                                              e1.printStackTrace() ;
836 //                                      }
837                                         
838                                         for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
839                                         {
840                                                 try {
841                                                         applications.get( 0 ).getComputingClients().get( i ).getClient().getStub().responseSave( true ) ;
842                                                         applications.get( 0 ).getComputingClients().get( i ).setSaveRequest( false ) ;                                                  
843                                                 } catch( RemoteException e ) {
844                                                         System.err.println( "Unable to send the save request response to " +
845                                                                         applications.get( 0 ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
846                                                         e.printStackTrace() ; 
847                                                 }
848                                         }
849                                         
850                                         applications.get( 0 ).setLastSaveDate( System.currentTimeMillis() ) ;
851                                 }
852                                 
853                         } else {
854                                 semaSave.release() ;
855                                 
856                                 for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
857                                 {
858                                         if( applications.get( 0 ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
859                                         {
860                                                 try {
861                                                         applications.get( 0 ).getComputingClients().get( i ).getClient().getStub().responseSave( false ) ;
862                                                 } catch( RemoteException e ) {
863                                                         System.err.println( "Unable to send the save request response to " +
864                                                                         applications.get( 0 ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
865                                                         e.printStackTrace() ; 
866                                                 }
867                                                 break ;
868                                         }
869                                 }
870                         }
871                 } else {
872                         semaSave.release() ;
873                         System.err.println( "!! Serious problem in treatRequestSave method!!" ) ;
874                 }
875         }       
876         
877         
878         @Override
879         public void restartOk( String _ip )
880         {
881                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
882                 {
883                         System.out.println( "Client " + _ip + " has finished to restart ("+applications.get(0).getComputingClients().size()+") ... " ) ;
884                         if( (System.currentTimeMillis() - applications.get( 0 ).getLastSaveDate()) > save_interleave )
885                         {
886                                 // Has it already finished?
887                                 for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
888                                 {
889                                         if( applications.get( 0 ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
890                                         {
891                                                 applications.get( 0 ).getComputingClients().get( i ).setRestartOk( true ) ;
892                                                                                                 
893                                                 break ;
894                                         }
895                                 }
896                                 
897                                 // Is every body ok?
898                                 boolean ok = false ;
899                                 for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
900                                 {
901                                         if( i == 0 )
902                                         {
903                                                 ok = applications.get( 0 ).getComputingClients().get( i ).getRestartOk() ;
904                                         } else {
905                                                 ok = ok & applications.get( 0 ).getComputingClients().get( i ).getRestartOk() ; 
906                                         }
907                                         
908                                         if( ! ok )
909                                         {
910                                                 break ;
911                                         }
912                                 }
913                                 
914                                 if( ok )
915                                 {
916                                         applications.get( 0 ).setLastSaveDate( System.currentTimeMillis() ) ;
917                                         
918                                         for( int i = 0 ; i < applications.get( 0 ).getComputingClients().size() ; i++ )
919                                         {
920                                                 applications.get( 0 ).getComputingClients().get( i ).setRestartOk( false ) ;
921                                         }
922                                 }
923                                 
924                         }
925                 }
926         }       
927         
928
929         @Override
930         public void endApplication() 
931         {
932                 Iterator<ComputingClient> it = computingClients.iterator() ;
933                 
934                 while( it.hasNext() )
935                 {
936                         ComputingClient cl = it.next() ;
937
938                         try {
939                                 cl.getClient().getStub().emergencyStop() ;
940                         } catch (RemoteException e) {
941                                 e.printStackTrace();
942                         }
943                         
944                         cl.getClient().setStatus( "connected" ) ;
945                         cl.getClient().setComputingClient( null ) ;
946                         it.remove() ;
947                         cl = null ;
948                 }
949                 
950                 applications.get( 0 ).setEndTime( System.currentTimeMillis() ) ;
951                 applications.get( 0 ).setRunning( false ) ;
952                 applications.get( 0 ).clear() ;
953                 
954         }
955
956
957
958         @Override
959         public String getAssociatedIP( String _ip )
960         {
961                 String ret = null ;
962                 
963                 for( int i = 0 ; i < vmIPs.size() ; i++ )
964                 {
965                         if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) )
966                         {
967                                 ret = vmIPs.get( i ).getVmIP() ;
968                                 break ;
969                         }
970                 }
971                 
972                 return ret ;
973         }
974         
975         
976         public Integer deployVM( String _name, String _archive, String _directory )
977         {
978                 int pb = -1 ;
979                 int nb = 0 ;
980                 
981                 if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 
982                                 && _directory != null && _directory.length() > 0 )
983                 {
984                         System.out.println( "Deploying the VM " + _name + " (" + _archive + ") ... " ) ;
985                         
986                         File file = new File( working_directory + "/" + _archive ) ;
987                         if( ! file.exists() )
988                         {
989                                 System.err.println( "There is no archive named " + _archive + " in my working directory!" ) ;
990                                 file = null ;
991                                 return 1 ;
992                         } else if( file.isDirectory() ) {
993                                 System.err.println( _archive + " is a directory!" ) ;
994                                 file = null ;
995                                 return 1 ;
996                         }
997                         
998                         file = null ;
999                         
1000                         // TODO do a better deployment !!
1001                         int ret ;
1002                         boolean error ;
1003                         
1004                         pb = 0 ;
1005                         
1006                         for( int i = 0 ; i < clients.size() ; i++ )
1007                         {
1008                                 ret = 1 ;
1009                                 error = false ;
1010                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) )
1011                                 {
1012                                         try {
1013                                                 ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ;
1014                                         } catch( RemoteException e ) {
1015                                                 System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ;
1016                                                 e.printStackTrace() ;
1017                                         }
1018                                         
1019                                         // The client does not have the archive, we have to send it.
1020                                         if( ret == 2 )
1021                                         {
1022                                                 System.out.print( "Sending VM archive to " + clients.get( i ).getName() + " ... " ) ;
1023                                         
1024                                                 String wd = "" ;
1025                                                 String snIP = "" ;
1026                                                 error = false ;
1027                                         
1028                                                 try {
1029                                                         wd = clients.get( i ).getStub().getWorkingDirectory() ;
1030                                                         snIP = clients.get( i ).getStub().getIPHost() ;
1031                                                 } catch (RemoteException e2) {
1032                                                         System.err.println( "Unable to retrieve information on " + clients.get( i ).getName() + "!" ) ;
1033                                                         e2.printStackTrace() ;
1034                                                         error = true ;
1035                                                         pb++ ;
1036                                                 }
1037                                         
1038                                                 String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive,
1039                                                                 snIP + ":" + wd } ;
1040                                 
1041                                                 if( ! error )
1042                                                 {
1043                                                         try {
1044                                                                 Process proc = Runtime.getRuntime().exec( command ) ;
1045                                                                 proc.waitFor() ;
1046                         
1047                                                                 if( proc.exitValue() == 0 )
1048                                                                 {
1049                                                                         System.out.println( "Initial VM archive successfully sent." ) ;
1050                                                                 } else {
1051                                                                         System.err.println( "Initial VM archive not sent!" ) ;
1052                                                                         System.err.println( "Error: " + proc.exitValue() ) ;
1053                                                                         BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ;
1054                                                         
1055                                                                         String l ;
1056                                                                         try {
1057                                                                                 while( (l = b.readLine()) != null )
1058                                                                                 {
1059                                                                                         System.err.println( l ) ;
1060                                                                                 }
1061                                                                         } catch( IOException e ) {
1062                                                                                 e.printStackTrace() ;
1063                                                                         }
1064                                                         
1065                                                                         error = true ;
1066                                                                         pb++ ;
1067                                                                 }
1068                                                         } catch( IOException e ) {
1069                                                                 System.err.println( "Error during initial VM archive send command: " ) ;
1070                                                                 e.printStackTrace() ;
1071                                                                 error = true ;
1072                                                                 pb++ ;
1073                                                         } catch( InterruptedException e ) {
1074                                                                 e.printStackTrace() ;
1075                                                                 error = true ;
1076                                                                 pb++ ;
1077                                                         }
1078                                                 }
1079                                 
1080                                 
1081                                                 if( error )
1082                                                 {
1083                                                         continue ;
1084                                                 }
1085                                 
1086                                                 // Second try ...
1087                                                 ret = 1 ;
1088                                                 try {
1089                                                         ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ;
1090                                                 } catch( RemoteException e ) {
1091                                                         System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ;
1092                                                         e.printStackTrace() ;
1093                                                         pb++ ;
1094                                                 }
1095                                         }
1096                                 
1097                                         if( ret == 0 )
1098                                         {
1099                                                 System.out.println( "Initial VM archive successfully deployed on " + clients.get( i ).getName() + "." ) ;
1100                                                 nb++ ;
1101                                         }
1102                                 }
1103                         }
1104                 }
1105                 
1106                 if( pb > 0 )
1107                 {
1108                         if( pb == 1 )
1109                                 System.err.println( "** " + pb + " machine is not deployed!" ) ;
1110                         if( pb > 1 )
1111                                 System.err.println( "** " + pb + " machines are not deployed!" ) ;
1112                 }
1113                 
1114                 return nb ;
1115         }
1116         
1117         
1118         public String getWorkingDirectory()
1119         {
1120                 return working_directory ;
1121         }
1122         
1123 }
1124
1125 /** La programmation est un art, respectons ceux qui la pratiquent !! **/
1126