1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package jgroup.util.log;
19
20 import static jgroup.util.log.ConnectionPatternEvent.ConnectionPatternType.ConnectionPattern;
21
22 import java.io.IOException;
23 import java.io.ObjectInputStream;
24 import java.io.Serializable;
25 import java.net.InetAddress;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.NoSuchElementException;
34 import java.util.Set;
35
36 import jgroup.core.ConfigManager;
37 import jgroup.relacs.config.Domain;
38 import jgroup.relacs.config.DomainSet;
39
40
41
42
43
44
45 public class ConnectionPatternEvent
46 extends Event
47 implements Iterable<Domain>
48 {
49
50
51
52
53
54 private static final long serialVersionUID = 227099539664502309L;
55
56
57
58
59 public enum Type implements EventType { Partition, Merge }
60
61 public enum ConnectionPatternType implements EventType { ConnectionPattern }
62
63
64
65
66
67
68
69 private List<ConnectionEvent> events = new ArrayList<ConnectionEvent>(3);
70
71
72 private String pattern;
73
74
75 private transient Set<DomainSet> partitions;
76
77
78 private transient Map<InetAddress, DomainSet> hostPartitions;
79
80
81
82
83
84
85 public ConnectionPatternEvent()
86 {
87 super();
88 }
89
90 public ConnectionPatternEvent(String description, String pattern, List<ConnectionEvent> events)
91 {
92 super(ConnectionPattern, description);
93 this.pattern = pattern;
94 this.events = events;
95 }
96
97 public void addEvent(Type type, Domain fromDomain, Domain toDomain)
98 {
99 events.add(new ConnectionEvent(type, fromDomain, toDomain));
100 }
101
102
103
104
105
106
107
108
109
110
111
112 private class ConnectionEvent
113 implements Serializable, Comparable<ConnectionEvent>
114 {
115
116 private static final long serialVersionUID = -5851464130156734196L;
117
118
119
120
121 private final Type type;
122
123
124
125
126 private Domain fromDomain, toDomain;
127
128
129
130
131 private String connectPattern;
132
133 public ConnectionEvent(Type type, Domain fromDomain, Domain toDomain)
134 {
135 this.type = type;
136 this.fromDomain = fromDomain;
137 this.toDomain = toDomain;
138 switch (type) {
139 case Partition:
140 this.connectPattern = fromDomain.getName() + " | " + toDomain.getName();
141 break;
142
143 case Merge:
144 this.connectPattern = fromDomain.getName() + " - " + toDomain.getName();
145 break;
146 }
147 }
148
149 public String toString()
150 {
151 return connectPattern;
152 }
153
154
155
156
157
158
159
160
161 public int compareTo(ConnectionEvent o)
162 {
163 if (o.type == type) {
164 return 0;
165 }
166 if (o.type == Type.Partition && type == Type.Merge) {
167 return -1;
168 } else {
169 return 1;
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182 private void readObject(ObjectInputStream in)
183 throws IOException, ClassNotFoundException
184 {
185 in.defaultReadObject();
186 DomainSet domains = ConfigManager.getDistributedSystem().getDomainSet();
187
188 fromDomain = domains.getDomain(fromDomain);
189 toDomain = domains.getDomain(toDomain);
190 }
191
192 }
193
194
195
196
197
198
199
200
201
202 public List<ConnectionEvent> getConnectionEvents()
203 {
204 return events;
205 }
206
207
208
209
210 public boolean containsPartition()
211 {
212 return partitionCount() > 1;
213 }
214
215
216
217
218 public int partitionCount()
219 {
220 int pCount = 0;
221 for (ConnectionEvent ev : events) {
222 if (ev.type == Type.Partition)
223 pCount++;
224 }
225 if (pCount == 0)
226 pCount = 1;
227 return pCount;
228 }
229
230
231
232
233
234
235
236
237
238 public DomainSet getPartition(InetAddress inetAdr)
239 {
240 if (hostPartitions == null)
241 hostPartitions = new HashMap<InetAddress, DomainSet>();
242 DomainSet domainSet = hostPartitions.get(inetAdr);
243 if (domainSet == null) {
244 domainSet = searchForHost(inetAdr);
245 hostPartitions.put(inetAdr, domainSet);
246 }
247 return domainSet;
248 }
249
250 private DomainSet searchForHost(InetAddress inetAdr)
251 {
252 Set<DomainSet> parts = getPartitions();
253 for (DomainSet domainSet : parts) {
254 if (domainSet.getHostDomain(inetAdr) != null)
255 return domainSet;
256 }
257 throw new NoSuchElementException(inetAdr.toString());
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272 public Set<DomainSet> getPartitions()
273 {
274 if (partitions == null)
275 partitions = new HashSet<DomainSet>();
276 if (!partitions.isEmpty())
277 return partitions;
278
279 Collections.sort(events);
280 for (ConnectionEvent ev : events) {
281 DomainSet xPartition = findPartition(ev.fromDomain);
282 DomainSet yPartition = findPartition(ev.toDomain);
283
284 switch (ev.type) {
285 case Partition:
286 if (xPartition == null) {
287 xPartition = new DomainSet(DomainSet.domainComparator);
288 partitions.add(xPartition);
289 }
290 if (yPartition == null) {
291 yPartition = new DomainSet(DomainSet.domainComparator);
292 partitions.add(yPartition);
293 }
294 xPartition.addDomain(ev.fromDomain);
295 yPartition.addDomain(ev.toDomain);
296 break;
297
298 case Merge:
299 if (xPartition == null && yPartition == null) {
300 xPartition = new DomainSet(DomainSet.domainComparator);
301 partitions.add(xPartition);
302 } else if (xPartition == null && yPartition != null) {
303 xPartition = yPartition;
304 } else {
305
306 assert false;
307 }
308 xPartition.addDomain(ev.fromDomain);
309 xPartition.addDomain(ev.toDomain);
310 break;
311 }
312 }
313 return partitions;
314 }
315
316 private DomainSet findPartition(Domain domain)
317 {
318 for (DomainSet domains : partitions) {
319 if (domains.containsDomain(domain)) {
320 return domains;
321 }
322 }
323 return null;
324 }
325
326
327
328
329
330
331 public String toString()
332 {
333 StringBuilder buf = commonToString(true);
334 buf.append(" [");
335 buf.append(pattern);
336 buf.append("]");
337 return buf.toString();
338 }
339
340
341
342
343
344
345 public Iterator<Domain> iterator()
346 {
347 Set<Domain> domains = new HashSet<Domain>(5);
348 for (ConnectionEvent ev : events) {
349 domains.add(ev.fromDomain);
350 domains.add(ev.toDomain);
351 }
352 return domains.iterator();
353 }
354
355 }