Logo AND Algorithmique Numérique Distribuée

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