Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
13 changed files
with
108 additions
and
54 deletions
... | @@ -188,7 +188,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { | ... | @@ -188,7 +188,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { |
188 | } | 188 | } |
189 | 189 | ||
190 | @Override | 190 | @Override |
191 | - public Builder matchOpticalSignalType(Byte signalType) { | 191 | + public Builder matchOpticalSignalType(Short signalType) { |
192 | return add(Criteria.matchOpticalSignalType(signalType)); | 192 | return add(Criteria.matchOpticalSignalType(signalType)); |
193 | 193 | ||
194 | } | 194 | } | ... | ... |
... | @@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
27 | */ | 27 | */ |
28 | public enum Type { | 28 | public enum Type { |
29 | 29 | ||
30 | + // Request has been forwarded to MASTER Node | ||
30 | /** | 31 | /** |
31 | * Signifies that a batch operation has been initiated. | 32 | * Signifies that a batch operation has been initiated. |
32 | */ | 33 | */ |
33 | BATCH_OPERATION_REQUESTED, | 34 | BATCH_OPERATION_REQUESTED, |
34 | 35 | ||
36 | + // MASTER Node has pushed the batch down to the Device | ||
37 | + // (e.g., Received barrier reply) | ||
35 | /** | 38 | /** |
36 | * Signifies that a batch operation has completed. | 39 | * Signifies that a batch operation has completed. |
37 | */ | 40 | */ | ... | ... |
... | @@ -25,29 +25,29 @@ import com.google.common.collect.Lists; | ... | @@ -25,29 +25,29 @@ import com.google.common.collect.Lists; |
25 | public class FlowRuleBatchRequest { | 25 | public class FlowRuleBatchRequest { |
26 | 26 | ||
27 | private final int batchId; | 27 | private final int batchId; |
28 | - private final List<FlowEntry> toAdd; | 28 | + private final List<FlowRule> toAdd; |
29 | - private final List<FlowEntry> toRemove; | 29 | + private final List<FlowRule> toRemove; |
30 | 30 | ||
31 | - public FlowRuleBatchRequest(int batchId, List<? extends FlowEntry> toAdd, List<? extends FlowEntry> toRemove) { | 31 | + public FlowRuleBatchRequest(int batchId, List<? extends FlowRule> toAdd, List<? extends FlowRule> toRemove) { |
32 | this.batchId = batchId; | 32 | this.batchId = batchId; |
33 | this.toAdd = Collections.unmodifiableList(toAdd); | 33 | this.toAdd = Collections.unmodifiableList(toAdd); |
34 | this.toRemove = Collections.unmodifiableList(toRemove); | 34 | this.toRemove = Collections.unmodifiableList(toRemove); |
35 | } | 35 | } |
36 | 36 | ||
37 | - public List<FlowEntry> toAdd() { | 37 | + public List<FlowRule> toAdd() { |
38 | return toAdd; | 38 | return toAdd; |
39 | } | 39 | } |
40 | 40 | ||
41 | - public List<FlowEntry> toRemove() { | 41 | + public List<FlowRule> toRemove() { |
42 | return toRemove; | 42 | return toRemove; |
43 | } | 43 | } |
44 | 44 | ||
45 | public FlowRuleBatchOperation asBatchOperation() { | 45 | public FlowRuleBatchOperation asBatchOperation() { |
46 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); | 46 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); |
47 | - for (FlowEntry e : toAdd) { | 47 | + for (FlowRule e : toAdd) { |
48 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e)); | 48 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e)); |
49 | } | 49 | } |
50 | - for (FlowEntry e : toRemove) { | 50 | + for (FlowRule e : toRemove) { |
51 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e)); | 51 | entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e)); |
52 | } | 52 | } |
53 | return new FlowRuleBatchOperation(entries); | 53 | return new FlowRuleBatchOperation(entries); | ... | ... |
... | @@ -147,7 +147,7 @@ public interface TrafficSelector { | ... | @@ -147,7 +147,7 @@ public interface TrafficSelector { |
147 | * @param signalType | 147 | * @param signalType |
148 | * @return a selection builder | 148 | * @return a selection builder |
149 | */ | 149 | */ |
150 | - public Builder matchOpticalSignalType(Byte signalType); | 150 | + public Builder matchOpticalSignalType(Short signalType); |
151 | 151 | ||
152 | /** | 152 | /** |
153 | * Builds an immutable traffic selector. | 153 | * Builds an immutable traffic selector. | ... | ... |
... | @@ -161,11 +161,11 @@ public final class Criteria { | ... | @@ -161,11 +161,11 @@ public final class Criteria { |
161 | /** | 161 | /** |
162 | * Creates a match on lambda field using the specified value. | 162 | * Creates a match on lambda field using the specified value. |
163 | * | 163 | * |
164 | - * @param lambda | 164 | + * @param sigType |
165 | * @return match criterion | 165 | * @return match criterion |
166 | */ | 166 | */ |
167 | - public static Criterion matchOpticalSignalType(Byte lambda) { | 167 | + public static Criterion matchOpticalSignalType(Short sigType) { |
168 | - return new OpticalSignalTypeCriterion(lambda, Type.OCH_SIGTYPE); | 168 | + return new OpticalSignalTypeCriterion(sigType, Type.OCH_SIGTYPE); |
169 | } | 169 | } |
170 | 170 | ||
171 | 171 | ||
... | @@ -587,10 +587,10 @@ public final class Criteria { | ... | @@ -587,10 +587,10 @@ public final class Criteria { |
587 | 587 | ||
588 | public static final class OpticalSignalTypeCriterion implements Criterion { | 588 | public static final class OpticalSignalTypeCriterion implements Criterion { |
589 | 589 | ||
590 | - private final byte signalType; | 590 | + private final Short signalType; |
591 | private final Type type; | 591 | private final Type type; |
592 | 592 | ||
593 | - public OpticalSignalTypeCriterion(byte signalType, Type type) { | 593 | + public OpticalSignalTypeCriterion(Short signalType, Type type) { |
594 | this.signalType = signalType; | 594 | this.signalType = signalType; |
595 | this.type = type; | 595 | this.type = type; |
596 | } | 596 | } |
... | @@ -600,7 +600,7 @@ public final class Criteria { | ... | @@ -600,7 +600,7 @@ public final class Criteria { |
600 | return this.type; | 600 | return this.type; |
601 | } | 601 | } |
602 | 602 | ||
603 | - public Byte signalType() { | 603 | + public Short signalType() { |
604 | return this.signalType; | 604 | return this.signalType; |
605 | } | 605 | } |
606 | 606 | ... | ... |
... | @@ -371,10 +371,11 @@ public class FlowRuleManager | ... | @@ -371,10 +371,11 @@ public class FlowRuleManager |
371 | final FlowRuleBatchRequest request = event.subject(); | 371 | final FlowRuleBatchRequest request = event.subject(); |
372 | switch (event.type()) { | 372 | switch (event.type()) { |
373 | case BATCH_OPERATION_REQUESTED: | 373 | case BATCH_OPERATION_REQUESTED: |
374 | - for (FlowEntry entry : request.toAdd()) { | 374 | + // Request has been forwarded to MASTER Node, and was |
375 | + for (FlowRule entry : request.toAdd()) { | ||
375 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry)); | 376 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry)); |
376 | } | 377 | } |
377 | - for (FlowEntry entry : request.toRemove()) { | 378 | + for (FlowRule entry : request.toRemove()) { |
378 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry)); | 379 | eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry)); |
379 | } | 380 | } |
380 | // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ? | 381 | // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ? |
... | @@ -392,21 +393,15 @@ public class FlowRuleManager | ... | @@ -392,21 +393,15 @@ public class FlowRuleManager |
392 | Futures.getUnchecked(result))); | 393 | Futures.getUnchecked(result))); |
393 | } | 394 | } |
394 | }, futureListeners); | 395 | }, futureListeners); |
395 | - | ||
396 | break; | 396 | break; |
397 | + | ||
397 | case BATCH_OPERATION_COMPLETED: | 398 | case BATCH_OPERATION_COMPLETED: |
398 | - Set<FlowRule> failedItems = event.result().failedItems(); | 399 | + // MASTER Node has pushed the batch down to the Device |
399 | - for (FlowEntry entry : request.toAdd()) { | 400 | + |
400 | - if (!failedItems.contains(entry)) { | 401 | + // Note: RULE_ADDED will be posted |
401 | - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, entry)); | 402 | + // when Flow was actually confirmed by stats reply. |
402 | - } | ||
403 | - } | ||
404 | - for (FlowEntry entry : request.toRemove()) { | ||
405 | - if (!failedItems.contains(entry)) { | ||
406 | - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, entry)); | ||
407 | - } | ||
408 | - } | ||
409 | break; | 403 | break; |
404 | + | ||
410 | default: | 405 | default: |
411 | break; | 406 | break; |
412 | } | 407 | } | ... | ... |
... | @@ -79,6 +79,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn | ... | @@ -79,6 +79,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn |
79 | private ApplicationId appId; | 79 | private ApplicationId appId; |
80 | 80 | ||
81 | //final short WAVELENGTH = 80; | 81 | //final short WAVELENGTH = 80; |
82 | + static final short SIGNAL_TYPE = (short) 1; | ||
82 | 83 | ||
83 | @Activate | 84 | @Activate |
84 | public void activate() { | 85 | public void activate() { |
... | @@ -151,7 +152,9 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn | ... | @@ -151,7 +152,9 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn |
151 | 152 | ||
152 | prev = link.dst(); | 153 | prev = link.dst(); |
153 | selectorBuilder.matchInport(link.dst().port()); | 154 | selectorBuilder.matchInport(link.dst().port()); |
155 | + selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE); //todo | ||
154 | selectorBuilder.matchLambda((short) la.toInt()); | 156 | selectorBuilder.matchLambda((short) la.toInt()); |
157 | + | ||
155 | } | 158 | } |
156 | 159 | ||
157 | // build the last T port rule | 160 | // build the last T port rule | ... | ... |
... | @@ -148,7 +148,7 @@ public class FlowRuleManagerTest { | ... | @@ -148,7 +148,7 @@ public class FlowRuleManagerTest { |
148 | int i = 0; | 148 | int i = 0; |
149 | System.err.println("events :" + listener.events); | 149 | System.err.println("events :" + listener.events); |
150 | for (FlowRuleEvent e : listener.events) { | 150 | for (FlowRuleEvent e : listener.events) { |
151 | - assertTrue("unexpected event", e.type().equals(events[i])); | 151 | + assertEquals("unexpected event", events[i], e.type()); |
152 | i++; | 152 | i++; |
153 | } | 153 | } |
154 | 154 | ||
... | @@ -178,15 +178,13 @@ public class FlowRuleManagerTest { | ... | @@ -178,15 +178,13 @@ public class FlowRuleManagerTest { |
178 | RULE_ADDED, RULE_ADDED); | 178 | RULE_ADDED, RULE_ADDED); |
179 | 179 | ||
180 | addFlowRule(1); | 180 | addFlowRule(1); |
181 | + System.err.println("events :" + listener.events); | ||
181 | assertEquals("should still be 2 rules", 2, flowCount()); | 182 | assertEquals("should still be 2 rules", 2, flowCount()); |
182 | 183 | ||
183 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1)); | 184 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1)); |
184 | validateEvents(RULE_UPDATED); | 185 | validateEvents(RULE_UPDATED); |
185 | } | 186 | } |
186 | 187 | ||
187 | - | ||
188 | - // TODO: If preserving iteration order is a requirement, redo FlowRuleStore. | ||
189 | - //backing store is sensitive to the order of additions/removals | ||
190 | private boolean validateState(Map<FlowRule, FlowEntryState> expected) { | 188 | private boolean validateState(Map<FlowRule, FlowEntryState> expected) { |
191 | Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); | 189 | Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); |
192 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); | 190 | Iterable<FlowEntry> rules = service.getFlowEntries(DID); |
... | @@ -539,17 +537,17 @@ public class FlowRuleManagerTest { | ... | @@ -539,17 +537,17 @@ public class FlowRuleManagerTest { |
539 | 537 | ||
540 | @Override | 538 | @Override |
541 | public boolean cancel(boolean mayInterruptIfRunning) { | 539 | public boolean cancel(boolean mayInterruptIfRunning) { |
542 | - return true; | 540 | + return false; |
543 | } | 541 | } |
544 | 542 | ||
545 | @Override | 543 | @Override |
546 | public boolean isCancelled() { | 544 | public boolean isCancelled() { |
547 | - return true; | 545 | + return false; |
548 | } | 546 | } |
549 | 547 | ||
550 | @Override | 548 | @Override |
551 | public boolean isDone() { | 549 | public boolean isDone() { |
552 | - return false; | 550 | + return true; |
553 | } | 551 | } |
554 | 552 | ||
555 | @Override | 553 | @Override |
... | @@ -562,12 +560,14 @@ public class FlowRuleManagerTest { | ... | @@ -562,12 +560,14 @@ public class FlowRuleManagerTest { |
562 | public CompletedBatchOperation get(long timeout, TimeUnit unit) | 560 | public CompletedBatchOperation get(long timeout, TimeUnit unit) |
563 | throws InterruptedException, | 561 | throws InterruptedException, |
564 | ExecutionException, TimeoutException { | 562 | ExecutionException, TimeoutException { |
565 | - return null; | 563 | + return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()); |
566 | } | 564 | } |
567 | 565 | ||
568 | @Override | 566 | @Override |
569 | public void addListener(Runnable task, Executor executor) { | 567 | public void addListener(Runnable task, Executor executor) { |
570 | - // TODO: add stuff. | 568 | + if (isDone()) { |
569 | + executor.execute(task); | ||
570 | + } | ||
571 | } | 571 | } |
572 | } | 572 | } |
573 | 573 | ... | ... |
... | @@ -447,7 +447,13 @@ implements MastershipStore { | ... | @@ -447,7 +447,13 @@ implements MastershipStore { |
447 | RoleValue oldValue = event.getOldValue(); | 447 | RoleValue oldValue = event.getOldValue(); |
448 | RoleValue newValue = event.getValue(); | 448 | RoleValue newValue = event.getValue(); |
449 | 449 | ||
450 | - if (Objects.equal(oldValue.get(MASTER), newValue.get(MASTER))) { | 450 | + NodeId oldMaster = null; |
451 | + if (oldValue != null) { | ||
452 | + oldMaster = oldValue.get(MASTER); | ||
453 | + } | ||
454 | + NodeId newMaster = newValue.get(MASTER); | ||
455 | + | ||
456 | + if (Objects.equal(oldMaster, newMaster)) { | ||
451 | notifyDelegate(new MastershipEvent( | 457 | notifyDelegate(new MastershipEvent( |
452 | MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); | 458 | MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); |
453 | } else { | 459 | } else { | ... | ... |
... | @@ -16,8 +16,12 @@ | ... | @@ -16,8 +16,12 @@ |
16 | package org.onlab.onos.store.trivial.impl; | 16 | package org.onlab.onos.store.trivial.impl; |
17 | 17 | ||
18 | import com.google.common.base.Function; | 18 | import com.google.common.base.Function; |
19 | +import com.google.common.cache.Cache; | ||
20 | +import com.google.common.cache.CacheBuilder; | ||
19 | import com.google.common.collect.FluentIterable; | 21 | import com.google.common.collect.FluentIterable; |
20 | import com.google.common.util.concurrent.Futures; | 22 | import com.google.common.util.concurrent.Futures; |
23 | +import com.google.common.util.concurrent.SettableFuture; | ||
24 | + | ||
21 | import org.apache.felix.scr.annotations.Activate; | 25 | import org.apache.felix.scr.annotations.Activate; |
22 | import org.apache.felix.scr.annotations.Component; | 26 | import org.apache.felix.scr.annotations.Component; |
23 | import org.apache.felix.scr.annotations.Deactivate; | 27 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore; | ... | @@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore; |
43 | import org.onlab.util.NewConcurrentHashMap; | 47 | import org.onlab.util.NewConcurrentHashMap; |
44 | import org.slf4j.Logger; | 48 | import org.slf4j.Logger; |
45 | 49 | ||
46 | -import java.util.Arrays; | 50 | +import java.util.ArrayList; |
47 | import java.util.Collections; | 51 | import java.util.Collections; |
48 | import java.util.List; | 52 | import java.util.List; |
49 | import java.util.concurrent.ConcurrentHashMap; | 53 | import java.util.concurrent.ConcurrentHashMap; |
50 | import java.util.concurrent.ConcurrentMap; | 54 | import java.util.concurrent.ConcurrentMap; |
51 | import java.util.concurrent.CopyOnWriteArrayList; | 55 | import java.util.concurrent.CopyOnWriteArrayList; |
52 | import java.util.concurrent.Future; | 56 | import java.util.concurrent.Future; |
57 | +import java.util.concurrent.TimeUnit; | ||
58 | +import java.util.concurrent.atomic.AtomicInteger; | ||
53 | 59 | ||
54 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | 60 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; |
55 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 61 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
... | @@ -72,6 +78,18 @@ public class SimpleFlowRuleStore | ... | @@ -72,6 +78,18 @@ public class SimpleFlowRuleStore |
72 | private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> | 78 | private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> |
73 | flowEntries = new ConcurrentHashMap<>(); | 79 | flowEntries = new ConcurrentHashMap<>(); |
74 | 80 | ||
81 | + private final AtomicInteger localBatchIdGen = new AtomicInteger(); | ||
82 | + | ||
83 | + // TODO: make this configurable | ||
84 | + private int pendingFutureTimeoutMinutes = 5; | ||
85 | + | ||
86 | + private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures = | ||
87 | + CacheBuilder.newBuilder() | ||
88 | + .expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES) | ||
89 | + // TODO Explicitly fail the future if expired? | ||
90 | + //.removalListener(listener) | ||
91 | + .build(); | ||
92 | + | ||
75 | @Activate | 93 | @Activate |
76 | public void activate() { | 94 | public void activate() { |
77 | log.info("Started"); | 95 | log.info("Started"); |
... | @@ -173,10 +191,6 @@ public class SimpleFlowRuleStore | ... | @@ -173,10 +191,6 @@ public class SimpleFlowRuleStore |
173 | } | 191 | } |
174 | // new flow rule added | 192 | // new flow rule added |
175 | existing.add(f); | 193 | existing.add(f); |
176 | - notifyDelegate(FlowRuleBatchEvent.requested( | ||
177 | - new FlowRuleBatchRequest(1, /* FIXME generate something */ | ||
178 | - Arrays.<FlowEntry>asList(f), | ||
179 | - Collections.<FlowEntry>emptyList()))); | ||
180 | } | 194 | } |
181 | } | 195 | } |
182 | 196 | ||
... | @@ -190,11 +204,6 @@ public class SimpleFlowRuleStore | ... | @@ -190,11 +204,6 @@ public class SimpleFlowRuleStore |
190 | if (entry.equals(rule)) { | 204 | if (entry.equals(rule)) { |
191 | synchronized (entry) { | 205 | synchronized (entry) { |
192 | entry.setState(FlowEntryState.PENDING_REMOVE); | 206 | entry.setState(FlowEntryState.PENDING_REMOVE); |
193 | - // TODO: Should we notify only if it's "remote" event? | ||
194 | - notifyDelegate(FlowRuleBatchEvent.requested( | ||
195 | - new FlowRuleBatchRequest(1, /* FIXME generate something */ | ||
196 | - Collections.<FlowEntry>emptyList(), | ||
197 | - Arrays.<FlowEntry>asList(entry)))); | ||
198 | } | 207 | } |
199 | } | 208 | } |
200 | } | 209 | } |
... | @@ -251,20 +260,47 @@ public class SimpleFlowRuleStore | ... | @@ -251,20 +260,47 @@ public class SimpleFlowRuleStore |
251 | @Override | 260 | @Override |
252 | public Future<CompletedBatchOperation> storeBatch( | 261 | public Future<CompletedBatchOperation> storeBatch( |
253 | FlowRuleBatchOperation batchOperation) { | 262 | FlowRuleBatchOperation batchOperation) { |
263 | + List<FlowRule> toAdd = new ArrayList<>(); | ||
264 | + List<FlowRule> toRemove = new ArrayList<>(); | ||
254 | for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { | 265 | for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { |
266 | + final FlowRule flowRule = entry.getTarget(); | ||
255 | if (entry.getOperator().equals(FlowRuleOperation.ADD)) { | 267 | if (entry.getOperator().equals(FlowRuleOperation.ADD)) { |
256 | - storeFlowRule(entry.getTarget()); | 268 | + if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { |
269 | + storeFlowRule(flowRule); | ||
270 | + toAdd.add(flowRule); | ||
271 | + } | ||
257 | } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) { | 272 | } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) { |
258 | - deleteFlowRule(entry.getTarget()); | 273 | + if (getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { |
274 | + deleteFlowRule(flowRule); | ||
275 | + toRemove.add(flowRule); | ||
276 | + } | ||
259 | } else { | 277 | } else { |
260 | throw new UnsupportedOperationException("Unsupported operation type"); | 278 | throw new UnsupportedOperationException("Unsupported operation type"); |
261 | } | 279 | } |
262 | } | 280 | } |
263 | - return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); | 281 | + |
282 | + if (toAdd.isEmpty() && toRemove.isEmpty()) { | ||
283 | + return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowRule>emptySet())); | ||
284 | + } | ||
285 | + | ||
286 | + SettableFuture<CompletedBatchOperation> r = SettableFuture.create(); | ||
287 | + final int batchId = localBatchIdGen.incrementAndGet(); | ||
288 | + | ||
289 | + pendingFutures.put(batchId, r); | ||
290 | + notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove))); | ||
291 | + | ||
292 | + return r; | ||
264 | } | 293 | } |
265 | 294 | ||
266 | @Override | 295 | @Override |
267 | public void batchOperationComplete(FlowRuleBatchEvent event) { | 296 | public void batchOperationComplete(FlowRuleBatchEvent event) { |
297 | + final Integer batchId = event.subject().batchId(); | ||
298 | + SettableFuture<CompletedBatchOperation> future | ||
299 | + = pendingFutures.getIfPresent(batchId); | ||
300 | + if (future != null) { | ||
301 | + future.set(event.result()); | ||
302 | + pendingFutures.invalidate(batchId); | ||
303 | + } | ||
268 | notifyDelegate(event); | 304 | notifyDelegate(event); |
269 | } | 305 | } |
270 | } | 306 | } | ... | ... |
... | @@ -289,7 +289,10 @@ public class FlowEntryBuilder { | ... | @@ -289,7 +289,10 @@ public class FlowEntryBuilder { |
289 | case OCH_SIGID: | 289 | case OCH_SIGID: |
290 | builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber()); | 290 | builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber()); |
291 | break; | 291 | break; |
292 | - case OCH_SIGTYPE_BASIC: | 292 | + case OCH_SIGTYPE: |
293 | + builder.matchOpticalSignalType(match.get(MatchField | ||
294 | + .OCH_SIGTYPE).getValue()); | ||
295 | + break; | ||
293 | case ARP_OP: | 296 | case ARP_OP: |
294 | case ARP_SHA: | 297 | case ARP_SHA: |
295 | case ARP_SPA: | 298 | case ARP_SPA: | ... | ... |
... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | import org.onlab.onos.net.flow.FlowRule; | 20 | import org.onlab.onos.net.flow.FlowRule; |
21 | import org.onlab.onos.net.flow.TrafficSelector; | 21 | import org.onlab.onos.net.flow.TrafficSelector; |
22 | +import org.onlab.onos.net.flow.criteria.Criteria; | ||
22 | import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; | 23 | import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; |
23 | import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; | 24 | import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; |
24 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; | 25 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; |
... | @@ -46,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked; | ... | @@ -46,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked; |
46 | import org.projectfloodlight.openflow.types.OFPort; | 47 | import org.projectfloodlight.openflow.types.OFPort; |
47 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; | 48 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; |
48 | import org.projectfloodlight.openflow.types.TransportPort; | 49 | import org.projectfloodlight.openflow.types.TransportPort; |
50 | +import org.projectfloodlight.openflow.types.U8; | ||
49 | import org.projectfloodlight.openflow.types.VlanPcp; | 51 | import org.projectfloodlight.openflow.types.VlanPcp; |
50 | import org.projectfloodlight.openflow.types.VlanVid; | 52 | import org.projectfloodlight.openflow.types.VlanVid; |
51 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
... | @@ -197,6 +199,12 @@ public abstract class FlowModBuilder { | ... | @@ -197,6 +199,12 @@ public abstract class FlowModBuilder { |
197 | mBuilder.setExact(MatchField.OCH_SIGID, | 199 | mBuilder.setExact(MatchField.OCH_SIGID, |
198 | new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1)); | 200 | new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1)); |
199 | break; | 201 | break; |
202 | + case OCH_SIGTYPE: | ||
203 | + Criteria.OpticalSignalTypeCriterion sc = | ||
204 | + (Criteria.OpticalSignalTypeCriterion) c; | ||
205 | + mBuilder.setExact(MatchField.OCH_SIGTYPE, | ||
206 | + U8.of(sc.signalType())); | ||
207 | + break; | ||
200 | case ARP_OP: | 208 | case ARP_OP: |
201 | case ARP_SHA: | 209 | case ARP_SHA: |
202 | case ARP_SPA: | 210 | case ARP_SPA: | ... | ... |
... | @@ -101,7 +101,7 @@ public class TopologyResource extends BaseResource { | ... | @@ -101,7 +101,7 @@ public class TopologyResource extends BaseResource { |
101 | new Prop("Vendor", device.manufacturer()), | 101 | new Prop("Vendor", device.manufacturer()), |
102 | new Prop("H/W Version", device.hwVersion()), | 102 | new Prop("H/W Version", device.hwVersion()), |
103 | new Prop("S/W Version", device.swVersion()), | 103 | new Prop("S/W Version", device.swVersion()), |
104 | - new Prop("S/W Version", device.serialNumber()), | 104 | + new Prop("Serial Number", device.serialNumber()), |
105 | new Separator(), | 105 | new Separator(), |
106 | new Prop("Latitude", annot.value("latitude")), | 106 | new Prop("Latitude", annot.value("latitude")), |
107 | new Prop("Longitude", annot.value("longitude")), | 107 | new Prop("Longitude", annot.value("longitude")), | ... | ... |
-
Please register or login to post a comment