Jonathan Hart | aa38097 | 2014-04-03 10:24:46 -0700 | [diff] [blame] | 1 | package net.onrc.onos.core.intent; |
Toshio Koide | ad17d5e | 2014-02-11 11:36:02 -0800 | [diff] [blame] | 2 | |
Toshio Koide | d48166c | 2014-02-21 19:18:06 -0800 | [diff] [blame] | 3 | import java.util.LinkedList; |
| 4 | |
| 5 | import com.esotericsoftware.kryo.serializers.FieldSerializer.Optional; |
| 6 | |
Toshio Koide | ad17d5e | 2014-02-11 11:36:02 -0800 | [diff] [blame] | 7 | /** |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 8 | * This is the base class for the connectivity abstraction. It allows applications |
| 9 | * to specify end hosts, apply some basic filtering to traffic, and constrain traffic. |
| 10 | * <p> |
| 11 | * This class is subclassed to provide other "high level" intent types like shortest |
| 12 | * path connectivity and bandwidth constrained shortest path, as well as "low level" |
| 13 | * intent types like full specified/reserved path connectivity. |
| 14 | * <p> |
| 15 | * The reasoning behind "intent" is that the applications can provide some abstract |
| 16 | * representation of how traffic should flow be handled by the networking, allowing |
| 17 | * the network OS to compile, reserve and optimize the dataplane to satisfy those |
| 18 | * constraints. |
Toshio Koide | ad17d5e | 2014-02-11 11:36:02 -0800 | [diff] [blame] | 19 | */ |
Toshio Koide | d9fa2a8 | 2014-02-19 17:35:18 -0800 | [diff] [blame] | 20 | public class Intent { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 21 | public enum IntentState { |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 22 | /** |
| 23 | * Intent has been created. |
| 24 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 25 | CREATED, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 26 | |
| 27 | /** |
| 28 | * Installation of this intent has been requested. |
| 29 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 30 | INST_REQ, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 31 | |
| 32 | /** |
| 33 | * Intent was not installed. |
| 34 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 35 | INST_NACK, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 36 | |
| 37 | /** |
| 38 | * Intent has been successfully installed in the dataplane. |
| 39 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 40 | INST_ACK, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 41 | |
| 42 | /** |
| 43 | * A delete/removal of the intent from this dataplane has been requested. |
| 44 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 45 | DEL_REQ, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 46 | |
| 47 | /** |
| 48 | * The framework is in the process of removing this intent from the dataplane. |
| 49 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 50 | DEL_PENDING, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 51 | |
| 52 | /** |
| 53 | * Intent has been successfully removed from the dataplane. |
| 54 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 55 | DEL_ACK, |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 56 | |
| 57 | /** |
| 58 | * Intent is pending reroute due to a network event. |
| 59 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 60 | REROUTE_REQ, |
| 61 | } |
Toshio Koide | b609b3b | 2014-02-14 18:25:52 -0800 | [diff] [blame] | 62 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 63 | private String id; |
| 64 | private IntentState state = IntentState.CREATED; |
| 65 | private boolean pathFrozen = false; |
Toshio Koide | 0e4d8d2 | 2014-02-14 10:56:10 -0800 | [diff] [blame] | 66 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 67 | @Optional(value = "logs") |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 68 | private final LinkedList<String> logs = new LinkedList<>(); |
Toshio Koide | d48166c | 2014-02-21 19:18:06 -0800 | [diff] [blame] | 69 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 70 | /** |
Ray Milkey | b41100a | 2014-04-10 10:42:15 -0700 | [diff] [blame] | 71 | * Default constructor for Kryo deserialization. |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 72 | */ |
| 73 | protected Intent() { |
| 74 | logs.add(String.format("created, time:%d", System.nanoTime())); // for measurement |
| 75 | } |
Toshio Koide | 13986d1 | 2014-02-11 20:25:32 -0800 | [diff] [blame] | 76 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 77 | /** |
| 78 | * Constructor. |
| 79 | * |
| 80 | * @param id Intent ID |
| 81 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 82 | public Intent(String id) { |
| 83 | logs.add(String.format("created, time:%d", System.nanoTime())); // for measurement |
| 84 | this.id = id; |
| 85 | } |
Toshio Koide | 13986d1 | 2014-02-11 20:25:32 -0800 | [diff] [blame] | 86 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 87 | /** |
| 88 | * Constructor. |
| 89 | * |
| 90 | * @param id Intent ID |
| 91 | * @param state current state of the new Intent |
| 92 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 93 | public Intent(String id, IntentState state) { |
| 94 | logs.add(String.format("created, time:%d", System.nanoTime())); // for measurement |
| 95 | setState(state); |
| 96 | this.id = id; |
| 97 | } |
Toshio Koide | b609b3b | 2014-02-14 18:25:52 -0800 | [diff] [blame] | 98 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 99 | /** |
| 100 | * Gets the Intent ID. |
| 101 | * |
| 102 | * @return Intent ID |
| 103 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 104 | public String getId() { |
| 105 | return id; |
| 106 | } |
Toshio Koide | b609b3b | 2014-02-14 18:25:52 -0800 | [diff] [blame] | 107 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 108 | /** |
| 109 | * Gets the current state of this Intent. |
| 110 | * |
| 111 | * @return current state of this Intent |
| 112 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 113 | public IntentState getState() { |
| 114 | return state; |
| 115 | } |
Toshio Koide | b609b3b | 2014-02-14 18:25:52 -0800 | [diff] [blame] | 116 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 117 | /** |
| 118 | * Sets the new state for this Intent, and stores the new state in |
| 119 | * this Intent's log. |
| 120 | * |
| 121 | * @param newState new state for this Intent |
| 122 | * @return the old state for this Intent |
| 123 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 124 | public IntentState setState(IntentState newState) { |
| 125 | logs.add(String.format("setState, oldState:%s, newState:%s, time:%d", |
| 126 | state, newState, System.nanoTime())); // for measurement |
| 127 | if (logs.size() > 20) { // TODO this size should be configurable |
| 128 | logs.removeFirst(); |
| 129 | } |
| 130 | IntentState oldState = state; |
| 131 | state = newState; |
| 132 | return oldState; |
| 133 | } |
Toshio Koide | 4f30873 | 2014-02-18 15:19:48 -0800 | [diff] [blame] | 134 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 135 | /** |
| 136 | * Checks to see if this Intent's path is frozen. |
| 137 | * <p> |
| 138 | * Frozen paths will not be rerouted when the network topology changes. |
| 139 | * |
| 140 | * @return true if frozen, false otherwise |
| 141 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 142 | public boolean isPathFrozen() { |
| 143 | return pathFrozen; |
| 144 | } |
Toshio Koide | 565d6dd | 2014-03-27 11:22:25 -0700 | [diff] [blame] | 145 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 146 | /** |
| 147 | * Sets the new frozen state for this Intent. |
| 148 | * |
| 149 | * @param isFrozen the new frozen state for this Intent |
| 150 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 151 | public void setPathFrozen(boolean isFrozen) { |
| 152 | pathFrozen = isFrozen; |
| 153 | } |
Toshio Koide | 565d6dd | 2014-03-27 11:22:25 -0700 | [diff] [blame] | 154 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 155 | /** |
| 156 | * Retrieves the logs for this intent which includes creation and state changes. |
| 157 | * |
| 158 | * @return a list of String log entries |
| 159 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 160 | public LinkedList<String> getLogs() { |
| 161 | return logs; |
| 162 | } |
Toshio Koide | d48166c | 2014-02-21 19:18:06 -0800 | [diff] [blame] | 163 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 164 | /** |
| 165 | * Generates a hash code using the Intent ID. |
| 166 | * |
| 167 | * @return hashcode |
| 168 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 169 | @Override |
| 170 | public int hashCode() { |
| 171 | return (id == null) ? 0 : id.hashCode(); |
| 172 | } |
Toshio Koide | a10c037 | 2014-02-20 17:28:10 -0800 | [diff] [blame] | 173 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 174 | /** |
| 175 | * Compares two intent object by type (class) and Intent ID. |
| 176 | * |
| 177 | * @param obj other Intent |
| 178 | * @return true if equal, false otherwise |
| 179 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 180 | @Override |
| 181 | public boolean equals(Object obj) { |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 182 | if (this == obj) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 183 | return true; |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 184 | } |
| 185 | if ((obj == null) || (getClass() != obj.getClass())) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 186 | return false; |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 187 | } |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 188 | Intent other = (Intent) obj; |
| 189 | if (id == null) { |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 190 | if (other.id != null) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 191 | return false; |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 192 | } |
| 193 | } else if (!id.equals(other.id)) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 194 | return false; |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 195 | } |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 196 | return true; |
| 197 | } |
Toshio Koide | d9fa2a8 | 2014-02-19 17:35:18 -0800 | [diff] [blame] | 198 | |
Brian O'Connor | a581b9d | 2014-06-15 23:32:36 -0700 | [diff] [blame] | 199 | /** |
| 200 | * Returns a String representation of this Intent. |
| 201 | * |
| 202 | * @return "Intent ID, State" |
| 203 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 204 | @Override |
| 205 | public String toString() { |
| 206 | return id.toString() + ", " + state.toString(); |
| 207 | } |
Toshio Koide | ad17d5e | 2014-02-11 11:36:02 -0800 | [diff] [blame] | 208 | } |