blob: cece84040f6d351fd9132fe43fea9d365a99cc12 [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;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070011import net.onrc.onos.ofcontroller.topology.Topology;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070012import net.onrc.onos.ofcontroller.topology.TopologyElement;
13import net.onrc.onos.ofcontroller.util.EventEntry;
14import net.onrc.onos.ofcontroller.util.FlowPath;
15
16import org.slf4j.Logger;
17import org.slf4j.LoggerFactory;
18
19/**
20 * Class for implementing the Path Computation and Path Maintenance.
21 */
22class PathComputation extends Thread implements IPathComputationService {
23 /** The logger. */
24 private final static Logger log = LoggerFactory.getLogger(PathComputation.class);
25
26 private FlowManager flowManager; // The Flow Manager to use
27 private IDatagridService datagridService; // The Datagrid Service to use
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070028 private Topology topology; // The network topology
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070029
30 // The queue with Flow Path and Topology Element updates
31 private BlockingQueue<EventEntry<?>> networkEvents =
32 new LinkedBlockingQueue<EventEntry<?>>();
33
34 // The pending Topology and Flow Path events
35 private List<EventEntry<TopologyElement>> topologyEvents =
36 new LinkedList<EventEntry<TopologyElement>>();
37 private List<EventEntry<FlowPath>> flowPathEvents =
38 new LinkedList<EventEntry<FlowPath>>();
39
40 /**
41 * Constructor for a given Flow Manager and Datagrid Service.
42 *
43 * @param flowManager the Flow Manager to use.
44 * @param datagridService the Datagrid Service to use.
45 */
46 PathComputation(FlowManager flowManager,
47 IDatagridService datagridService) {
48 this.flowManager = flowManager;
49 this.datagridService = datagridService;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070050 this.topology = new Topology();
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070051 }
52
53 /**
54 * Run the thread.
55 */
56 @Override
57 public void run() {
58 //
59 // Obtain the initial Topology state
60 //
61 Collection<TopologyElement> topologyElements =
62 datagridService.getAllTopologyElements();
63 for (TopologyElement topologyElement : topologyElements) {
64 EventEntry<TopologyElement> eventEntry =
65 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
66 topologyEvents.add(eventEntry);
67 }
68 //
69 // Obtain the initial Flow Path state
70 //
71 Collection<FlowPath> flowPaths = datagridService.getAllFlows();
72 for (FlowPath flowPath : flowPaths) {
73 EventEntry<FlowPath> eventEntry =
74 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
75 flowPathEvents.add(eventEntry);
76 }
77 // Process the events (if any)
78 processEvents();
79
80 //
81 // The main loop
82 //
83 Collection<EventEntry<?>> collection = new LinkedList<EventEntry<?>>();
84 try {
85 while (true) {
86 EventEntry<?> eventEntry = networkEvents.take();
87 collection.add(eventEntry);
88 networkEvents.drainTo(collection);
89
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -070090 //
91 // Demultiplex all events:
92 // - EventEntry<TopologyElement>
93 // - EventEntry<FlowPath>
94 //
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070095 for (EventEntry<?> event : collection) {
96 if (event.eventData() instanceof TopologyElement) {
97 EventEntry<TopologyElement> topologyEventEntry =
98 (EventEntry<TopologyElement>)event;
99 topologyEvents.add(topologyEventEntry);
100 } else if (event.eventData() instanceof FlowPath) {
101 EventEntry<FlowPath> flowPathEventEntry =
102 (EventEntry<FlowPath>)event;
103 flowPathEvents.add(flowPathEventEntry);
104 }
105 }
106 collection.clear();
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700107
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700108 // Process the events (if any)
109 processEvents();
110 }
111 } catch (Exception exception) {
112 log.debug("Exception processing Network Events: ", exception);
113 }
114 }
115
116 /**
117 * Process the events (if any)
118 */
119 private void processEvents() {
120 if (topologyEvents.isEmpty() && flowPathEvents.isEmpty())
121 return; // Nothing to do
122
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700123 //
124 // Add the topology events
125 //
126 boolean isTopologyModified = false;
127 for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
128 TopologyElement topologyElement = eventEntry.eventData();
129 switch (eventEntry.eventType()) {
130 case ENTRY_ADD:
131 isTopologyModified = topology.addTopologyElement(topologyElement);
132 break;
133 case ENTRY_REMOVE:
134 isTopologyModified = topology.removeTopologyElement(topologyElement);
135 break;
136 }
137 }
138
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700139 // TODO: Implement it!
140
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700141 // Cleanup
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700142 topologyEvents.clear();
143 flowPathEvents.clear();
144 }
145
146 /**
147 * Receive a notification that a Flow is added.
148 *
149 * @param flowPath the flow that is added.
150 */
151 @Override
152 public void notificationRecvFlowAdded(FlowPath flowPath) {
153 EventEntry<FlowPath> eventEntry =
154 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
155 networkEvents.add(eventEntry);
156 }
157
158 /**
159 * Receive a notification that a Flow is removed.
160 *
161 * @param flowPath the flow that is removed.
162 */
163 @Override
164 public void notificationRecvFlowRemoved(FlowPath flowPath) {
165 EventEntry<FlowPath> eventEntry =
166 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
167 networkEvents.add(eventEntry);
168 }
169
170 /**
171 * Receive a notification that a Flow is updated.
172 *
173 * @param flowPath the flow that is updated.
174 */
175 @Override
176 public void notificationRecvFlowUpdated(FlowPath flowPath) {
177 // NOTE: The ADD and UPDATE events are processed in same way
178 EventEntry<FlowPath> eventEntry =
179 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
180 networkEvents.add(eventEntry);
181 }
182
183 /**
184 * Receive a notification that a Topology Element is added.
185 *
186 * @param topologyElement the Topology Element that is added.
187 */
188 @Override
189 public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
190 EventEntry<TopologyElement> eventEntry =
191 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
192 networkEvents.add(eventEntry);
193 }
194
195 /**
196 * Receive a notification that a Topology Element is removed.
197 *
198 * @param topologyElement the Topology Element that is removed.
199 */
200 @Override
201 public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
202 EventEntry<TopologyElement> eventEntry =
203 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
204 networkEvents.add(eventEntry);
205 }
206
207 /**
208 * Receive a notification that a Topology Element is updated.
209 *
210 * @param topologyElement the Topology Element that is updated.
211 */
212 @Override
213 public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
214 // NOTE: The ADD and UPDATE events are processed in same way
215 EventEntry<TopologyElement> eventEntry =
216 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
217 networkEvents.add(eventEntry);
218 }
219}