blob: d4950d29abef81efa322bb7f1ae0c2b89f6ba567 [file] [log] [blame]
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
3import java.util.Collection;
4import java.util.LinkedList;
5import java.util.List;
6
7import java.util.concurrent.BlockingQueue;
8import java.util.concurrent.LinkedBlockingQueue;
9
10import net.onrc.onos.datagrid.IDatagridService;
11import net.onrc.onos.ofcontroller.topology.TopologyElement;
12import net.onrc.onos.ofcontroller.util.EventEntry;
13import net.onrc.onos.ofcontroller.util.FlowPath;
14
15import org.slf4j.Logger;
16import org.slf4j.LoggerFactory;
17
18/**
19 * Class for implementing the Path Computation and Path Maintenance.
20 */
21class PathComputation extends Thread implements IPathComputationService {
22 /** The logger. */
23 private final static Logger log = LoggerFactory.getLogger(PathComputation.class);
24
25 private FlowManager flowManager; // The Flow Manager to use
26 private IDatagridService datagridService; // The Datagrid Service to use
27
28 // The queue with Flow Path and Topology Element updates
29 private BlockingQueue<EventEntry<?>> networkEvents =
30 new LinkedBlockingQueue<EventEntry<?>>();
31
32 // The pending Topology and Flow Path events
33 private List<EventEntry<TopologyElement>> topologyEvents =
34 new LinkedList<EventEntry<TopologyElement>>();
35 private List<EventEntry<FlowPath>> flowPathEvents =
36 new LinkedList<EventEntry<FlowPath>>();
37
38 /**
39 * Constructor for a given Flow Manager and Datagrid Service.
40 *
41 * @param flowManager the Flow Manager to use.
42 * @param datagridService the Datagrid Service to use.
43 */
44 PathComputation(FlowManager flowManager,
45 IDatagridService datagridService) {
46 this.flowManager = flowManager;
47 this.datagridService = datagridService;
48 }
49
50 /**
51 * Run the thread.
52 */
53 @Override
54 public void run() {
55 //
56 // Obtain the initial Topology state
57 //
58 Collection<TopologyElement> topologyElements =
59 datagridService.getAllTopologyElements();
60 for (TopologyElement topologyElement : topologyElements) {
61 EventEntry<TopologyElement> eventEntry =
62 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
63 topologyEvents.add(eventEntry);
64 }
65 //
66 // Obtain the initial Flow Path state
67 //
68 Collection<FlowPath> flowPaths = datagridService.getAllFlows();
69 for (FlowPath flowPath : flowPaths) {
70 EventEntry<FlowPath> eventEntry =
71 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
72 flowPathEvents.add(eventEntry);
73 }
74 // Process the events (if any)
75 processEvents();
76
77 //
78 // The main loop
79 //
80 Collection<EventEntry<?>> collection = new LinkedList<EventEntry<?>>();
81 try {
82 while (true) {
83 EventEntry<?> eventEntry = networkEvents.take();
84 collection.add(eventEntry);
85 networkEvents.drainTo(collection);
86
87 // Demultiplex all events
88 for (EventEntry<?> event : collection) {
89 if (event.eventData() instanceof TopologyElement) {
90 EventEntry<TopologyElement> topologyEventEntry =
91 (EventEntry<TopologyElement>)event;
92 topologyEvents.add(topologyEventEntry);
93 } else if (event.eventData() instanceof FlowPath) {
94 EventEntry<FlowPath> flowPathEventEntry =
95 (EventEntry<FlowPath>)event;
96 flowPathEvents.add(flowPathEventEntry);
97 }
98 }
99 collection.clear();
100 // Process the events (if any)
101 processEvents();
102 }
103 } catch (Exception exception) {
104 log.debug("Exception processing Network Events: ", exception);
105 }
106 }
107
108 /**
109 * Process the events (if any)
110 */
111 private void processEvents() {
112 if (topologyEvents.isEmpty() && flowPathEvents.isEmpty())
113 return; // Nothing to do
114
115 // TODO: Implement it!
116
117 System.out.println("PAVPAV: Topology Events = " + topologyEvents.size() + " Flow Path Events = " + flowPathEvents.size());
118
119 topologyEvents.clear();
120 flowPathEvents.clear();
121 }
122
123 /**
124 * Receive a notification that a Flow is added.
125 *
126 * @param flowPath the flow that is added.
127 */
128 @Override
129 public void notificationRecvFlowAdded(FlowPath flowPath) {
130 EventEntry<FlowPath> eventEntry =
131 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
132 networkEvents.add(eventEntry);
133 }
134
135 /**
136 * Receive a notification that a Flow is removed.
137 *
138 * @param flowPath the flow that is removed.
139 */
140 @Override
141 public void notificationRecvFlowRemoved(FlowPath flowPath) {
142 EventEntry<FlowPath> eventEntry =
143 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
144 networkEvents.add(eventEntry);
145 }
146
147 /**
148 * Receive a notification that a Flow is updated.
149 *
150 * @param flowPath the flow that is updated.
151 */
152 @Override
153 public void notificationRecvFlowUpdated(FlowPath flowPath) {
154 // NOTE: The ADD and UPDATE events are processed in same way
155 EventEntry<FlowPath> eventEntry =
156 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
157 networkEvents.add(eventEntry);
158 }
159
160 /**
161 * Receive a notification that a Topology Element is added.
162 *
163 * @param topologyElement the Topology Element that is added.
164 */
165 @Override
166 public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
167 EventEntry<TopologyElement> eventEntry =
168 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
169 networkEvents.add(eventEntry);
170 }
171
172 /**
173 * Receive a notification that a Topology Element is removed.
174 *
175 * @param topologyElement the Topology Element that is removed.
176 */
177 @Override
178 public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
179 EventEntry<TopologyElement> eventEntry =
180 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
181 networkEvents.add(eventEntry);
182 }
183
184 /**
185 * Receive a notification that a Topology Element is updated.
186 *
187 * @param topologyElement the Topology Element that is updated.
188 */
189 @Override
190 public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
191 // NOTE: The ADD and UPDATE events are processed in same way
192 EventEntry<TopologyElement> eventEntry =
193 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
194 networkEvents.add(eventEntry);
195 }
196}