Logo AND Algorithmique Numérique Distribuée

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