Logo AND Algorithmique Numérique Distribuée

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