1 7 package org.jboss.cache.buddyreplication; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 import org.jboss.cache.config.BuddyReplicationConfig.BuddyLocatorConfig; 12 import org.jgroups.Address; 13 import org.jgroups.stack.IpAddress; 14 15 import java.net.InetAddress ; 16 import java.net.NetworkInterface ; 17 import java.net.SocketException ; 18 import java.util.ArrayList ; 19 import java.util.Enumeration ; 20 import java.util.List ; 21 import java.util.Map ; 22 23 37 public class NextMemberBuddyLocator implements BuddyLocator 38 { 39 private Log log = LogFactory.getLog(NextMemberBuddyLocator.class); 40 41 private NextMemberBuddyLocatorConfig config = new NextMemberBuddyLocatorConfig(); 42 43 public BuddyLocatorConfig getConfig() 44 { 45 return config; 46 } 47 48 public void init(BuddyLocatorConfig buddyLocatorConfig) 49 { 50 if (buddyLocatorConfig instanceof NextMemberBuddyLocatorConfig) 51 { 52 this.config = (NextMemberBuddyLocatorConfig) buddyLocatorConfig; 53 } 54 else if (buddyLocatorConfig != null) 55 { 56 this.config = new NextMemberBuddyLocatorConfig(buddyLocatorConfig); 57 } 58 else 59 { 60 this.config = new NextMemberBuddyLocatorConfig(); 62 } 63 } 64 65 public List <Address> locateBuddies(Map <Address, String > buddyPoolMap, List <Address> currentMembership, Address dataOwner) 66 { 67 int numBuddiesToFind = Math.min(config.getNumBuddies(), currentMembership.size()); 68 List <Address> buddies = new ArrayList <Address>(numBuddiesToFind); 69 70 int dataOwnerSubscript = currentMembership.indexOf(dataOwner); 72 int i = 0; 73 boolean ignoreColocatedBuddiesForSession = config.isIgnoreColocatedBuddies(); 74 75 76 while (buddies.size() < numBuddiesToFind) 77 { 78 int subscript = i + dataOwnerSubscript + 1; 79 if (subscript >= currentMembership.size()) subscript = subscript - currentMembership.size(); 81 82 if (subscript >= currentMembership.size() && ignoreColocatedBuddiesForSession) 85 { 86 ignoreColocatedBuddiesForSession = false; 87 i = 0; 88 if (log.isInfoEnabled()) 89 log.info("Expected to look for " + numBuddiesToFind + " buddies but could only find " + buddies.size() + " suitable candidates - trying with colocated buddies as well."); 90 91 continue; 92 } 93 94 if (subscript >= currentMembership.size() && buddyPoolMap != null) 96 { 97 buddyPoolMap = null; 98 ignoreColocatedBuddiesForSession = config.isIgnoreColocatedBuddies(); i = 0; 100 if (log.isInfoEnabled()) 101 log.info("Expected to look for " + numBuddiesToFind + " buddies but could only find " + buddies.size() + " suitable candidates - trying again, ignoring buddy pool hints."); 102 continue; 103 } 104 105 if (subscript >= currentMembership.size()) 108 { 109 if (log.isInfoEnabled()) 110 log.info("Expected to look for " + numBuddiesToFind + " buddies but could only find " + buddies.size() + " suitable candidates!"); 111 break; 112 } 113 114 Address candidate = currentMembership.get(subscript); 115 if ( 116 !candidate.equals(dataOwner) && !buddies.contains(candidate) && (!ignoreColocatedBuddiesForSession || !isColocated(candidate, dataOwner)) && (isInSameBuddyPool(buddyPoolMap, candidate, dataOwner)) ) 121 { 122 buddies.add(candidate); 123 } 124 i++; 125 } 126 127 if (log.isTraceEnabled()) log.trace("Selected buddy group as " + buddies); 128 return buddies; 129 } 130 131 private boolean isInSameBuddyPool(Map <Address, String > buddyPoolMap, Address candidate, Address dataOwner) 132 { 133 if (buddyPoolMap == null) return true; 134 Object ownerPoolName = buddyPoolMap.get(dataOwner); 135 Object candidatePoolName = buddyPoolMap.get(candidate); 136 return !(ownerPoolName == null || candidatePoolName == null) && ownerPoolName.equals(candidatePoolName); 137 } 138 139 private boolean isColocated(Address candidate, Address dataOwner) 140 { 141 InetAddress inetC = ((IpAddress) candidate).getIpAddress(); 143 InetAddress inetD = ((IpAddress) dataOwner).getIpAddress(); 144 145 if (inetC.equals(inetD)) return true; 146 147 try 149 { 150 for (Enumeration <NetworkInterface > nics = NetworkInterface.getNetworkInterfaces(); nics.hasMoreElements();) 151 { 152 NetworkInterface i = nics.nextElement(); 153 for (Enumeration <InetAddress > addrs = i.getInetAddresses(); addrs.hasMoreElements();) 154 { 155 InetAddress addr = addrs.nextElement(); 156 if (addr.equals(inetC)) return true; 157 } 158 } 159 } 160 catch (SocketException e) 161 { 162 if (log.isDebugEnabled()) log.debug("Unable to read NICs on host", e); 163 if (log.isWarnEnabled()) 164 { 165 log.warn("UNable to read all network interfaces on host " + inetD + " to determine colocation of " + inetC + ". Assuming " + inetC + " is NOT colocated with " + inetD); 166 } 167 } 168 169 return false; 170 } 171 } | Popular Tags |