blob: 194327c232d33e7f062af1c8cb181590f2928aa5 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Toshio Koidec87810e2014-02-11 13:03:21 -08002
Toshio Koide27ffd412014-02-18 19:15:27 -08003import java.util.HashMap;
Toshio Koidec87810e2014-02-11 13:03:21 -08004
Toshio Koide4f308732014-02-18 15:19:48 -08005import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hartaa380972014-04-03 10:24:46 -07006import net.onrc.onos.core.intent.ConstrainedBFSTree;
7import net.onrc.onos.core.intent.ConstrainedShortestPathIntent;
8import net.onrc.onos.core.intent.ErrorIntent;
Jonathan Harta99ec672014-04-03 11:30:34 -07009import net.onrc.onos.core.intent.ErrorIntent.ErrorType;
Jonathan Hartaa380972014-04-03 10:24:46 -070010import net.onrc.onos.core.intent.Intent;
Jonathan Harta99ec672014-04-03 11:30:34 -070011import net.onrc.onos.core.intent.Intent.IntentState;
Jonathan Hartaa380972014-04-03 10:24:46 -070012import net.onrc.onos.core.intent.IntentMap;
13import net.onrc.onos.core.intent.IntentOperation;
Jonathan Harta99ec672014-04-03 11:30:34 -070014import net.onrc.onos.core.intent.IntentOperation.Operator;
Jonathan Hartaa380972014-04-03 10:24:46 -070015import net.onrc.onos.core.intent.IntentOperationList;
Yuta HIGUCHI1fc395e2014-05-13 14:06:28 -070016import net.onrc.onos.core.intent.Path;
Jonathan Hartaa380972014-04-03 10:24:46 -070017import net.onrc.onos.core.intent.PathIntent;
18import net.onrc.onos.core.intent.PathIntentMap;
19import net.onrc.onos.core.intent.ShortestPathIntent;
Jonathan Hart472062d2014-04-03 10:56:48 -070020import net.onrc.onos.core.topology.Switch;
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070021import net.onrc.onos.core.topology.MutableTopology;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070022import net.onrc.onos.core.util.Dpid;
Toshio Koidec87810e2014-02-11 13:03:21 -080023
Toshio Koideb39c9d32014-02-20 01:21:47 -080024import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
26
Toshio Koidec87810e2014-02-11 13:03:21 -080027/**
Toshio Koidefdb75932014-06-16 17:59:24 -070028 * The runtime used by PathCalcRuntimeModule class.
29 * <p>
30 * It calculates shortest-path and constrained-shortest-path.
Toshio Koidec87810e2014-02-11 13:03:21 -080031 */
Toshio Koide4f308732014-02-18 15:19:48 -080032public class PathCalcRuntime implements IFloodlightService {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070033 private MutableTopology mutableTopology;
Ray Milkeyec838942014-04-09 11:28:43 -070034 private static final Logger log = LoggerFactory.getLogger(PathCalcRuntime.class);
Toshio Koidec87810e2014-02-11 13:03:21 -080035
Toshio Koidefdb75932014-06-16 17:59:24 -070036 /**
37 * Constructor.
38 *
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070039 * @param mutableTopology a topology object to use for the path calculation.
Toshio Koidefdb75932014-06-16 17:59:24 -070040 */
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070041 public PathCalcRuntime(MutableTopology mutableTopology) {
42 this.mutableTopology = mutableTopology;
Ray Milkey269ffb92014-04-03 14:43:30 -070043 }
Toshio Koidec87810e2014-02-11 13:03:21 -080044
Ray Milkey269ffb92014-04-03 14:43:30 -070045 /**
Toshio Koidefdb75932014-06-16 17:59:24 -070046 * Calculates shortest-path and constrained-shortest-path intents into low-level path intents.
Ray Milkey269ffb92014-04-03 14:43:30 -070047 *
48 * @param intentOpList IntentOperationList having instances of ShortestPathIntent/ConstrainedShortestPathIntent
49 * @param pathIntents a set of current low-level intents
50 * @return IntentOperationList. PathIntent and/or ErrorIntent instances.
51 */
Jonathan Hartc00f5c22014-06-10 15:14:40 -070052 public IntentOperationList calcPathIntents(final IntentOperationList intentOpList,
53 final IntentMap appIntents, final PathIntentMap pathIntents) {
Ray Milkey269ffb92014-04-03 14:43:30 -070054 IntentOperationList pathIntentOpList = new IntentOperationList();
55 HashMap<Switch, ConstrainedBFSTree> spfTrees = new HashMap<>();
Toshio Koide59bc8ea2014-02-21 17:48:46 -080056
Jonathan Harte37e4e22014-05-13 19:12:02 -070057 // TODO optimize locking of Topology
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070058 mutableTopology.acquireReadLock();
Toshio Koidec87810e2014-02-11 13:03:21 -080059
Ray Milkey269ffb92014-04-03 14:43:30 -070060 for (IntentOperation intentOp : intentOpList) {
61 switch (intentOp.operator) {
62 case ADD:
63 if (!(intentOp.intent instanceof ShortestPathIntent)) {
64 log.error("Unsupported intent type: {}", intentOp.intent.getClass().getName());
65 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
66 ErrorType.UNSUPPORTED_INTENT,
67 "Unsupported intent type.",
68 intentOp.intent));
69 continue;
70 }
Toshio Koidec87810e2014-02-11 13:03:21 -080071
Ray Milkey269ffb92014-04-03 14:43:30 -070072 ShortestPathIntent spIntent = (ShortestPathIntent) intentOp.intent;
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070073 Switch srcSwitch = mutableTopology.getSwitch(new Dpid(spIntent.getSrcSwitchDpid()));
74 Switch dstSwitch = mutableTopology.getSwitch(new Dpid(spIntent.getDstSwitchDpid()));
Ray Milkey269ffb92014-04-03 14:43:30 -070075 if (srcSwitch == null || dstSwitch == null) {
Jonathan Hartd6108c52014-06-18 11:50:26 -070076 log.debug("Switch not found. src:{}, dst:{}",
Ray Milkey269ffb92014-04-03 14:43:30 -070077 spIntent.getSrcSwitchDpid(),
Jonathan Hartd6108c52014-06-18 11:50:26 -070078 spIntent.getDstSwitchDpid());
Ray Milkey269ffb92014-04-03 14:43:30 -070079 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
80 ErrorType.SWITCH_NOT_FOUND,
81 "Switch not found.",
82 spIntent));
83 continue;
84 }
Toshio Koidea10c0372014-02-20 17:28:10 -080085
Ray Milkey269ffb92014-04-03 14:43:30 -070086 double bandwidth = 0.0;
87 ConstrainedBFSTree tree = null;
88 if (spIntent instanceof ConstrainedShortestPathIntent) {
89 bandwidth = ((ConstrainedShortestPathIntent) intentOp.intent).getBandwidth();
90 tree = new ConstrainedBFSTree(srcSwitch, pathIntents, bandwidth);
91 } else {
92 tree = spfTrees.get(srcSwitch);
93 if (tree == null) {
94 tree = new ConstrainedBFSTree(srcSwitch);
95 spfTrees.put(srcSwitch, tree);
96 }
97 }
98 Path path = tree.getPath(dstSwitch);
99 if (path == null) {
Jonathan Hartd6108c52014-06-18 11:50:26 -0700100 log.debug("Path not found. Intent: {}", spIntent.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
102 ErrorType.PATH_NOT_FOUND,
103 "Path not found.",
104 spIntent));
105 continue;
106 }
Toshio Koidea10c0372014-02-20 17:28:10 -0800107
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 // generate new path-intent ID
109 String oldPathIntentId = spIntent.getPathIntentId();
110 String newPathIntentId;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700111 if (oldPathIntentId == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700112 newPathIntentId = PathIntent.createFirstId(spIntent.getId());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700113 } else {
Ray Milkey269ffb92014-04-03 14:43:30 -0700114 newPathIntentId = PathIntent.createNextId(oldPathIntentId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700115 }
Toshio Koidea10c0372014-02-20 17:28:10 -0800116
Ray Milkey269ffb92014-04-03 14:43:30 -0700117 // create new path-intent
Toshio Koide7d3cee02014-06-05 18:56:19 -0700118 PathIntent newPathIntent = new PathIntent(newPathIntentId, path, bandwidth, spIntent);
119 newPathIntent.setState(IntentState.INST_REQ);
120
121 // create and add operation(s)
122 if (oldPathIntentId == null) {
123 // operation for new path-intent
Brian O'Connora581b9d2014-06-15 23:32:36 -0700124 spIntent.setPathIntentId(newPathIntent);
Toshio Koide7d3cee02014-06-05 18:56:19 -0700125 pathIntentOpList.add(Operator.ADD, newPathIntent);
126 log.debug("new intent:{}", newPathIntent);
127 } else {
128 PathIntent oldPathIntent = (PathIntent) pathIntents.getIntent(oldPathIntentId);
129 if (newPathIntent.hasSameFields(oldPathIntent)) {
130 // skip the same operation (reroute)
131 spIntent.setState(IntentState.INST_ACK);
132 log.debug("skip intent:{}", newPathIntent);
133 } else {
134 // update existing path-intent (reroute)
Brian O'Connora581b9d2014-06-15 23:32:36 -0700135 spIntent.setPathIntentId(newPathIntent);
Toshio Koide7d3cee02014-06-05 18:56:19 -0700136 pathIntentOpList.add(Operator.REMOVE, oldPathIntent);
137 pathIntentOpList.add(Operator.ADD, newPathIntent);
138 log.debug("update intent:{} -> {}", oldPathIntent, newPathIntent);
139 }
140 }
Toshio Koide59bc8ea2014-02-21 17:48:46 -0800141
Ray Milkey269ffb92014-04-03 14:43:30 -0700142 break;
143 case REMOVE:
Jonathan Hartc00f5c22014-06-10 15:14:40 -0700144 ShortestPathIntent targetAppIntent =
145 (ShortestPathIntent) appIntents.getIntent(
146 intentOp.intent.getId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700147 if (targetAppIntent != null) {
148 String pathIntentId = targetAppIntent.getPathIntentId();
149 if (pathIntentId != null) {
150 Intent targetPathIntent = pathIntents.getIntent(pathIntentId);
151 if (targetPathIntent != null) {
152 pathIntentOpList.add(Operator.REMOVE, targetPathIntent);
153 }
154 }
155 }
156 break;
157 case ERROR:
158 // just ignore
159 break;
Ray Milkey0b122ed2014-04-14 10:06:03 -0700160 default:
161 log.error("Unknown intent operator {}", intentOp.operator);
162 break;
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 }
164 }
Jonathan Harte37e4e22014-05-13 19:12:02 -0700165 // TODO optimize locking of Topology
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700166 mutableTopology.releaseReadLock();
Ray Milkey269ffb92014-04-03 14:43:30 -0700167
168 return pathIntentOpList;
169 }
Ray Milkey0f913a02014-04-07 20:58:17 -0700170}