blob: 89e8da684e67eedf13e5a68da6b24eec7617cba2 [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
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -070087 //
88 // Demultiplex all events:
89 // - EventEntry<TopologyElement>
90 // - EventEntry<FlowPath>
91 //
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070092 for (EventEntry<?> event : collection) {
93 if (event.eventData() instanceof TopologyElement) {
94 EventEntry<TopologyElement> topologyEventEntry =
95 (EventEntry<TopologyElement>)event;
96 topologyEvents.add(topologyEventEntry);
97 } else if (event.eventData() instanceof FlowPath) {
98 EventEntry<FlowPath> flowPathEventEntry =
99 (EventEntry<FlowPath>)event;
100 flowPathEvents.add(flowPathEventEntry);
101 }
102 }
103 collection.clear();
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700104
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700105 // Process the events (if any)
106 processEvents();
107 }
108 } catch (Exception exception) {
109 log.debug("Exception processing Network Events: ", exception);
110 }
111 }
112
113 /**
114 * Process the events (if any)
115 */
116 private void processEvents() {
117 if (topologyEvents.isEmpty() && flowPathEvents.isEmpty())
118 return; // Nothing to do
119
120 // TODO: Implement it!
121
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700122 // Cleanup
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700123 topologyEvents.clear();
124 flowPathEvents.clear();
125 }
126
127 /**
128 * Receive a notification that a Flow is added.
129 *
130 * @param flowPath the flow that is added.
131 */
132 @Override
133 public void notificationRecvFlowAdded(FlowPath flowPath) {
134 EventEntry<FlowPath> eventEntry =
135 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
136 networkEvents.add(eventEntry);
137 }
138
139 /**
140 * Receive a notification that a Flow is removed.
141 *
142 * @param flowPath the flow that is removed.
143 */
144 @Override
145 public void notificationRecvFlowRemoved(FlowPath flowPath) {
146 EventEntry<FlowPath> eventEntry =
147 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
148 networkEvents.add(eventEntry);
149 }
150
151 /**
152 * Receive a notification that a Flow is updated.
153 *
154 * @param flowPath the flow that is updated.
155 */
156 @Override
157 public void notificationRecvFlowUpdated(FlowPath flowPath) {
158 // NOTE: The ADD and UPDATE events are processed in same way
159 EventEntry<FlowPath> eventEntry =
160 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
161 networkEvents.add(eventEntry);
162 }
163
164 /**
165 * Receive a notification that a Topology Element is added.
166 *
167 * @param topologyElement the Topology Element that is added.
168 */
169 @Override
170 public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
171 EventEntry<TopologyElement> eventEntry =
172 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
173 networkEvents.add(eventEntry);
174 }
175
176 /**
177 * Receive a notification that a Topology Element is removed.
178 *
179 * @param topologyElement the Topology Element that is removed.
180 */
181 @Override
182 public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
183 EventEntry<TopologyElement> eventEntry =
184 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
185 networkEvents.add(eventEntry);
186 }
187
188 /**
189 * Receive a notification that a Topology Element is updated.
190 *
191 * @param topologyElement the Topology Element that is updated.
192 */
193 @Override
194 public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
195 // NOTE: The ADD and UPDATE events are processed in same way
196 EventEntry<TopologyElement> eventEntry =
197 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
198 networkEvents.add(eventEntry);
199 }
200}