blob: 5be4191e75ab0e4ff28b7843942b29e3dd7d8782 [file] [log] [blame]
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -07001package net.onrc.onos.datagrid;
2
3import java.io.FileNotFoundException;
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.HashMap;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -07007import java.util.LinkedList;
Jonathan Hart18ad55c2013-11-11 22:49:55 -08008import java.util.List;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -07009import java.util.Map;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070010import java.util.Set;
Jonathan Hart18ad55c2013-11-11 22:49:55 -080011import java.util.concurrent.TimeUnit;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070012
13import net.floodlightcontroller.core.IFloodlightProviderService;
14import net.floodlightcontroller.core.module.FloodlightModuleContext;
15import net.floodlightcontroller.core.module.FloodlightModuleException;
16import net.floodlightcontroller.core.module.IFloodlightModule;
17import net.floodlightcontroller.core.module.IFloodlightService;
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -070018import net.floodlightcontroller.restserver.IRestApiService;
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -070019import net.onrc.onos.datagrid.web.DatagridWebRoutable;
Pavlin Radoslavov9a859022013-10-30 10:08:24 -070020import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
Jonathan Hart7804bea2014-01-07 10:50:52 -080021import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
22import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
23import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
24import net.onrc.onos.ofcontroller.proxyarp.PacketOutNotification;
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -070025import net.onrc.onos.ofcontroller.topology.TopologyElement;
Pavlin Radoslavovb7506842013-10-29 17:46:54 -070026import net.onrc.onos.ofcontroller.util.FlowEntry;
27import net.onrc.onos.ofcontroller.util.FlowEntryId;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070028import net.onrc.onos.ofcontroller.util.FlowId;
29import net.onrc.onos.ofcontroller.util.FlowPath;
30import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
31
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070032import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -080035import com.esotericsoftware.kryo.Kryo;
36import com.esotericsoftware.kryo.io.Input;
37import com.esotericsoftware.kryo.io.Output;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070038import com.hazelcast.config.Config;
39import com.hazelcast.config.FileSystemXmlConfig;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070040import com.hazelcast.core.EntryEvent;
41import com.hazelcast.core.EntryListener;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070042import com.hazelcast.core.Hazelcast;
43import com.hazelcast.core.HazelcastInstance;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070044import com.hazelcast.core.IMap;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070045import com.hazelcast.instance.GroupProperties;
46
47/**
48 * A datagrid service that uses Hazelcast as a datagrid.
49 * The relevant data is stored in the Hazelcast datagrid and shared as
50 * appropriate in a multi-node cluster.
51 */
52public class HazelcastDatagrid implements IFloodlightModule, IDatagridService {
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070053 private final static int MAX_BUFFER_SIZE = 64*1024;
54
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070055 protected final static Logger log = LoggerFactory.getLogger(HazelcastDatagrid.class);
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070056 protected IFloodlightProviderService floodlightProvider;
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -070057 protected IRestApiService restApi;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070058
59 protected static final String HazelcastConfigFile = "datagridConfig";
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070060 private HazelcastInstance hazelcastInstance = null;
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -070061 private Config hazelcastConfig = null;
62
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070063 private KryoFactory kryoFactory = new KryoFactory();
Pavlin Radoslavov9a859022013-10-30 10:08:24 -070064 private IFlowEventHandlerService flowEventHandlerService = null;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070065
66 // State related to the Flow map
67 protected static final String mapFlowName = "mapFlow";
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070068 private IMap<Long, byte[]> mapFlow = null;
69 private MapFlowListener mapFlowListener = null;
70 private String mapFlowListenerId = null;
71
Pavlin Radoslavovb7506842013-10-29 17:46:54 -070072 // State related to the Flow Entry map
73 protected static final String mapFlowEntryName = "mapFlowEntry";
74 private IMap<Long, byte[]> mapFlowEntry = null;
75 private MapFlowEntryListener mapFlowEntryListener = null;
76 private String mapFlowEntryListenerId = null;
77
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -070078 // State related to the Network Topology map
79 protected static final String mapTopologyName = "mapTopology";
80 private IMap<String, byte[]> mapTopology = null;
81 private MapTopologyListener mapTopologyListener = null;
82 private String mapTopologyListenerId = null;
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -080083
Jonathan Hart7804bea2014-01-07 10:50:52 -080084 // State related to the packet out map
85 protected static final String packetOutMapName = "packetOutMap";
86 private IMap<PacketOutNotification, byte[]> packetOutMap = null;
87 private List<IPacketOutEventHandler> packetOutEventHandlers = new ArrayList<IPacketOutEventHandler>();
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -080088
Jonathan Hart18ad55c2013-11-11 22:49:55 -080089 private final byte[] dummyByte = {0};
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -080090
Jonathan Hart7804bea2014-01-07 10:50:52 -080091 // State related to the ARP reply map
92 protected static final String arpReplyMapName = "arpReplyMap";
93 private IMap<ArpReplyNotification, byte[]> arpReplyMap = null;
94 private List<IArpReplyEventHandler> arpReplyEventHandlers = new ArrayList<IArpReplyEventHandler>();
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -070095
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -070096 /**
97 * Class for receiving notifications for Flow state.
98 *
99 * The datagrid map is:
100 * - Key : Flow ID (Long)
Pavlin Radoslavov5367d212013-11-07 11:18:51 -0800101 * - Value : Serialized FlowPath (byte[])
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700102 */
103 class MapFlowListener implements EntryListener<Long, byte[]> {
104 /**
105 * Receive a notification that an entry is added.
106 *
107 * @param event the notification event for the entry.
108 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800109 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800110 public void entryAdded(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800111 byte[] valueBytes = event.getValue();
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700112
113 //
114 // Decode the value and deliver the notification
115 //
116 Kryo kryo = kryoFactory.newKryo();
117 Input input = new Input(valueBytes);
118 FlowPath flowPath = kryo.readObject(input, FlowPath.class);
119 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700120 flowEventHandlerService.notificationRecvFlowAdded(flowPath);
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700121 }
122
123 /**
124 * Receive a notification that an entry is removed.
125 *
126 * @param event the notification event for the entry.
127 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800128 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800129 public void entryRemoved(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800130 byte[] valueBytes = event.getValue();
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700131
132 //
133 // Decode the value and deliver the notification
134 //
135 Kryo kryo = kryoFactory.newKryo();
136 Input input = new Input(valueBytes);
137 FlowPath flowPath = kryo.readObject(input, FlowPath.class);
138 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700139 flowEventHandlerService.notificationRecvFlowRemoved(flowPath);
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700140 }
141
142 /**
143 * Receive a notification that an entry is updated.
144 *
145 * @param event the notification event for the entry.
146 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800147 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800148 public void entryUpdated(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800149 byte[] valueBytes = event.getValue();
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700150
151 //
152 // Decode the value and deliver the notification
153 //
154 Kryo kryo = kryoFactory.newKryo();
155 Input input = new Input(valueBytes);
156 FlowPath flowPath = kryo.readObject(input, FlowPath.class);
157 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700158 flowEventHandlerService.notificationRecvFlowUpdated(flowPath);
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700159 }
160
161 /**
162 * Receive a notification that an entry is evicted.
163 *
164 * @param event the notification event for the entry.
165 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800166 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800167 public void entryEvicted(EntryEvent<Long, byte[]> event) {
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700168 // NOTE: We don't use eviction for this map
169 }
170 }
171
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700172 /**
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700173 * Class for receiving notifications for FlowEntry state.
174 *
175 * The datagrid map is:
176 * - Key : FlowEntry ID (Long)
177 * - Value : Serialized FlowEntry (byte[])
178 */
179 class MapFlowEntryListener implements EntryListener<Long, byte[]> {
180 /**
181 * Receive a notification that an entry is added.
182 *
183 * @param event the notification event for the entry.
184 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800185 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800186 public void entryAdded(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800187 byte[] valueBytes = event.getValue();
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700188
189 //
190 // Decode the value and deliver the notification
191 //
192 Kryo kryo = kryoFactory.newKryo();
193 Input input = new Input(valueBytes);
194 FlowEntry flowEntry = kryo.readObject(input, FlowEntry.class);
195 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700196 flowEventHandlerService.notificationRecvFlowEntryAdded(flowEntry);
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700197 }
198
199 /**
200 * Receive a notification that an entry is removed.
201 *
202 * @param event the notification event for the entry.
203 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800204 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800205 public void entryRemoved(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800206 byte[] valueBytes = event.getValue();
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700207
208 //
209 // Decode the value and deliver the notification
210 //
211 Kryo kryo = kryoFactory.newKryo();
212 Input input = new Input(valueBytes);
213 FlowEntry flowEntry = kryo.readObject(input, FlowEntry.class);
214 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700215 flowEventHandlerService.notificationRecvFlowEntryRemoved(flowEntry);
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700216 }
217
218 /**
219 * Receive a notification that an entry is updated.
220 *
221 * @param event the notification event for the entry.
222 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800223 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800224 public void entryUpdated(EntryEvent<Long, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800225 byte[] valueBytes = event.getValue();
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700226
227 //
228 // Decode the value and deliver the notification
229 //
230 Kryo kryo = kryoFactory.newKryo();
231 Input input = new Input(valueBytes);
232 FlowEntry flowEntry = kryo.readObject(input, FlowEntry.class);
233 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700234 flowEventHandlerService.notificationRecvFlowEntryUpdated(flowEntry);
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700235 }
236
237 /**
238 * Receive a notification that an entry is evicted.
239 *
240 * @param event the notification event for the entry.
241 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800242 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800243 public void entryEvicted(EntryEvent<Long, byte[]> event) {
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700244 // NOTE: We don't use eviction for this map
245 }
246 }
247
248 /**
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700249 * Class for receiving notifications for Network Topology state.
250 *
251 * The datagrid map is:
252 * - Key: TopologyElement ID (String)
253 * - Value: Serialized TopologyElement (byte[])
254 */
255 class MapTopologyListener implements EntryListener<String, byte[]> {
256 /**
257 * Receive a notification that an entry is added.
258 *
259 * @param event the notification event for the entry.
260 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800261 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800262 public void entryAdded(EntryEvent<String, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800263 byte[] valueBytes = event.getValue();
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700264
265 //
266 // Decode the value and deliver the notification
267 //
268 Kryo kryo = kryoFactory.newKryo();
269 Input input = new Input(valueBytes);
270 TopologyElement topologyElement =
271 kryo.readObject(input, TopologyElement.class);
272 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700273 flowEventHandlerService.notificationRecvTopologyElementAdded(topologyElement);
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700274 }
275
276 /**
277 * Receive a notification that an entry is removed.
278 *
279 * @param event the notification event for the entry.
280 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800281 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800282 public void entryRemoved(EntryEvent<String, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800283 byte[] valueBytes = event.getValue();
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700284
285 //
286 // Decode the value and deliver the notification
287 //
288 Kryo kryo = kryoFactory.newKryo();
289 Input input = new Input(valueBytes);
290 TopologyElement topologyElement =
291 kryo.readObject(input, TopologyElement.class);
292 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700293 flowEventHandlerService.notificationRecvTopologyElementRemoved(topologyElement);
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700294 }
295
296 /**
297 * Receive a notification that an entry is updated.
298 *
299 * @param event the notification event for the entry.
300 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800301 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800302 public void entryUpdated(EntryEvent<String, byte[]> event) {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800303 byte[] valueBytes = event.getValue();
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700304
305 //
306 // Decode the value and deliver the notification
307 //
308 Kryo kryo = kryoFactory.newKryo();
309 Input input = new Input(valueBytes);
310 TopologyElement topologyElement =
311 kryo.readObject(input, TopologyElement.class);
312 kryoFactory.deleteKryo(kryo);
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700313 flowEventHandlerService.notificationRecvTopologyElementUpdated(topologyElement);
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700314 }
315
316 /**
317 * Receive a notification that an entry is evicted.
318 *
319 * @param event the notification event for the entry.
320 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800321 @Override
Pavlin Radoslavov95e6e902013-12-11 12:03:29 -0800322 public void entryEvicted(EntryEvent<String, byte[]> event) {
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700323 // NOTE: We don't use eviction for this map
324 }
325 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800326
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800327 /**
Jonathan Hart7804bea2014-01-07 10:50:52 -0800328 * Class for receiving notifications for sending packet-outs.
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800329 *
330 * The datagrid map is:
Jonathan Hart7804bea2014-01-07 10:50:52 -0800331 * - Key: Packet-out to send (PacketOutNotification)
332 * - Value: dummy value (we only need the key) (byte[])
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800333 */
Jonathan Hart7804bea2014-01-07 10:50:52 -0800334 class PacketOutMapListener implements EntryListener<PacketOutNotification, byte[]> {
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800335 /**
336 * Receive a notification that an entry is added.
337 *
338 * @param event the notification event for the entry.
339 */
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800340 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800341 public void entryAdded(EntryEvent<PacketOutNotification, byte[]> event) {
342 for (IPacketOutEventHandler packetOutEventHandler : packetOutEventHandlers) {
343 packetOutEventHandler.packetOutNotification(event.getKey());
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800344 }
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800345 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800346
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800347 /**
348 * Receive a notification that an entry is removed.
349 *
350 * @param event the notification event for the entry.
351 */
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800352 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800353 public void entryRemoved(EntryEvent<PacketOutNotification, byte[]> event) {
Jonathan Hart799242b2013-11-12 12:57:29 -0800354 // Not used
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800355 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800356
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800357 /**
358 * Receive a notification that an entry is updated.
359 *
360 * @param event the notification event for the entry.
361 */
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800362 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800363 public void entryUpdated(EntryEvent<PacketOutNotification, byte[]> event) {
Jonathan Hart799242b2013-11-12 12:57:29 -0800364 // Not used
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800365 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800366
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800367 /**
368 * Receive a notification that an entry is evicted.
369 *
370 * @param event the notification event for the entry.
371 */
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800372 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800373 public void entryEvicted(EntryEvent<PacketOutNotification, byte[]> event) {
Jonathan Hart799242b2013-11-12 12:57:29 -0800374 // Not used
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800375 }
376 }
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800377
Jonathan Hart7804bea2014-01-07 10:50:52 -0800378 /**
379 * Class for receiving notifications for sending packet-outs.
380 *
381 * The datagrid map is:
382 * - Key: Packet-out to send (PacketOutNotification)
383 * - Value: dummy value (we only need the key) (byte[])
384 */
385 class ArpReplyMapListener implements EntryListener<ArpReplyNotification, byte[]> {
386 /**
387 * Receive a notification that an entry is added.
388 *
389 * @param event the notification event for the entry.
390 */
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800391 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800392 public void entryAdded(EntryEvent<ArpReplyNotification, byte[]> event) {
393 for (IArpReplyEventHandler arpReplyEventHandler : arpReplyEventHandlers) {
394 arpReplyEventHandler.arpReplyEvent(event.getKey());
395 }
396 }
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800397
Jonathan Hart7804bea2014-01-07 10:50:52 -0800398 // These methods aren't used for ARP replies
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800399 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800400 public void entryRemoved(EntryEvent<ArpReplyNotification, byte[]> event) {}
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800401 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800402 public void entryUpdated(EntryEvent<ArpReplyNotification, byte[]> event) {}
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800403 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800404 public void entryEvicted(EntryEvent<ArpReplyNotification, byte[]> event) {}
405 }
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700406
407 /**
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700408 * Initialize the Hazelcast Datagrid operation.
409 *
410 * @param conf the configuration filename.
411 */
412 public void init(String configFilename) {
413 /*
414 System.setProperty("hazelcast.socket.receive.buffer.size", "32");
415 System.setProperty("hazelcast.socket.send.buffer.size", "32");
416 */
417 // System.setProperty("hazelcast.heartbeat.interval.seconds", "100");
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800418
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700419 // Init from configuration file
420 try {
421 hazelcastConfig = new FileSystemXmlConfig(configFilename);
422 } catch (FileNotFoundException e) {
423 log.error("Error opening Hazelcast XML configuration. File not found: " + configFilename, e);
424 }
425 /*
426 hazelcastConfig.setProperty(GroupProperties.PROP_IO_THREAD_COUNT, "1");
427 hazelcastConfig.setProperty(GroupProperties.PROP_OPERATION_THREAD_COUNT, "1");
428 hazelcastConfig.setProperty(GroupProperties.PROP_EVENT_THREAD_COUNT, "1");
429 */
430 //
431 hazelcastConfig.setProperty(GroupProperties.PROP_EVENT_QUEUE_CAPACITY, "4000000");
432 hazelcastConfig.setProperty(GroupProperties.PROP_SOCKET_RECEIVE_BUFFER_SIZE, "4096");
433 hazelcastConfig.setProperty(GroupProperties.PROP_SOCKET_SEND_BUFFER_SIZE, "4096");
434 }
435
436 /**
437 * Shutdown the Hazelcast Datagrid operation.
438 */
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800439 @Override
440 protected void finalize() {
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700441 close();
442 }
443
444 /**
445 * Shutdown the Hazelcast Datagrid operation.
446 */
447 public void close() {
448 Hazelcast.shutdownAll();
449 }
450
451 /**
452 * Get the collection of offered module services.
453 *
454 * @return the collection of offered module services.
455 */
456 @Override
457 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800458 Collection<Class<? extends IFloodlightService>> l =
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700459 new ArrayList<Class<? extends IFloodlightService>>();
460 l.add(IDatagridService.class);
461 return l;
462 }
463
464 /**
465 * Get the collection of implemented services.
466 *
467 * @return the collection of implemented services.
468 */
469 @Override
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800470 public Map<Class<? extends IFloodlightService>, IFloodlightService>
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700471 getServiceImpls() {
472 Map<Class<? extends IFloodlightService>,
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800473 IFloodlightService> m =
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700474 new HashMap<Class<? extends IFloodlightService>,
475 IFloodlightService>();
476 m.put(IDatagridService.class, this);
477 return m;
478 }
479
480 /**
481 * Get the collection of modules this module depends on.
482 *
483 * @return the collection of modules this module depends on.
484 */
485 @Override
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800486 public Collection<Class<? extends IFloodlightService>>
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700487 getModuleDependencies() {
488 Collection<Class<? extends IFloodlightService>> l =
489 new ArrayList<Class<? extends IFloodlightService>>();
490 l.add(IFloodlightProviderService.class);
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -0700491 l.add(IRestApiService.class);
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700492 return l;
493 }
494
495 /**
496 * Initialize the module.
497 *
498 * @param context the module context to use for the initialization.
499 */
500 @Override
501 public void init(FloodlightModuleContext context)
502 throws FloodlightModuleException {
503 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -0700504 restApi = context.getServiceImpl(IRestApiService.class);
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700505
506 // Get the configuration file name and configure the Datagrid
507 Map<String, String> configMap = context.getConfigParams(this);
508 String configFilename = configMap.get(HazelcastConfigFile);
509 this.init(configFilename);
510 }
511
512 /**
513 * Startup module operation.
514 *
515 * @param context the module context to use for the startup.
516 */
517 @Override
518 public void startUp(FloodlightModuleContext context) {
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700519 hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig);
Pavlin Radoslavovda7ef612013-10-30 16:12:14 -0700520
521 restApi.addRestletRoutable(new DatagridWebRoutable());
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800522
Jonathan Hart7804bea2014-01-07 10:50:52 -0800523 packetOutMap = hazelcastInstance.getMap(packetOutMapName);
524 packetOutMap.addEntryListener(new PacketOutMapListener(), true);
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800525
Jonathan Hart7804bea2014-01-07 10:50:52 -0800526 arpReplyMap = hazelcastInstance.getMap(arpReplyMapName);
527 arpReplyMap.addEntryListener(new ArpReplyMapListener(), true);
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700528 }
529
530 /**
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700531 * Register Flow Event Handler Service for receiving Flow-related
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700532 * notifications.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700533 *
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700534 * NOTE: Only a single Flow Event Handler Service can be registered.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700535 *
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700536 * @param flowEventHandlerService the Flow Event Handler Service to register.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700537 */
538 @Override
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700539 public void registerFlowEventHandlerService(IFlowEventHandlerService flowEventHandlerService) {
540 this.flowEventHandlerService = flowEventHandlerService;
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700541
542 // Initialize the Flow-related map state
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700543 mapFlowListener = new MapFlowListener();
544 mapFlow = hazelcastInstance.getMap(mapFlowName);
545 mapFlowListenerId = mapFlow.addEntryListener(mapFlowListener, true);
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700546
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700547 // Initialize the FlowEntry-related map state
548 mapFlowEntryListener = new MapFlowEntryListener();
549 mapFlowEntry = hazelcastInstance.getMap(mapFlowEntryName);
550 mapFlowEntryListenerId = mapFlowEntry.addEntryListener(mapFlowEntryListener, true);
551
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700552 // Initialize the Topology-related map state
553 mapTopologyListener = new MapTopologyListener();
554 mapTopology = hazelcastInstance.getMap(mapTopologyName);
555 mapTopologyListenerId = mapTopology.addEntryListener(mapTopologyListener, true);
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700556 }
557
558 /**
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700559 * De-register Flow Event Handler Service for receiving Flow-related
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700560 * notifications.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700561 *
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700562 * NOTE: Only a single Flow Event Handler Service can be registered.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700563 *
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700564 * @param flowEventHandlerService the Flow Event Handler Service to
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700565 * de-register.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700566 */
567 @Override
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700568 public void deregisterFlowEventHandlerService(IFlowEventHandlerService flowEventHandlerService) {
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700569 // Clear the Flow-related map state
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700570 mapFlow.removeEntryListener(mapFlowListenerId);
571 mapFlow = null;
572 mapFlowListener = null;
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700573
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700574 // Clear the FlowEntry-related map state
575 mapFlowEntry.removeEntryListener(mapFlowEntryListenerId);
576 mapFlowEntry = null;
577 mapFlowEntryListener = null;
578
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700579 // Clear the Topology-related map state
580 mapTopology.removeEntryListener(mapTopologyListenerId);
581 mapTopology = null;
582 mapTopologyListener = null;
583
Pavlin Radoslavov9a859022013-10-30 10:08:24 -0700584 this.flowEventHandlerService = null;
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700585 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800586
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800587 @Override
Jonathan Hartc6325622014-01-14 16:37:50 -0800588 public void registerPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
589 if (packetOutEventHandler != null) {
590 packetOutEventHandlers.add(packetOutEventHandler);
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800591 }
592 }
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800593
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800594 @Override
Jonathan Hartc6325622014-01-14 16:37:50 -0800595 public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
596 packetOutEventHandlers.remove(packetOutEventHandler);
Jonathan Hart7804bea2014-01-07 10:50:52 -0800597 }
Yuta HIGUCHI2d5ac522014-01-22 10:21:41 -0800598
Jonathan Hart7804bea2014-01-07 10:50:52 -0800599 @Override
600 public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
601 if (arpReplyEventHandler != null) {
602 arpReplyEventHandlers.add(arpReplyEventHandler);
603 }
604 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800605
Jonathan Hart7804bea2014-01-07 10:50:52 -0800606 @Override
607 public void deregisterArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
608 arpReplyEventHandlers.remove(arpReplyEventHandler);
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800609 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800610
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700611 /**
612 * Get all Flows that are currently in the datagrid.
613 *
614 * @return all Flows that are currently in the datagrid.
615 */
616 @Override
617 public Collection<FlowPath> getAllFlows() {
618 Collection<FlowPath> allFlows = new LinkedList<FlowPath>();
619
620 //
621 // Get all current entries
622 //
623 Collection<byte[]> values = mapFlow.values();
624 Kryo kryo = kryoFactory.newKryo();
625 for (byte[] valueBytes : values) {
626 //
627 // Decode the value
628 //
629 Input input = new Input(valueBytes);
630 FlowPath flowPath = kryo.readObject(input, FlowPath.class);
631 allFlows.add(flowPath);
632 }
633 kryoFactory.deleteKryo(kryo);
634
635 return allFlows;
636 }
637
638 /**
Pavlin Radoslavov379c9042013-11-26 15:40:49 -0800639 * Get a Flow for a given Flow ID.
640 *
641 * @param flowId the Flow ID of the Flow to get.
642 * @return the Flow if found, otherwise null.
643 */
644 @Override
645 public FlowPath getFlow(FlowId flowId) {
646 byte[] valueBytes = mapFlow.get(flowId.value());
647 if (valueBytes == null)
648 return null;
649
650 Kryo kryo = kryoFactory.newKryo();
651 //
652 // Decode the value
653 //
654 Input input = new Input(valueBytes);
655 FlowPath flowPath = kryo.readObject(input, FlowPath.class);
656 kryoFactory.deleteKryo(kryo);
657
658 return flowPath;
659 }
660
661 /**
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700662 * Send a notification that a Flow is added.
663 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700664 * @param flowPath the Flow that is added.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700665 */
666 @Override
667 public void notificationSendFlowAdded(FlowPath flowPath) {
668 //
669 // Encode the value
670 //
671 byte[] buffer = new byte[MAX_BUFFER_SIZE];
672 Kryo kryo = kryoFactory.newKryo();
673 Output output = new Output(buffer, -1);
674 kryo.writeObject(output, flowPath);
675 byte[] valueBytes = output.toBytes();
676 kryoFactory.deleteKryo(kryo);
677
678 //
679 // Put the entry:
680 // - Key : Flow ID (Long)
681 // - Value : Serialized Flow (byte[])
682 //
683 mapFlow.putAsync(flowPath.flowId().value(), valueBytes);
684 }
685
686 /**
687 * Send a notification that a Flow is removed.
688 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700689 * @param flowId the Flow ID of the Flow that is removed.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700690 */
691 @Override
692 public void notificationSendFlowRemoved(FlowId flowId) {
693 //
694 // Remove the entry:
695 // - Key : Flow ID (Long)
696 // - Value : Serialized Flow (byte[])
697 //
698 mapFlow.removeAsync(flowId.value());
699 }
700
701 /**
702 * Send a notification that a Flow is updated.
703 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700704 * @param flowPath the Flow that is updated.
Pavlin Radoslavov1308dc62013-10-25 15:54:31 -0700705 */
706 @Override
707 public void notificationSendFlowUpdated(FlowPath flowPath) {
708 // NOTE: Adding an entry with an existing key automatically updates it
709 notificationSendFlowAdded(flowPath);
710 }
711
712 /**
713 * Send a notification that all Flows are removed.
714 */
715 @Override
716 public void notificationSendAllFlowsRemoved() {
717 //
718 // Remove all entries
719 // NOTE: We remove the entries one-by-one so the per-entry
720 // notifications will be delivered.
721 //
722 // mapFlow.clear();
723 Set<Long> keySet = mapFlow.keySet();
724 for (Long key : keySet) {
725 mapFlow.removeAsync(key);
726 }
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700727 }
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700728
729 /**
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700730 * Get all Flow Entries that are currently in the datagrid.
731 *
732 * @return all Flow Entries that are currently in the datagrid.
733 */
734 @Override
735 public Collection<FlowEntry> getAllFlowEntries() {
736 Collection<FlowEntry> allFlowEntries = new LinkedList<FlowEntry>();
737
738 //
739 // Get all current entries
740 //
741 Collection<byte[]> values = mapFlowEntry.values();
742 Kryo kryo = kryoFactory.newKryo();
743 for (byte[] valueBytes : values) {
744 //
745 // Decode the value
746 //
747 Input input = new Input(valueBytes);
748 FlowEntry flowEntry = kryo.readObject(input, FlowEntry.class);
749 allFlowEntries.add(flowEntry);
750 }
751 kryoFactory.deleteKryo(kryo);
752
753 return allFlowEntries;
754 }
755
756 /**
Pavlin Radoslavov379c9042013-11-26 15:40:49 -0800757 * Get a Flow Entry for a given Flow Entry ID.
758 *
759 * @param flowEntryId the Flow Entry ID of the Flow Entry to get.
760 * @return the Flow Entry if found, otherwise null.
761 */
762 @Override
763 public FlowEntry getFlowEntry(FlowEntryId flowEntryId) {
764 byte[] valueBytes = mapFlowEntry.get(flowEntryId.value());
765 if (valueBytes == null)
766 return null;
767
768 Kryo kryo = kryoFactory.newKryo();
769 //
770 // Decode the value
771 //
772 Input input = new Input(valueBytes);
773 FlowEntry flowEntry = kryo.readObject(input, FlowEntry.class);
774 kryoFactory.deleteKryo(kryo);
775
776 return flowEntry;
777 }
778
779 /**
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700780 * Send a notification that a FlowEntry is added.
781 *
782 * @param flowEntry the FlowEntry that is added.
783 */
784 @Override
785 public void notificationSendFlowEntryAdded(FlowEntry flowEntry) {
786 //
787 // Encode the value
788 //
789 byte[] buffer = new byte[MAX_BUFFER_SIZE];
790 Kryo kryo = kryoFactory.newKryo();
791 Output output = new Output(buffer, -1);
792 kryo.writeObject(output, flowEntry);
793 byte[] valueBytes = output.toBytes();
794 kryoFactory.deleteKryo(kryo);
795
796 //
797 // Put the entry:
798 // - Key : FlowEntry ID (Long)
799 // - Value : Serialized FlowEntry (byte[])
800 //
801 mapFlowEntry.putAsync(flowEntry.flowEntryId().value(), valueBytes);
802 }
803
804 /**
805 * Send a notification that a FlowEntry is removed.
806 *
807 * @param flowEntryId the FlowEntry ID of the FlowEntry that is removed.
808 */
809 @Override
810 public void notificationSendFlowEntryRemoved(FlowEntryId flowEntryId) {
811 //
812 // Remove the entry:
813 // - Key : FlowEntry ID (Long)
814 // - Value : Serialized FlowEntry (byte[])
815 //
816 mapFlowEntry.removeAsync(flowEntryId.value());
817 }
818
819 /**
820 * Send a notification that a FlowEntry is updated.
821 *
822 * @param flowEntry the FlowEntry that is updated.
823 */
824 @Override
825 public void notificationSendFlowEntryUpdated(FlowEntry flowEntry) {
826 // NOTE: Adding an entry with an existing key automatically updates it
827 notificationSendFlowEntryAdded(flowEntry);
828 }
829
830 /**
831 * Send a notification that all Flow Entries are removed.
832 */
833 @Override
834 public void notificationSendAllFlowEntriesRemoved() {
835 //
836 // Remove all entries
837 // NOTE: We remove the entries one-by-one so the per-entry
838 // notifications will be delivered.
839 //
840 // mapFlowEntry.clear();
841 Set<Long> keySet = mapFlowEntry.keySet();
842 for (Long key : keySet) {
843 mapFlowEntry.removeAsync(key);
844 }
845 }
846
847 /**
Pavlin Radoslavovaaace7f2013-10-25 19:42:00 -0700848 * Get all Topology Elements that are currently in the datagrid.
849 *
850 * @return all Topology Elements that are currently in the datagrid.
851 */
852 @Override
853 public Collection<TopologyElement> getAllTopologyElements() {
854 Collection<TopologyElement> allTopologyElements =
855 new LinkedList<TopologyElement>();
856
857 //
858 // Get all current entries
859 //
860 Collection<byte[]> values = mapTopology.values();
861 Kryo kryo = kryoFactory.newKryo();
862 for (byte[] valueBytes : values) {
863 //
864 // Decode the value
865 //
866 Input input = new Input(valueBytes);
867 TopologyElement topologyElement =
868 kryo.readObject(input, TopologyElement.class);
869 allTopologyElements.add(topologyElement);
870 }
871 kryoFactory.deleteKryo(kryo);
872
873 return allTopologyElements;
874 }
875
876 /**
877 * Send a notification that a Topology Element is added.
878 *
879 * @param topologyElement the Topology Element that is added.
880 */
881 @Override
882 public void notificationSendTopologyElementAdded(TopologyElement topologyElement) {
883 //
884 // Encode the value
885 //
886 byte[] buffer = new byte[MAX_BUFFER_SIZE];
887 Kryo kryo = kryoFactory.newKryo();
888 Output output = new Output(buffer, -1);
889 kryo.writeObject(output, topologyElement);
890 byte[] valueBytes = output.toBytes();
891 kryoFactory.deleteKryo(kryo);
892
893 //
894 // Put the entry:
895 // - Key : TopologyElement ID (String)
896 // - Value : Serialized TopologyElement (byte[])
897 //
898 mapTopology.putAsync(topologyElement.elementId(), valueBytes);
899 }
900
901 /**
902 * Send a notification that a Topology Element is removed.
903 *
904 * @param topologyElement the Topology Element that is removed.
905 */
906 @Override
907 public void notificationSendTopologyElementRemoved(TopologyElement topologyElement) {
908 //
909 // Remove the entry:
910 // - Key : TopologyElement ID (String)
911 // - Value : Serialized TopologyElement (byte[])
912 //
913 mapTopology.removeAsync(topologyElement.elementId());
914 }
915
916 /**
917 * Send a notification that a Topology Element is updated.
918 *
919 * @param topologyElement the Topology Element that is updated.
920 */
921 @Override
922 public void notificationSendTopologyElementUpdated(TopologyElement topologyElement) {
923 // NOTE: Adding an entry with an existing key automatically updates it
924 notificationSendTopologyElementAdded(topologyElement);
925 }
926
927 /**
928 * Send a notification that all Topology Elements are removed.
929 */
930 @Override
931 public void notificationSendAllTopologyElementsRemoved() {
932 //
933 // Remove all entries
934 // NOTE: We remove the entries one-by-one so the per-entry
935 // notifications will be delivered.
936 //
937 // mapTopology.clear();
938 Set<String> keySet = mapTopology.keySet();
939 for (String key : keySet) {
940 mapTopology.removeAsync(key);
941 }
942 }
Yuta HIGUCHI67a7a3e2014-01-03 14:51:34 -0800943
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800944 @Override
Jonathan Hart7804bea2014-01-07 10:50:52 -0800945 public void sendPacketOutNotification(PacketOutNotification packetOutNotification) {
946 packetOutMap.putAsync(packetOutNotification, dummyByte, 1L, TimeUnit.MILLISECONDS);
Jonathan Hart18ad55c2013-11-11 22:49:55 -0800947 }
Jonathan Hart7804bea2014-01-07 10:50:52 -0800948
949 @Override
950 public void sendArpReplyNotification(ArpReplyNotification arpReply) {
951 arpReplyMap.putAsync(arpReply, dummyByte, 1L, TimeUnit.MILLISECONDS);
952 }
Pavlin Radoslavov1eee2c82013-10-15 02:30:32 -0700953}