Open Kilda Java Documentation
MockFloodlightProvider.java
Go to the documentation of this file.
1 /* Copyright 2017 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
32 package org.openkilda.floodlight;
33 
34 import static org.junit.Assert.fail;
35 
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Map.Entry;
44 import java.util.concurrent.ConcurrentHashMap;
45 import java.util.concurrent.ConcurrentLinkedQueue;
46 import java.util.concurrent.ConcurrentMap;
47 import java.util.concurrent.ExecutorService;
48 import java.util.concurrent.Executors;
49 import java.util.concurrent.Future;
50 import java.util.concurrent.TimeUnit;
51 
52 import net.floodlightcontroller.core.FloodlightContext;
53 import net.floodlightcontroller.core.HAListenerTypeMarker;
54 import net.floodlightcontroller.core.HARole;
55 import net.floodlightcontroller.core.IControllerCompletionListener;
56 import net.floodlightcontroller.core.IFloodlightProviderService;
57 import net.floodlightcontroller.core.IHAListener;
58 import net.floodlightcontroller.core.IInfoProvider;
59 import net.floodlightcontroller.core.IListener.Command;
60 import net.floodlightcontroller.core.IOFMessageListener;
61 import net.floodlightcontroller.core.IOFSwitch;
62 import net.floodlightcontroller.core.RoleInfo;
63 import net.floodlightcontroller.core.internal.Controller.IUpdate;
64 import net.floodlightcontroller.core.internal.Controller.ModuleLoaderState;
65 import net.floodlightcontroller.core.internal.RoleManager;
66 import net.floodlightcontroller.core.module.FloodlightModuleContext;
67 import net.floodlightcontroller.core.module.FloodlightModuleException;
68 import net.floodlightcontroller.core.module.IFloodlightModule;
69 import net.floodlightcontroller.core.module.IFloodlightService;
70 import net.floodlightcontroller.core.util.ListenerDispatcher;
71 
72 import org.projectfloodlight.openflow.protocol.OFMessage;
73 import org.projectfloodlight.openflow.protocol.OFPacketIn;
74 import org.projectfloodlight.openflow.protocol.OFType;
75 
76 import net.floodlightcontroller.packet.Ethernet;
77 
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
80 
85 public class MockFloodlightProvider implements IFloodlightModule, IFloodlightProviderService {
86  private final static Logger log = LoggerFactory.getLogger(MockFloodlightProvider.class);
87  protected ConcurrentMap<OFType, ListenerDispatcher<OFType,IOFMessageListener>> listeners;
88  protected ListenerDispatcher<HAListenerTypeMarker, IHAListener> haListeners;
89  private HARole role;
90  private final boolean useAsyncUpdates;
91  private volatile ExecutorService executorService;
92  private volatile Future<?> mostRecentUpdateFuture;
93  // paag
94  private ConcurrentLinkedQueue<IControllerCompletionListener> completionListeners;
95 
99  public MockFloodlightProvider(boolean useAsyncUpdates) {
100  listeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType,
101  IOFMessageListener>>();
102  haListeners =
103  new ListenerDispatcher<HAListenerTypeMarker, IHAListener>();
104  completionListeners =
105  new ConcurrentLinkedQueue<IControllerCompletionListener>();
106  role = null;
107  this.useAsyncUpdates = useAsyncUpdates;
108  }
109 
111  this(false);
112  }
113 
114  @Override
115  public synchronized void addOFMessageListener(OFType type,
116  IOFMessageListener listener) {
117  ListenerDispatcher<OFType, IOFMessageListener> ldd =
118  listeners.get(type);
119  if (ldd == null) {
120  ldd = new ListenerDispatcher<OFType, IOFMessageListener>();
121  listeners.put(type, ldd);
122  }
123  ldd.addListener(type, listener);
124  }
125 
126  @Override
127  public synchronized void removeOFMessageListener(OFType type,
128  IOFMessageListener listener) {
129  ListenerDispatcher<OFType, IOFMessageListener> ldd =
130  listeners.get(type);
131  if (ldd != null) {
132  ldd.removeListener(listener);
133  }
134  }
135 
139  @Override
140  public Map<OFType, List<IOFMessageListener>> getListeners() {
141  Map<OFType, List<IOFMessageListener>> lers =
142  new HashMap<OFType, List<IOFMessageListener>>();
143  for(Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e :
144  listeners.entrySet()) {
145  lers.put(e.getKey(), e.getValue().getOrderedListeners());
146  }
147  return Collections.unmodifiableMap(lers);
148  }
149 
150  public void clearListeners() {
151  this.listeners.clear();
152  }
153 
154  public void dispatchMessage(IOFSwitch sw, OFMessage msg) {
155  dispatchMessage(sw, msg, new FloodlightContext());
156  }
157 
158  public void dispatchMessage(IOFSwitch sw, OFMessage msg, FloodlightContext bc) {
159  List<IOFMessageListener> theListeners = listeners.get(msg.getType()).getOrderedListeners();
160  if (theListeners != null) {
161  Command result = Command.CONTINUE;
162  Iterator<IOFMessageListener> it = theListeners.iterator();
163  if (OFType.PACKET_IN.equals(msg.getType())) {
164  OFPacketIn pi = (OFPacketIn)msg;
165  Ethernet eth = new Ethernet();
166  eth.deserialize(pi.getData(), 0, pi.getData().length);
167  IFloodlightProviderService.bcStore.put(bc,
168  IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
169  eth);
170  }
171  while (it.hasNext() && !Command.STOP.equals(result)) {
172  result = it.next().receive(sw, msg, bc);
173  }
174  }
175  // paag
176  for (IControllerCompletionListener listener:completionListeners)
177  listener.onMessageConsumed(sw, msg, bc);
178  }
179 
180  @Override
181  public void handleOutgoingMessage(IOFSwitch sw, OFMessage m) {
182  FloodlightContext bc = new FloodlightContext();
183  List<IOFMessageListener> msgListeners = null;
184  if (listeners.containsKey(m.getType())) {
185  msgListeners = listeners.get(m.getType()).getOrderedListeners();
186  }
187 
188  if (msgListeners != null) {
189  for (IOFMessageListener listener : msgListeners) {
190  if (Command.STOP.equals(listener.receive(sw, m, bc))) {
191  break;
192  }
193  }
194  }
195  }
196 
197  public void handleOutgoingMessages(IOFSwitch sw, List<OFMessage> msglist, FloodlightContext bc) {
198  for (OFMessage m:msglist) {
199  handleOutgoingMessage(sw, m);
200  }
201  }
202 
203  @Override
204  public void run() {
205  logListeners();
206  if (useAsyncUpdates)
207  executorService = Executors.newSingleThreadExecutor();
208  }
209 
210  public void shutdown() {
211  if (executorService != null) {
212  executorService.shutdownNow();
213  executorService = null;
214  mostRecentUpdateFuture = null;
215  }
216  }
217 
218  @Override
219  public Collection<Class<? extends IFloodlightService>> getModuleServices() {
220  Collection<Class<? extends IFloodlightService>> services =
221  new ArrayList<Class<? extends IFloodlightService>>(1);
222  services.add(IFloodlightProviderService.class);
223  return services;
224  }
225 
226  @Override
227  public Map<Class<? extends IFloodlightService>, IFloodlightService>
229  Map<Class<? extends IFloodlightService>,
230  IFloodlightService> m =
231  new HashMap<Class<? extends IFloodlightService>,
232  IFloodlightService>();
233  m.put(IFloodlightProviderService.class, this);
234  return m;
235  }
236 
237  @Override
238  public Collection<Class<? extends IFloodlightService>>
240  return null;
241  }
242 
243  @Override
244  public void init(FloodlightModuleContext context) throws FloodlightModuleException {
245  // do nothing.
246  }
247 
248  @Override
249  public void startUp(FloodlightModuleContext context) {
250  // do nothing.
251  }
252 
253  @Override
254  public void addInfoProvider(String type, IInfoProvider provider) {
255  // do nothing.
256  }
257 
258  @Override
259  public void removeInfoProvider(String type, IInfoProvider provider) {
260  // do nothing.
261  }
262 
263  @Override
264  public Map<String, Object> getControllerInfo(String type) {
265  // mock up something
266  Map<String, Object> summary = new HashMap<String, Object>();
267  summary.put("test-summary-1", 2);
268  summary.put("test-summary-2", 5);
269  return summary;
270  }
271 
272  @Override
273  public void addUpdateToQueue(final IUpdate update) {
274  if (useAsyncUpdates) {
275  mostRecentUpdateFuture = executorService.submit(new Runnable() {
276  @Override
277  public void run() {
278  update.dispatch();
279  }
280  });
281  } else {
282  update.dispatch();
283  }
284  }
285 
286  public void waitForUpdates(long timeout, TimeUnit unit) throws InterruptedException {
287 
288  long timeoutNanos = unit.toNanos(timeout);
289  long start = System.nanoTime();
290  for (;;) {
291  Future<?> future = mostRecentUpdateFuture;
292  if ((future == null) || future.isDone())
293  break;
294  Thread.sleep(100);
295  long now = System.nanoTime();
296  if (now > start + timeoutNanos) {
297  fail("Timeout waiting for update tasks to complete");
298  }
299  }
300  }
301 
302  @Override
303  public void addHAListener(IHAListener listener) {
304  haListeners.addListener(null,listener);
305  }
306 
307  @Override
308  public void removeHAListener(IHAListener listener) {
309  haListeners.removeListener(listener);
310  }
311 
312  @Override
313  public HARole getRole() {
314  /* DISABLE THIS CHECK FOR NOW. OTHER UNIT TESTS NEED TO BE UPDATED
315  * FIRST
316  if (this.role == null)
317  throw new IllegalStateException("You need to call setRole on "
318  + "MockFloodlightProvider before calling startUp on "
319  + "other modules");
320  */
321  return this.role;
322  }
323 
324  @Override
325  public void setRole(HARole role, String roleChangeDescription) {
326  this.role = role;
327  }
328 
334  public void transitionToActive() {
335  IUpdate update = new IUpdate() {
336  @Override
337  public void dispatch() {
338  for (IHAListener rl : haListeners.getOrderedListeners()) {
339  rl.transitionToActive();
340  }
341  }
342  };
343  addUpdateToQueue(update);
344  }
345 
346  @Override
347  public Map<String, String> getControllerNodeIPs() {
348  return null;
349  }
350 
351  @Override
352  public long getSystemStartTime() {
353  return 0;
354  }
355 
356  private void logListeners() {
357  for (Map.Entry<OFType,
358  ListenerDispatcher<OFType,
359  IOFMessageListener>> entry
360  : listeners.entrySet()) {
361 
362  OFType type = entry.getKey();
363  ListenerDispatcher<OFType, IOFMessageListener> ldd =
364  entry.getValue();
365 
366  StringBuffer sb = new StringBuffer();
367  sb.append("OFListeners for ");
368  sb.append(type);
369  sb.append(": ");
370  for (IOFMessageListener l : ldd.getOrderedListeners()) {
371  sb.append(l.getName());
372  sb.append(",");
373  }
374  log.debug(sb.toString());
375  }
376  }
377 
378  @Override
379  public RoleInfo getRoleInfo() {
380  // TODO Auto-generated method stub
381  return null;
382  }
383 
384  @Override
385  public Map<String, Long> getMemory() {
386  Map<String, Long> m = new HashMap<String, Long>();
387  m.put("total", 1000000000L);
388  m.put("free", 20000000L);
389  return m;
390  }
391 
392  @Override
393  public Long getUptime() {
394  return 1000000L;
395  }
396 
397  @Override
398  public void handleMessage(IOFSwitch sw, OFMessage m,
399  FloodlightContext bContext) {
400  // do nothing
401  }
402 
403  @Override
404  public RoleManager getRoleManager() {
405  return null;
406  }
407 
408  @Override
409  public ModuleLoaderState getModuleLoaderState() {
410  return null;
411  }
412 
413  @Override
414  public String getControllerId() {
415  return null;
416  }
417 
418  // paag
419  @Override
420  public void addCompletionListener(IControllerCompletionListener listener) {
421  completionListeners.add(listener);
422  }
423 
424  // paag
425  @Override
426  public void removeCompletionListener(IControllerCompletionListener listener) {
427  completionListeners.remove(listener);
428  }
429 }
synchronized void removeOFMessageListener(OFType type, IOFMessageListener listener)
void handleMessage(IOFSwitch sw, OFMessage m, FloodlightContext bContext)
Map< String, Object > getControllerInfo(String type)
Collection< Class<? extends IFloodlightService > > getModuleDependencies()
void dispatchMessage(IOFSwitch sw, OFMessage msg, FloodlightContext bc)
void removeCompletionListener(IControllerCompletionListener listener)
void removeInfoProvider(String type, IInfoProvider provider)
ListenerDispatcher< HAListenerTypeMarker, IHAListener > haListeners
Collection< Class<? extends IFloodlightService > > getModuleServices()
synchronized void addOFMessageListener(OFType type, IOFMessageListener listener)
ConcurrentMap< OFType, ListenerDispatcher< OFType, IOFMessageListener > > listeners
list result
Definition: plan-d.py:72
void handleOutgoingMessages(IOFSwitch sw, List< OFMessage > msglist, FloodlightContext bc)
void addInfoProvider(String type, IInfoProvider provider)
Map< Class<? extends IFloodlightService >, IFloodlightService > getServiceImpls()
void addCompletionListener(IControllerCompletionListener listener)
Map< OFType, List< IOFMessageListener > > getListeners()
net
Definition: plan-b.py:46
void setRole(HARole role, String roleChangeDescription)