blob: 7b93acc536b7b920edfe29afcc0a1fd5d90b3e7d [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent;
Toshio Koide5526c4f2014-02-11 12:39:03 -08002
3import java.util.Collection;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.HashSet;
Toshio Koide5526c4f2014-02-11 12:39:03 -08007
Jonathan Hart472062d2014-04-03 10:56:48 -07008import net.onrc.onos.core.topology.Link;
9import net.onrc.onos.core.topology.LinkEvent;
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070010import net.onrc.onos.core.util.Dpid;
11import net.onrc.onos.core.util.PortNumber;
12import net.onrc.onos.core.util.SwitchPort;
Toshio Koide5526c4f2014-02-11 12:39:03 -080013
14/**
Brian O'Connora581b9d2014-06-15 23:32:36 -070015 * In addition to maintaining the Intent ID to Intent mapping of its
16 * superclass, this class maintains a mapping from switch port to
17 * PathIntent. It is used to quickly identify Intents that are affected
18 * when a network event involves a particular switch port.
Toshio Koide5526c4f2014-02-11 12:39:03 -080019 */
Toshio Koide4f308732014-02-18 15:19:48 -080020public class PathIntentMap extends IntentMap {
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070021 private final HashMap<Dpid, HashMap<PortNumber, HashSet<PathIntent>>> intents;
Toshio Koidea9078af2014-02-21 16:57:04 -080022
Brian O'Connora581b9d2014-06-15 23:32:36 -070023 /**
24 * Constructor.
25 */
Ray Milkey269ffb92014-04-03 14:43:30 -070026 public PathIntentMap() {
27 intents = new HashMap<>();
28 }
Toshio Koidea9078af2014-02-21 16:57:04 -080029
Brian O'Connora581b9d2014-06-15 23:32:36 -070030 /**
31 * Retrieve all PathIntents that contain the specified switch port.
32 *
33 * @param swPort the switch port to retrieve Intents for.
34 * @return a set of all intents that contain swPort
35 */
Ray Milkey269ffb92014-04-03 14:43:30 -070036 private HashSet<PathIntent> get(SwitchPort swPort) {
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070037 Dpid dpid = swPort.getDpid();
38 PortNumber port = swPort.getNumber();
39 HashMap<PortNumber, HashSet<PathIntent>> portToIntents = intents.get(dpid);
Ray Milkey269ffb92014-04-03 14:43:30 -070040 if (portToIntents == null) {
41 portToIntents = new HashMap<>();
42 intents.put(dpid, portToIntents);
43 }
44 HashSet<PathIntent> targetIntents = portToIntents.get(port);
45 if (targetIntents == null) {
46 targetIntents = new HashSet<>();
47 portToIntents.put(port, targetIntents);
48 }
49 return targetIntents;
50 }
Toshio Koidea9078af2014-02-21 16:57:04 -080051
Brian O'Connora581b9d2014-06-15 23:32:36 -070052 /**
53 * Add a PathIntent to a particular switch port.
54 *
55 * @param swPort switch port
56 * @param intent Path Intent
57 */
Ray Milkey269ffb92014-04-03 14:43:30 -070058 private void put(SwitchPort swPort, PathIntent intent) {
59 get(swPort).add(intent);
60 }
Toshio Koidec406e792014-02-14 16:52:42 -080061
Brian O'Connora581b9d2014-06-15 23:32:36 -070062 /**
63 * Add a PathIntent to the map. The function will automatically
64 * update the map with all switch ports contained in the Intent.
65 *
66 * @param intent the PathIntent
67 */
Ray Milkey269ffb92014-04-03 14:43:30 -070068 @Override
69 protected void putIntent(Intent intent) {
Ray Milkeyb29e6262014-04-09 16:02:14 -070070 if (!(intent instanceof PathIntent)) {
71 return; // TODO throw exception
72 }
Ray Milkey269ffb92014-04-03 14:43:30 -070073 super.putIntent(intent);
Toshio Koidea9078af2014-02-21 16:57:04 -080074
Ray Milkey269ffb92014-04-03 14:43:30 -070075 PathIntent pathIntent = (PathIntent) intent;
76 for (LinkEvent linkEvent : pathIntent.getPath()) {
77 put(linkEvent.getSrc(), (PathIntent) intent);
78 put(linkEvent.getDst(), (PathIntent) intent);
79 }
80 }
Toshio Koidec406e792014-02-14 16:52:42 -080081
Brian O'Connora581b9d2014-06-15 23:32:36 -070082 /**
83 * Removes a PathIntent from the map, including all switch ports.
84 *
85 * @param intentId the ID of the PathIntent to be removed
86 */
Ray Milkey269ffb92014-04-03 14:43:30 -070087 @Override
88 protected void removeIntent(String intentId) {
89 PathIntent intent = (PathIntent) getIntent(intentId);
90 for (LinkEvent linkEvent : intent.getPath()) {
91 get(linkEvent.getSrc()).remove(intent);
92 get(linkEvent.getDst()).remove(intent);
93 }
94 super.removeIntent(intentId);
95 }
Toshio Koide5526c4f2014-02-11 12:39:03 -080096
Brian O'Connora581b9d2014-06-15 23:32:36 -070097 /**
98 * Retrieve all intents that use a particular link.
99 *
100 * @param linkEvent the link to look up
101 * @return a collection of PathIntents that use the link
102 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700103 public Collection<PathIntent> getIntentsByLink(LinkEvent linkEvent) {
104 return getIntentsByPort(
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700105 linkEvent.getSrc().getDpid(),
106 linkEvent.getSrc().getNumber());
Ray Milkey269ffb92014-04-03 14:43:30 -0700107 }
Toshio Koidea9078af2014-02-21 16:57:04 -0800108
Brian O'Connora581b9d2014-06-15 23:32:36 -0700109 /**
110 * Retrieve all intents that use a particular port.
111 *
112 * @param dpid the switch's DPID
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700113 * @param portNumber the switch's port
Brian O'Connora581b9d2014-06-15 23:32:36 -0700114 * @return a collection of PathIntents that use the port
115 */
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700116 public Collection<PathIntent> getIntentsByPort(Dpid dpid, PortNumber portNumber) {
117 HashMap<PortNumber, HashSet<PathIntent>> portToIntents = intents.get(dpid);
Ray Milkey269ffb92014-04-03 14:43:30 -0700118 if (portToIntents != null) {
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700119 HashSet<PathIntent> targetIntents = portToIntents.get(portNumber);
Ray Milkey269ffb92014-04-03 14:43:30 -0700120 if (targetIntents != null) {
121 return Collections.unmodifiableCollection(targetIntents);
122 }
123 }
124 return new HashSet<>();
125 }
Toshio Koidea9078af2014-02-21 16:57:04 -0800126
Brian O'Connora581b9d2014-06-15 23:32:36 -0700127 /**
128 * Retrieve all intents that use a particular switch.
129 *
130 * @param dpid the switch's DPID
131 * @return a collection of PathIntents that use the switch
132 */
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700133 public Collection<PathIntent> getIntentsByDpid(Dpid dpid) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700134 HashSet<PathIntent> result = new HashSet<>();
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -0700135 HashMap<PortNumber, HashSet<PathIntent>> portToIntents = intents.get(dpid);
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 if (portToIntents != null) {
137 for (HashSet<PathIntent> targetIntents : portToIntents.values()) {
138 result.addAll(targetIntents);
139 }
140 }
141 return result;
142 }
Toshio Koide5526c4f2014-02-11 12:39:03 -0800143
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 /**
Brian O'Connora581b9d2014-06-15 23:32:36 -0700145 * Calculate available bandwidth of specified link.
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 *
Brian O'Connora581b9d2014-06-15 23:32:36 -0700147 * @param link the Link
148 * @return the available bandwidth
Ray Milkey269ffb92014-04-03 14:43:30 -0700149 */
150 public Double getAvailableBandwidth(Link link) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700151 if (link == null) {
152 return null;
153 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 Double bandwidth = link.getCapacity();
155 LinkEvent linkEvent = new LinkEvent(link);
156 if (!bandwidth.isInfinite()) {
157 for (PathIntent intent : getIntentsByLink(linkEvent)) {
158 Double intentBandwidth = intent.getBandwidth();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700159 if (intentBandwidth == null || intentBandwidth.isInfinite() || intentBandwidth.isNaN()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700160 continue;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700161 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 bandwidth -= intentBandwidth;
163 }
164 }
165 return bandwidth;
166 }
Toshio Koide5526c4f2014-02-11 12:39:03 -0800167}