tom

Merge remote-tracking branch 'origin/master'

...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
12 import org.onlab.onos.net.Host; 13 import org.onlab.onos.net.Host;
13 import org.onlab.onos.net.HostId; 14 import org.onlab.onos.net.HostId;
14 import org.onlab.onos.net.Path; 15 import org.onlab.onos.net.Path;
...@@ -53,14 +54,18 @@ public class ReactiveForwarding { ...@@ -53,14 +54,18 @@ public class ReactiveForwarding {
53 54
54 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 55 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
55 56
57 + private ApplicationId appId;
58 +
56 @Activate 59 @Activate
57 public void activate() { 60 public void activate() {
61 + appId = ApplicationId.getAppId();
58 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); 62 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
59 - log.info("Started"); 63 + log.info("Started with Application ID {}", appId.id());
60 } 64 }
61 65
62 @Deactivate 66 @Deactivate
63 public void deactivate() { 67 public void deactivate() {
68 + flowRuleService.removeFlowRulesById(appId);
64 packetService.removeProcessor(processor); 69 packetService.removeProcessor(processor);
65 processor = null; 70 processor = null;
66 log.info("Stopped"); 71 log.info("Stopped");
...@@ -169,7 +174,7 @@ public class ReactiveForwarding { ...@@ -169,7 +174,7 @@ public class ReactiveForwarding {
169 treat.add(Instructions.createOutput(portNumber)); 174 treat.add(Instructions.createOutput(portNumber));
170 175
171 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), 176 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
172 - builder.build(), treat.build(), 0); 177 + builder.build(), treat.build(), 0, appId);
173 178
174 flowRuleService.applyFlowRules(f); 179 flowRuleService.applyFlowRules(f);
175 } 180 }
......
1 +package org.onlab.onos;
2 +
3 +import java.util.Objects;
4 +import java.util.concurrent.atomic.AtomicInteger;
5 +
6 +/**
7 + * Application id generator class.
8 + */
9 +public final class ApplicationId {
10 +
11 + private static AtomicInteger idDispenser;
12 + private final Integer id;
13 +
14 + // Ban public construction
15 + private ApplicationId(Integer id) {
16 + this.id = id;
17 + }
18 +
19 + public Integer id() {
20 + return id;
21 + }
22 +
23 + public static ApplicationId valueOf(Integer id) {
24 + return new ApplicationId(id);
25 + }
26 +
27 + @Override
28 + public int hashCode() {
29 + return Objects.hash(id);
30 + }
31 +
32 + @Override
33 + public boolean equals(Object obj) {
34 + if (this == obj) {
35 + return true;
36 + }
37 + if (obj == null) {
38 + return false;
39 + }
40 + if (!(obj instanceof ApplicationId)) {
41 + return false;
42 + }
43 + ApplicationId other = (ApplicationId) obj;
44 + return Objects.equals(this.id, other.id);
45 + }
46 +
47 + /**
48 + * Returns a new application id.
49 + *
50 + * @return app id
51 + */
52 + public static ApplicationId getAppId() {
53 + if (ApplicationId.idDispenser == null) {
54 + ApplicationId.idDispenser = new AtomicInteger(1);
55 + }
56 + return new ApplicationId(ApplicationId.idDispenser.getAndIncrement());
57 + }
58 +
59 +}
...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Objects; 6 import java.util.Objects;
7 7
8 +import org.onlab.onos.ApplicationId;
8 import org.onlab.onos.net.DeviceId; 9 import org.onlab.onos.net.DeviceId;
9 import org.slf4j.Logger; 10 import org.slf4j.Logger;
10 11
...@@ -24,6 +25,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -24,6 +25,8 @@ public class DefaultFlowRule implements FlowRule {
24 25
25 private final FlowId id; 26 private final FlowId id;
26 27
28 + private final ApplicationId appId;
29 +
27 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 30 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
28 TrafficTreatment treatment, int priority, FlowRuleState state, 31 TrafficTreatment treatment, int priority, FlowRuleState state,
29 long life, long packets, long bytes, long flowId) { 32 long life, long packets, long bytes, long flowId) {
...@@ -32,7 +35,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -32,7 +35,7 @@ public class DefaultFlowRule implements FlowRule {
32 this.selector = selector; 35 this.selector = selector;
33 this.treatment = treatment; 36 this.treatment = treatment;
34 this.state = state; 37 this.state = state;
35 - 38 + this.appId = ApplicationId.valueOf((int) (flowId >> 32));
36 this.id = FlowId.valueOf(flowId); 39 this.id = FlowId.valueOf(flowId);
37 40
38 this.life = life; 41 this.life = life;
...@@ -42,18 +45,18 @@ public class DefaultFlowRule implements FlowRule { ...@@ -42,18 +45,18 @@ public class DefaultFlowRule implements FlowRule {
42 } 45 }
43 46
44 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 47 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
45 - TrafficTreatment treatement, int priority) { 48 + TrafficTreatment treatement, int priority, ApplicationId appId) {
46 - this(deviceId, selector, treatement, priority, FlowRuleState.CREATED); 49 + this(deviceId, selector, treatement, priority, FlowRuleState.CREATED, appId);
47 } 50 }
48 51
49 public DefaultFlowRule(FlowRule rule, FlowRuleState state) { 52 public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
50 this(rule.deviceId(), rule.selector(), rule.treatment(), 53 this(rule.deviceId(), rule.selector(), rule.treatment(),
51 - rule.priority(), state, rule.id()); 54 + rule.priority(), state, rule.id(), rule.appId());
52 } 55 }
53 56
54 private DefaultFlowRule(DeviceId deviceId, 57 private DefaultFlowRule(DeviceId deviceId,
55 TrafficSelector selector, TrafficTreatment treatment, 58 TrafficSelector selector, TrafficTreatment treatment,
56 - int priority, FlowRuleState state) { 59 + int priority, FlowRuleState state, ApplicationId appId) {
57 this.deviceId = deviceId; 60 this.deviceId = deviceId;
58 this.priority = priority; 61 this.priority = priority;
59 this.selector = selector; 62 this.selector = selector;
...@@ -62,13 +65,15 @@ public class DefaultFlowRule implements FlowRule { ...@@ -62,13 +65,15 @@ public class DefaultFlowRule implements FlowRule {
62 this.life = 0; 65 this.life = 0;
63 this.packets = 0; 66 this.packets = 0;
64 this.bytes = 0; 67 this.bytes = 0;
65 - this.id = FlowId.valueOf(this.hashCode()); 68 + this.appId = appId;
69 +
70 + this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
66 this.created = System.currentTimeMillis(); 71 this.created = System.currentTimeMillis();
67 } 72 }
68 73
69 private DefaultFlowRule(DeviceId deviceId, 74 private DefaultFlowRule(DeviceId deviceId,
70 TrafficSelector selector, TrafficTreatment treatment, 75 TrafficSelector selector, TrafficTreatment treatment,
71 - int priority, FlowRuleState state, FlowId flowId) { 76 + int priority, FlowRuleState state, FlowId flowId, ApplicationId appId) {
72 this.deviceId = deviceId; 77 this.deviceId = deviceId;
73 this.priority = priority; 78 this.priority = priority;
74 this.selector = selector; 79 this.selector = selector;
...@@ -77,6 +82,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -77,6 +82,7 @@ public class DefaultFlowRule implements FlowRule {
77 this.life = 0; 82 this.life = 0;
78 this.packets = 0; 83 this.packets = 0;
79 this.bytes = 0; 84 this.bytes = 0;
85 + this.appId = appId;
80 this.id = flowId; 86 this.id = flowId;
81 this.created = System.currentTimeMillis(); 87 this.created = System.currentTimeMillis();
82 } 88 }
...@@ -88,6 +94,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -88,6 +94,11 @@ public class DefaultFlowRule implements FlowRule {
88 } 94 }
89 95
90 @Override 96 @Override
97 + public ApplicationId appId() {
98 + return appId;
99 + }
100 +
101 + @Override
91 public int priority() { 102 public int priority() {
92 return priority; 103 return priority;
93 } 104 }
...@@ -136,7 +147,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -136,7 +147,11 @@ public class DefaultFlowRule implements FlowRule {
136 * @see java.lang.Object#equals(java.lang.Object) 147 * @see java.lang.Object#equals(java.lang.Object)
137 */ 148 */
138 public int hashCode() { 149 public int hashCode() {
139 - return Objects.hash(deviceId, selector, treatment); 150 + return Objects.hash(deviceId, id);
151 + }
152 +
153 + public int hash() {
154 + return Objects.hash(deviceId, selector, id);
140 } 155 }
141 156
142 @Override 157 @Override
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 5
5 /** 6 /**
...@@ -53,6 +54,13 @@ public interface FlowRule { ...@@ -53,6 +54,13 @@ public interface FlowRule {
53 FlowId id(); 54 FlowId id();
54 55
55 /** 56 /**
57 + * Returns the application id of this flow.
58 + *
59 + * @return an applicationId
60 + */
61 + ApplicationId appId();
62 +
63 + /**
56 * Returns the flow rule priority given in natural order; higher numbers 64 * Returns the flow rule priority given in natural order; higher numbers
57 * mean higher priorities. 65 * mean higher priorities.
58 * 66 *
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.provider.Provider; 4 import org.onlab.onos.net.provider.Provider;
4 5
5 /** 6 /**
...@@ -25,4 +26,10 @@ public interface FlowRuleProvider extends Provider { ...@@ -25,4 +26,10 @@ public interface FlowRuleProvider extends Provider {
25 */ 26 */
26 void removeFlowRule(FlowRule... flowRules); 27 void removeFlowRule(FlowRule... flowRules);
27 28
29 + /**
30 + * Removes rules by their id.
31 + * @param id the id to remove
32 + */
33 + void removeRulesById(ApplicationId id, FlowRule... flowRules);
34 +
28 } 35 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 5
5 /** 6 /**
...@@ -43,6 +44,20 @@ public interface FlowRuleService { ...@@ -43,6 +44,20 @@ public interface FlowRuleService {
43 */ 44 */
44 void removeFlowRules(FlowRule... flowRules); 45 void removeFlowRules(FlowRule... flowRules);
45 46
47 + /**
48 + * Removes all rules by id.
49 + *
50 + * @param appId id to remove
51 + */
52 + void removeFlowRulesById(ApplicationId appId);
53 +
54 + /**
55 + * Returns a list of rules with this application id.
56 + *
57 + * @param id the id to look up
58 + * @return collection of flow rules
59 + */
60 + Iterable<FlowRule> getFlowRulesById(ApplicationId id);
46 61
47 /** 62 /**
48 * Adds the specified flow rule listener. 63 * Adds the specified flow rule listener.
...@@ -58,4 +73,6 @@ public interface FlowRuleService { ...@@ -58,4 +73,6 @@ public interface FlowRuleService {
58 */ 73 */
59 void removeListener(FlowRuleListener listener); 74 void removeListener(FlowRuleListener listener);
60 75
76 +
77 +
61 } 78 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.store.Store; 5 import org.onlab.onos.store.Store;
5 6
...@@ -9,6 +10,13 @@ import org.onlab.onos.store.Store; ...@@ -9,6 +10,13 @@ import org.onlab.onos.store.Store;
9 public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { 10 public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> {
10 11
11 /** 12 /**
13 + * Returns the stored flow.
14 + * @param rule the rule to look for
15 + * @return a flow rule
16 + */
17 + FlowRule getFlowRule(FlowRule rule);
18 +
19 + /**
12 * Returns the flow entries associated with a device. 20 * Returns the flow entries associated with a device.
13 * 21 *
14 * @param deviceId the device ID 22 * @param deviceId the device ID
...@@ -17,6 +25,14 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat ...@@ -17,6 +25,14 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
17 Iterable<FlowRule> getFlowEntries(DeviceId deviceId); 25 Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
18 26
19 /** 27 /**
28 + * Returns the flow entries associated with an application.
29 + *
30 + * @param appId the application id
31 + * @return the flow entries
32 + */
33 + Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId);
34 +
35 + /**
20 * Stores a new flow rule without generating events. 36 * Stores a new flow rule without generating events.
21 * 37 *
22 * @param rule the flow rule to add 38 * @param rule the flow rule to add
......
...@@ -7,14 +7,13 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -7,14 +7,13 @@ import org.apache.felix.scr.annotations.Deactivate;
7 import org.apache.felix.scr.annotations.Reference; 7 import org.apache.felix.scr.annotations.Reference;
8 import org.apache.felix.scr.annotations.ReferenceCardinality; 8 import org.apache.felix.scr.annotations.ReferenceCardinality;
9 import org.apache.felix.scr.annotations.Service; 9 import org.apache.felix.scr.annotations.Service;
10 +import org.onlab.onos.ApplicationId;
10 import org.onlab.onos.event.AbstractListenerRegistry; 11 import org.onlab.onos.event.AbstractListenerRegistry;
11 import org.onlab.onos.event.EventDeliveryService; 12 import org.onlab.onos.event.EventDeliveryService;
12 import org.onlab.onos.net.Device; 13 import org.onlab.onos.net.Device;
13 import org.onlab.onos.net.DeviceId; 14 import org.onlab.onos.net.DeviceId;
14 import org.onlab.onos.net.device.DeviceService; 15 import org.onlab.onos.net.device.DeviceService;
15 -import org.onlab.onos.net.flow.DefaultFlowRule;
16 import org.onlab.onos.net.flow.FlowRule; 16 import org.onlab.onos.net.flow.FlowRule;
17 -import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
18 import org.onlab.onos.net.flow.FlowRuleEvent; 17 import org.onlab.onos.net.flow.FlowRuleEvent;
19 import org.onlab.onos.net.flow.FlowRuleListener; 18 import org.onlab.onos.net.flow.FlowRuleListener;
20 import org.onlab.onos.net.flow.FlowRuleProvider; 19 import org.onlab.onos.net.flow.FlowRuleProvider;
...@@ -81,7 +80,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -81,7 +80,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
81 @Override 80 @Override
82 public void applyFlowRules(FlowRule... flowRules) { 81 public void applyFlowRules(FlowRule... flowRules) {
83 for (int i = 0; i < flowRules.length; i++) { 82 for (int i = 0; i < flowRules.length; i++) {
84 - FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD); 83 + FlowRule f = flowRules[i];
85 final Device device = deviceService.getDevice(f.deviceId()); 84 final Device device = deviceService.getDevice(f.deviceId());
86 final FlowRuleProvider frp = getProvider(device.providerId()); 85 final FlowRuleProvider frp = getProvider(device.providerId());
87 store.storeFlowRule(f); 86 store.storeFlowRule(f);
...@@ -92,14 +91,33 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -92,14 +91,33 @@ implements FlowRuleService, FlowRuleProviderRegistry {
92 @Override 91 @Override
93 public void removeFlowRules(FlowRule... flowRules) { 92 public void removeFlowRules(FlowRule... flowRules) {
94 FlowRule f; 93 FlowRule f;
94 + FlowRuleProvider frp;
95 + Device device;
95 for (int i = 0; i < flowRules.length; i++) { 96 for (int i = 0; i < flowRules.length; i++) {
96 - f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE); 97 + f = flowRules[i];
97 - final Device device = deviceService.getDevice(f.deviceId()); 98 + device = deviceService.getDevice(f.deviceId());
98 - final FlowRuleProvider frp = getProvider(device.providerId()); 99 + frp = getProvider(device.providerId());
99 store.deleteFlowRule(f); 100 store.deleteFlowRule(f);
100 frp.removeFlowRule(f); 101 frp.removeFlowRule(f);
101 } 102 }
103 + }
102 104
105 + @Override
106 + public void removeFlowRulesById(ApplicationId id) {
107 + Iterable<FlowRule> rules = getFlowRulesById(id);
108 + FlowRuleProvider frp;
109 + Device device;
110 + for (FlowRule f : rules) {
111 + store.deleteFlowRule(f);
112 + device = deviceService.getDevice(f.deviceId());
113 + frp = getProvider(device.providerId());
114 + frp.removeRulesById(id, f);
115 + }
116 + }
117 +
118 + @Override
119 + public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
120 + return store.getFlowEntriesByAppId(id);
103 } 121 }
104 122
105 @Override 123 @Override
...@@ -130,8 +148,27 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -130,8 +148,27 @@ implements FlowRuleService, FlowRuleProviderRegistry {
130 public void flowRemoved(FlowRule flowRule) { 148 public void flowRemoved(FlowRule flowRule) {
131 checkNotNull(flowRule, FLOW_RULE_NULL); 149 checkNotNull(flowRule, FLOW_RULE_NULL);
132 checkValidity(); 150 checkValidity();
133 - FlowRuleEvent event = store.removeFlowRule(flowRule); 151 + FlowRule stored = store.getFlowRule(flowRule);
152 + if (stored == null) {
153 + log.debug("Rule already evicted from store: {}", flowRule);
154 + return;
155 + }
156 + Device device = deviceService.getDevice(flowRule.deviceId());
157 + FlowRuleProvider frp = getProvider(device.providerId());
158 + FlowRuleEvent event = null;
159 + switch (stored.state()) {
160 + case ADDED:
161 + case PENDING_ADD:
162 + frp.applyFlowRule(flowRule);
163 + break;
164 + case PENDING_REMOVE:
165 + case REMOVED:
166 + event = store.removeFlowRule(flowRule);
167 + break;
168 + default:
169 + break;
134 170
171 + }
135 if (event != null) { 172 if (event != null) {
136 log.debug("Flow {} removed", flowRule); 173 log.debug("Flow {} removed", flowRule);
137 post(event); 174 post(event);
...@@ -142,7 +179,22 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -142,7 +179,22 @@ implements FlowRuleService, FlowRuleProviderRegistry {
142 public void flowMissing(FlowRule flowRule) { 179 public void flowMissing(FlowRule flowRule) {
143 checkNotNull(flowRule, FLOW_RULE_NULL); 180 checkNotNull(flowRule, FLOW_RULE_NULL);
144 checkValidity(); 181 checkValidity();
145 - log.debug("Flow {} has not been installed.", flowRule); 182 + Device device = deviceService.getDevice(flowRule.deviceId());
183 + FlowRuleProvider frp = getProvider(device.providerId());
184 + switch (flowRule.state()) {
185 + case PENDING_REMOVE:
186 + case REMOVED:
187 + store.removeFlowRule(flowRule);
188 + frp.removeFlowRule(flowRule);
189 + break;
190 + case ADDED:
191 + case PENDING_ADD:
192 + frp.applyFlowRule(flowRule);
193 + break;
194 + default:
195 + log.debug("Flow {} has not been installed.", flowRule);
196 + }
197 +
146 198
147 } 199 }
148 200
...@@ -150,6 +202,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -150,6 +202,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
150 public void extraneousFlow(FlowRule flowRule) { 202 public void extraneousFlow(FlowRule flowRule) {
151 checkNotNull(flowRule, FLOW_RULE_NULL); 203 checkNotNull(flowRule, FLOW_RULE_NULL);
152 checkValidity(); 204 checkValidity();
205 + removeFlowRules(flowRule);
153 log.debug("Flow {} is on switch but not in store.", flowRule); 206 log.debug("Flow {} is on switch but not in store.", flowRule);
154 } 207 }
155 208
......
...@@ -43,8 +43,11 @@ import java.util.Iterator; ...@@ -43,8 +43,11 @@ import java.util.Iterator;
43 import java.util.List; 43 import java.util.List;
44 import java.util.Map.Entry; 44 import java.util.Map.Entry;
45 import java.util.Set; 45 import java.util.Set;
46 +import java.util.concurrent.BlockingQueue;
46 import java.util.concurrent.ConcurrentHashMap; 47 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.concurrent.ConcurrentMap; 48 import java.util.concurrent.ConcurrentMap;
49 +import java.util.concurrent.LinkedBlockingQueue;
50 +import java.util.concurrent.TimeUnit;
48 51
49 import static org.junit.Assert.*; 52 import static org.junit.Assert.*;
50 import static org.onlab.onos.net.Device.Type.SWITCH; 53 import static org.onlab.onos.net.Device.Type.SWITCH;
...@@ -182,7 +185,7 @@ public class DistributedDeviceManagerTest { ...@@ -182,7 +185,7 @@ public class DistributedDeviceManagerTest {
182 validateEvents(DEVICE_ADDED, DEVICE_ADDED); 185 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
183 186
184 connectDevice(DID1, SW2); 187 connectDevice(DID1, SW2);
185 - validateEvents(DEVICE_UPDATED); 188 + validateEvents(DEVICE_UPDATED, DEVICE_UPDATED);
186 } 189 }
187 190
188 @Test 191 @Test
...@@ -251,12 +254,16 @@ public class DistributedDeviceManagerTest { ...@@ -251,12 +254,16 @@ public class DistributedDeviceManagerTest {
251 } 254 }
252 255
253 protected void validateEvents(Enum... types) { 256 protected void validateEvents(Enum... types) {
254 - int i = 0; 257 + for (Enum type : types) {
255 - assertEquals("wrong events received", types.length, listener.events.size()); 258 + try {
256 - for (Event event : listener.events) { 259 + Event event = listener.events.poll(1, TimeUnit.SECONDS);
257 - assertEquals("incorrect event type", types[i], event.type()); 260 + assertNotNull("Timed out waiting for " + event, event);
258 - i++; 261 + assertEquals("incorrect event type", type, event.type());
262 + } catch (InterruptedException e) {
263 + fail("Unexpected interrupt");
264 + }
259 } 265 }
266 + assertTrue("Unexpected events left", listener.events.isEmpty());
260 listener.events.clear(); 267 listener.events.clear();
261 } 268 }
262 269
...@@ -281,7 +288,7 @@ public class DistributedDeviceManagerTest { ...@@ -281,7 +288,7 @@ public class DistributedDeviceManagerTest {
281 } 288 }
282 289
283 private static class TestListener implements DeviceListener { 290 private static class TestListener implements DeviceListener {
284 - final List<DeviceEvent> events = new ArrayList<>(); 291 + final BlockingQueue<DeviceEvent> events = new LinkedBlockingQueue<>();
285 292
286 @Override 293 @Override
287 public void event(DeviceEvent event) { 294 public void event(DeviceEvent event) {
......
...@@ -14,6 +14,7 @@ import java.util.List; ...@@ -14,6 +14,7 @@ import java.util.List;
14 import org.junit.After; 14 import org.junit.After;
15 import org.junit.Before; 15 import org.junit.Before;
16 import org.junit.Test; 16 import org.junit.Test;
17 +import org.onlab.onos.ApplicationId;
17 import org.onlab.onos.event.impl.TestEventDispatcher; 18 import org.onlab.onos.event.impl.TestEventDispatcher;
18 import org.onlab.onos.net.DefaultDevice; 19 import org.onlab.onos.net.DefaultDevice;
19 import org.onlab.onos.net.Device; 20 import org.onlab.onos.net.Device;
...@@ -61,6 +62,7 @@ public class FlowRuleManagerTest { ...@@ -61,6 +62,7 @@ public class FlowRuleManagerTest {
61 protected FlowRuleProviderService providerService; 62 protected FlowRuleProviderService providerService;
62 protected TestProvider provider; 63 protected TestProvider provider;
63 protected TestListener listener = new TestListener(); 64 protected TestListener listener = new TestListener();
65 + private ApplicationId appId;
64 66
65 @Before 67 @Before
66 public void setUp() { 68 public void setUp() {
...@@ -75,6 +77,7 @@ public class FlowRuleManagerTest { ...@@ -75,6 +77,7 @@ public class FlowRuleManagerTest {
75 mgr.addListener(listener); 77 mgr.addListener(listener);
76 provider = new TestProvider(PID); 78 provider = new TestProvider(PID);
77 providerService = registry.register(provider); 79 providerService = registry.register(provider);
80 + appId = ApplicationId.getAppId();
78 assertTrue("provider should be registered", 81 assertTrue("provider should be registered",
79 registry.getProviders().contains(provider.id())); 82 registry.getProviders().contains(provider.id()));
80 } 83 }
...@@ -93,7 +96,7 @@ public class FlowRuleManagerTest { ...@@ -93,7 +96,7 @@ public class FlowRuleManagerTest {
93 private FlowRule flowRule(int tsval, int trval) { 96 private FlowRule flowRule(int tsval, int trval) {
94 TestSelector ts = new TestSelector(tsval); 97 TestSelector ts = new TestSelector(tsval);
95 TestTreatment tr = new TestTreatment(trval); 98 TestTreatment tr = new TestTreatment(trval);
96 - return new DefaultFlowRule(DID, ts, tr, 0); 99 + return new DefaultFlowRule(DID, ts, tr, 0, appId);
97 } 100 }
98 101
99 private FlowRule flowRule(FlowRule rule, FlowRuleState state) { 102 private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
...@@ -159,8 +162,8 @@ public class FlowRuleManagerTest { ...@@ -159,8 +162,8 @@ public class FlowRuleManagerTest {
159 public void applyFlowRules() { 162 public void applyFlowRules() {
160 163
161 FlowRule r1 = flowRule(1, 1); 164 FlowRule r1 = flowRule(1, 1);
162 - FlowRule r2 = flowRule(1, 2); 165 + FlowRule r2 = flowRule(2, 2);
163 - FlowRule r3 = flowRule(1, 3); 166 + FlowRule r3 = flowRule(3, 3);
164 167
165 assertTrue("store should be empty", 168 assertTrue("store should be empty",
166 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); 169 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
...@@ -196,6 +199,7 @@ public class FlowRuleManagerTest { ...@@ -196,6 +199,7 @@ public class FlowRuleManagerTest {
196 @Test 199 @Test
197 public void flowRemoved() { 200 public void flowRemoved() {
198 FlowRule f1 = addFlowRule(1); 201 FlowRule f1 = addFlowRule(1);
202 + service.removeFlowRules(f1);
199 addFlowRule(2); 203 addFlowRule(2);
200 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED); 204 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
201 providerService.flowRemoved(rem1); 205 providerService.flowRemoved(rem1);
...@@ -293,6 +297,11 @@ public class FlowRuleManagerTest { ...@@ -293,6 +297,11 @@ public class FlowRuleManagerTest {
293 public void removeFlowRule(FlowRule... flowRules) { 297 public void removeFlowRule(FlowRule... flowRules) {
294 } 298 }
295 299
300 + @Override
301 + public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
302 + }
303 +
304 +
296 } 305 }
297 306
298 private class TestSelector implements TrafficSelector { 307 private class TestSelector implements TrafficSelector {
......
1 package org.onlab.onos.store.device.impl; 1 package org.onlab.onos.store.device.impl;
2 2
3 +import static com.google.common.base.Predicates.notNull;
3 import com.google.common.base.Optional; 4 import com.google.common.base.Optional;
4 import com.google.common.cache.LoadingCache; 5 import com.google.common.cache.LoadingCache;
6 +import com.google.common.collect.FluentIterable;
5 import com.google.common.collect.ImmutableList; 7 import com.google.common.collect.ImmutableList;
6 import com.google.common.collect.ImmutableSet; 8 import com.google.common.collect.ImmutableSet;
7 import com.google.common.collect.ImmutableSet.Builder; 9 import com.google.common.collect.ImmutableSet.Builder;
8 import com.hazelcast.core.IMap; 10 import com.hazelcast.core.IMap;
9 import com.hazelcast.core.ISet; 11 import com.hazelcast.core.ISet;
12 +
10 import org.apache.felix.scr.annotations.Activate; 13 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 14 import org.apache.felix.scr.annotations.Component;
12 import org.apache.felix.scr.annotations.Deactivate; 15 import org.apache.felix.scr.annotations.Deactivate;
...@@ -95,6 +98,7 @@ public class DistributedDeviceStore ...@@ -95,6 +98,7 @@ public class DistributedDeviceStore
95 rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue); 98 rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue);
96 99
97 loadDeviceCache(); 100 loadDeviceCache();
101 + loadDevicePortsCache();
98 102
99 log.info("Started"); 103 log.info("Started");
100 } 104 }
...@@ -122,13 +126,16 @@ public class DistributedDeviceStore ...@@ -122,13 +126,16 @@ public class DistributedDeviceStore
122 } 126 }
123 127
124 private void loadDeviceCache() { 128 private void loadDeviceCache() {
125 - log.info("{}:{}", rawDevices.size(), devices.size()); 129 + for (byte[] keyBytes : rawDevices.keySet()) {
126 - if (rawDevices.size() != devices.size()) { 130 + final DeviceId id = deserialize(keyBytes);
127 - for (Map.Entry<byte[], byte[]> e : rawDevices.entrySet()) { 131 + devices.refresh(id);
128 - final DeviceId key = deserialize(e.getKey()); 132 + }
129 - final DefaultDevice val = deserialize(e.getValue()); 133 + }
130 - devices.put(key, Optional.of(val)); 134 +
131 - } 135 + private void loadDevicePortsCache() {
136 + for (byte[] keyBytes : rawDevicePorts.keySet()) {
137 + final DeviceId id = deserialize(keyBytes);
138 + devicePorts.refresh(id);
132 } 139 }
133 } 140 }
134 141
...@@ -180,10 +187,12 @@ public class DistributedDeviceStore ...@@ -180,10 +187,12 @@ public class DistributedDeviceStore
180 desc.swVersion(), 187 desc.swVersion(),
181 desc.serialNumber()); 188 desc.serialNumber());
182 synchronized (this) { 189 synchronized (this) {
190 + final byte[] deviceIdBytes = serialize(device.id());
191 + rawDevices.put(deviceIdBytes, serialize(updated));
183 devices.put(device.id(), Optional.of(updated)); 192 devices.put(device.id(), Optional.of(updated));
184 availableDevices.add(serialize(device.id())); 193 availableDevices.add(serialize(device.id()));
185 } 194 }
186 - return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, device, null); 195 + return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, updated, null);
187 } 196 }
188 197
189 // Otherwise merely attempt to change availability 198 // Otherwise merely attempt to change availability
...@@ -227,7 +236,7 @@ public class DistributedDeviceStore ...@@ -227,7 +236,7 @@ public class DistributedDeviceStore
227 236
228 events.addAll(pruneOldPorts(device, ports, processed)); 237 events.addAll(pruneOldPorts(device, ports, processed));
229 } 238 }
230 - return events; 239 + return FluentIterable.from(events).filter(notNull()).toList();
231 } 240 }
232 241
233 // Creates a new port based on the port description adds it to the map and 242 // Creates a new port based on the port description adds it to the map and
...@@ -254,7 +263,7 @@ public class DistributedDeviceStore ...@@ -254,7 +263,7 @@ public class DistributedDeviceStore
254 portDescription.isEnabled()); 263 portDescription.isEnabled());
255 ports.put(port.number(), updatedPort); 264 ports.put(port.number(), updatedPort);
256 updatePortMap(device.id(), ports); 265 updatePortMap(device.id(), ports);
257 - return new DeviceEvent(PORT_UPDATED, device, port); 266 + return new DeviceEvent(PORT_UPDATED, device, updatedPort);
258 } 267 }
259 return null; 268 return null;
260 } 269 }
...@@ -351,17 +360,17 @@ public class DistributedDeviceStore ...@@ -351,17 +360,17 @@ public class DistributedDeviceStore
351 360
352 @Override 361 @Override
353 protected void onAdd(DeviceId deviceId, DefaultDevice device) { 362 protected void onAdd(DeviceId deviceId, DefaultDevice device) {
354 - delegate.notify(new DeviceEvent(DEVICE_ADDED, device)); 363 + notifyDelegate(new DeviceEvent(DEVICE_ADDED, device));
355 } 364 }
356 365
357 @Override 366 @Override
358 protected void onRemove(DeviceId deviceId, DefaultDevice device) { 367 protected void onRemove(DeviceId deviceId, DefaultDevice device) {
359 - delegate.notify(new DeviceEvent(DEVICE_REMOVED, device)); 368 + notifyDelegate(new DeviceEvent(DEVICE_REMOVED, device));
360 } 369 }
361 370
362 @Override 371 @Override
363 protected void onUpdate(DeviceId deviceId, DefaultDevice device) { 372 protected void onUpdate(DeviceId deviceId, DefaultDevice device) {
364 - delegate.notify(new DeviceEvent(DEVICE_UPDATED, device)); 373 + notifyDelegate(new DeviceEvent(DEVICE_UPDATED, device));
365 } 374 }
366 } 375 }
367 376
...@@ -372,17 +381,17 @@ public class DistributedDeviceStore ...@@ -372,17 +381,17 @@ public class DistributedDeviceStore
372 381
373 @Override 382 @Override
374 protected void onAdd(DeviceId deviceId, Map<PortNumber, Port> ports) { 383 protected void onAdd(DeviceId deviceId, Map<PortNumber, Port> ports) {
375 -// delegate.notify(new DeviceEvent(PORT_ADDED, getDevice(deviceId))); 384 +// notifyDelegate(new DeviceEvent(PORT_ADDED, getDevice(deviceId)));
376 } 385 }
377 386
378 @Override 387 @Override
379 protected void onRemove(DeviceId deviceId, Map<PortNumber, Port> ports) { 388 protected void onRemove(DeviceId deviceId, Map<PortNumber, Port> ports) {
380 -// delegate.notify(new DeviceEvent(PORT_REMOVED, getDevice(deviceId))); 389 +// notifyDelegate(new DeviceEvent(PORT_REMOVED, getDevice(deviceId)));
381 } 390 }
382 391
383 @Override 392 @Override
384 protected void onUpdate(DeviceId deviceId, Map<PortNumber, Port> ports) { 393 protected void onUpdate(DeviceId deviceId, Map<PortNumber, Port> ports) {
385 -// delegate.notify(new DeviceEvent(PORT_UPDATED, getDevice(deviceId))); 394 +// notifyDelegate(new DeviceEvent(PORT_UPDATED, getDevice(deviceId)));
386 } 395 }
387 } 396 }
388 397
......
...@@ -107,7 +107,7 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD ...@@ -107,7 +107,7 @@ public abstract class AbstractDistributedStore<E extends Event, D extends StoreD
107 @Override 107 @Override
108 public void entryRemoved(EntryEvent<byte[], byte[]> event) { 108 public void entryRemoved(EntryEvent<byte[], byte[]> event) {
109 K key = deserialize(event.getKey()); 109 K key = deserialize(event.getKey());
110 - V val = deserialize(event.getValue()); 110 + V val = deserialize(event.getOldValue());
111 cache.invalidate(key); 111 cache.invalidate(key);
112 onRemove(key, val); 112 onRemove(key, val);
113 } 113 }
......
1 package org.onlab.onos.net.trivial.impl; 1 package org.onlab.onos.net.trivial.impl;
2 2
3 +import com.google.common.collect.FluentIterable;
3 import com.google.common.collect.ImmutableList; 4 import com.google.common.collect.ImmutableList;
5 +
4 import org.apache.felix.scr.annotations.Activate; 6 import org.apache.felix.scr.annotations.Activate;
5 import org.apache.felix.scr.annotations.Component; 7 import org.apache.felix.scr.annotations.Component;
6 import org.apache.felix.scr.annotations.Deactivate; 8 import org.apache.felix.scr.annotations.Deactivate;
...@@ -33,6 +35,7 @@ import java.util.Set; ...@@ -33,6 +35,7 @@ import java.util.Set;
33 import java.util.concurrent.ConcurrentHashMap; 35 import java.util.concurrent.ConcurrentHashMap;
34 36
35 import static com.google.common.base.Preconditions.checkArgument; 37 import static com.google.common.base.Preconditions.checkArgument;
38 +import static com.google.common.base.Predicates.notNull;
36 import static org.onlab.onos.net.device.DeviceEvent.Type.*; 39 import static org.onlab.onos.net.device.DeviceEvent.Type.*;
37 import static org.slf4j.LoggerFactory.getLogger; 40 import static org.slf4j.LoggerFactory.getLogger;
38 41
...@@ -123,7 +126,7 @@ public class SimpleDeviceStore ...@@ -123,7 +126,7 @@ public class SimpleDeviceStore
123 devices.put(device.id(), updated); 126 devices.put(device.id(), updated);
124 availableDevices.add(device.id()); 127 availableDevices.add(device.id());
125 } 128 }
126 - return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, device, null); 129 + return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, updated, null);
127 } 130 }
128 131
129 // Otherwise merely attempt to change availability 132 // Otherwise merely attempt to change availability
...@@ -165,7 +168,7 @@ public class SimpleDeviceStore ...@@ -165,7 +168,7 @@ public class SimpleDeviceStore
165 168
166 events.addAll(pruneOldPorts(device, ports, processed)); 169 events.addAll(pruneOldPorts(device, ports, processed));
167 } 170 }
168 - return events; 171 + return FluentIterable.from(events).filter(notNull()).toList();
169 } 172 }
170 173
171 // Creates a new port based on the port description adds it to the map and 174 // Creates a new port based on the port description adds it to the map and
......
...@@ -4,12 +4,18 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; ...@@ -4,12 +4,18 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
4 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 4 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
5 import static org.slf4j.LoggerFactory.getLogger; 5 import static org.slf4j.LoggerFactory.getLogger;
6 6
7 +import java.util.Collection;
8 +import java.util.Collections;
9 +
7 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 12 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Service; 13 import org.apache.felix.scr.annotations.Service;
14 +import org.onlab.onos.ApplicationId;
11 import org.onlab.onos.net.DeviceId; 15 import org.onlab.onos.net.DeviceId;
16 +import org.onlab.onos.net.flow.DefaultFlowRule;
12 import org.onlab.onos.net.flow.FlowRule; 17 import org.onlab.onos.net.flow.FlowRule;
18 +import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
13 import org.onlab.onos.net.flow.FlowRuleEvent; 19 import org.onlab.onos.net.flow.FlowRuleEvent;
14 import org.onlab.onos.net.flow.FlowRuleEvent.Type; 20 import org.onlab.onos.net.flow.FlowRuleEvent.Type;
15 import org.onlab.onos.net.flow.FlowRuleStore; 21 import org.onlab.onos.net.flow.FlowRuleStore;
...@@ -33,7 +39,11 @@ public class SimpleFlowRuleStore ...@@ -33,7 +39,11 @@ public class SimpleFlowRuleStore
33 private final Logger log = getLogger(getClass()); 39 private final Logger log = getLogger(getClass());
34 40
35 // store entries as a pile of rules, no info about device tables 41 // store entries as a pile of rules, no info about device tables
36 - private final Multimap<DeviceId, FlowRule> flowEntries = ArrayListMultimap.create(); 42 + private final Multimap<DeviceId, FlowRule> flowEntries =
43 + ArrayListMultimap.<DeviceId, FlowRule>create();
44 +
45 + private final Multimap<ApplicationId, FlowRule> flowEntriesById =
46 + ArrayListMultimap.<ApplicationId, FlowRule>create();
37 47
38 @Activate 48 @Activate
39 public void activate() { 49 public void activate() {
...@@ -45,48 +55,76 @@ public class SimpleFlowRuleStore ...@@ -45,48 +55,76 @@ public class SimpleFlowRuleStore
45 log.info("Stopped"); 55 log.info("Stopped");
46 } 56 }
47 57
58 +
48 @Override 59 @Override
49 - public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) { 60 + public synchronized FlowRule getFlowRule(FlowRule rule) {
50 - return ImmutableSet.copyOf(flowEntries.get(deviceId)); 61 + for (FlowRule f : flowEntries.get(rule.deviceId())) {
62 + if (f.equals(rule)) {
63 + return f;
64 + }
65 + }
66 + return null;
51 } 67 }
52 68
53 @Override 69 @Override
54 - public void storeFlowRule(FlowRule rule) { 70 + public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
55 - DeviceId did = rule.deviceId(); 71 + Collection<FlowRule> rules = flowEntries.get(deviceId);
56 - flowEntries.put(did, rule); 72 + if (rules == null) {
73 + return Collections.emptyList();
74 + }
75 + return ImmutableSet.copyOf(rules);
57 } 76 }
58 77
59 @Override 78 @Override
60 - public void deleteFlowRule(FlowRule rule) { 79 + public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
61 - DeviceId did = rule.deviceId(); 80 + Collection<FlowRule> rules = flowEntriesById.get(appId);
81 + if (rules == null) {
82 + return Collections.emptyList();
83 + }
84 + return ImmutableSet.copyOf(rules);
85 + }
86 +
87 + @Override
88 + public synchronized void storeFlowRule(FlowRule rule) {
89 + FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
90 + DeviceId did = f.deviceId();
91 + if (!flowEntries.containsEntry(did, f)) {
92 + flowEntries.put(did, f);
93 + flowEntriesById.put(rule.appId(), f);
94 + }
95 + }
96 +
97 + @Override
98 + public synchronized void deleteFlowRule(FlowRule rule) {
99 + FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
100 + DeviceId did = f.deviceId();
62 101
63 /* 102 /*
64 * find the rule and mark it for deletion. 103 * find the rule and mark it for deletion.
65 * Ultimately a flow removed will come remove it. 104 * Ultimately a flow removed will come remove it.
66 */ 105 */
67 106
68 - if (flowEntries.containsEntry(did, rule)) { 107 + if (flowEntries.containsEntry(did, f)) {
69 - synchronized (flowEntries) { 108 + //synchronized (flowEntries) {
70 - 109 + flowEntries.remove(did, f);
71 - flowEntries.remove(did, rule); 110 + flowEntries.put(did, f);
72 - flowEntries.put(did, rule); 111 + flowEntriesById.remove(rule.appId(), rule);
73 - } 112 + //}
74 } 113 }
75 } 114 }
76 115
77 @Override 116 @Override
78 - public FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) { 117 + public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
79 DeviceId did = rule.deviceId(); 118 DeviceId did = rule.deviceId();
80 119
81 // check if this new rule is an update to an existing entry 120 // check if this new rule is an update to an existing entry
82 if (flowEntries.containsEntry(did, rule)) { 121 if (flowEntries.containsEntry(did, rule)) {
83 - synchronized (flowEntries) { 122 + //synchronized (flowEntries) {
84 - // Multimaps support duplicates so we have to remove our rule 123 + // Multimaps support duplicates so we have to remove our rule
85 - // and replace it with the current version. 124 + // and replace it with the current version.
86 - 125 + flowEntries.remove(did, rule);
87 - flowEntries.remove(did, rule); 126 + flowEntries.put(did, rule);
88 - flowEntries.put(did, rule); 127 + //}
89 - }
90 return new FlowRuleEvent(Type.RULE_UPDATED, rule); 128 return new FlowRuleEvent(Type.RULE_UPDATED, rule);
91 } 129 }
92 130
...@@ -95,16 +133,20 @@ public class SimpleFlowRuleStore ...@@ -95,16 +133,20 @@ public class SimpleFlowRuleStore
95 } 133 }
96 134
97 @Override 135 @Override
98 - public FlowRuleEvent removeFlowRule(FlowRule rule) { 136 + public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
99 - synchronized (this) { 137 + //synchronized (this) {
100 - if (flowEntries.remove(rule.deviceId(), rule)) { 138 + if (flowEntries.remove(rule.deviceId(), rule)) {
101 - return new FlowRuleEvent(RULE_REMOVED, rule); 139 + return new FlowRuleEvent(RULE_REMOVED, rule);
102 - } else { 140 + } else {
103 - return null; 141 + return null;
104 - }
105 } 142 }
143 + //}
106 } 144 }
107 145
108 146
109 147
148 +
149 +
150 +
151 +
110 } 152 }
......
...@@ -183,7 +183,7 @@ public class FlowRuleBuilder { ...@@ -183,7 +183,7 @@ public class FlowRuleBuilder {
183 break; 183 break;
184 case ETH_DST: 184 case ETH_DST:
185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong()); 185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
186 - builder.add(Criteria.matchEthSrc(dMac)); 186 + builder.add(Criteria.matchEthDst(dMac));
187 break; 187 break;
188 case ETH_TYPE: 188 case ETH_TYPE:
189 int ethType = match.get(MatchField.ETH_TYPE).getValue(); 189 int ethType = match.get(MatchField.ETH_TYPE).getValue();
......
...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
12 import org.onlab.onos.net.DeviceId; 13 import org.onlab.onos.net.DeviceId;
13 import org.onlab.onos.net.flow.FlowRule; 14 import org.onlab.onos.net.flow.FlowRule;
14 import org.onlab.onos.net.flow.FlowRuleProvider; 15 import org.onlab.onos.net.flow.FlowRuleProvider;
...@@ -102,12 +103,17 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -102,12 +103,17 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
102 103
103 } 104 }
104 105
105 -
106 private void removeRule(FlowRule flowRule) { 106 private void removeRule(FlowRule flowRule) {
107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri())); 107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
108 sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel()); 108 sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel());
109 } 109 }
110 110
111 + @Override
112 + public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
113 + // TODO: optimize using the ApplicationId
114 + removeFlowRule(flowRules);
115 + }
116 +
111 117
112 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved. 118 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
113 // possibly barriers as well. May not be internal at all... 119 // possibly barriers as well. May not be internal at all...
...@@ -179,4 +185,6 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -179,4 +185,6 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
179 } 185 }
180 186
181 187
188 +
189 +
182 } 190 }
......