Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Adding error messages and minor bug 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 " + computingClients.get( i ).getClient().getName() ) ;
687                                         return 0 ;
688                                 }
689                         }
690                         
691                         System.err.println( "Unable to found computing client with IP " + _ip + "!" ) ;
692                         return 1 ;
693                 }
694                 
695                 System.err.println( "Unable to change save name. IP or save name empty ! (IP: " + _ip + " ; save name: " + _saveName +")" ) ;
696                 
697                 return 1 ;
698         }
699
700         @Override
701         public ArrayList<ServicesClient> startApplication( int _nb ) 
702         {
703                 int nb = clients.size() - computingClients.size() ;
704                 
705                 if( nb > _nb && ! running )
706                 {
707                         running = true ;
708                         
709                         final ArrayList<ServicesClient> ac = new ArrayList<ServicesClient>() ;
710                         final ArrayList<ComputingClient> tmp = new ArrayList<ComputingClient>() ;
711                         
712                         RunningApplication app = new RunningApplication( "Test" ) ;
713                         
714                         int i = 0 ;
715                         boolean ok ;
716                         
717                         while( i < clients.size() && ac.size() < _nb )
718                         {
719                                 ok = false ;
720                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) 
721                                 {
722                                         synchronized( startingClients )
723                                         {
724                                                 while( ac.size() + startingClients.getNb() >= _nb )
725                                                 {
726                                                         if( ac.size() == _nb ) break ;
727                                                         
728                                                         try {
729                                                                 startingClients.wait() ;
730                                                         } catch (InterruptedException e) {
731                                                                 e.printStackTrace();
732                                                         }
733                                                 }
734                                                 
735                                                 if( ac.size() < _nb )
736                                                 {
737                                                         startingClients.inc() ;
738                                                         ok = true ;
739                                                 }
740                                         }
741                                         
742                                         if( ok )
743                                         {
744                                                 synchronized( limitThread )
745                                                 {
746                                                         while( limitThread.getNb() >= maxThread )
747                                                         {
748                                                                 try {
749                                                                         limitThread.wait() ;
750                                                                 } catch (InterruptedException e) {
751                                                                         e.printStackTrace();
752                                                                 }
753                                                         } 
754                                                         
755                                                         limitThread.inc() ;
756                                                 }
757                                                 
758                                                 final int indice = i ;
759                                                 new Thread( new Runnable(){
760                                                         
761                                                         @Override
762                                                         public void run() 
763                                                         {
764                                                                 int res = 1 ;
765                                                                 try {
766                                                                         res = clients.get( indice ).getStub().startVM( 0 ) ;
767                                                                 } catch( RemoteException e ) {
768                                                                         e.printStackTrace();
769                                                                 }
770                                                                 
771                                                                 if( res == 0 )
772                                                                 {
773                                                                         ac.add( clients.get( indice ).getStub() ) ;
774                                                                         clients.get( indice ).setStatus( "running" ) ;
775                                                                         ComputingClient cl = new ComputingClient( clients.get( indice ) ) ;
776                                                                         clients.get( indice ).setComputingClient( cl ) ;
777                                                                         computingClients.add( cl ) ;
778                                                                         tmp.add( cl ) ;
779                                                                 } else {
780                                                                         System.err.println( "Problem while launching the VM on " 
781                                                                                         + clients.get( indice ).getName() + "!" ) ;
782                                                                 }
783                                                                 
784                                                                 synchronized( limitThread )
785                                                                 {
786                                                                         limitThread.dec() ;
787                                                                         limitThread.notifyAll() ;
788                                                                 }
789                                                                 
790                                                                 synchronized( startingClients )
791                                                                 {
792                                                                         startingClients.dec() ;
793                                                                         startingClients.notifyAll() ;
794                                                                 }
795                                                         }
796                                                 }).start() ;
797                                         }
798                                 }
799                                 
800                                 i++ ;
801                         }
802                         
803                         if( ac.size() == _nb )
804                         {
805                                 app.setComputingClients( tmp ) ;
806                                 app.setRunning( true ) ;
807 //                              app.setStartTime( System.currentTimeMillis() ) ;
808                                 
809                                 int index, index2 ;
810                                 /* Choosing save neighbors */
811                                 for( i = 0 ; i < tmp.size() ; i++ )
812                                 {
813                                         if( i == tmp.size() - 1 )
814                                         {
815                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
816                                                 index2 = computingClients.indexOf( tmp.get( 0 ) ) ;
817                                                 
818                                                 if( index == -1 || index2 == -1 )
819                                                 {
820                                                         System.err.println( "Problem in ComputingClients list!" ) ;
821                                                 } else {
822                                                         try {
823                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() )) ;
824                                                         } catch( RemoteException e ) {
825                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
826                                                                 e.printStackTrace() ;
827                                                         }
828                                                 }
829                                         } else {
830                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
831                                                 index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ;
832                                                 
833                                                 if( index == -1 || index2 == -1 )
834                                                 {
835                                                         System.err.println( "Problem in ComputingClients list!" ) ;
836                                                 } else {
837                                                         try {
838                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ) ;
839                                                         } catch( RemoteException e ) {
840                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
841                                                                 e.printStackTrace() ;
842                                                         }
843                                                 }
844                                         }
845                                 }
846                         }
847                         
848                         applications.add( app ) ;
849                         
850                         ind = applications.indexOf( app ) ;
851                         
852                         return ac ;
853                 }
854                 
855                 return null ;
856         }
857         
858         
859         @Override
860         public void requestSave( String _ip )
861         {
862                 try {
863                         semaSave.acquire() ;
864                 } catch( InterruptedException e ) {
865                         System.err.println( "Unable to obtain the semaphore for semaSave!" ) ;
866                         e.printStackTrace() ;
867                 }
868                 
869                 final String ip = _ip ;
870                 
871                 new Thread( new Runnable() {
872                         
873                         @Override
874                         public void run() 
875                         {
876                                 treatRequestSave( ip ) ;
877                         }
878                 } ).start() ;
879         }
880
881         
882         public void treatRequestSave( String _ip )
883         {
884                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
885                 {
886                         if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave )
887                         {
888                                 // Mark it as a requester
889                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
890                                 {
891                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
892                                         {
893                                                 applications.get( ind ).getComputingClients().get( i ).setSaveRequest( true ) ;
894                                                                                                 
895                                                 break ;
896                                         }
897                                 }
898                                 
899                                 semaSave.release() ;
900                                 
901                                 // Is every body ok?
902                                 boolean ok = false ;
903                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
904                                 {
905                                         if( i == 0 )
906                                         {
907                                                 ok = applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ;
908                                         } else {
909                                                 ok = ok & applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ;     
910                                         }
911                                         
912                                         if( ! ok )
913                                         {
914                                                 break ;
915                                         }
916                                 }
917                                 
918                                 if( ok )
919                                 {
920 //                                      try {
921 //                                              Thread.sleep( 5000 ) ;
922 //                                      } catch( InterruptedException e1 ) {
923 //                                              e1.printStackTrace() ;
924 //                                      }
925                                         
926                                         for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
927                                         {
928                                                 try {
929                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( true ) ;
930                                                         applications.get( ind ).getComputingClients().get( i ).setSaveRequest( false ) ;                                                        
931                                                 } catch( RemoteException e ) {
932                                                         System.err.println( "Unable to send the save request response to " +
933                                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
934                                                         e.printStackTrace() ; 
935                                                 }
936                                         }
937                                         
938                                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
939                                 }
940                                 
941                         } else {
942                                 semaSave.release() ;
943                                 
944                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
945                                 {
946                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
947                                         {
948                                                 try {
949                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( false ) ;
950                                                 } catch( RemoteException e ) {
951                                                         System.err.println( "Unable to send the save request response to " +
952                                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
953                                                         e.printStackTrace() ; 
954                                                 }
955                                                 break ;
956                                         }
957                                 }
958                         }
959                 } else {
960                         semaSave.release() ;
961                         System.err.println( "!! Serious problem in treatRequestSave method!!" ) ;
962                 }
963         }       
964         
965         
966         @Override
967         public void restartOk( String _ip )
968         {
969                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
970                 {
971                         System.out.println( "Client " + _ip + " has finished to restart ("+applications.get( ind ).getComputingClients().size()+") ... " ) ;
972 //                      if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave )
973                         {
974                                 // Has it already finished?
975                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
976                                 {
977                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
978                                         {
979                                                 applications.get( ind ).getComputingClients().get( i ).setRestartOk( true ) ;
980                                                                                                 
981                                                 break ;
982                                         }
983                                 }
984                                 
985                                 // Is everybody ok?
986                                 boolean ok = false ;
987                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
988                                 {
989                                         if( i == 0 )
990                                         {
991                                                 ok = applications.get( ind ).getComputingClients().get( i ).getRestartOk() ;
992                                         } else {
993                                                 ok = ok & applications.get( ind ).getComputingClients().get( i ).getRestartOk() ;       
994                                         }
995                                         
996                                         if( ! ok )
997                                         {
998                                                 break ;
999                                         }
1000                                 }
1001                                 
1002                                 if( ok )
1003                                 {
1004                                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
1005                                         
1006                                         for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
1007                                         {
1008                                                 applications.get( ind ).getComputingClients().get( i ).setRestartOk( false ) ;
1009                                         }
1010                                 }
1011                                 
1012                         }
1013                 }
1014         }       
1015         
1016         
1017         @Override
1018         public void goApplication()
1019         {
1020                 synchronized( applications ) {
1021                 if( running && applications.get( ind ).getStartTime() != 0 )
1022                 {
1023                         applications.get( ind ).setStartTime( System.currentTimeMillis() ) ;
1024                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
1025                 }}
1026         }
1027         
1028
1029         @Override
1030         public void endApplication() 
1031         {
1032                 synchronized( applications )
1033                 {
1034                 if( running )
1035                 {
1036                         Iterator<ComputingClient> it = computingClients.iterator() ;
1037                 
1038                         while( it.hasNext() )
1039                         {
1040                                 ComputingClient cl = it.next() ;
1041
1042                                 try {
1043                                         cl.getClient().getStub().emergencyStop() ;
1044                                 } catch (RemoteException e) {
1045                                         e.printStackTrace();
1046                                 }
1047                         
1048                                 cl.getClient().setStatus( "connected" ) ;
1049                                 cl.getClient().setComputingClient( null ) ;
1050                                 it.remove() ;
1051                                 cl = null ;
1052                         }
1053                 
1054                         applications.get( ind ).setEndTime( System.currentTimeMillis() ) ;
1055                         applications.get( ind ).setRunning( false ) ;
1056                         applications.get( ind ).clear() ;
1057 //                      applications.remove( ind ) ;
1058                         
1059                         running = false ;
1060                         
1061                         System.out.println( "Application " + applications.get( ind ).getName() + " ends in " + 
1062                                         applications.get( ind ).getExecutionTime() + " seconds." ) ;
1063                 }}
1064         }
1065
1066
1067
1068         @Override
1069         public String getAssociatedIP( String _ip )
1070         {
1071                 String ret = null ;
1072                 
1073                 for( int i = 0 ; i < vmIPs.size() ; i++ )
1074                 {
1075                         if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) )
1076                         {
1077                                 ret = vmIPs.get( i ).getVmIP() ;
1078                                 break ;
1079                         }
1080                 }
1081                 
1082                 return ret ;
1083         }
1084         
1085         
1086         public Integer deployVM( final String _name, final String _archive, final String _directory )
1087         {
1088                 int nb = 0, pb = 0 ;
1089                 
1090                 if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 
1091                                 && _directory != null && _directory.length() > 0 )
1092                 {
1093                         System.out.println( "Deploying the VM " + _name + " (" + _archive + ") ... " ) ;
1094                         
1095                         File file = new File( working_directory + "/" + _archive ) ;
1096                         if( ! file.exists() )
1097                         {
1098                                 System.err.println( "There is no archive named " + _archive + " in my working directory!" ) ;
1099                                 file = null ;
1100                                 return 1 ;
1101                         } else if( file.isDirectory() ) {
1102                                 System.err.println( _archive + " is a directory!" ) ;
1103                                 file = null ;
1104                                 return 1 ;
1105                         }
1106                         
1107                         file = null ;
1108                         
1109                         // TODO do a better deployment !!
1110 //                      int ret ;
1111 //                      boolean error, ok, server ;
1112 //                      ArrayList<ConnectedClient> deployed = new ArrayList<ConnectedClient>() ;
1113                         
1114 //                      boolean server = true ;
1115 //                      boolean ok ;
1116                         
1117                         for( int i = 0 ; i < clients.size() ; i++ )
1118                         {
1119 //                              ret = 1 ;
1120                                 nb++ ;
1121 //                              error = false ;
1122 //                              ok = false ;
1123                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) )
1124                                 {                                       
1125                                         synchronized( limitThread )
1126                                         {
1127                                                 while( limitThread.getNb() >= maxThread )
1128                                                 {
1129                                                         try {
1130                                                                 limitThread.wait() ;
1131                                                         } catch (InterruptedException e) {
1132                                                                 e.printStackTrace();
1133                                                         }
1134                                                 } 
1135         
1136                                                 limitThread.inc() ;
1137                                         }
1138                                         
1139                                         final int indice = i ;
1140                                         new Thread( new Runnable() {
1141
1142                                                 @Override
1143                                                 public void run() {
1144                                                         int ret = -1 ;
1145                                                         boolean error = true  ;
1146                                                         
1147                                                         try {
1148                                                                 ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ;
1149                                                         } catch( RemoteException e ) {
1150                                                                 System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ;
1151                                                                 e.printStackTrace() ;
1152                                                         }
1153                                         
1154                                                         // The client does not have the archive, we have to send it.
1155                                                         if( ret == 2 )
1156                                                         {
1157                                                                 // Attention au multi-envois !!!
1158                                                                 System.out.print( "Sending VM archive to " + clients.get( indice ).getName() + " ... " ) ;
1159                                         
1160                                                                 String wd = "" ;
1161                                                                 String snIP = "" ;
1162                                                                 error = false ;
1163                                         
1164                                                                 try {
1165                                                                         wd = clients.get( indice ).getStub().getWorkingDirectory() ;
1166                                                                         snIP = clients.get( indice ).getStub().getIPHost() ;
1167                                                                 } catch (RemoteException e2) {
1168                                                                         System.err.println( "Unable to retrieve information on " + clients.get( indice ).getName() + "!" ) ;
1169                                                                         e2.printStackTrace() ;
1170                                                                         error = true ;
1171                                                                 }
1172                                         
1173                                                                 String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive,
1174                                                                                 snIP + ":" + wd } ;
1175                                 
1176                                                                 if( ! error )
1177                                                                 {
1178                                                                         try {
1179                                                                                 Process proc = Runtime.getRuntime().exec( command ) ;
1180                                                                                 proc.waitFor() ;
1181                         
1182                                                                                 if( proc.exitValue() == 0 )
1183                                                                                 {
1184                                                                                         System.out.println( "Initial VM archive successfully sent." ) ;
1185                                                                                 } else {
1186                                                                                         System.err.println( "Initial VM archive not sent!" ) ;
1187                                                                                         System.err.println( "Error: " + proc.exitValue() ) ;
1188                                                                                         BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ;
1189                                                         
1190                                                                                         String l ;
1191                                                                                         try {
1192                                                                                                 while( (l = b.readLine()) != null )
1193                                                                                                 {
1194                                                                                                         System.err.println( l ) ;
1195                                                                                                 }
1196                                                                                         } catch( IOException e ) {
1197                                                                                                 e.printStackTrace() ;
1198                                                                                         }
1199                                                         
1200                                                                                         error = true ;
1201                                                                                 }
1202                                                                         } catch( IOException e ) {
1203                                                                                 System.err.println( "Error during initial VM archive send command: " ) ;
1204                                                                                 e.printStackTrace() ;
1205                                                                                 error = true ;
1206                                                                         } catch( InterruptedException e ) {
1207                                                                                 e.printStackTrace() ;
1208                                                                                 error = true ;
1209                                                                         }
1210                                                                 }
1211                                 
1212                                                                 
1213                                                                 if( ! error )
1214                                                                 {                               
1215                                                                         // Second try ...
1216                                                                         ret = 1 ;
1217                                                                         try {
1218                                                                                 ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ;
1219                                                                         } catch( RemoteException e ) {
1220                                                                                 System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ;
1221                                                                                 e.printStackTrace() ;
1222                                                                         }
1223                                                                 }
1224                                                         }
1225                                 
1226                                                         if( ret == 0 )
1227                                                         {
1228                                                                 System.out.println( "Initial VM archive successfully deployed on " + clients.get( indice ).getName() + "." ) ;
1229                                                                 
1230                                                                 synchronized( deployingClients )
1231                                                                 {
1232                                                                         deployingClients.inc() ;
1233                                                                 }
1234                                                         }
1235                                                         
1236                                                         synchronized( limitThread )
1237                                                         {
1238                                                                 limitThread.dec() ;
1239                                                                 limitThread.notifyAll() ;
1240                                                         }
1241                                                 }
1242                                         }).start() ;            
1243                                 }
1244                         }
1245                 }
1246                 
1247                 synchronized( limitThread )
1248                 {
1249                         while( limitThread.getNb() > 0  )
1250                         {
1251                                 try {
1252                                         limitThread.wait() ;
1253                                 } catch( InterruptedException e ) {
1254                                         e.printStackTrace() ;
1255                                 }
1256                         }
1257                 }
1258                 
1259                 if( nb - deployingClients.getNb() > 0 )
1260                 {
1261                         if( pb == 1 )
1262                                 System.err.println( "** " + pb + " machine is not deployed!" ) ;
1263                         if( pb > 1 )
1264                                 System.err.println( "** " + pb + " machines are not deployed!" ) ;
1265                 }
1266                 
1267                 return nb ;
1268         }
1269         
1270         
1271         public String getWorkingDirectory()
1272         {
1273                 return working_directory ;
1274         }
1275         
1276         
1277         private class OperatingClients
1278         {
1279                 private int nb ;
1280                 
1281                 OperatingClients() { nb = 0 ; }
1282                 
1283                 protected void inc() { nb++ ; }
1284                 
1285                 protected void dec() { nb-- ; }
1286                 
1287                 protected int getNb() { return nb ; }
1288         }
1289         
1290         
1291         private class LimitThread
1292         {
1293                 private int nb ;
1294                 
1295                 LimitThread() { nb = 0 ; }
1296                 
1297                 protected void inc() { nb++ ; }
1298                 
1299                 protected void dec() { nb-- ; }
1300                 
1301                 protected int getNb() { return nb ; }
1302         }
1303         
1304 }
1305
1306 /** La programmation est un art, respectons ceux qui la pratiquent !! **/
1307