Committed by
Gerrit Code Review
Implement map listener in DistributedMcastStore
Fix the problem that only local delegation is triggered Change-Id: Ibe7b4a6abb447b9a8e3a0959882ef2da0d21f4be
Showing
1 changed file
with
84 additions
and
45 deletions
... | @@ -31,14 +31,18 @@ import org.onosproject.net.mcast.McastStoreDelegate; | ... | @@ -31,14 +31,18 @@ import org.onosproject.net.mcast.McastStoreDelegate; |
31 | import org.onosproject.store.AbstractStore; | 31 | import org.onosproject.store.AbstractStore; |
32 | import org.onosproject.store.serializers.KryoNamespaces; | 32 | import org.onosproject.store.serializers.KryoNamespaces; |
33 | import org.onosproject.store.service.ConsistentMap; | 33 | import org.onosproject.store.service.ConsistentMap; |
34 | +import org.onosproject.store.service.MapEvent; | ||
35 | +import org.onosproject.store.service.MapEventListener; | ||
34 | import org.onosproject.store.service.Serializer; | 36 | import org.onosproject.store.service.Serializer; |
35 | import org.onosproject.store.service.StorageService; | 37 | import org.onosproject.store.service.StorageService; |
36 | import org.slf4j.Logger; | 38 | import org.slf4j.Logger; |
37 | 39 | ||
38 | import java.util.Map; | 40 | import java.util.Map; |
39 | import java.util.Set; | 41 | import java.util.Set; |
42 | +import java.util.concurrent.ConcurrentHashMap; | ||
40 | import java.util.concurrent.atomic.AtomicReference; | 43 | import java.util.concurrent.atomic.AtomicReference; |
41 | 44 | ||
45 | +import static com.google.common.base.Preconditions.checkState; | ||
42 | import static org.slf4j.LoggerFactory.getLogger; | 46 | import static org.slf4j.LoggerFactory.getLogger; |
43 | 47 | ||
44 | /** | 48 | /** |
... | @@ -62,11 +66,16 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -62,11 +66,16 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
62 | 66 | ||
63 | protected ConsistentMap<McastRoute, MulticastData> mcastRib; | 67 | protected ConsistentMap<McastRoute, MulticastData> mcastRib; |
64 | protected Map<McastRoute, MulticastData> mcastRoutes; | 68 | protected Map<McastRoute, MulticastData> mcastRoutes; |
69 | + private final MapEventListener<McastRoute, MulticastData> mcastMapListener = | ||
70 | + new McastMapListener(); | ||
65 | 71 | ||
72 | + // NOTE: MapEvent cannot provide correct old value of sink since MulticastData | ||
73 | + // is a object reference. Use this localSink to track sink. | ||
74 | + private Map<McastRoute, Set<ConnectPoint>> localSink = | ||
75 | + new ConcurrentHashMap<>(); | ||
66 | 76 | ||
67 | @Activate | 77 | @Activate |
68 | public void activate() { | 78 | public void activate() { |
69 | - | ||
70 | mcastRib = storageService.<McastRoute, MulticastData>consistentMapBuilder() | 79 | mcastRib = storageService.<McastRoute, MulticastData>consistentMapBuilder() |
71 | .withName(MCASTRIB) | 80 | .withName(MCASTRIB) |
72 | .withSerializer(Serializer.using(KryoNamespace.newBuilder() | 81 | .withSerializer(Serializer.using(KryoNamespace.newBuilder() |
... | @@ -79,10 +88,9 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -79,10 +88,9 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
79 | ).build())) | 88 | ).build())) |
80 | //.withRelaxedReadConsistency() | 89 | //.withRelaxedReadConsistency() |
81 | .build(); | 90 | .build(); |
82 | - | 91 | + mcastRib.addListener(mcastMapListener); |
83 | mcastRoutes = mcastRib.asJavaMap(); | 92 | mcastRoutes = mcastRib.asJavaMap(); |
84 | 93 | ||
85 | - | ||
86 | log.info("Started"); | 94 | log.info("Started"); |
87 | } | 95 | } |
88 | 96 | ||
... | @@ -95,16 +103,10 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -95,16 +103,10 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
95 | public void storeRoute(McastRoute route, Type operation) { | 103 | public void storeRoute(McastRoute route, Type operation) { |
96 | switch (operation) { | 104 | switch (operation) { |
97 | case ADD: | 105 | case ADD: |
98 | - if (mcastRoutes.putIfAbsent(route, MulticastData.empty()) == null) { | 106 | + mcastRoutes.putIfAbsent(route, MulticastData.empty()); |
99 | - delegate.notify(new McastEvent(McastEvent.Type.ROUTE_ADDED, | ||
100 | - McastRouteInfo.mcastRouteInfo(route))); | ||
101 | - } | ||
102 | break; | 107 | break; |
103 | case REMOVE: | 108 | case REMOVE: |
104 | - if (mcastRoutes.remove(route) != null) { | 109 | + mcastRoutes.remove(route); |
105 | - delegate.notify(new McastEvent(McastEvent.Type.ROUTE_REMOVED, | ||
106 | - McastRouteInfo.mcastRouteInfo(route))); | ||
107 | - } | ||
108 | break; | 110 | break; |
109 | default: | 111 | default: |
110 | log.warn("Unknown mcast operation type: {}", operation); | 112 | log.warn("Unknown mcast operation type: {}", operation); |
... | @@ -121,15 +123,6 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -121,15 +123,6 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
121 | } | 123 | } |
122 | return v; | 124 | return v; |
123 | }); | 125 | }); |
124 | - | ||
125 | - | ||
126 | - if (data != null) { | ||
127 | - delegate.notify(new McastEvent(McastEvent.Type.SOURCE_ADDED, | ||
128 | - McastRouteInfo.mcastRouteInfo(route, | ||
129 | - data.sinks(), | ||
130 | - source))); | ||
131 | - } | ||
132 | - | ||
133 | } | 126 | } |
134 | 127 | ||
135 | @Override | 128 | @Override |
... | @@ -152,31 +145,6 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -152,31 +145,6 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
152 | } | 145 | } |
153 | return v; | 146 | return v; |
154 | }); | 147 | }); |
155 | - | ||
156 | - | ||
157 | - if (data != null) { | ||
158 | - switch (operation) { | ||
159 | - case ADD: | ||
160 | - delegate.notify(new McastEvent( | ||
161 | - McastEvent.Type.SINK_ADDED, | ||
162 | - McastRouteInfo.mcastRouteInfo(route, | ||
163 | - sink, | ||
164 | - data.source()))); | ||
165 | - break; | ||
166 | - case REMOVE: | ||
167 | - if (data != null) { | ||
168 | - delegate.notify(new McastEvent( | ||
169 | - McastEvent.Type.SINK_REMOVED, | ||
170 | - McastRouteInfo.mcastRouteInfo(route, | ||
171 | - sink, | ||
172 | - data.source()))); | ||
173 | - } | ||
174 | - break; | ||
175 | - default: | ||
176 | - log.warn("Unknown mcast operation type: {}", operation); | ||
177 | - } | ||
178 | - } | ||
179 | - | ||
180 | } | 148 | } |
181 | 149 | ||
182 | @Override | 150 | @Override |
... | @@ -194,4 +162,75 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD | ... | @@ -194,4 +162,75 @@ public class DistributedMcastStore extends AbstractStore<McastEvent, McastStoreD |
194 | return mcastRoutes.keySet(); | 162 | return mcastRoutes.keySet(); |
195 | } | 163 | } |
196 | 164 | ||
165 | + private class McastMapListener implements MapEventListener<McastRoute, MulticastData> { | ||
166 | + @Override | ||
167 | + public void event(MapEvent<McastRoute, MulticastData> event) { | ||
168 | + McastRoute route = event.key(); | ||
169 | + MulticastData newValue, oldValue; | ||
170 | + | ||
171 | + switch (event.type()) { | ||
172 | + case INSERT: | ||
173 | + checkState(event.newValue() != null, "Map insert event should have newValue"); | ||
174 | + newValue = event.newValue().value(); | ||
175 | + if (newValue.source() != null) { | ||
176 | + notifyDelegate(new McastEvent(McastEvent.Type.SOURCE_ADDED, | ||
177 | + McastRouteInfo.mcastRouteInfo(route, | ||
178 | + newValue.sinks(), newValue.source()))); | ||
179 | + } | ||
180 | + if (!newValue.sinks().isEmpty()) { | ||
181 | + newValue.sinks().forEach(sink -> { | ||
182 | + notifyDelegate(new McastEvent(McastEvent.Type.SINK_ADDED, | ||
183 | + McastRouteInfo.mcastRouteInfo(route, | ||
184 | + sink, newValue.source()))); | ||
185 | + }); | ||
186 | + } | ||
187 | + if (newValue.source() == null && newValue.sinks().isEmpty()) { | ||
188 | + notifyDelegate(new McastEvent(McastEvent.Type.ROUTE_ADDED, | ||
189 | + McastRouteInfo.mcastRouteInfo(route))); | ||
190 | + } | ||
191 | + localSink.put(route, newValue.sinks()); | ||
192 | + break; | ||
193 | + case REMOVE: | ||
194 | + checkState(event.oldValue() != null, "Map remove event should have oldValue"); | ||
195 | + oldValue = event.oldValue().value(); | ||
196 | + notifyDelegate(new McastEvent(McastEvent.Type.ROUTE_REMOVED, | ||
197 | + McastRouteInfo.mcastRouteInfo(route))); | ||
198 | + oldValue.sinks().forEach(sink -> { | ||
199 | + notifyDelegate(new McastEvent( | ||
200 | + McastEvent.Type.SINK_REMOVED, | ||
201 | + McastRouteInfo.mcastRouteInfo(route, sink, oldValue.source()))); | ||
202 | + }); | ||
203 | + localSink.remove(route); | ||
204 | + break; | ||
205 | + case UPDATE: | ||
206 | + checkState(event.newValue() != null, "Map update event should have newValue"); | ||
207 | + checkState(event.oldValue() != null, "Map update event should have oldValue"); | ||
208 | + newValue = event.newValue().value(); | ||
209 | + oldValue = event.oldValue().value(); | ||
210 | + if (newValue.source() != null && oldValue.source() == null) { | ||
211 | + notifyDelegate(new McastEvent(McastEvent.Type.SOURCE_ADDED, | ||
212 | + McastRouteInfo.mcastRouteInfo(route, | ||
213 | + newValue.sinks(), newValue.source()))); | ||
214 | + } | ||
215 | + newValue.sinks().stream() | ||
216 | + .filter(sink -> !localSink.get(route).contains(sink)) | ||
217 | + .forEach(addedSink -> { | ||
218 | + notifyDelegate(new McastEvent(McastEvent.Type.SINK_ADDED, | ||
219 | + McastRouteInfo.mcastRouteInfo(route, | ||
220 | + addedSink, newValue.source()))); | ||
221 | + }); | ||
222 | + localSink.get(route).stream() | ||
223 | + .filter(sink -> !newValue.sinks().contains(sink)) | ||
224 | + .forEach(removedSink -> { | ||
225 | + notifyDelegate(new McastEvent(McastEvent.Type.SINK_REMOVED, | ||
226 | + McastRouteInfo.mcastRouteInfo(route, | ||
227 | + removedSink, newValue.source()))); | ||
228 | + }); | ||
229 | + localSink.put(route, newValue.sinks()); | ||
230 | + break; | ||
231 | + default: | ||
232 | + break; | ||
233 | + } | ||
234 | + } | ||
235 | + } | ||
197 | } | 236 | } | ... | ... |
-
Please register or login to post a comment