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