blob: e1b95e2e9cd7e93f6fdc13479bf8e1d542bf7ca1 [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;
Jonathan Harte37e4e22014-05-13 19:12:02 -070021import net.onrc.onos.core.topology.Topology;
Toshio Koidec87810e2014-02-11 13:03:21 -080022
Toshio Koideb39c9d32014-02-20 01:21:47 -080023import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
Toshio Koidec87810e2014-02-11 13:03:21 -080026/**
27 * @author Toshio Koide (t-koide@onlab.us)
28 */
Toshio Koide4f308732014-02-18 15:19:48 -080029public class PathCalcRuntime implements IFloodlightService {
Jonathan Harte37e4e22014-05-13 19:12:02 -070030 private Topology topology;
Ray Milkeyec838942014-04-09 11:28:43 -070031 private static final Logger log = LoggerFactory.getLogger(PathCalcRuntime.class);
Toshio Koidec87810e2014-02-11 13:03:21 -080032
Jonathan Harte37e4e22014-05-13 19:12:02 -070033 public PathCalcRuntime(Topology topology) {
34 this.topology = topology;
Ray Milkey269ffb92014-04-03 14:43:30 -070035 }
Toshio Koidec87810e2014-02-11 13:03:21 -080036
Ray Milkey269ffb92014-04-03 14:43:30 -070037 /**
Ray Milkeyb41100a2014-04-10 10:42:15 -070038 * calculate shortest-path and constrained-shortest-path intents into low-level path intents.
Ray Milkey269ffb92014-04-03 14:43:30 -070039 *
40 * @param intentOpList IntentOperationList having instances of ShortestPathIntent/ConstrainedShortestPathIntent
41 * @param pathIntents a set of current low-level intents
42 * @return IntentOperationList. PathIntent and/or ErrorIntent instances.
43 */
Jonathan Hartc00f5c22014-06-10 15:14:40 -070044 public IntentOperationList calcPathIntents(final IntentOperationList intentOpList,
45 final IntentMap appIntents, final PathIntentMap pathIntents) {
Ray Milkey269ffb92014-04-03 14:43:30 -070046 IntentOperationList pathIntentOpList = new IntentOperationList();
47 HashMap<Switch, ConstrainedBFSTree> spfTrees = new HashMap<>();
Toshio Koide59bc8ea2014-02-21 17:48:46 -080048
Jonathan Harte37e4e22014-05-13 19:12:02 -070049 // TODO optimize locking of Topology
50 topology.acquireReadLock();
51 log.debug("Topology: {}", topology.getLinks());
Toshio Koidec87810e2014-02-11 13:03:21 -080052
Ray Milkey269ffb92014-04-03 14:43:30 -070053 for (IntentOperation intentOp : intentOpList) {
54 switch (intentOp.operator) {
55 case ADD:
56 if (!(intentOp.intent instanceof ShortestPathIntent)) {
57 log.error("Unsupported intent type: {}", intentOp.intent.getClass().getName());
58 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
59 ErrorType.UNSUPPORTED_INTENT,
60 "Unsupported intent type.",
61 intentOp.intent));
62 continue;
63 }
Toshio Koidec87810e2014-02-11 13:03:21 -080064
Ray Milkey269ffb92014-04-03 14:43:30 -070065 ShortestPathIntent spIntent = (ShortestPathIntent) intentOp.intent;
Jonathan Harte37e4e22014-05-13 19:12:02 -070066 Switch srcSwitch = topology.getSwitch(spIntent.getSrcSwitchDpid());
67 Switch dstSwitch = topology.getSwitch(spIntent.getDstSwitchDpid());
Ray Milkey269ffb92014-04-03 14:43:30 -070068 if (srcSwitch == null || dstSwitch == null) {
Jonathan Harte37e4e22014-05-13 19:12:02 -070069 log.error("Switch not found. src:{}, dst:{}, Topology:{}",
Ray Milkey269ffb92014-04-03 14:43:30 -070070 spIntent.getSrcSwitchDpid(),
71 spIntent.getDstSwitchDpid(),
Jonathan Harte37e4e22014-05-13 19:12:02 -070072 topology.getLinks());
Ray Milkey269ffb92014-04-03 14:43:30 -070073 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
74 ErrorType.SWITCH_NOT_FOUND,
75 "Switch not found.",
76 spIntent));
77 continue;
78 }
Toshio Koidea10c0372014-02-20 17:28:10 -080079
Ray Milkey269ffb92014-04-03 14:43:30 -070080 double bandwidth = 0.0;
81 ConstrainedBFSTree tree = null;
82 if (spIntent instanceof ConstrainedShortestPathIntent) {
83 bandwidth = ((ConstrainedShortestPathIntent) intentOp.intent).getBandwidth();
84 tree = new ConstrainedBFSTree(srcSwitch, pathIntents, bandwidth);
85 } else {
86 tree = spfTrees.get(srcSwitch);
87 if (tree == null) {
88 tree = new ConstrainedBFSTree(srcSwitch);
89 spfTrees.put(srcSwitch, tree);
90 }
91 }
92 Path path = tree.getPath(dstSwitch);
93 if (path == null) {
Jonathan Harte37e4e22014-05-13 19:12:02 -070094 log.error("Path not found. Intent: {}, Topology: {}", spIntent.toString(), topology.getLinks());
Ray Milkey269ffb92014-04-03 14:43:30 -070095 pathIntentOpList.add(Operator.ERROR, new ErrorIntent(
96 ErrorType.PATH_NOT_FOUND,
97 "Path not found.",
98 spIntent));
99 continue;
100 }
Toshio Koidea10c0372014-02-20 17:28:10 -0800101
Ray Milkey269ffb92014-04-03 14:43:30 -0700102 // generate new path-intent ID
103 String oldPathIntentId = spIntent.getPathIntentId();
104 String newPathIntentId;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700105 if (oldPathIntentId == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700106 newPathIntentId = PathIntent.createFirstId(spIntent.getId());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700107 } else {
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 newPathIntentId = PathIntent.createNextId(oldPathIntentId);
Ray Milkey269ffb92014-04-03 14:43:30 -0700109 }
Toshio Koidea10c0372014-02-20 17:28:10 -0800110
Ray Milkey269ffb92014-04-03 14:43:30 -0700111 // create new path-intent
Toshio Koide7d3cee02014-06-05 18:56:19 -0700112 PathIntent newPathIntent = new PathIntent(newPathIntentId, path, bandwidth, spIntent);
113 newPathIntent.setState(IntentState.INST_REQ);
114
115 // create and add operation(s)
116 if (oldPathIntentId == null) {
117 // operation for new path-intent
Brian O'Connora581b9d2014-06-15 23:32:36 -0700118 spIntent.setPathIntentId(newPathIntent);
Toshio Koide7d3cee02014-06-05 18:56:19 -0700119 pathIntentOpList.add(Operator.ADD, newPathIntent);
120 log.debug("new intent:{}", newPathIntent);
121 } else {
122 PathIntent oldPathIntent = (PathIntent) pathIntents.getIntent(oldPathIntentId);
123 if (newPathIntent.hasSameFields(oldPathIntent)) {
124 // skip the same operation (reroute)
125 spIntent.setState(IntentState.INST_ACK);
126 log.debug("skip intent:{}", newPathIntent);
127 } else {
128 // update existing path-intent (reroute)
Brian O'Connora581b9d2014-06-15 23:32:36 -0700129 spIntent.setPathIntentId(newPathIntent);
Toshio Koide7d3cee02014-06-05 18:56:19 -0700130 pathIntentOpList.add(Operator.REMOVE, oldPathIntent);
131 pathIntentOpList.add(Operator.ADD, newPathIntent);
132 log.debug("update intent:{} -> {}", oldPathIntent, newPathIntent);
133 }
134 }
Toshio Koide59bc8ea2014-02-21 17:48:46 -0800135
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 break;
137 case REMOVE:
Jonathan Hartc00f5c22014-06-10 15:14:40 -0700138 ShortestPathIntent targetAppIntent =
139 (ShortestPathIntent) appIntents.getIntent(
140 intentOp.intent.getId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 if (targetAppIntent != null) {
142 String pathIntentId = targetAppIntent.getPathIntentId();
143 if (pathIntentId != null) {
144 Intent targetPathIntent = pathIntents.getIntent(pathIntentId);
145 if (targetPathIntent != null) {
146 pathIntentOpList.add(Operator.REMOVE, targetPathIntent);
147 }
148 }
149 }
150 break;
151 case ERROR:
152 // just ignore
153 break;
Ray Milkey0b122ed2014-04-14 10:06:03 -0700154 default:
155 log.error("Unknown intent operator {}", intentOp.operator);
156 break;
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 }
158 }
Jonathan Harte37e4e22014-05-13 19:12:02 -0700159 // TODO optimize locking of Topology
160 topology.releaseReadLock();
Ray Milkey269ffb92014-04-03 14:43:30 -0700161
162 return pathIntentOpList;
163 }
Ray Milkey0f913a02014-04-07 20:58:17 -0700164}