blob: d4950d29abef81efa322bb7f1ae0c2b89f6ba567 [file] [log] [blame]
package net.onrc.onos.ofcontroller.flowmanager;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import net.onrc.onos.datagrid.IDatagridService;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.ofcontroller.util.EventEntry;
import net.onrc.onos.ofcontroller.util.FlowPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class for implementing the Path Computation and Path Maintenance.
*/
class PathComputation extends Thread implements IPathComputationService {
/** The logger. */
private final static Logger log = LoggerFactory.getLogger(PathComputation.class);
private FlowManager flowManager; // The Flow Manager to use
private IDatagridService datagridService; // The Datagrid Service to use
// The queue with Flow Path and Topology Element updates
private BlockingQueue<EventEntry<?>> networkEvents =
new LinkedBlockingQueue<EventEntry<?>>();
// The pending Topology and Flow Path events
private List<EventEntry<TopologyElement>> topologyEvents =
new LinkedList<EventEntry<TopologyElement>>();
private List<EventEntry<FlowPath>> flowPathEvents =
new LinkedList<EventEntry<FlowPath>>();
/**
* Constructor for a given Flow Manager and Datagrid Service.
*
* @param flowManager the Flow Manager to use.
* @param datagridService the Datagrid Service to use.
*/
PathComputation(FlowManager flowManager,
IDatagridService datagridService) {
this.flowManager = flowManager;
this.datagridService = datagridService;
}
/**
* Run the thread.
*/
@Override
public void run() {
//
// Obtain the initial Topology state
//
Collection<TopologyElement> topologyElements =
datagridService.getAllTopologyElements();
for (TopologyElement topologyElement : topologyElements) {
EventEntry<TopologyElement> eventEntry =
new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
topologyEvents.add(eventEntry);
}
//
// Obtain the initial Flow Path state
//
Collection<FlowPath> flowPaths = datagridService.getAllFlows();
for (FlowPath flowPath : flowPaths) {
EventEntry<FlowPath> eventEntry =
new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
flowPathEvents.add(eventEntry);
}
// Process the events (if any)
processEvents();
//
// The main loop
//
Collection<EventEntry<?>> collection = new LinkedList<EventEntry<?>>();
try {
while (true) {
EventEntry<?> eventEntry = networkEvents.take();
collection.add(eventEntry);
networkEvents.drainTo(collection);
// Demultiplex all events
for (EventEntry<?> event : collection) {
if (event.eventData() instanceof TopologyElement) {
EventEntry<TopologyElement> topologyEventEntry =
(EventEntry<TopologyElement>)event;
topologyEvents.add(topologyEventEntry);
} else if (event.eventData() instanceof FlowPath) {
EventEntry<FlowPath> flowPathEventEntry =
(EventEntry<FlowPath>)event;
flowPathEvents.add(flowPathEventEntry);
}
}
collection.clear();
// Process the events (if any)
processEvents();
}
} catch (Exception exception) {
log.debug("Exception processing Network Events: ", exception);
}
}
/**
* Process the events (if any)
*/
private void processEvents() {
if (topologyEvents.isEmpty() && flowPathEvents.isEmpty())
return; // Nothing to do
// TODO: Implement it!
System.out.println("PAVPAV: Topology Events = " + topologyEvents.size() + " Flow Path Events = " + flowPathEvents.size());
topologyEvents.clear();
flowPathEvents.clear();
}
/**
* Receive a notification that a Flow is added.
*
* @param flowPath the flow that is added.
*/
@Override
public void notificationRecvFlowAdded(FlowPath flowPath) {
EventEntry<FlowPath> eventEntry =
new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
networkEvents.add(eventEntry);
}
/**
* Receive a notification that a Flow is removed.
*
* @param flowPath the flow that is removed.
*/
@Override
public void notificationRecvFlowRemoved(FlowPath flowPath) {
EventEntry<FlowPath> eventEntry =
new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
networkEvents.add(eventEntry);
}
/**
* Receive a notification that a Flow is updated.
*
* @param flowPath the flow that is updated.
*/
@Override
public void notificationRecvFlowUpdated(FlowPath flowPath) {
// NOTE: The ADD and UPDATE events are processed in same way
EventEntry<FlowPath> eventEntry =
new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
networkEvents.add(eventEntry);
}
/**
* Receive a notification that a Topology Element is added.
*
* @param topologyElement the Topology Element that is added.
*/
@Override
public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
EventEntry<TopologyElement> eventEntry =
new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
networkEvents.add(eventEntry);
}
/**
* Receive a notification that a Topology Element is removed.
*
* @param topologyElement the Topology Element that is removed.
*/
@Override
public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
EventEntry<TopologyElement> eventEntry =
new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
networkEvents.add(eventEntry);
}
/**
* Receive a notification that a Topology Element is updated.
*
* @param topologyElement the Topology Element that is updated.
*/
@Override
public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
// NOTE: The ADD and UPDATE events are processed in same way
EventEntry<TopologyElement> eventEntry =
new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
networkEvents.add(eventEntry);
}
}