blob: f93e4ae57627955517991083897ffe11ae733e04 [file] [log] [blame]
Toshio Koide4f308732014-02-18 15:19:48 -08001package net.onrc.onos.intent.runtime;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
Toshio Koide798bc1b2014-02-20 14:02:40 -08006import java.util.HashSet;
Toshio Koidedf2eab92014-02-20 11:24:59 -08007import java.util.Iterator;
Toshio Koidebf875662014-02-24 12:19:15 -08008import java.util.LinkedList;
Toshio Koide4f308732014-02-18 15:19:48 -08009import java.util.Map;
Toshio Koide066506e2014-02-20 19:52:09 -080010import java.util.Map.Entry;
Toshio Koide93be5d62014-02-23 19:30:57 -080011import java.util.concurrent.locks.ReentrantLock;
Toshio Koide4f308732014-02-18 15:19:48 -080012
Toshio Koidea94060f2014-02-21 22:58:32 -080013import org.slf4j.Logger;
14import org.slf4j.LoggerFactory;
15
Toshio Koide4f308732014-02-18 15:19:48 -080016import net.floodlightcontroller.core.module.FloodlightModuleContext;
17import net.floodlightcontroller.core.module.FloodlightModuleException;
18import net.floodlightcontroller.core.module.IFloodlightModule;
19import net.floodlightcontroller.core.module.IFloodlightService;
20import net.onrc.onos.datagrid.IDatagridService;
21import net.onrc.onos.datagrid.IEventChannel;
Toshio Koide066506e2014-02-20 19:52:09 -080022import net.onrc.onos.datagrid.IEventChannelListener;
23import net.onrc.onos.intent.Intent;
Toshio Koidedf2eab92014-02-20 11:24:59 -080024import net.onrc.onos.intent.Intent.IntentState;
Toshio Koide4f308732014-02-18 15:19:48 -080025import net.onrc.onos.intent.IntentMap;
Toshio Koidedf2eab92014-02-20 11:24:59 -080026import net.onrc.onos.intent.IntentOperation;
Toshio Koide0c9106d2014-02-19 15:26:38 -080027import net.onrc.onos.intent.IntentOperation.Operator;
Toshio Koide4f308732014-02-18 15:19:48 -080028import net.onrc.onos.intent.IntentOperationList;
Toshio Koide0c9106d2014-02-19 15:26:38 -080029import net.onrc.onos.intent.PathIntent;
Toshio Koide4f308732014-02-18 15:19:48 -080030import net.onrc.onos.intent.PathIntentMap;
Toshio Koide066506e2014-02-20 19:52:09 -080031import net.onrc.onos.intent.ShortestPathIntent;
Toshio Koidedf2eab92014-02-20 11:24:59 -080032import net.onrc.onos.intent.persist.PersistIntent;
Toshio Koide0c9106d2014-02-19 15:26:38 -080033import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
34import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
Toshio Koide27ffd412014-02-18 19:15:27 -080035import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
Toshio Koide0c9106d2014-02-19 15:26:38 -080036import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
37import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
38import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
Nick Karanatsios8abe7172014-02-19 20:31:48 -080039import net.onrc.onos.registry.controller.IControllerRegistryService;
Toshio Koide4f308732014-02-18 15:19:48 -080040
Toshio Koide0c9106d2014-02-19 15:26:38 -080041/**
42 * @author Toshio Koide (t-koide@onlab.us)
43 */
Toshio Koide066506e2014-02-20 19:52:09 -080044public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService, INetworkGraphListener, IEventChannelListener<Long, IntentStateList> {
Toshio Koidebf875662014-02-24 12:19:15 -080045 class PerfLog {
46 private String step;
47 private long time;
48
49 public PerfLog(String step) {
50 this.step = step;
51 this.time = System.nanoTime();
52 }
53
54 public void logThis() {
55 log.error("Time:{}, Step:{}", time, step);
56 }
57 }
58 class PerfLogger {
59 private LinkedList<PerfLog> logData = new LinkedList<>();
60
61 public PerfLogger(String logPhase) {
62 log("start_" + logPhase);
63 }
64
65 public void log(String step) {
66 logData.add(new PerfLog(step));
67 }
68
69 public void flushLog() {
70 log("finish");
71 for (PerfLog log: logData) {
72 log.logThis();
73 }
74 logData.clear();
75 }
76 }
Toshio Koide4f308732014-02-18 15:19:48 -080077 private PathCalcRuntime runtime;
78 private IDatagridService datagridService;
Toshio Koide27ffd412014-02-18 19:15:27 -080079 private INetworkGraphService networkGraphService;
Toshio Koide4f308732014-02-18 15:19:48 -080080 private IntentMap highLevelIntents;
Toshio Koide27ffd412014-02-18 19:15:27 -080081 private PathIntentMap pathIntents;
Toshio Koide798bc1b2014-02-20 14:02:40 -080082 private IControllerRegistryService controllerRegistry;
83 private PersistIntent persistIntent;
Toshio Koide27ffd412014-02-18 19:15:27 -080084
Toshio Koide066506e2014-02-20 19:52:09 -080085 private IEventChannel<Long, IntentOperationList> opEventChannel;
Toshio Koide93be5d62014-02-23 19:30:57 -080086 private final ReentrantLock lock = new ReentrantLock();
Brian O'Connor5518d282014-02-25 22:25:58 -080087 private HashSet<LinkEvent> unmatchedLinkEvents = new HashSet<>();
Toshio Koide066506e2014-02-20 19:52:09 -080088 private static final String INTENT_OP_EVENT_CHANNEL_NAME = "onos.pathintent";
89 private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
Toshio Koidea94060f2014-02-21 22:58:32 -080090 private static final Logger log = LoggerFactory.getLogger(PathCalcRuntimeModule.class);
Toshio Koide4f308732014-02-18 15:19:48 -080091
Toshio Koide798bc1b2014-02-20 14:02:40 -080092 // ================================================================================
93 // private methods
94 // ================================================================================
95
Toshio Koidea94060f2014-02-21 22:58:32 -080096 private void reroutePaths(Collection<Intent> oldPaths) {
Toshio Koidea9078af2014-02-21 16:57:04 -080097 if (oldPaths == null || oldPaths.isEmpty())
Toshio Koide798bc1b2014-02-20 14:02:40 -080098 return;
Toshio Koidea10c0372014-02-20 17:28:10 -080099
Toshio Koide0c9106d2014-02-19 15:26:38 -0800100 IntentOperationList reroutingOperation = new IntentOperationList();
Toshio Koide982c81f2014-02-23 16:53:10 -0800101 for (Intent intent : oldPaths) {
102 PathIntent pathIntent = (PathIntent) intent;
Toshio Koide565d6dd2014-03-27 11:22:25 -0700103 if (pathIntent.isPathFrozen())
Toshio Koide93797dc2014-02-27 23:54:26 -0800104 continue;
Brian O'Connor5518d282014-02-25 22:25:58 -0800105 if (pathIntent.getState().equals(IntentState.INST_ACK) && // XXX: path intents in flight
Toshio Koide93797dc2014-02-27 23:54:26 -0800106 !reroutingOperation.contains(pathIntent.getParentIntent())) {
Toshio Koide982c81f2014-02-23 16:53:10 -0800107 reroutingOperation.add(Operator.ADD, pathIntent.getParentIntent());
108 }
Toshio Koide0c9106d2014-02-19 15:26:38 -0800109 }
Toshio Koide8315d7d2014-02-21 22:58:32 -0800110 executeIntentOperations(reroutingOperation);
Toshio Koidea94060f2014-02-21 22:58:32 -0800111 }
112
Toshio Koide27ffd412014-02-18 19:15:27 -0800113
Toshio Koide798bc1b2014-02-20 14:02:40 -0800114 // ================================================================================
115 // IFloodlightModule implementations
116 // ================================================================================
117
Toshio Koide4f308732014-02-18 15:19:48 -0800118 @Override
119 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
120 Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(1);
Toshio Koideeb90d912014-02-18 21:30:22 -0800121 l.add(IPathCalcRuntimeService.class);
Toshio Koide4f308732014-02-18 15:19:48 -0800122 return l;
123 }
124
125 @Override
126 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Toshio Koidea9078af2014-02-21 16:57:04 -0800127 Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>();
Toshio Koide27ffd412014-02-18 19:15:27 -0800128 m.put(IPathCalcRuntimeService.class, this);
Toshio Koide4f308732014-02-18 15:19:48 -0800129 return m;
130 }
131
132 @Override
133 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Toshio Koidea9078af2014-02-21 16:57:04 -0800134 Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(2);
Toshio Koide4f308732014-02-18 15:19:48 -0800135 l.add(IDatagridService.class);
Toshio Koide27ffd412014-02-18 19:15:27 -0800136 l.add(INetworkGraphService.class);
Toshio Koide4f308732014-02-18 15:19:48 -0800137 return l;
138 }
139
140 @Override
141 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
142 datagridService = context.getServiceImpl(IDatagridService.class);
Toshio Koided9fa2a82014-02-19 17:35:18 -0800143 networkGraphService = context.getServiceImpl(INetworkGraphService.class);
Toshio Koide798bc1b2014-02-20 14:02:40 -0800144 controllerRegistry = context.getServiceImpl(IControllerRegistryService.class);
Toshio Koide4f308732014-02-18 15:19:48 -0800145 }
146
147 @Override
148 public void startUp(FloodlightModuleContext context) {
Toshio Koideeb90d912014-02-18 21:30:22 -0800149 highLevelIntents = new IntentMap();
150 runtime = new PathCalcRuntime(networkGraphService.getNetworkGraph());
Toshio Koide0c9106d2014-02-19 15:26:38 -0800151 pathIntents = new PathIntentMap();
Toshio Koide066506e2014-02-20 19:52:09 -0800152 opEventChannel = datagridService.createChannel(INTENT_OP_EVENT_CHANNEL_NAME, Long.class, IntentOperationList.class);
153 datagridService.addListener(INTENT_STATE_EVENT_CHANNEL_NAME, this, Long.class, IntentStateList.class);
Toshio Koide0c9106d2014-02-19 15:26:38 -0800154 networkGraphService.registerNetworkGraphListener(this);
Toshio Koide798bc1b2014-02-20 14:02:40 -0800155 persistIntent = new PersistIntent(controllerRegistry, networkGraphService);
Toshio Koide4f308732014-02-18 15:19:48 -0800156 }
Toshio Koide27ffd412014-02-18 19:15:27 -0800157
Toshio Koide798bc1b2014-02-20 14:02:40 -0800158 // ================================================================================
159 // IPathCalcRuntimeService implementations
160 // ================================================================================
161
Toshio Koide27ffd412014-02-18 19:15:27 -0800162 @Override
163 public IntentOperationList executeIntentOperations(IntentOperationList list) {
Toshio Koidebf875662014-02-24 12:19:15 -0800164 if (list == null || list.size() == 0)
165 return null;
166 PerfLogger p = new PerfLogger("executeIntentOperations_" + list.get(0).operator);
Toshio Koide275d8142014-02-24 16:41:52 -0800167
168 lock.lock(); // TODO optimize locking using smaller steps
Toshio Koide93be5d62014-02-23 19:30:57 -0800169 try {
170 // update the map of high-level intents
Toshio Koidebf875662014-02-24 12:19:15 -0800171 p.log("begin_updateInMemoryIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800172 highLevelIntents.executeOperations(list);
Toshio Koidedf2eab92014-02-20 11:24:59 -0800173
Toshio Koide93be5d62014-02-23 19:30:57 -0800174 // change states of high-level intents
175 IntentStateList states = new IntentStateList();
176 for (IntentOperation op : list) {
Toshio Koidefa735a12014-03-28 10:49:07 -0700177 switch (op.operator) {
178 case ADD:
179 switch (op.intent.getState()) {
180 case CREATED:
181 states.put(op.intent.getId(), IntentState.INST_REQ);
182 break;
183 case INST_ACK:
184 states.put(op.intent.getId(), IntentState.REROUTE_REQ);
185 break;
186 default:
187 break;
188 }
189 break;
190 case REMOVE:
191 switch (op.intent.getState()) {
192 case CREATED:
193 states.put(op.intent.getId(), IntentState.DEL_REQ);
194 break;
195 default:
196 break;
197 }
198 break;
199 default:
200 break;
201 }
Toshio Koidedf2eab92014-02-20 11:24:59 -0800202 }
Toshio Koide93be5d62014-02-23 19:30:57 -0800203 highLevelIntents.changeStates(states);
Toshio Koidebf875662014-02-24 12:19:15 -0800204 p.log("end_updateInMemoryIntents");
Toshio Koidedf2eab92014-02-20 11:24:59 -0800205
Toshio Koide93be5d62014-02-23 19:30:57 -0800206 // calculate path-intents (low-level operations)
Toshio Koidebf875662014-02-24 12:19:15 -0800207 p.log("begin_calcPathIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800208 IntentOperationList pathIntentOperations = runtime.calcPathIntents(list, highLevelIntents, pathIntents);
Toshio Koidebf875662014-02-24 12:19:15 -0800209 p.log("end_calcPathIntents");
Toshio Koide600ae5f2014-02-20 18:42:00 -0800210
Toshio Koide93be5d62014-02-23 19:30:57 -0800211 // persist calculated low-level operations into data store
Toshio Koidebf875662014-02-24 12:19:15 -0800212 p.log("begin_persistPathIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800213 long key = persistIntent.getKey();
214 persistIntent.persistIfLeader(key, pathIntentOperations);
Toshio Koidebf875662014-02-24 12:19:15 -0800215 p.log("end_persistPathIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800216
217 // remove error-intents and reflect them to high-level intents
Toshio Koidebf875662014-02-24 12:19:15 -0800218 p.log("begin_removeErrorIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800219 states.clear();
220 Iterator<IntentOperation> i = pathIntentOperations.iterator();
221 while (i.hasNext()) {
222 IntentOperation op = i.next();
223 if (op.operator.equals(Operator.ERROR)) {
224 states.put(op.intent.getId(), IntentState.INST_NACK);
225 i.remove();
226 }
Toshio Koide600ae5f2014-02-20 18:42:00 -0800227 }
Toshio Koide93be5d62014-02-23 19:30:57 -0800228 highLevelIntents.changeStates(states);
Toshio Koidebf875662014-02-24 12:19:15 -0800229 p.log("end_removeErrorIntents");
Toshio Koidea94060f2014-02-21 22:58:32 -0800230
Toshio Koide93be5d62014-02-23 19:30:57 -0800231 // update the map of path intents and publish the path operations
Toshio Koidebf875662014-02-24 12:19:15 -0800232 p.log("begin_updateInMemoryPathIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800233 pathIntents.executeOperations(pathIntentOperations);
Toshio Koidebf875662014-02-24 12:19:15 -0800234 p.log("end_updateInMemoryPathIntents");
Toshio Koide93be5d62014-02-23 19:30:57 -0800235
Toshio Koide500431f2014-02-28 02:02:25 -0800236 // XXX Demo special: add a complete path to remove operation
Toshio Koidebf875662014-02-24 12:19:15 -0800237 p.log("begin_addPathToRemoveOperation");
Toshio Koide93be5d62014-02-23 19:30:57 -0800238 for (IntentOperation op: pathIntentOperations) {
239 if(op.operator.equals(Operator.REMOVE)) {
240 op.intent = pathIntents.getIntent(op.intent.getId());
241 }
242 if (op.intent instanceof PathIntent) {
243 log.debug("operation: {}, intent:{}", op.operator, op.intent);
244 }
245 }
Toshio Koidebf875662014-02-24 12:19:15 -0800246 p.log("end_addPathToRemoveOperation");
Toshio Koide93be5d62014-02-23 19:30:57 -0800247
248 // send notification
Toshio Koidebf875662014-02-24 12:19:15 -0800249 p.log("begin_sendNotification");
Toshio Koide3a52ef32014-02-28 12:10:26 -0800250 // XXX: Send notifications using the same key every time
251 // and receive them by entryAdded() and entryUpdated()
252 opEventChannel.addEntry(0L, pathIntentOperations);
Toshio Koidebf875662014-02-24 12:19:15 -0800253 p.log("end_sendNotification");
Toshio Koide3a52ef32014-02-28 12:10:26 -0800254 //opEventChannel.removeEntry(key);
Toshio Koide93be5d62014-02-23 19:30:57 -0800255 return pathIntentOperations;
256 }
257 finally {
Toshio Koidebf875662014-02-24 12:19:15 -0800258 p.flushLog();
Toshio Koide93be5d62014-02-23 19:30:57 -0800259 lock.unlock();
260 }
Toshio Koide27ffd412014-02-18 19:15:27 -0800261 }
262
263 @Override
264 public IntentMap getHighLevelIntents() {
Toshio Koide4f308732014-02-18 15:19:48 -0800265 return highLevelIntents;
266 }
Toshio Koide27ffd412014-02-18 19:15:27 -0800267
268 @Override
269 public IntentMap getPathIntents() {
270 return pathIntents;
271 }
272
273 @Override
Toshio Koide4f308732014-02-18 15:19:48 -0800274 public void purgeIntents() {
275 highLevelIntents.purge();
Toshio Koide27ffd412014-02-18 19:15:27 -0800276 pathIntents.purge();
Toshio Koide4f308732014-02-18 15:19:48 -0800277 }
Toshio Koide0c9106d2014-02-19 15:26:38 -0800278
Toshio Koide798bc1b2014-02-20 14:02:40 -0800279 // ================================================================================
280 // INetworkGraphListener implementations
281 // ================================================================================
282
Toshio Koide0c9106d2014-02-19 15:26:38 -0800283 @Override
Toshio Koide798bc1b2014-02-20 14:02:40 -0800284 public void networkGraphEvents(Collection<SwitchEvent> addedSwitchEvents,
285 Collection<SwitchEvent> removedSwitchEvents,
286 Collection<PortEvent> addedPortEvents,
287 Collection<PortEvent> removedPortEvents,
288 Collection<LinkEvent> addedLinkEvents,
289 Collection<LinkEvent> removedLinkEvents,
290 Collection<DeviceEvent> addedDeviceEvents,
291 Collection<DeviceEvent> removedDeviceEvents) {
Toshio Koidea9078af2014-02-21 16:57:04 -0800292
Toshio Koidebf875662014-02-24 12:19:15 -0800293 PerfLogger p = new PerfLogger("networkGraphEvents");
Toshio Koidea94060f2014-02-21 22:58:32 -0800294 HashSet<Intent> affectedPaths = new HashSet<>();
Toshio Koide93797dc2014-02-27 23:54:26 -0800295
Brian O'Connor5518d282014-02-25 22:25:58 -0800296 boolean rerouteAll = false;
297 for(LinkEvent le : addedLinkEvents) {
298 LinkEvent rev = new LinkEvent(le.getDst().getDpid(), le.getDst().getNumber(), le.getSrc().getDpid(), le.getSrc().getNumber());
299 if(unmatchedLinkEvents.contains(rev)) {
300 rerouteAll = true;
301 unmatchedLinkEvents.remove(rev);
302 log.debug("Found matched LinkEvent: {} {}", rev, le);
303 }
304 else {
305 unmatchedLinkEvents.add(le);
306 log.debug("Adding unmatched LinkEvent: {}", le);
307 }
308 }
309 for(LinkEvent le : removedLinkEvents) {
310 if (unmatchedLinkEvents.contains(le)) {
311 unmatchedLinkEvents.remove(le);
312 log.debug("Removing LinkEvent: {}", le);
313 }
314 }
315 if(unmatchedLinkEvents.size() > 0) {
316 log.debug("Unmatched link events: {} events", unmatchedLinkEvents.size());
317 }
Toshio Koidea9078af2014-02-21 16:57:04 -0800318
Brian O'Connor5518d282014-02-25 22:25:58 -0800319 if ( rerouteAll ) {//addedLinkEvents.size() > 0) { // ||
Toshio Koidebf875662014-02-24 12:19:15 -0800320// addedPortEvents.size() > 0 ||
321// addedSwitchEvents.size() > 0) {
322 p.log("begin_getAllIntents");
Toshio Koidea94060f2014-02-21 22:58:32 -0800323 affectedPaths.addAll(getPathIntents().getAllIntents());
Toshio Koidebf875662014-02-24 12:19:15 -0800324 p.log("end_getAllIntents");
Toshio Koidea94060f2014-02-21 22:58:32 -0800325 }
Brian O'Connor5518d282014-02-25 22:25:58 -0800326 else if (removedSwitchEvents.size() > 0 ||
327 removedLinkEvents.size() > 0 ||
328 removedPortEvents.size() > 0) {
Toshio Koidebf875662014-02-24 12:19:15 -0800329 p.log("begin_getIntentsByLink");
Toshio Koidea94060f2014-02-21 22:58:32 -0800330 for (LinkEvent linkEvent: removedLinkEvents)
331 affectedPaths.addAll(pathIntents.getIntentsByLink(linkEvent));
Toshio Koidebf875662014-02-24 12:19:15 -0800332 p.log("end_getIntentsByLink");
Toshio Koidea9078af2014-02-21 16:57:04 -0800333
Toshio Koidebf875662014-02-24 12:19:15 -0800334 p.log("begin_getIntentsByPort");
Toshio Koidea94060f2014-02-21 22:58:32 -0800335 for (PortEvent portEvent: removedPortEvents)
336 affectedPaths.addAll(pathIntents.getIntentsByPort(portEvent.getDpid(), portEvent.getNumber()));
Toshio Koidebf875662014-02-24 12:19:15 -0800337 p.log("end_getIntentsByPort");
Toshio Koidea9078af2014-02-21 16:57:04 -0800338
Toshio Koidebf875662014-02-24 12:19:15 -0800339 p.log("begin_getIntentsByDpid");
Toshio Koidea94060f2014-02-21 22:58:32 -0800340 for (SwitchEvent switchEvent: removedSwitchEvents)
341 affectedPaths.addAll(pathIntents.getIntentsByDpid(switchEvent.getDpid()));
Toshio Koidebf875662014-02-24 12:19:15 -0800342 p.log("end_getIntentsByDpid");
Toshio Koidea94060f2014-02-21 22:58:32 -0800343 }
Toshio Koide240b1302014-02-26 20:08:41 -0800344 p.log("begin_reroutePaths");
Toshio Koidea9078af2014-02-21 16:57:04 -0800345 reroutePaths(affectedPaths);
Toshio Koide240b1302014-02-26 20:08:41 -0800346 p.log("end_reroutePaths");
Toshio Koidebf875662014-02-24 12:19:15 -0800347 p.flushLog();
Toshio Koide0c9106d2014-02-19 15:26:38 -0800348 }
Toshio Koide066506e2014-02-20 19:52:09 -0800349
350 // ================================================================================
351 // IEventChannelListener implementations
352 // ================================================================================
353
354 @Override
355 public void entryAdded(IntentStateList value) {
356 entryUpdated(value);
357 }
358
359 @Override
360 public void entryRemoved(IntentStateList value) {
361 // do nothing
362 }
363
364 @Override
365 public void entryUpdated(IntentStateList value) {
Toshio Koide8315d7d2014-02-21 22:58:32 -0800366 // TODO draw state transition diagram in multiple ONOS instances and update this method
Toshio Koidebf875662014-02-24 12:19:15 -0800367 PerfLogger p = new PerfLogger("entryUpdated");
Toshio Koide93be5d62014-02-23 19:30:57 -0800368 lock.lock(); // TODO optimize locking using smaller steps
369 try {
Toshio Koide93be5d62014-02-23 19:30:57 -0800370 // reflect state changes of path-level intent into application-level intents
Toshio Koidebf875662014-02-24 12:19:15 -0800371 p.log("begin_changeStateByNotification");
Toshio Koide500431f2014-02-28 02:02:25 -0800372 IntentStateList highLevelIntentStates = new IntentStateList();
373 IntentStateList pathIntentStates = new IntentStateList();
Toshio Koide93be5d62014-02-23 19:30:57 -0800374 for (Entry<String, IntentState> entry: value.entrySet()) {
375 PathIntent pathIntent = (PathIntent) pathIntents.getIntent(entry.getKey());
376 if (pathIntent == null) continue;
Toshio Koide8315d7d2014-02-21 22:58:32 -0800377
Toshio Koide93be5d62014-02-23 19:30:57 -0800378 Intent parentIntent = pathIntent.getParentIntent();
379 if (parentIntent == null ||
380 !(parentIntent instanceof ShortestPathIntent) ||
381 !((ShortestPathIntent) parentIntent).getPathIntentId().equals(pathIntent.getId()))
382 continue;
Toshio Koide066506e2014-02-20 19:52:09 -0800383
Toshio Koide93be5d62014-02-23 19:30:57 -0800384 IntentState state = entry.getValue();
385 switch (state) {
Toshio Koide500431f2014-02-28 02:02:25 -0800386 //case INST_REQ:
Toshio Koide93be5d62014-02-23 19:30:57 -0800387 case INST_ACK:
388 case INST_NACK:
Toshio Koide500431f2014-02-28 02:02:25 -0800389 //case DEL_REQ:
Toshio Koide93be5d62014-02-23 19:30:57 -0800390 case DEL_ACK:
391 case DEL_PENDING:
Toshio Koide500431f2014-02-28 02:02:25 -0800392 highLevelIntentStates.put(parentIntent.getId(), state);
393 pathIntentStates.put(entry.getKey(), entry.getValue());
Toshio Koide93be5d62014-02-23 19:30:57 -0800394 break;
395 default:
396 break;
397 }
Toshio Koide066506e2014-02-20 19:52:09 -0800398 }
Toshio Koide500431f2014-02-28 02:02:25 -0800399 highLevelIntents.changeStates(highLevelIntentStates);
400 pathIntents.changeStates(pathIntentStates);
Toshio Koidebf875662014-02-24 12:19:15 -0800401 p.log("end_changeStateByNotification");
Toshio Koide066506e2014-02-20 19:52:09 -0800402 }
Toshio Koide93be5d62014-02-23 19:30:57 -0800403 finally {
Toshio Koidebf875662014-02-24 12:19:15 -0800404 p.flushLog();
Toshio Koide93be5d62014-02-23 19:30:57 -0800405 lock.unlock();
406 }
Toshio Koide066506e2014-02-20 19:52:09 -0800407 }
Toshio Koidea9078af2014-02-21 16:57:04 -0800408}