package net.floodlightcontroller.core.internal;
import java.util.concurrent.TimeUnit;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.internal.OFSwitchHandshakeHandler.WaitAppHandshakeState;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
/**
* This class is a plugin that can be used by applications to tap into the
* switch handshake. It operates much like the switch handshake. Messages should
* be sent upon entering the plugin and OF response messages should be handled
* just like any part of the switch handshake.
*
* @author Jason Parraga <jason.parraga@bigswitch.com>
*/
public abstract class OFSwitchAppHandshakePlugin {
private static final Logger log = LoggerFactory.getLogger(OFSwitchAppHandshakePlugin.class);
private WaitAppHandshakeState state;
@edu.umd.cs.findbugs.annotations.SuppressWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
private IOFSwitch sw;
private volatile Timeout timeout;
private final PluginResult defaultResult;
private final int timeoutS;
/**
* Constructor for OFSwitchAppHandshakePlugin
* @param defaultResult the default result in the event of a timeout
* @param defaultTimeoutS the timeout length in seconds
*/
protected OFSwitchAppHandshakePlugin(PluginResult defaultResult, int timeoutS){
Preconditions.checkNotNull(defaultResult, "defaultResult");
Preconditions.checkNotNull(timeoutS, "timeoutS");
this.defaultResult = defaultResult;
this.timeoutS = timeoutS;
}
/**
* Process incoming OF Messages
*
* @param m The OF Message received
*/
protected abstract void processOFMessage(OFMessage m);
/**
* Enter this plugin. Should be used to send messages.
*/
protected abstract void enterPlugin();
/**
* Gets the switch associated with the handshake for use by the plugin
* writer.
*
* @return the switch associated with the handshake.
*/
protected IOFSwitch getSwitch() {
return this.sw;
}
/**
* Initialization for plugin called by the OFSwitchHandshakeHandler
*
* @param state the current state of the OFSwitchHandshakeHandler
* @param sw the current switch of the OFSwitchHandshakeHandler
*/
final void init(WaitAppHandshakeState state, IOFSwitch sw, Timer timer) {
this.state = state;
this.sw = sw;
this.timeout = timer.newTimeout(new PluginTimeoutTask(), timeoutS, TimeUnit.SECONDS);
}
/**
* Called to denote that the plugin has finished
*
* @param result
* the result of the plugin in regards to handshaking
*/
protected final void exitPlugin(PluginResult result) {
timeout.cancel();
state.exitPlugin(result);
}
/**
* Plugin timeout task that will exit the plugin
* with the default result value when timed out.
*
*/
private final class PluginTimeoutTask implements TimerTask {
@Override
public void run(Timeout timeout) throws Exception {
if (!timeout.isCancelled()) {
log.warn("App handshake plugin for {} timed out. Returning result {}.",
sw, defaultResult);
exitPlugin(defaultResult);
}
}
}
public enum PluginResultType {
CONTINUE(),
DISCONNECT(),
QUARANTINE();
}
}