/*
* Copyright (c) 2011,2013 Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.sdnplatform.core.test;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFType;
import org.openflow.protocol.factory.BasicFactory;
import org.sdnplatform.core.ListenerContext;
import org.sdnplatform.core.IControllerService;
import org.sdnplatform.core.IHAListener;
import org.sdnplatform.core.IInfoProvider;
import org.sdnplatform.core.IOFMessageListener;
import org.sdnplatform.core.IOFSwitch;
import org.sdnplatform.core.IOFSwitchDriver;
import org.sdnplatform.core.IOFSwitchFilter;
import org.sdnplatform.core.IOFSwitchListener;
import org.sdnplatform.core.RoleInfo;
import org.sdnplatform.core.IListener.Command;
import org.sdnplatform.core.module.ModuleContext;
import org.sdnplatform.core.module.ModuleException;
import org.sdnplatform.core.module.IModule;
import org.sdnplatform.core.module.IPlatformService;
import org.sdnplatform.core.util.ListenerDispatcher;
import org.sdnplatform.packet.Ethernet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public class MockControllerProvider implements IModule, IControllerService {
protected static Logger log = LoggerFactory.getLogger(MockControllerProvider.class);
protected ConcurrentMap<OFType, ListenerDispatcher<OFType,IOFMessageListener>> listeners;
protected List<IOFSwitchListener> switchListeners;
protected List<IHAListener> haListeners;
protected Map<Long, IOFSwitch> switches;
protected BasicFactory factory;
/**
*
*/
public MockControllerProvider() {
listeners = new ConcurrentHashMap<OFType, ListenerDispatcher<OFType,
IOFMessageListener>>();
switches = new ConcurrentHashMap<Long, IOFSwitch>();
switchListeners = new CopyOnWriteArrayList<IOFSwitchListener>();
haListeners = new CopyOnWriteArrayList<IHAListener>();
factory = new BasicFactory();
}
@Override
public synchronized void addOFMessageListener(OFType type,
IOFMessageListener listener) {
ListenerDispatcher<OFType, IOFMessageListener> ldd =
listeners.get(type);
if (ldd == null) {
ldd = new ListenerDispatcher<OFType, IOFMessageListener>();
listeners.put(type, ldd);
}
ldd.addListener(type, listener);
}
@Override
public synchronized void removeOFMessageListener(OFType type,
IOFMessageListener listener) {
ListenerDispatcher<OFType, IOFMessageListener> ldd =
listeners.get(type);
if (ldd != null) {
ldd.removeListener(listener);
}
}
/**
* @return the listeners
*/
@Override
public Map<OFType, List<IOFMessageListener>> getListeners() {
Map<OFType, List<IOFMessageListener>> lers =
new HashMap<OFType, List<IOFMessageListener>>();
for(Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e :
listeners.entrySet()) {
lers.put(e.getKey(), e.getValue().getOrderedListeners());
}
return Collections.unmodifiableMap(lers);
}
public void clearListeners() {
this.listeners.clear();
}
@Override
public Map<Long, IOFSwitch> getSwitches() {
return this.switches;
}
public void setSwitches(Map<Long, IOFSwitch> switches) {
this.switches = switches;
}
@Override
public void addOFSwitchListener(IOFSwitchListener listener) {
switchListeners.add(listener);
}
@Override
public void removeOFSwitchListener(IOFSwitchListener listener) {
switchListeners.remove(listener);
}
public void dispatchMessage(IOFSwitch sw, OFMessage msg) {
dispatchMessage(sw, msg, new ListenerContext());
}
public void dispatchMessage(IOFSwitch sw, OFMessage msg, ListenerContext bc) {
List<IOFMessageListener> theListeners = listeners.get(msg.getType()).getOrderedListeners();
if (theListeners != null) {
Command result = Command.CONTINUE;
Iterator<IOFMessageListener> it = theListeners.iterator();
if (OFType.PACKET_IN.equals(msg.getType())) {
OFPacketIn pi = (OFPacketIn)msg;
Ethernet eth = new Ethernet();
eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
IControllerService.bcStore.put(bc,
IControllerService.CONTEXT_PI_PAYLOAD,
eth);
}
while (it.hasNext() && !Command.STOP.equals(result)) {
result = it.next().receive(sw, msg, bc);
}
}
}
@Override
public void handleOutgoingMessage(IOFSwitch sw, OFMessage m, ListenerContext bc) {
List<IOFMessageListener> msgListeners = null;
if (listeners.containsKey(m.getType())) {
msgListeners = listeners.get(m.getType()).getOrderedListeners();
}
if (msgListeners != null) {
for (IOFMessageListener listener : msgListeners) {
if (listener instanceof IOFSwitchFilter) {
if (!((IOFSwitchFilter)listener).isInterested(sw)) {
continue;
}
}
if (Command.STOP.equals(listener.receive(sw, m, bc))) {
break;
}
}
}
}
public void handleOutgoingMessages(IOFSwitch sw, List<OFMessage> msglist, ListenerContext bc) {
for (OFMessage m:msglist) {
handleOutgoingMessage(sw, m, bc);
}
}
/**
* @return the switchListeners
*/
public List<IOFSwitchListener> getSwitchListeners() {
return switchListeners;
}
@Override
public void terminate() {
}
@Override
public boolean injectOfMessage(IOFSwitch sw, OFMessage msg) {
dispatchMessage(sw, msg);
return true;
}
@Override
public boolean injectOfMessage(IOFSwitch sw, OFMessage msg,
ListenerContext bContext) {
dispatchMessage(sw, msg, bContext);
return true;
}
@Override
public BasicFactory getOFMessageFactory() {
return factory;
}
@Override
public void run() {
logListeners();
}
@Override
public Collection<Class<? extends IPlatformService>> getModuleServices() {
Collection<Class<? extends IPlatformService>> services =
new ArrayList<Class<? extends IPlatformService>>(1);
services.add(IControllerService.class);
return services;
}
@Override
public Map<Class<? extends IPlatformService>, IPlatformService>
getServiceImpls() {
Map<Class<? extends IPlatformService>,
IPlatformService> m =
new HashMap<Class<? extends IPlatformService>,
IPlatformService>();
m.put(IControllerService.class, this);
return m;
}
@Override
public Collection<Class<? extends IPlatformService>>
getModuleDependencies() {
return null;
}
@Override
public void init(ModuleContext context)
throws ModuleException {
// TODO Auto-generated method stub
}
@Override
public void startUp(ModuleContext context) {
// TODO Auto-generated method stub
}
@Override
public void addInfoProvider(String type, IInfoProvider provider) {
// TODO Auto-generated method stub
}
@Override
public void removeInfoProvider(String type, IInfoProvider provider) {
// TODO Auto-generated method stub
}
@Override
public Map<String, Object> getControllerInfo(String type) {
// TODO Auto-generated method stub
return null;
}
@Override
public void addHAListener(IHAListener listener) {
haListeners.add(listener);
}
@Override
public void removeHAListener(IHAListener listener) {
haListeners.remove(listener);
}
@Override
public Role getRole() {
return null;
}
@Override
public void setRole(Role role, String roleChangeDescription) {
}
/**
* Dispatches a new role change notification
* @param oldRole
* @param newRole
*/
public void dispatchRoleChanged(Role oldRole, Role newRole) {
for (IHAListener rl : haListeners) {
rl.roleChanged(oldRole, newRole);
}
}
@Override
public Map<String, String> getControllerNodeIPs() {
// TODO Auto-generated method stub
return null;
}
@Override
public long getSystemStartTime() {
// TODO Auto-generated method stub
return 0;
}
private void logListeners() {
for (Map.Entry<OFType,
ListenerDispatcher<OFType,
IOFMessageListener>> entry
: listeners.entrySet()) {
OFType type = entry.getKey();
ListenerDispatcher<OFType, IOFMessageListener> ldd =
entry.getValue();
StringBuffer sb = new StringBuffer();
sb.append("OFListeners for ");
sb.append(type);
sb.append(": ");
for (IOFMessageListener l : ldd.getOrderedListeners()) {
sb.append(l.getName());
sb.append(",");
}
log.debug(sb.toString());
}
}
@Override
public void setAlwaysClearFlowsOnSwAdd(boolean value) {
// TODO Auto-generated method stub
}
@Override
public void addOFSwitchDriver(String desc, IOFSwitchDriver driver) {
// TODO Auto-generated method stub
}
@Override
public RoleInfo getRoleInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public Map<String, Long> getMemory() {
Map<String, Long> m = new HashMap<String, Long>();
Runtime runtime = Runtime.getRuntime();
m.put("total", runtime.totalMemory());
m.put("free", runtime.freeMemory());
return m;
}
@Override
public Long getUptime() {
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
return rb.getUptime();
}
}