RemoteNodeList.java

Go to the documentation of this file.
00001 /*
00002  * RemoteNodeList.java
00003  *
00004  * Created on 20 août 2003, 21:48
00005  *  Copyright (C) 2003 Philippe MOULIN
00006  *  www.net2map.org
00007  *
00008  *  This program is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU General Public License
00010  *  as published by the Free Software Foundation; either version 2
00011  *  of the License, or (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License
00019  *  along with this program; if not, write to the Free Software
00020  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021  */
00022 
00023 package org.net2map.pov.p2p;
00024 
00025 import java.beans.*;
00026 
00027 import java.util.Enumeration;
00028 import java.util.Hashtable;
00029 import java.io.*;
00030 
00031 //JXTA Imports
00032 import net.jxta.discovery.DiscoveryEvent;
00033 import net.jxta.discovery.DiscoveryListener;
00034 import net.jxta.discovery.DiscoveryService;
00035 import net.jxta.exception.PeerGroupException;
00036 import net.jxta.peergroup.PeerGroup;
00037 import net.jxta.peergroup.PeerGroupFactory;
00038 import net.jxta.protocol.DiscoveryResponseMsg;
00039 import net.jxta.protocol.PeerAdvertisement;
00040 import net.jxta.protocol.PipeAdvertisement;
00041 import net.jxta.endpoint.*;
00042 import net.jxta.document.*;
00043 
00044 //import net.pkg.jal.*;
00045 
00050 public class RemoteNodeList 
00051        extends Thread 
00052        implements java.io.Serializable,
00053                   Runnable,
00054                   DiscoveryListener
00055 {
00056     public static org.apache.log4j.Logger logger = 
00057     org.apache.log4j.Logger.getLogger(RemoteNodeList.class.getName());
00058     
00059     private Hashtable colRemoteNodes;
00060 
00061     private static final String PROP_SAMPLE_PROPERTY = "SampleProperty";
00062     private static final int minRemoteNodesCount = 2;
00063     private static final int maxRemoteNodesCount = 7;
00064     
00065     private int discoveryCycleCounter = 30;
00066     private int discoveryCycleDuration = 600;
00067     
00068     private String sampleProperty;
00069     private boolean hasToStop = false;
00070     
00071     private PropertyChangeSupport propertySupport;
00072     //private LocalNode theLocalNode = null;
00073     //private POV_PeerGroup thePOV_PeerGroup = null;
00074     //private static Peer theLocalPeer = null;
00075         
00076     private static boolean seedNodesInserted = false;
00078 
00080     private static RemoteNodeList instance = null;
00087     public static RemoteNodeList getInstance()
00088     {
00089         if (instance == null)
00090         {
00091             synchronized(RemoteNodeList.class)
00092             {
00093                 if (instance == null)
00094                 {
00095                     instance = new RemoteNodeList();
00096                 }
00097             }      
00098         }
00099         return instance;
00100     }
00102     private RemoteNodeList() 
00103     {
00104         logger.setLevel(org.apache.log4j.Level.DEBUG);
00105         propertySupport = new PropertyChangeSupport( this );
00106         //theLocalNode = paramLocalNode;
00107         //thePOV_PeerGroup = paramPOV_PeerGroup;
00108         colRemoteNodes = new Hashtable();
00109 
00110                     
00111         // Add ourselves as a DiscoveryListener for DiscoveryResponse events
00112         POV_PeerGroup.getInstance().getDiscoveryService().addDiscoveryListener(this);
00114         LocalNode.getInstance().getNetPeerGroup().getDiscoveryService().addDiscoveryListener(this);
00115     }
00116     
00117     private void insertSeedNodesInRemoteNodeList()
00118     {
00119         if (!seedNodesInserted)
00120         {
00121             logger.warn("Reading seed nodes file...");
00122             try
00123             {
00124                 String theSeedNodeFile = 
00125                 ToolBox.getWebPage(new java.net.URL("http://www.net2map.org/SeedNodes.xml"));
00126                 PeerAdvertisement thePeerAdvertisement =
00127                 (PeerAdvertisement)
00128                 AdvertisementFactory
00129                 .newAdvertisement(new MimeMediaType("text/xml"), 
00130                                 new StringReader(theSeedNodeFile));
00131                                 //If this node is not me...
00132      
00133                 if(!thePeerAdvertisement.getPeerID().toString().equals(
00134                     LocalNode.getInstance().getMyPeerID().toString() ))
00135                 {   //And if this node is not already in the remote node list
00136                     if (!isRemoteNodeInList(thePeerAdvertisement.getPeerID().toString()))
00137                     {
00138                         logger.info("Found a new node!");
00139                         //Add this node to the remote node list
00140                         addRemoteNode(thePeerAdvertisement.getPeerID().toString(), 
00141                         new RemoteNode(thePeerAdvertisement));
00142                     }
00143                     else
00144                     {
00145                         logger.info("That seed node was already in the list!");
00146                     }
00147                 }
00148                 else
00149                 {
00150                     logger.info("I am a seed node!");
00151                 }
00152             }
00153             catch(Exception theException)
00154             {
00155                 logger.error("Exception " + theException);
00156                 theException.printStackTrace();
00157             }
00158         seedNodesInserted = true;
00159         }
00160         
00161     }
00162 
00163     public String getSampleProperty() 
00164     {
00165         return sampleProperty;
00166     }
00167     
00168     public void setSampleProperty(String value) 
00169     {
00170         String oldValue = sampleProperty;
00171         sampleProperty = value;
00172         propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY, oldValue, sampleProperty);
00173     }
00174     
00175     
00176     public void addPropertyChangeListener(PropertyChangeListener listener) 
00177     {
00178         propertySupport.addPropertyChangeListener(listener);
00179     }
00180     
00181     public void removePropertyChangeListener(PropertyChangeListener listener) 
00182     {
00183         propertySupport.removePropertyChangeListener(listener);
00184     }
00185     
00190     public RemoteNode getRemoteNode( String paramPeerID ) 
00191     {
00192         return (RemoteNode)colRemoteNodes.get(paramPeerID);
00193     }
00194     
00198     public synchronized void addRemoteNode( String paramPeerID, 
00199                                             RemoteNode paramRemoteNode )
00200     {
00201         colRemoteNodes.put(paramPeerID, paramRemoteNode);
00202     }
00203     
00204     public void removeRemoteNode( String paramPeerID )
00205     {
00206         colRemoteNodes.remove(paramPeerID);
00207     }
00208     public synchronized boolean isRemoteNodeInList( String paramPeerID)
00209     {
00210         return ( colRemoteNodes.containsKey(paramPeerID));
00211     }
00212     
00213     public synchronized void discoveryEvent(net.jxta.discovery.DiscoveryEvent discoveryEvent) 
00214     {
00215         DiscoveryResponseMsg res = discoveryEvent.getResponse();
00216         String name = "unknown";
00217 
00218         // Get the responding peer's advertisement
00219         PeerAdvertisement peerAdv = res.getPeerAdvertisement();
00220         // some peers may not respond with their peerAdv
00221         if (peerAdv != null) 
00222         { 
00223             name = peerAdv.getName();
00224             logger.warn("A peer has responded!");
00225             //System.out.println("\t Description:\t" + peerAdv.getDescription());
00226             logger.warn("\t ID><GROUP:\t" + peerAdv.getID().toString());
00227             logger.warn("\t PeerGroupID:\t" + peerAdv.getPeerGroupID());
00228             logger.warn("\t PeerID:\t" + peerAdv.getPeerID().toString());
00229             logger.warn("\t Name:\t" + peerAdv.getName());
00230         }
00231 
00232         logger.warn( "Got a Discovery Response [" +
00233                       res.getResponseCount() + " elements] from peer: " +
00234                       name +
00235                       "\n(myPeerID=" +
00236                       LocalNode.getInstance().getMyPeerID().toString() +
00237                       ")");
00238         //printout each discovered peer
00239         PeerAdvertisement adv = null;
00240         PipeAdvertisement thePipeAdvertisement = null;
00241         Enumeration enum = res.getAdvertisements();
00242         if (enum != null ) 
00243         {
00244             while (enum.hasMoreElements()) 
00245             {
00246                 Object theAdvertisement = enum.nextElement();
00247                 //is it a PeerAdvertisement?
00248                 if(! (theAdvertisement instanceof PeerAdvertisement))
00249                 {
00250                     logger.warn("received a " + theAdvertisement.getClass().toString());
00251                     //is it a pipe advertisement?
00252                     if(theAdvertisement instanceof PipeAdvertisement)
00253                     {                        
00254                         thePipeAdvertisement = (PipeAdvertisement) theAdvertisement;
00255                         logger.warn("This is a pipe advertisement:\n\tgetAdvType:\"" +
00256                                      thePipeAdvertisement.getAdvType() +
00257                                      "\" \n\tgetAdvertisementType:\"" +
00258                                      thePipeAdvertisement.getAdvertisementType() +
00259                                      "\" \n\tgetID:\""+
00260                                      thePipeAdvertisement.getID().toString() +
00261                                      "\" \n\tgetName:\"" +
00262                                      thePipeAdvertisement.getName() +
00263                                      "\" \n\tgetPipeID:\"" +
00264                                      thePipeAdvertisement.getPipeID() +
00265                                      "\" \n\tgetType:\"" +
00266                                      thePipeAdvertisement.getType() +
00267                                      "\""
00268                                      );
00269                     }
00270                 }
00271                 else //this is a peer advertisement. let's look into it...
00272                 {
00273                     adv = (PeerAdvertisement) theAdvertisement;
00274                     logger.warn("Peer name = " + adv.getName());
00275 
00276                     logger.warn("\t ID><GROUP:\t" + adv.getID().toString());
00277                     logger.warn("\t PeerGroupID:\t" + adv.getPeerGroupID());
00278                     logger.warn("\t PeerID:\t" + adv.getPeerID().toString());
00279                     logger.warn("\t MyPeerID:\t" + LocalNode.getInstance().getMyPeerID().toString()); 
00280                     //If this node is not me...
00281                     if(!adv.getPeerID().toString().equals(
00282                         LocalNode.getInstance().getMyPeerID().toString() ))
00283                     {   //And if this node is not already in the remote node list
00284                         if (!isRemoteNodeInList(adv.getPeerID().toString()))
00285                         {
00286                             logger.warn("Found a new node!" );
00287                             if(colRemoteNodes.size() >= maxRemoteNodesCount)
00288                             {
00289                                 removeABadNodeFromList();
00290                             }
00291                             //Add this node to the remote node list
00292                             addRemoteNode(adv.getPeerID().toString(), 
00293                                         new RemoteNode(adv));
00294                         }
00295                         else
00296                         {
00297                             logger.warn("(already in the list)");
00298                         }
00299                     }
00300                     else
00301                     {
00302                         logger.warn("(it's me!)");
00303                     }
00304                     logger.warn("--------------------------------------------");
00305                 }
00306             }
00307         }
00308     }
00309     
00310     public void run() 
00311     {
00312         try 
00313         {
00314 
00315             while (!this.hasToStop) 
00316             {
00317                 doPeriodicWork();
00318                 // wait a second
00319                 try 
00320                 {
00321                     Thread.sleep(1 * 1000);
00322                 } 
00323                 catch(Exception e) 
00324                 {}
00325             } //end while
00326         } 
00327         catch(Exception e) 
00328         {
00329             e.printStackTrace();
00330         }
00331         System.out.println("NODE LIST:\tRemoteNodeList thread finished");
00332     }
00333     
00334     public void stopDiscoveryThread()
00335     {
00336         this.hasToStop = true;
00337         System.out.println("NODE LIST:\tStop request received, please wait...");
00338     }
00339     
00340     private void doPeriodicWork()
00341     {
00342         if(discoveryCycleCounter >= discoveryCycleDuration)
00343         {
00344             if(colRemoteNodes.size() > maxRemoteNodesCount)
00345             {
00346                 removeABadNodeFromList();
00347             }
00348             insertSeedNodesInRemoteNodeList();
00349             discoverRemoteNodes();
00350             discoveryCycleCounter = 0;
00351         }
00352         else
00353         {        
00354             discoveryCycleCounter++;
00355         }
00356     }
00357     
00358     private void discoverRemoteNodes()
00359     {
00360         System.out.println("RemoteNodeList is sending a PEER Discovery Message");
00361         logger.warn("RemoteNodeList is sending a PEER Discovery Message");
00362         // look for any peer
00363         POV_PeerGroup.getInstance()
00364         .getDiscoveryService()
00365         .getRemoteAdvertisements( null, 
00366                                   DiscoveryService.PEER,
00367                                   null, 
00368                                   null, 
00369                                   5);
00370          
00372 /*
00373          LocalNode.getInstance().getNetPeerGroup()             
00374          .getDiscoveryService()             
00375          .getRemoteAdvertisements( null, 
00376                                    DiscoveryService.PEER,
00377                                    null, 
00378                                    null, 
00379                                    5);
00380   */       
00381         Enumeration theRemoteNodes = colRemoteNodes.elements();   
00382         RemoteNode currentRemoteNode;
00383         while(theRemoteNodes.hasMoreElements())
00384         {
00385             /*((RemoteNode)theRemoteNodes.nextElement())
00386              .getAdvertisements(theLocalNode.getDiscoveryService());*/    
00387             currentRemoteNode = 
00388             (RemoteNode)theRemoteNodes.nextElement();
00389             logger.warn( "" + 
00390                          currentRemoteNode.getPeerName() + 
00391                          "\t" + 
00392                          currentRemoteNode.getConsecutiveFailureCount() + 
00393                          "\t" +
00394                          currentRemoteNode.getPeerID());
00395             currentRemoteNode.connectToSecurePipe();
00396         }
00397         
00398     }
00399     
00400     public synchronized int getRemoteNodesCount()
00401     {
00402         return(colRemoteNodes.size());
00403     }
00404     
00405     public synchronized void sendMessageToRemoteNodes(Message theMessage)
00406     {
00407         Enumeration theRemoteNodeEnumeration = colRemoteNodes.elements();
00408         while(theRemoteNodeEnumeration.hasMoreElements())
00409         {
00410             RemoteNode theRemoteNode = (RemoteNode)theRemoteNodeEnumeration.nextElement();
00411             theRemoteNode.receiveMessage(theMessage);
00412         }
00413     }
00414     
00416     private synchronized void removeABadNodeFromList()
00417     {             
00418         Enumeration theRemoteNodes = colRemoteNodes.elements();              
00419         RemoteNode currentRemoteNode;        
00420         RemoteNode nodeSelectedForRemoval = null;
00421         int remoteNodesCount = 0;
00422         int worstConsecutiveFailureCountYet = 0;
00423         while(theRemoteNodes.hasMoreElements())        
00424         {
00425             remoteNodesCount++;
00426             currentRemoteNode = 
00427             (RemoteNode)theRemoteNodes.nextElement();
00428             logger.warn( "Node " + 
00429                          currentRemoteNode.getPeerName() + 
00430                          " has made " +
00431                          currentRemoteNode.getConsecutiveFailureCount() +
00432                          " failures ");
00433             if(currentRemoteNode.getConsecutiveFailureCount() > worstConsecutiveFailureCountYet)
00434             {
00435                 worstConsecutiveFailureCountYet = currentRemoteNode.getConsecutiveFailureCount();
00436                 nodeSelectedForRemoval = currentRemoteNode;
00437             }
00438         }
00439         logger.warn("Node count: " + remoteNodesCount);
00440         if(null == nodeSelectedForRemoval)
00441         {
00442             logger.warn("Did not find any bad node to remove");
00443         }
00444         else
00445         {
00446             logger.warn("Removing node " + 
00447                         nodeSelectedForRemoval.getPeerName() + 
00448                         " which has made " +
00449                         worstConsecutiveFailureCountYet +
00450                         " consecutive failures");
00451             removeRemoteNode(nodeSelectedForRemoval.getPeerID());
00452         }
00453     }
00454     
00455     public synchronized void handleIncomingMessage(Message theMessage, RemoteNode theSender)
00456     {
00457         LocalNode.getInstance().handleIncomingMessage(theMessage, theSender);
00458     }
00459 }
Accueil | Téléchargement | Manuel | Doc. technique | Sources CVS | Faq | Nous contacter
©2003 - All Rights Reserved