Showing
17 changed files
with
336 additions
and
78 deletions
... | @@ -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 | } | ... | ... |
core/store/src/test/java/org/onlab/onos/store/device/impl/DistributedDeviceStoreTest.java
0 → 100644
This diff is collapsed. Click to expand it.
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(); | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment