DistributedFlowRuleStore: remote batch support
Change-Id: I373a942697624440e025a8022a13394396058a71
Showing
8 changed files
with
113 additions
and
81 deletions
... | @@ -30,7 +30,7 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -30,7 +30,7 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
30 | * @param request batch operation request. | 30 | * @param request batch operation request. |
31 | * @return event. | 31 | * @return event. |
32 | */ | 32 | */ |
33 | - public static FlowRuleBatchEvent create(FlowRuleBatchRequest request) { | 33 | + public static FlowRuleBatchEvent requested(FlowRuleBatchRequest request) { |
34 | FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_REQUESTED, request, null); | 34 | FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_REQUESTED, request, null); |
35 | return event; | 35 | return event; |
36 | } | 36 | } |
... | @@ -41,7 +41,7 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -41,7 +41,7 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
41 | * @param result completed batch operation result. | 41 | * @param result completed batch operation result. |
42 | * @return event. | 42 | * @return event. |
43 | */ | 43 | */ |
44 | - public static FlowRuleBatchEvent create(FlowRuleBatchRequest request, CompletedBatchOperation result) { | 44 | + public static FlowRuleBatchEvent completed(FlowRuleBatchRequest request, CompletedBatchOperation result) { |
45 | FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_COMPLETED, request, result); | 45 | FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_COMPLETED, request, result); |
46 | return event; | 46 | return event; |
47 | } | 47 | } | ... | ... |
... | @@ -9,10 +9,12 @@ import com.google.common.collect.Lists; | ... | @@ -9,10 +9,12 @@ import com.google.common.collect.Lists; |
9 | 9 | ||
10 | public class FlowRuleBatchRequest { | 10 | public class FlowRuleBatchRequest { |
11 | 11 | ||
12 | + private final int batchId; | ||
12 | private final List<FlowEntry> toAdd; | 13 | private final List<FlowEntry> toAdd; |
13 | private final List<FlowEntry> toRemove; | 14 | private final List<FlowEntry> toRemove; |
14 | 15 | ||
15 | - public FlowRuleBatchRequest(List<FlowEntry> toAdd, List<FlowEntry> toRemove) { | 16 | + public FlowRuleBatchRequest(int batchId, List<FlowEntry> toAdd, List<FlowEntry> toRemove) { |
17 | + this.batchId = batchId; | ||
16 | this.toAdd = Collections.unmodifiableList(toAdd); | 18 | this.toAdd = Collections.unmodifiableList(toAdd); |
17 | this.toRemove = Collections.unmodifiableList(toRemove); | 19 | this.toRemove = Collections.unmodifiableList(toRemove); |
18 | } | 20 | } |
... | @@ -35,4 +37,8 @@ public class FlowRuleBatchRequest { | ... | @@ -35,4 +37,8 @@ public class FlowRuleBatchRequest { |
35 | } | 37 | } |
36 | return new FlowRuleBatchOperation(entries); | 38 | return new FlowRuleBatchOperation(entries); |
37 | } | 39 | } |
40 | + | ||
41 | + public int batchId() { | ||
42 | + return batchId; | ||
43 | + } | ||
38 | } | 44 | } | ... | ... |
... | @@ -2,12 +2,14 @@ package org.onlab.onos.net.flow.impl; | ... | @@ -2,12 +2,14 @@ package org.onlab.onos.net.flow.impl; |
2 | 2 | ||
3 | import static com.google.common.base.Preconditions.checkNotNull; | 3 | import static com.google.common.base.Preconditions.checkNotNull; |
4 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; |
5 | +import static org.onlab.util.Tools.namedThreads; | ||
5 | 6 | ||
6 | import java.util.List; | 7 | import java.util.List; |
7 | import java.util.Map; | 8 | import java.util.Map; |
8 | import java.util.Set; | 9 | import java.util.Set; |
9 | import java.util.concurrent.CancellationException; | 10 | import java.util.concurrent.CancellationException; |
10 | import java.util.concurrent.ExecutionException; | 11 | import java.util.concurrent.ExecutionException; |
12 | +import java.util.concurrent.ExecutorService; | ||
11 | import java.util.concurrent.Executors; | 13 | import java.util.concurrent.Executors; |
12 | import java.util.concurrent.Future; | 14 | import java.util.concurrent.Future; |
13 | import java.util.concurrent.TimeUnit; | 15 | import java.util.concurrent.TimeUnit; |
... | @@ -74,6 +76,8 @@ public class FlowRuleManager | ... | @@ -74,6 +76,8 @@ public class FlowRuleManager |
74 | 76 | ||
75 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); | 77 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); |
76 | 78 | ||
79 | + private final ExecutorService futureListeners = Executors.newCachedThreadPool(namedThreads("provider-future-listeners")); | ||
80 | + | ||
77 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
78 | protected FlowRuleStore store; | 82 | protected FlowRuleStore store; |
79 | 83 | ||
... | @@ -92,6 +96,8 @@ public class FlowRuleManager | ... | @@ -92,6 +96,8 @@ public class FlowRuleManager |
92 | 96 | ||
93 | @Deactivate | 97 | @Deactivate |
94 | public void deactivate() { | 98 | public void deactivate() { |
99 | + futureListeners.shutdownNow(); | ||
100 | + | ||
95 | store.unsetDelegate(delegate); | 101 | store.unsetDelegate(delegate); |
96 | eventDispatcher.removeSink(FlowRuleEvent.class); | 102 | eventDispatcher.removeSink(FlowRuleEvent.class); |
97 | log.info("Stopped"); | 103 | log.info("Stopped"); |
... | @@ -398,9 +404,9 @@ public class FlowRuleManager | ... | @@ -398,9 +404,9 @@ public class FlowRuleManager |
398 | result.addListener(new Runnable() { | 404 | result.addListener(new Runnable() { |
399 | @Override | 405 | @Override |
400 | public void run() { | 406 | public void run() { |
401 | - store.batchOperationComplete(FlowRuleBatchEvent.create(request, Futures.getUnchecked(result))); | 407 | + store.batchOperationComplete(FlowRuleBatchEvent.completed(request, Futures.getUnchecked(result))); |
402 | } | 408 | } |
403 | - }, Executors.newCachedThreadPool()); | 409 | + }, futureListeners); |
404 | 410 | ||
405 | break; | 411 | break; |
406 | case BATCH_OPERATION_COMPLETED: | 412 | case BATCH_OPERATION_COMPLETED: | ... | ... |
... | @@ -3,15 +3,20 @@ package org.onlab.onos.store.flow.impl; | ... | @@ -3,15 +3,20 @@ package org.onlab.onos.store.flow.impl; |
3 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 3 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
4 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; |
5 | import static org.onlab.onos.store.flow.impl.FlowStoreMessageSubjects.*; | 5 | import static org.onlab.onos.store.flow.impl.FlowStoreMessageSubjects.*; |
6 | +import static org.onlab.util.Tools.namedThreads; | ||
6 | 7 | ||
7 | import java.io.IOException; | 8 | import java.io.IOException; |
8 | import java.util.ArrayList; | 9 | import java.util.ArrayList; |
9 | import java.util.Arrays; | 10 | import java.util.Arrays; |
10 | import java.util.Collection; | 11 | import java.util.Collection; |
11 | import java.util.Collections; | 12 | import java.util.Collections; |
13 | +import java.util.Map; | ||
14 | +import java.util.concurrent.ExecutorService; | ||
15 | +import java.util.concurrent.Executors; | ||
12 | import java.util.concurrent.Future; | 16 | import java.util.concurrent.Future; |
13 | import java.util.concurrent.TimeUnit; | 17 | import java.util.concurrent.TimeUnit; |
14 | import java.util.concurrent.TimeoutException; | 18 | import java.util.concurrent.TimeoutException; |
19 | +import java.util.concurrent.atomic.AtomicInteger; | ||
15 | import java.util.List; | 20 | import java.util.List; |
16 | 21 | ||
17 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -22,7 +27,9 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -22,7 +27,9 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
22 | import org.apache.felix.scr.annotations.Service; | 27 | import org.apache.felix.scr.annotations.Service; |
23 | import org.onlab.onos.ApplicationId; | 28 | import org.onlab.onos.ApplicationId; |
24 | import org.onlab.onos.cluster.ClusterService; | 29 | import org.onlab.onos.cluster.ClusterService; |
30 | +import org.onlab.onos.net.Device; | ||
25 | import org.onlab.onos.net.DeviceId; | 31 | import org.onlab.onos.net.DeviceId; |
32 | +import org.onlab.onos.net.device.DeviceService; | ||
26 | import org.onlab.onos.net.flow.CompletedBatchOperation; | 33 | import org.onlab.onos.net.flow.CompletedBatchOperation; |
27 | import org.onlab.onos.net.flow.DefaultFlowEntry; | 34 | import org.onlab.onos.net.flow.DefaultFlowEntry; |
28 | import org.onlab.onos.net.flow.FlowEntry; | 35 | import org.onlab.onos.net.flow.FlowEntry; |
... | @@ -52,8 +59,12 @@ import org.slf4j.Logger; | ... | @@ -52,8 +59,12 @@ import org.slf4j.Logger; |
52 | 59 | ||
53 | import com.google.common.collect.ArrayListMultimap; | 60 | import com.google.common.collect.ArrayListMultimap; |
54 | import com.google.common.collect.ImmutableSet; | 61 | import com.google.common.collect.ImmutableSet; |
62 | +import com.google.common.collect.Iterables; | ||
63 | +import com.google.common.collect.Maps; | ||
55 | import com.google.common.collect.Multimap; | 64 | import com.google.common.collect.Multimap; |
56 | import com.google.common.util.concurrent.Futures; | 65 | import com.google.common.util.concurrent.Futures; |
66 | +import com.google.common.util.concurrent.ListenableFuture; | ||
67 | +import com.google.common.util.concurrent.SettableFuture; | ||
57 | 68 | ||
58 | /** | 69 | /** |
59 | * Manages inventory of flow rules using a distributed state management protocol. | 70 | * Manages inventory of flow rules using a distributed state management protocol. |
... | @@ -74,13 +85,26 @@ public class DistributedFlowRuleStore | ... | @@ -74,13 +85,26 @@ public class DistributedFlowRuleStore |
74 | ArrayListMultimap.<Short, FlowRule>create(); | 85 | ArrayListMultimap.<Short, FlowRule>create(); |
75 | 86 | ||
76 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 87 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
77 | - private ReplicaInfoService replicaInfoManager; | 88 | + protected ReplicaInfoService replicaInfoManager; |
78 | 89 | ||
79 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 90 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
80 | - private ClusterCommunicationService clusterCommunicator; | 91 | + protected ClusterCommunicationService clusterCommunicator; |
81 | 92 | ||
82 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 93 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
83 | - private ClusterService clusterService; | 94 | + protected ClusterService clusterService; |
95 | + | ||
96 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
97 | + protected DeviceService deviceService; | ||
98 | + | ||
99 | + private final AtomicInteger localBatchIdGen = new AtomicInteger(); | ||
100 | + | ||
101 | + | ||
102 | + // FIXME switch to expiraing map/Cache? | ||
103 | + private Map<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures = Maps.newConcurrentMap(); | ||
104 | + | ||
105 | + private final ExecutorService futureListeners = | ||
106 | + Executors.newCachedThreadPool(namedThreads("flowstore-peer-responders")); | ||
107 | + | ||
84 | 108 | ||
85 | protected static final KryoSerializer SERIALIZER = new KryoSerializer() { | 109 | protected static final KryoSerializer SERIALIZER = new KryoSerializer() { |
86 | @Override | 110 | @Override |
... | @@ -97,36 +121,26 @@ public class DistributedFlowRuleStore | ... | @@ -97,36 +121,26 @@ public class DistributedFlowRuleStore |
97 | 121 | ||
98 | @Activate | 122 | @Activate |
99 | public void activate() { | 123 | public void activate() { |
100 | - clusterCommunicator.addSubscriber(STORE_FLOW_RULE, new ClusterMessageHandler() { | 124 | + clusterCommunicator.addSubscriber(APPLY_BATCH_FLOWS, new ClusterMessageHandler() { |
101 | 125 | ||
102 | @Override | 126 | @Override |
103 | - public void handle(ClusterMessage message) { | 127 | + public void handle(final ClusterMessage message) { |
104 | - FlowRule rule = SERIALIZER.decode(message.payload()); | 128 | + FlowRuleBatchOperation operation = SERIALIZER.decode(message.payload()); |
105 | - log.info("received add request for {}", rule); | 129 | + log.info("received batch request {}", operation); |
106 | - storeFlowRule(rule); | 130 | + final ListenableFuture<CompletedBatchOperation> f = storeBatchInternal(operation); |
107 | - // FIXME what to respond. | 131 | + |
108 | - try { | 132 | + f.addListener(new Runnable() { |
109 | - message.respond(SERIALIZER.encode("ACK")); | 133 | + |
110 | - } catch (IOException e) { | 134 | + @Override |
111 | - log.error("Failed to respond back", e); | 135 | + public void run() { |
112 | - } | 136 | + CompletedBatchOperation result = Futures.getUnchecked(f); |
113 | - } | 137 | + try { |
114 | - }); | 138 | + message.respond(SERIALIZER.encode(result)); |
115 | - | 139 | + } catch (IOException e) { |
116 | - clusterCommunicator.addSubscriber(DELETE_FLOW_RULE, new ClusterMessageHandler() { | 140 | + log.error("Failed to respond back", e); |
117 | - | 141 | + } |
118 | - @Override | 142 | + } |
119 | - public void handle(ClusterMessage message) { | 143 | + }, futureListeners); |
120 | - FlowRule rule = SERIALIZER.decode(message.payload()); | ||
121 | - log.info("received delete request for {}", rule); | ||
122 | - deleteFlowRule(rule); | ||
123 | - // FIXME what to respond. | ||
124 | - try { | ||
125 | - message.respond(SERIALIZER.encode("ACK")); | ||
126 | - } catch (IOException e) { | ||
127 | - log.error("Failed to respond back", e); | ||
128 | - } | ||
129 | - | ||
130 | } | 144 | } |
131 | }); | 145 | }); |
132 | 146 | ||
... | @@ -159,7 +173,13 @@ public class DistributedFlowRuleStore | ... | @@ -159,7 +173,13 @@ public class DistributedFlowRuleStore |
159 | // make it device specific. | 173 | // make it device specific. |
160 | @Override | 174 | @Override |
161 | public int getFlowRuleCount() { | 175 | public int getFlowRuleCount() { |
162 | - return flowEntries.size(); | 176 | + // implementing in-efficient operation for debugging purpose. |
177 | + int sum = 0; | ||
178 | + for (Device device : deviceService.getDevices()) { | ||
179 | + final DeviceId did = device.id(); | ||
180 | + sum += Iterables.size(getFlowEntries(did)); | ||
181 | + } | ||
182 | + return sum; | ||
163 | } | 183 | } |
164 | 184 | ||
165 | @Override | 185 | @Override |
... | @@ -218,6 +238,7 @@ public class DistributedFlowRuleStore | ... | @@ -218,6 +238,7 @@ public class DistributedFlowRuleStore |
218 | storeBatch(new FlowRuleBatchOperation(Arrays.asList(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)))); | 238 | storeBatch(new FlowRuleBatchOperation(Arrays.asList(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)))); |
219 | } | 239 | } |
220 | 240 | ||
241 | + @Override | ||
221 | public Future<CompletedBatchOperation> storeBatch(FlowRuleBatchOperation operation) { | 242 | public Future<CompletedBatchOperation> storeBatch(FlowRuleBatchOperation operation) { |
222 | if (operation.getOperations().isEmpty()) { | 243 | if (operation.getOperations().isEmpty()) { |
223 | return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); | 244 | return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); |
... | @@ -236,7 +257,7 @@ public class DistributedFlowRuleStore | ... | @@ -236,7 +257,7 @@ public class DistributedFlowRuleStore |
236 | 257 | ||
237 | ClusterMessage message = new ClusterMessage( | 258 | ClusterMessage message = new ClusterMessage( |
238 | clusterService.getLocalNode().id(), | 259 | clusterService.getLocalNode().id(), |
239 | - FlowStoreMessageSubjects.STORE_FLOW_RULE, | 260 | + APPLY_BATCH_FLOWS, |
240 | SERIALIZER.encode(operation)); | 261 | SERIALIZER.encode(operation)); |
241 | 262 | ||
242 | try { | 263 | try { |
... | @@ -250,7 +271,7 @@ public class DistributedFlowRuleStore | ... | @@ -250,7 +271,7 @@ public class DistributedFlowRuleStore |
250 | return null; | 271 | return null; |
251 | } | 272 | } |
252 | 273 | ||
253 | - private Future<CompletedBatchOperation> storeBatchInternal(FlowRuleBatchOperation operation) { | 274 | + private ListenableFuture<CompletedBatchOperation> storeBatchInternal(FlowRuleBatchOperation operation) { |
254 | List<FlowEntry> toRemove = new ArrayList<>(); | 275 | List<FlowEntry> toRemove = new ArrayList<>(); |
255 | List<FlowEntry> toAdd = new ArrayList<>(); | 276 | List<FlowEntry> toAdd = new ArrayList<>(); |
256 | // TODO: backup changes to hazelcast map | 277 | // TODO: backup changes to hazelcast map |
... | @@ -261,8 +282,8 @@ public class DistributedFlowRuleStore | ... | @@ -261,8 +282,8 @@ public class DistributedFlowRuleStore |
261 | StoredFlowEntry entry = getFlowEntryInternal(flowRule); | 282 | StoredFlowEntry entry = getFlowEntryInternal(flowRule); |
262 | if (entry != null) { | 283 | if (entry != null) { |
263 | entry.setState(FlowEntryState.PENDING_REMOVE); | 284 | entry.setState(FlowEntryState.PENDING_REMOVE); |
285 | + toRemove.add(entry); | ||
264 | } | 286 | } |
265 | - toRemove.add(entry); | ||
266 | } else if (op.equals(FlowRuleOperation.ADD)) { | 287 | } else if (op.equals(FlowRuleOperation.ADD)) { |
267 | StoredFlowEntry flowEntry = new DefaultFlowEntry(flowRule); | 288 | StoredFlowEntry flowEntry = new DefaultFlowEntry(flowRule); |
268 | DeviceId deviceId = flowRule.deviceId(); | 289 | DeviceId deviceId = flowRule.deviceId(); |
... | @@ -276,9 +297,13 @@ public class DistributedFlowRuleStore | ... | @@ -276,9 +297,13 @@ public class DistributedFlowRuleStore |
276 | if (toAdd.isEmpty() && toRemove.isEmpty()) { | 297 | if (toAdd.isEmpty() && toRemove.isEmpty()) { |
277 | return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); | 298 | return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); |
278 | } | 299 | } |
279 | - notifyDelegate(FlowRuleBatchEvent.create(new FlowRuleBatchRequest(toAdd, toRemove))); | 300 | + |
280 | - // TODO: imlpement this. | 301 | + SettableFuture<CompletedBatchOperation> r = SettableFuture.create(); |
281 | - return Futures.immediateFailedFuture(new RuntimeException("Implement this.")); | 302 | + final int batchId = localBatchIdGen.incrementAndGet(); |
303 | + | ||
304 | + pendingFutures.put(batchId, r); | ||
305 | + notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove))); | ||
306 | + return r; | ||
282 | } | 307 | } |
283 | 308 | ||
284 | @Override | 309 | @Override |
... | @@ -293,18 +318,9 @@ public class DistributedFlowRuleStore | ... | @@ -293,18 +318,9 @@ public class DistributedFlowRuleStore |
293 | return addOrUpdateFlowRuleInternal(rule); | 318 | return addOrUpdateFlowRuleInternal(rule); |
294 | } | 319 | } |
295 | 320 | ||
296 | - ClusterMessage message = new ClusterMessage( | 321 | + log.error("Tried to update FlowRule {} state," |
297 | - clusterService.getLocalNode().id(), | 322 | + + " while the Node was not the master.", rule); |
298 | - FlowStoreMessageSubjects.ADD_OR_UPDATE_FLOW_RULE, | 323 | + return null; |
299 | - SERIALIZER.encode(rule)); | ||
300 | - | ||
301 | - try { | ||
302 | - ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get()); | ||
303 | - return SERIALIZER.decode(response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); | ||
304 | - } catch (IOException | TimeoutException e) { | ||
305 | - // FIXME: throw a FlowStoreException | ||
306 | - throw new RuntimeException(e); | ||
307 | - } | ||
308 | } | 324 | } |
309 | 325 | ||
310 | private synchronized FlowRuleEvent addOrUpdateFlowRuleInternal(FlowEntry rule) { | 326 | private synchronized FlowRuleEvent addOrUpdateFlowRuleInternal(FlowEntry rule) { |
... | @@ -338,18 +354,9 @@ public class DistributedFlowRuleStore | ... | @@ -338,18 +354,9 @@ public class DistributedFlowRuleStore |
338 | return removeFlowRuleInternal(rule); | 354 | return removeFlowRuleInternal(rule); |
339 | } | 355 | } |
340 | 356 | ||
341 | - ClusterMessage message = new ClusterMessage( | 357 | + log.error("Tried to remove FlowRule {}," |
342 | - clusterService.getLocalNode().id(), | 358 | + + " while the Node was not the master.", rule); |
343 | - FlowStoreMessageSubjects.REMOVE_FLOW_RULE, | 359 | + return null; |
344 | - SERIALIZER.encode(rule)); | ||
345 | - | ||
346 | - try { | ||
347 | - ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get()); | ||
348 | - return SERIALIZER.decode(response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); | ||
349 | - } catch (IOException | TimeoutException e) { | ||
350 | - // FIXME: throw a FlowStoreException | ||
351 | - throw new RuntimeException(e); | ||
352 | - } | ||
353 | } | 360 | } |
354 | 361 | ||
355 | private synchronized FlowRuleEvent removeFlowRuleInternal(FlowEntry rule) { | 362 | private synchronized FlowRuleEvent removeFlowRuleInternal(FlowEntry rule) { |
... | @@ -364,6 +371,11 @@ public class DistributedFlowRuleStore | ... | @@ -364,6 +371,11 @@ public class DistributedFlowRuleStore |
364 | 371 | ||
365 | @Override | 372 | @Override |
366 | public void batchOperationComplete(FlowRuleBatchEvent event) { | 373 | public void batchOperationComplete(FlowRuleBatchEvent event) { |
374 | + SettableFuture<CompletedBatchOperation> future | ||
375 | + = pendingFutures.get(event.subject().batchId()); | ||
376 | + if (future != null) { | ||
377 | + future.set(event.result()); | ||
378 | + } | ||
367 | notifyDelegate(event); | 379 | notifyDelegate(event); |
368 | } | 380 | } |
369 | } | 381 | } | ... | ... |
... | @@ -7,10 +7,10 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject; | ... | @@ -7,10 +7,10 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject; |
7 | */ | 7 | */ |
8 | public final class FlowStoreMessageSubjects { | 8 | public final class FlowStoreMessageSubjects { |
9 | private FlowStoreMessageSubjects() {} | 9 | private FlowStoreMessageSubjects() {} |
10 | - public static final MessageSubject STORE_FLOW_RULE = new MessageSubject("peer-forward-store-flow-rule"); | 10 | + |
11 | - public static final MessageSubject DELETE_FLOW_RULE = new MessageSubject("peer-forward-delete-flow-rule"); | 11 | + public static final MessageSubject APPLY_BATCH_FLOWS |
12 | - public static final MessageSubject ADD_OR_UPDATE_FLOW_RULE = | 12 | + = new MessageSubject("peer-forward-apply-batch"); |
13 | - new MessageSubject("peer-forward-add-or-update-flow-rule"); | 13 | + |
14 | - public static final MessageSubject REMOVE_FLOW_RULE = new MessageSubject("peer-forward-remove-flow-rule"); | 14 | + public static final MessageSubject GET_FLOW_ENTRY |
15 | - public static final MessageSubject GET_FLOW_ENTRY = new MessageSubject("peer-forward-get-flow-entry"); | 15 | + = new MessageSubject("peer-forward-get-flow-entry"); |
16 | } | 16 | } | ... | ... |
... | @@ -58,7 +58,6 @@ implements MastershipStore { | ... | @@ -58,7 +58,6 @@ implements MastershipStore { |
58 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 58 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
59 | protected ClusterService clusterService; | 59 | protected ClusterService clusterService; |
60 | 60 | ||
61 | - @SuppressWarnings({ "unchecked", "rawtypes" }) | ||
62 | @Override | 61 | @Override |
63 | @Activate | 62 | @Activate |
64 | public void activate() { | 63 | public void activate() { |
... | @@ -76,9 +75,9 @@ implements MastershipStore { | ... | @@ -76,9 +75,9 @@ implements MastershipStore { |
76 | } | 75 | } |
77 | }; | 76 | }; |
78 | 77 | ||
79 | - roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer); | 78 | + roleMap = new SMap<>(theInstance.<byte[], byte[]>getMap("nodeRoles"), this.serializer); |
80 | roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true); | 79 | roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true); |
81 | - terms = new SMap(theInstance.getMap("terms"), this.serializer); | 80 | + terms = new SMap<>(theInstance.<byte[], byte[]>getMap("terms"), this.serializer); |
82 | clusterSize = theInstance.getAtomicLong("clustersize"); | 81 | clusterSize = theInstance.getAtomicLong("clustersize"); |
83 | 82 | ||
84 | log.info("Started"); | 83 | log.info("Started"); | ... | ... |
... | @@ -5,6 +5,7 @@ import java.util.ArrayList; | ... | @@ -5,6 +5,7 @@ import java.util.ArrayList; |
5 | import java.util.Arrays; | 5 | import java.util.Arrays; |
6 | import java.util.HashMap; | 6 | import java.util.HashMap; |
7 | import java.util.HashSet; | 7 | import java.util.HashSet; |
8 | +import java.util.LinkedList; | ||
8 | 9 | ||
9 | import org.onlab.onos.cluster.ControllerNode; | 10 | import org.onlab.onos.cluster.ControllerNode; |
10 | import org.onlab.onos.cluster.DefaultControllerNode; | 11 | import org.onlab.onos.cluster.DefaultControllerNode; |
... | @@ -27,12 +28,15 @@ import org.onlab.onos.net.Port; | ... | @@ -27,12 +28,15 @@ import org.onlab.onos.net.Port; |
27 | import org.onlab.onos.net.PortNumber; | 28 | import org.onlab.onos.net.PortNumber; |
28 | import org.onlab.onos.net.device.DefaultDeviceDescription; | 29 | import org.onlab.onos.net.device.DefaultDeviceDescription; |
29 | import org.onlab.onos.net.device.DefaultPortDescription; | 30 | import org.onlab.onos.net.device.DefaultPortDescription; |
31 | +import org.onlab.onos.net.flow.CompletedBatchOperation; | ||
30 | import org.onlab.onos.net.flow.DefaultFlowEntry; | 32 | import org.onlab.onos.net.flow.DefaultFlowEntry; |
31 | import org.onlab.onos.net.flow.DefaultFlowRule; | 33 | import org.onlab.onos.net.flow.DefaultFlowRule; |
32 | import org.onlab.onos.net.flow.DefaultTrafficSelector; | 34 | import org.onlab.onos.net.flow.DefaultTrafficSelector; |
33 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; | 35 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; |
34 | import org.onlab.onos.net.flow.FlowEntry; | 36 | import org.onlab.onos.net.flow.FlowEntry; |
35 | import org.onlab.onos.net.flow.FlowId; | 37 | import org.onlab.onos.net.flow.FlowId; |
38 | +import org.onlab.onos.net.flow.FlowRuleBatchEntry; | ||
39 | +import org.onlab.onos.net.flow.FlowRuleBatchOperation; | ||
36 | import org.onlab.onos.net.flow.StoredFlowEntry; | 40 | import org.onlab.onos.net.flow.StoredFlowEntry; |
37 | import org.onlab.onos.net.flow.criteria.Criteria; | 41 | import org.onlab.onos.net.flow.criteria.Criteria; |
38 | import org.onlab.onos.net.flow.criteria.Criterion; | 42 | import org.onlab.onos.net.flow.criteria.Criterion; |
... | @@ -80,6 +84,7 @@ public final class KryoNamespaces { | ... | @@ -80,6 +84,7 @@ public final class KryoNamespaces { |
80 | Arrays.asList().getClass(), | 84 | Arrays.asList().getClass(), |
81 | HashMap.class, | 85 | HashMap.class, |
82 | HashSet.class, | 86 | HashSet.class, |
87 | + LinkedList.class, | ||
83 | // | 88 | // |
84 | // | 89 | // |
85 | ControllerNode.State.class, | 90 | ControllerNode.State.class, |
... | @@ -118,7 +123,11 @@ public final class KryoNamespaces { | ... | @@ -118,7 +123,11 @@ public final class KryoNamespaces { |
118 | DefaultTrafficTreatment.class, | 123 | DefaultTrafficTreatment.class, |
119 | Instructions.DropInstruction.class, | 124 | Instructions.DropInstruction.class, |
120 | Instructions.OutputInstruction.class, | 125 | Instructions.OutputInstruction.class, |
121 | - RoleInfo.class | 126 | + RoleInfo.class, |
127 | + FlowRuleBatchOperation.class, | ||
128 | + CompletedBatchOperation.class, | ||
129 | + FlowRuleBatchEntry.class, | ||
130 | + FlowRuleBatchEntry.FlowRuleOperation.class | ||
122 | ) | 131 | ) |
123 | .register(URI.class, new URISerializer()) | 132 | .register(URI.class, new URISerializer()) |
124 | .register(NodeId.class, new NodeIdSerializer()) | 133 | .register(NodeId.class, new NodeIdSerializer()) | ... | ... |
... | @@ -176,8 +176,8 @@ public class SimpleFlowRuleStore | ... | @@ -176,8 +176,8 @@ public class SimpleFlowRuleStore |
176 | } | 176 | } |
177 | // new flow rule added | 177 | // new flow rule added |
178 | existing.add(f); | 178 | existing.add(f); |
179 | - notifyDelegate(FlowRuleBatchEvent.create( | 179 | + notifyDelegate(FlowRuleBatchEvent.requested( |
180 | - new FlowRuleBatchRequest( | 180 | + new FlowRuleBatchRequest( 1, /* FIXME generate something */ |
181 | Arrays.<FlowEntry>asList(f), | 181 | Arrays.<FlowEntry>asList(f), |
182 | Collections.<FlowEntry>emptyList()))); | 182 | Collections.<FlowEntry>emptyList()))); |
183 | } | 183 | } |
... | @@ -194,8 +194,8 @@ public class SimpleFlowRuleStore | ... | @@ -194,8 +194,8 @@ public class SimpleFlowRuleStore |
194 | synchronized (entry) { | 194 | synchronized (entry) { |
195 | entry.setState(FlowEntryState.PENDING_REMOVE); | 195 | entry.setState(FlowEntryState.PENDING_REMOVE); |
196 | // TODO: Should we notify only if it's "remote" event? | 196 | // TODO: Should we notify only if it's "remote" event? |
197 | - notifyDelegate(FlowRuleBatchEvent.create( | 197 | + notifyDelegate(FlowRuleBatchEvent.requested( |
198 | - new FlowRuleBatchRequest( | 198 | + new FlowRuleBatchRequest(1, /* FIXME generate something */ |
199 | Collections.<FlowEntry>emptyList(), | 199 | Collections.<FlowEntry>emptyList(), |
200 | Arrays.<FlowEntry>asList(entry)))); | 200 | Arrays.<FlowEntry>asList(entry)))); |
201 | } | 201 | } | ... | ... |
-
Please register or login to post a comment