Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Correction of the start application time setup.
[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, dead ;
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                                         dead = false ;
517                                         
518                                         if( cl.getTimeout() > max_timeout || cl.getFail() )
519                                         {
520                                                 dead = true ;
521                                                 if( ! cl.getFail() )
522                                                 {
523                                                         try {
524                                                                 cl.getStub().echo() ;
525                                                                 cl.resetTimeout() ;
526                                                                 dead = false ;
527                                                         } catch( RemoteException e ) {
528                                                                 dead = true ;
529                                                         }
530                                                 } 
531                                                 
532                                                 if( dead )
533                                                 {
534                                                         System.out.println( "Disconnection of " + cl.getName() ) ;
535                                                         if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) )
536                                                         {
537                                                                 System.out.println( "A VM was running on it!!" ) ;
538                                                                 System.out.println( "I will redeploy a save and restart all VM ..." ) ;
539                                 
540 //                                                              for( int i = 0 ; i < computingClients.size() ; i++ )
541 //                                                              {
542 //                                                                      if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) )
543 //                                                                      {
544 //                                                                              computingClients.remove( i ) ;
545 //                                                                              break ;
546 //                                                                      }
547 //                                                              }
548                                                                 synchronized( counter )
549                                                                 {
550                                                                         counter.inc() ;
551                                                                 }
552                                                                 
553                                                                 new Server.FaultManager( cl ).start() ;
554                                                                 nb_disconnections_computing++ ;
555                                                         } else {
556                                                                 System.out.println( "There was no VM running on it." ) ;
557                                                                 System.out.println( "Maybe it will come back later :)" ) ;
558                                                         }
559                                                 
560                                                         synchronized( clients )
561                                                         {
562                                                                 it.remove() ;
563                                                         }
564                                                         nb_disconnections++ ;
565                                                         change = true ;
566                                                 }
567                                         }
568                                 }
569                                 
570                                 if( change )
571                                 {
572                                         synchronized( clients )
573                                         {
574                                                 if( clients.size() == 0 )
575                                                 {
576                                                         System.out.println( "There is no client connected." ) ;
577                                                 } else if( clients.size() == 1 ) {
578                                                         System.out.println( "There is one client connected." ) ;
579                                                 } else {
580                                                         System.out.println( "There are " + clients.size() + " clients connected." ) ;
581                                                 }
582                                         }
583                                 }
584                                 
585                                 
586                                 if( nb_disconnections_computing > 0 )
587                                 {
588                                         System.out.println( "Sending emergency stop signal to all computing nodes ... " ) ;
589                                         
590                                         for( int i = 0 ; i < clients.size() ; i++ )
591                                         {
592                                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "running" ) 
593                                                         || clients.get( i ).getStatus().equalsIgnoreCase( "saving" ) )
594                                                 {
595                                                         try {
596                                                                 clients.get( i ).getStub().emergencyStop() ;
597                                                         } catch( RemoteException e ) {
598                                                                 System.err.println( "Unable to invoke emergency stop signal on " + clients.get( i ).getName() ) ;
599                                                                 e.printStackTrace() ;
600                                                                 yield() ;
601                                                         }
602                                                 }
603                                         }
604                                         
605                                         System.out.println( "I will redeploy save and restart VMs ... " ) ;
606                                         
607                                         synchronized( counter ) 
608                                         {
609                                                 if( counter.getNb() > 0 )
610                                                 {
611                                                         System.out.println( "... waiting all redeployments done ..." ) ;
612                                                 }
613                                         
614                                                 while( counter.getNb() != 0 )
615                                                 {
616                                                         try {
617                                                                 counter.wait() ;
618                                                         } catch( InterruptedException e ) {
619                                                                 e.printStackTrace() ;
620                                                                 yield() ;
621                                                         }
622                                                 }
623                                         }
624                                         
625                                         for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
626                                         {
627                                                 applications.get( ind ).getComputingClients().get( i ).setRestartOk( false ) ;
628                                                 
629                                                 new RestartVM( applications.get( ind ).getComputingClients().get( i ).getClient() ).start() ;
630                                                 
631 //                                              final ServicesClient sc = applications.get( ind ).getComputingClients().get( i ).getClient().getStub() ;
632                                                 
633 //                                              new Thread( new Runnable() {
634 //                                                      
635 //                                                      @Override
636 //                                                      public void run() 
637 //                                                      {
638 //                                                              try {
639 //                                                                      if( sc.restartVMAfterCrash() != 0 )
640 //                                                                      {
641 //                                                                              System.err.println( "Problem while restarting VM on " +sc.getName() + "!" ) ;
642 //                                                                      }
643 //                                                              } catch( RemoteException e ) {
644 //                                                                      try {
645 //                                                                              System.err.println( "Problem while restarting VM on " + sc.getName() + "!" ) ;
646 //                                                                      } catch( RemoteException e1 ) {
647 //                                                                              System.err.println( "Problem while restarting a VM!" ) ;
648 //                                                                              e1.printStackTrace() ;
649 //                                                                      }
650 //                                                                      e.printStackTrace() ;
651 //                                                                      yield() ;
652 //                                                              }
653 //                                                      }
654 //                                              } ).start() ;
655                                         }
656                                 }
657                                 
658                                 try 
659                                 {
660                                         Thread.sleep( 2000 ) ;
661                                 } catch( InterruptedException e ) {
662                                         e.printStackTrace() ;
663                                         yield() ;
664                                 }
665                         }
666                 }
667         }
668
669         @Override
670         public Integer saveOk( String _ip, String _saveName ) 
671         {
672                 int i ;
673                 for( i = 0 ; i < computingClients.size() ; i ++ )
674                 {
675                         if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) 
676                         {
677                                 computingClients.get( i ).setLastSave( _saveName ) ;
678                                 computingClients.get( i ).setSaveStatus( true ) ;
679                                 break ;
680                         }
681                 }
682                 
683                 
684                 boolean all_ok = true ;
685                 i = 0 ;
686                 
687                 while( all_ok && i < computingClients.size() )
688                 {
689                         all_ok = all_ok & computingClients.get( i ).getSaveStatus() ;
690                         i++ ;
691                 }
692                 
693                 if( all_ok )
694                 {
695                         for( i = 0 ; i < computingClients.size() ; i++ )
696                         {
697                                 try {
698                                         computingClients.get( i ).getClient().getStub().saveOk() ;
699                                 } catch (RemoteException e) {
700                                         System.err.println( "Unable to invoke the saveOk method on " + computingClients.get( i ).getClient().getName() ) ;
701                                         e.printStackTrace() ;
702                                 }
703                                 computingClients.get( i ).setSaveStatus( false ) ;
704                         }
705                         
706                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
707                 }
708                 
709                 return 0 ;
710         }
711         
712         
713         public Integer changeSaveName( String _ip, String _saveName )
714         {
715                 if( _ip != null && _ip.length() > 0 && _saveName != null && _saveName.length() > 0 )
716                 {
717                         for( int i = 0 ; i < computingClients.size() ; i ++ )
718                         {
719                                 if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) 
720                                 {
721                                         computingClients.get( i ).setLastSave( _saveName ) ;
722                                         System.out.println( "Save name successfully changed on " + computingClients.get( i ).getClient().getName() ) ;
723                                         return 0 ;
724                                 }
725                         }
726                         
727                         System.err.println( "Unable to found computing client with IP " + _ip + "!" ) ;
728                         return 1 ;
729                 }
730                 
731                 System.err.println( "Unable to change save name. IP or save name empty ! (IP: " + _ip + " ; save name: " + _saveName +")" ) ;
732                 
733                 return 1 ;
734         }
735
736         
737         @Override
738         public ArrayList<ServicesClient> startApplication( int _nb ) 
739         {
740                 int nb = clients.size() - computingClients.size() ;
741                 
742                 if( nb > _nb && ! running )
743                 {
744                         running = true ;
745                         
746                         final ArrayList<ServicesClient> ac = new ArrayList<ServicesClient>() ;
747                         final ArrayList<ComputingClient> tmp = new ArrayList<ComputingClient>() ;
748                         
749                         RunningApplication app = new RunningApplication( "Test" ) ;
750                         
751                         int i = 0 ;
752                         boolean ok ;
753                         
754                         while( i < clients.size() && ac.size() < _nb )
755                         {
756                                 ok = false ;
757                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) 
758                                 {
759                                         synchronized( startingClients )
760                                         {
761                                                 while( ac.size() + startingClients.getNb() >= _nb )
762                                                 {
763                                                         if( ac.size() == _nb ) break ;
764                                                         
765                                                         try {
766                                                                 startingClients.wait() ;
767                                                         } catch( InterruptedException e ) {
768                                                                 e.printStackTrace() ;
769                                                         }
770                                                 }
771                                                 
772                                                 if( ac.size() < _nb )
773                                                 {
774                                                         startingClients.inc() ;
775                                                         ok = true ;
776                                                 }
777                                         }
778                                         
779                                         if( ok )
780                                         {
781                                                 synchronized( limitThread )
782                                                 {
783                                                         while( limitThread.getNb() >= maxThread )
784                                                         {
785                                                                 try {
786                                                                         limitThread.wait() ;
787                                                                 } catch (InterruptedException e) {
788                                                                         e.printStackTrace();
789                                                                 }
790                                                         } 
791                                                         
792                                                         limitThread.inc() ;
793                                                 }
794                                                 
795                                                 final int indice = i ;
796                                                 new Thread( new Runnable()
797                                                 {       
798                                                         @Override
799                                                         public void run() 
800                                                         {
801                                                                 int res = 1 ;
802                                                                 try {
803                                                                         res = clients.get( indice ).getStub().startVM( 0 ) ;
804                                                                 } catch( RemoteException e ) {
805                                                                         e.printStackTrace() ;
806                                                                 }
807                                                                 
808                                                                 if( res == 0 )
809                                                                 {
810                                                                         ac.add( clients.get( indice ).getStub() ) ;
811                                                                         clients.get( indice ).setStatus( "running" ) ;
812                                                                         ComputingClient cl = new ComputingClient( clients.get( indice ) ) ;
813                                                                         clients.get( indice ).setComputingClient( cl ) ;
814                                                                         computingClients.add( cl ) ;
815                                                                         tmp.add( cl ) ;
816                                                                 } else {
817                                                                         System.err.println( "Problem while launching the VM on " 
818                                                                                         + clients.get( indice ).getName() + "!" ) ;
819                                                                 }
820                                                                 
821                                                                 synchronized( limitThread )
822                                                                 {
823                                                                         limitThread.dec() ;
824                                                                         limitThread.notifyAll() ;
825                                                                 }
826                                                                 
827                                                                 synchronized( startingClients )
828                                                                 {
829                                                                         startingClients.dec() ;
830                                                                         startingClients.notifyAll() ;
831                                                                 }
832                                                         }
833                                                 }).start() ;
834                                         }
835                                 }
836                                 
837                                 i++ ;
838                         }
839                         
840                         if( ac.size() == _nb )
841                         {
842                                 app.setComputingClients( tmp ) ;
843                                 app.setRunning( true ) ;
844                                 app.setStartTime( System.currentTimeMillis() ) ;
845                                 
846                                 int index, index2 ;
847                                 /* Choosing save neighbors */
848                                 for( i = 0 ; i < tmp.size() ; i++ )
849                                 {
850                                         if( i == tmp.size() - 1 )
851                                         {
852                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
853                                                 index2 = computingClients.indexOf( tmp.get( 0 ) ) ;
854                                                 
855                                                 if( index == -1 || index2 == -1 )
856                                                 {
857                                                         System.err.println( "Problem in ComputingClients list!" ) ;
858                                                 } else {
859                                                         try {
860                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() )) ;
861                                                         } catch( RemoteException e ) {
862                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
863                                                                 e.printStackTrace() ;
864                                                         }
865                                                 }
866                                         } else {
867                                                 index = computingClients.indexOf( tmp.get( i ) ) ;
868                                                 index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ;
869                                                 
870                                                 if( index == -1 || index2 == -1 )
871                                                 {
872                                                         System.err.println( "Problem in ComputingClients list!" ) ;
873                                                 } else {
874                                                         try {
875                                                                 computingClients.get( index ).setSaveNeighbor( new SaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ) ;
876                                                         } catch( RemoteException e ) {
877                                                                 System.err.println( "Unable to create the save neighbor!" ) ;
878                                                                 e.printStackTrace() ;
879                                                         }
880                                                 }
881                                         }
882                                 }
883                         }
884                         
885                         applications.add( app ) ;
886                         
887                         ind = applications.indexOf( app ) ;
888                         
889                         return ac ;
890                 }
891                 
892                 return null ;
893         }
894         
895         
896         @Override
897         public void requestSave( String _ip )
898         {
899                 try {
900                         semaSave.acquire() ;
901                 } catch( InterruptedException e ) {
902                         System.err.println( "Unable to obtain the semaphore for semaSave!" ) ;
903                         e.printStackTrace() ;
904                 }
905                 
906                 final String ip = _ip ;
907                 
908                 new Thread( new Runnable() {
909                         
910                         @Override
911                         public void run() 
912                         {
913                                 treatRequestSave( ip ) ;
914                         }
915                 } ).start() ;
916         }
917
918         
919         public void treatRequestSave( String _ip )
920         {
921                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
922                 {
923                         if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave )
924                         {
925                                 // Mark it as a requester
926                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
927                                 {
928                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
929                                         {
930                                                 applications.get( ind ).getComputingClients().get( i ).setSaveRequest( true ) ;
931                                                                                                 
932                                                 break ;
933                                         }
934                                 }
935                                 
936                                 semaSave.release() ;
937                                 
938                                 // Is every body ok?
939                                 boolean ok = false ;
940                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
941                                 {
942                                         if( i == 0 )
943                                         {
944                                                 ok = applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ;
945                                         } else {
946                                                 ok = ok & applications.get( ind ).getComputingClients().get( i ).getSaveRequest() ;     
947                                         }
948                                         
949                                         if( ! ok )
950                                         {
951                                                 break ;
952                                         }
953                                 }
954                                 
955                                 if( ok )
956                                 {
957 //                                      try {
958 //                                              Thread.sleep( 5000 ) ;
959 //                                      } catch( InterruptedException e1 ) {
960 //                                              e1.printStackTrace() ;
961 //                                      }
962                                         
963                                         for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
964                                         {
965                                                 try {
966                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( true ) ;
967                                                         applications.get( ind ).getComputingClients().get( i ).setSaveRequest( false ) ;                                                        
968                                                 } catch( RemoteException e ) {
969                                                         System.err.println( "Unable to send the save request response to " +
970                                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
971                                                         e.printStackTrace() ; 
972                                                 }
973                                         }
974                                         
975                                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
976                                 }
977                                 
978                         } else {
979                                 semaSave.release() ;
980                                 
981                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
982                                 {
983                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
984                                         {
985                                                 try {
986                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getStub().responseSave( false ) ;
987                                                 } catch( RemoteException e ) {
988                                                         System.err.println( "Unable to send the save request response to " +
989                                                                         applications.get( ind ).getComputingClients().get( i ).getClient().getName() + "!" ) ;
990                                                         e.printStackTrace() ; 
991                                                 }
992                                                 break ;
993                                         }
994                                 }
995                         }
996                 } else {
997                         semaSave.release() ;
998                         System.err.println( "!! Serious problem in treatRequestSave method!!" ) ;
999                 }
1000         }       
1001         
1002         
1003         @Override
1004         public void restartOk( String _ip )
1005         {
1006                 if( applications.size() > 0 && _ip != null && _ip.length() > 0 )
1007                 {
1008                         System.out.println( "Client " + _ip + " has finished to restart ("+applications.get( ind ).getComputingClients().size()+") ... " ) ;
1009 //                      if( (System.currentTimeMillis() - applications.get( ind ).getLastSaveDate()) > save_interleave )
1010                         {
1011                                 // Has it already finished?
1012                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
1013                                 {
1014                                         if( applications.get( ind ).getComputingClients().get( i ).getClient().getIP().equalsIgnoreCase( _ip ) )
1015                                         {
1016                                                 applications.get( ind ).getComputingClients().get( i ).setRestartOk( true ) ;
1017                                                                                                 
1018                                                 break ;
1019                                         }
1020                                 }
1021                                 
1022                                 // Is everybody ok?
1023                                 boolean ok = false ;
1024                                 for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
1025                                 {
1026                                         if( i == 0 )
1027                                         {
1028                                                 ok = applications.get( ind ).getComputingClients().get( i ).getRestartOk() ;
1029                                         } else {
1030                                                 ok = ok & applications.get( ind ).getComputingClients().get( i ).getRestartOk() ;       
1031                                         }
1032                                         
1033                                         if( ! ok )
1034                                         {
1035                                                 break ;
1036                                         }
1037                                 }
1038                                 
1039                                 if( ok )
1040                                 {
1041                                         applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
1042                                         
1043                                         for( int i = 0 ; i < applications.get( ind ).getComputingClients().size() ; i++ )
1044                                         {
1045                                                 applications.get( ind ).getComputingClients().get( i ).setRestartOk( false ) ;
1046                                         }
1047                                 }
1048                                 
1049                         }
1050                 }
1051         }       
1052         
1053         
1054         @Override
1055         public void goApplication()
1056         {
1057                 synchronized( applications ) {
1058                         if( running && ! applications.get( ind ).getStartMark() )
1059                         {
1060                                 System.out.println( "Application is starting." ) ;
1061                                 applications.get( ind ).setStartMark() ;
1062                                 applications.get( ind ).setStartTime( System.currentTimeMillis() ) ;
1063                                 applications.get( ind ).setLastSaveDate( System.currentTimeMillis() ) ;
1064                         }
1065                 }
1066         }
1067         
1068
1069         @Override
1070         public void endApplication() 
1071         {
1072                 synchronized( applications )
1073                 {
1074                         if( running )
1075                         {
1076                                 applications.get( ind ).setEndTime( System.currentTimeMillis() ) ;
1077                                 applications.get( ind ).setRunning( false ) ;
1078                                 applications.get( ind ).clear() ;
1079                         
1080                                 Iterator<ComputingClient> it = computingClients.iterator() ;
1081                 
1082                                 while( it.hasNext() )
1083                                 {
1084                                         ComputingClient cl = it.next() ;
1085
1086                                         try {
1087                                                 cl.getClient().getStub().emergencyStop() ;
1088                                         } catch (RemoteException e) {
1089                                                 e.printStackTrace();
1090                                         }
1091                         
1092                                         cl.getClient().setStatus( "connected" ) ;
1093                                         cl.getClient().setComputingClient( null ) ;
1094                                         it.remove() ;
1095                                         cl = null ;
1096                                 }
1097                 
1098                         
1099                                 applications.get( ind ).clear() ;
1100                         
1101                                 running = false ;
1102                         
1103                                 System.out.println( "Application " + applications.get( ind ).getName() + " ends in " + 
1104                                         applications.get( ind ).getExecutionTime() + " seconds." ) ;
1105                         }
1106                 }
1107         }
1108
1109
1110
1111         @Override
1112         public String getAssociatedIP( String _ip )
1113         {
1114                 String ret = null ;
1115                 
1116                 for( int i = 0 ; i < vmIPs.size() ; i++ )
1117                 {
1118                         if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) )
1119                         {
1120                                 ret = vmIPs.get( i ).getVmIP() ;
1121                                 break ;
1122                         }
1123                 }
1124                 
1125                 return ret ;
1126         }
1127         
1128         
1129         public Integer deployVM( final String _name, final String _archive, final String _directory )
1130         {
1131                 int nb = 0, pb = 0 ;
1132                 
1133                 if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 
1134                                 && _directory != null && _directory.length() > 0 )
1135                 {
1136                         System.out.println( "Deploying the VM " + _name + " (" + _archive + ") ... " ) ;
1137                         
1138                         File file = new File( working_directory + "/" + _archive ) ;
1139                         if( ! file.exists() )
1140                         {
1141                                 System.err.println( "There is no archive named " + _archive + " in my working directory!" ) ;
1142                                 file = null ;
1143                                 return 1 ;
1144                         } else if( file.isDirectory() ) {
1145                                 System.err.println( _archive + " is a directory!" ) ;
1146                                 file = null ;
1147                                 return 1 ;
1148                         }
1149                         
1150                         file = null ;
1151                         
1152                         // TODO do a better deployment !!
1153 //                      int ret ;
1154 //                      boolean error, ok, server ;
1155 //                      ArrayList<ConnectedClient> deployed = new ArrayList<ConnectedClient>() ;
1156                         
1157 //                      boolean server = true ;
1158 //                      boolean ok ;
1159                         
1160                         for( int i = 0 ; i < clients.size() ; i++ )
1161                         {
1162 //                              ret = 1 ;
1163                                 nb++ ;
1164 //                              error = false ;
1165 //                              ok = false ;
1166                                 if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) )
1167                                 {                                       
1168                                         synchronized( limitThread )
1169                                         {
1170                                                 while( limitThread.getNb() >= maxThread )
1171                                                 {
1172                                                         try {
1173                                                                 limitThread.wait() ;
1174                                                         } catch (InterruptedException e) {
1175                                                                 e.printStackTrace();
1176                                                         }
1177                                                 } 
1178         
1179                                                 limitThread.inc() ;
1180                                         }
1181                                         
1182                                         final int indice = i ;
1183                                         new Thread( new Runnable() {
1184
1185                                                 @Override
1186                                                 public void run() {
1187                                                         int ret = -1 ;
1188                                                         boolean error = true  ;
1189                                                         
1190                                                         try {
1191                                                                 ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ;
1192                                                         } catch( RemoteException e ) {
1193                                                                 System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ;
1194                                                                 e.printStackTrace() ;
1195                                                         }
1196                                         
1197                                                         // The client does not have the archive, we have to send it.
1198                                                         if( ret == 2 )
1199                                                         {
1200                                                                 // Attention au multi-envois !!!
1201                                                                 System.out.print( "Sending VM archive to " + clients.get( indice ).getName() + " ... " ) ;
1202                                         
1203                                                                 String wd = "" ;
1204                                                                 String snIP = "" ;
1205                                                                 error = false ;
1206                                         
1207                                                                 try {
1208                                                                         wd = clients.get( indice ).getStub().getWorkingDirectory() ;
1209                                                                         snIP = clients.get( indice ).getStub().getIPHost() ;
1210                                                                 } catch (RemoteException e2) {
1211                                                                         System.err.println( "Unable to retrieve information on " + clients.get( indice ).getName() + "!" ) ;
1212                                                                         e2.printStackTrace() ;
1213                                                                         error = true ;
1214                                                                 }
1215                                         
1216                                                                 String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive,
1217                                                                                 snIP + ":" + wd } ;
1218                                 
1219                                                                 if( ! error )
1220                                                                 {
1221                                                                         try {
1222                                                                                 Process proc = Runtime.getRuntime().exec( command ) ;
1223                                                                                 proc.waitFor() ;
1224                         
1225                                                                                 if( proc.exitValue() == 0 )
1226                                                                                 {
1227                                                                                         System.out.println( "Initial VM archive successfully sent." ) ;
1228                                                                                 } else {
1229                                                                                         System.err.println( "Initial VM archive not sent!" ) ;
1230                                                                                         System.err.println( "Error: " + proc.exitValue() ) ;
1231                                                                                         BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ;
1232                                                         
1233                                                                                         String l ;
1234                                                                                         try {
1235                                                                                                 while( (l = b.readLine()) != null )
1236                                                                                                 {
1237                                                                                                         System.err.println( l ) ;
1238                                                                                                 }
1239                                                                                         } catch( IOException e ) {
1240                                                                                                 e.printStackTrace() ;
1241                                                                                         }
1242                                                         
1243                                                                                         error = true ;
1244                                                                                 }
1245                                                                         } catch( IOException e ) {
1246                                                                                 System.err.println( "Error during initial VM archive send command: " ) ;
1247                                                                                 e.printStackTrace() ;
1248                                                                                 error = true ;
1249                                                                         } catch( InterruptedException e ) {
1250                                                                                 e.printStackTrace() ;
1251                                                                                 error = true ;
1252                                                                         }
1253                                                                 }
1254                                 
1255                                                                 
1256                                                                 if( ! error )
1257                                                                 {                               
1258                                                                         // Second try ...
1259                                                                         ret = 1 ;
1260                                                                         try {
1261                                                                                 ret = clients.get( indice ).getStub().deployVM( _name, _archive, _directory ) ;
1262                                                                         } catch( RemoteException e ) {
1263                                                                                 System.err.println( "Unable to deploy the VM on " + clients.get( indice ).getName() + "!" ) ;
1264                                                                                 e.printStackTrace() ;
1265                                                                         }
1266                                                                 }
1267                                                         }
1268                                 
1269                                                         if( ret == 0 )
1270                                                         {
1271                                                                 System.out.println( "Initial VM archive successfully deployed on " + clients.get( indice ).getName() + "." ) ;
1272                                                                 
1273                                                                 synchronized( deployingClients )
1274                                                                 {
1275                                                                         deployingClients.inc() ;
1276                                                                 }
1277                                                         }
1278                                                         
1279                                                         synchronized( limitThread )
1280                                                         {
1281                                                                 limitThread.dec() ;
1282                                                                 limitThread.notifyAll() ;
1283                                                         }
1284                                                 }
1285                                         }).start() ;            
1286                                 }
1287                         }
1288                 }
1289                 
1290                 synchronized( limitThread )
1291                 {
1292                         while( limitThread.getNb() > 0  )
1293                         {
1294                                 try {
1295                                         limitThread.wait() ;
1296                                 } catch( InterruptedException e ) {
1297                                         e.printStackTrace() ;
1298                                 }
1299                         }
1300                 }
1301                 
1302                 if( nb - deployingClients.getNb() > 0 )
1303                 {
1304                         if( pb == 1 )
1305                                 System.err.println( "** " + pb + " machine is not deployed!" ) ;
1306                         if( pb > 1 )
1307                                 System.err.println( "** " + pb + " machines are not deployed!" ) ;
1308                 }
1309                 
1310                 return nb ;
1311         }
1312         
1313         
1314         public String getWorkingDirectory()
1315         {
1316                 return working_directory ;
1317         }
1318         
1319         
1320         private class OperatingClients
1321         {
1322                 private int nb ;
1323                 
1324                 OperatingClients() { nb = 0 ; }
1325                 
1326                 protected void inc() { nb++ ; }
1327                 
1328                 protected void dec() { nb-- ; }
1329                 
1330                 protected int getNb() { return nb ; }
1331         }
1332         
1333         
1334         private class LimitThread
1335         {
1336                 private int nb ;
1337                 
1338                 LimitThread() { nb = 0 ; }
1339                 
1340                 protected void inc() { nb++ ; }
1341                 
1342                 protected void dec() { nb-- ; }
1343                 
1344                 protected int getNb() { return nb ; }
1345         }
1346         
1347         
1348         private class RestartVM extends Thread
1349         {
1350                 private ConnectedClient cc ;
1351                 
1352                 protected RestartVM( ConnectedClient _cc )
1353                 {
1354                         cc = _cc ;
1355                 }
1356                         
1357                 public void run()
1358                 {
1359                         boolean error = false ;
1360                         if( cc != null )
1361                         {
1362                                 try {
1363                                         if( cc.getStub().restartVMAfterCrash() != 0 )
1364                                         {
1365                                                 System.err.println( "Problem while restarting VM on " + cc.getName() + "!" ) ;
1366                                                 error = true ;
1367                                         }
1368                                 } catch( RemoteException e ) {
1369                                         e.printStackTrace() ;
1370                                         error = true ;
1371                                         yield() ;
1372                                 }
1373                         } else {
1374                                 System.err.println( "The client to restart is null!" ) ;
1375                         }
1376                         
1377                         if( error )
1378                         {
1379                                 cc.setFail( true ) ;
1380                                 
1381                                 try {
1382                                         System.out.print( "Trying to stop the client ... " ) ;
1383                                         cc.getStub().stop() ;
1384                                         System.out.println( "successful client stop." );
1385                                 } catch( RemoteException e ) {
1386                                         System.out.println( "unsuccessful client stop!" ) ;
1387                                         e.printStackTrace() ;
1388                                 }
1389                         }
1390                 }
1391         }
1392         
1393 }
1394
1395 /** La programmation est un art, respectons ceux qui la pratiquent !! **/
1396