Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 1 | package net.onrc.onos.ofcontroller.networkgraph; |
| 2 | |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 3 | import net.onrc.onos.datastore.topology.RCLink; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 4 | import net.onrc.onos.datastore.topology.RCPort; |
| 5 | import net.onrc.onos.datastore.topology.RCSwitch; |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 6 | import net.onrc.onos.ofcontroller.util.Dpid; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 7 | |
| 8 | import org.slf4j.Logger; |
| 9 | import org.slf4j.LoggerFactory; |
| 10 | |
| 11 | import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException; |
| 12 | |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 13 | /** |
| 14 | * The "NB" read-only Network Map. |
| 15 | * |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 16 | * TODO To be synchronized based on TopologyEvent Notification. |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 17 | * |
| 18 | */ |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 19 | public class NetworkGraphImpl extends AbstractNetworkGraph { |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 20 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 21 | private static final Logger log = LoggerFactory |
| 22 | .getLogger(NetworkGraphImpl.class); |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 23 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 24 | public NetworkGraphImpl() { |
| 25 | super(); |
| 26 | } |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 27 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 28 | void addSwitch(Switch sw) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 29 | if (sw == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 30 | throw new IllegalArgumentException("Switch cannot be null"); |
| 31 | } |
| 32 | switches.put(sw.getDpid(), sw); |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 33 | } |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 34 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 35 | /** |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 36 | * Deactivate Switch (and its Ports?) |
| 37 | * |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 38 | * @param sw |
| 39 | */ |
| 40 | void deactivateSwitch(Switch sw) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 41 | if (sw == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 42 | throw new IllegalArgumentException("Switch cannot be null"); |
| 43 | } |
| 44 | SwitchImpl s = getSwitchImpl(sw); |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 45 | // XXX When modifying existing object should we change the object itself |
| 46 | // or create a modified copy and switch them? |
| 47 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 48 | // TODO Deactivate Switch |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 49 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 50 | // XXX Are we sure we want to deactivate Ports also? |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 51 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 52 | // TODO Auto-generated method stub |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 53 | } |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 54 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 55 | void addPort(Port port) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 56 | if (port == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 57 | throw new IllegalArgumentException("Port cannot be null"); |
| 58 | } |
| 59 | // TODO Auto-generated method stub |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 60 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | void deactivatePort(Port port) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 64 | if (port == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 65 | throw new IllegalArgumentException("Port cannot be null"); |
| 66 | } |
| 67 | // TODO Auto-generated method stub |
| 68 | |
| 69 | } |
| 70 | |
| 71 | void addLink(Link link) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 72 | if (link == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 73 | throw new IllegalArgumentException("Link cannot be null"); |
| 74 | } |
| 75 | // TODO Auto-generated method stub |
| 76 | |
| 77 | } |
| 78 | |
| 79 | void removeLink(Link link) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 80 | if (link == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 81 | throw new IllegalArgumentException("Link cannot be null"); |
| 82 | } |
| 83 | // TODO Auto-generated method stub |
| 84 | |
| 85 | } |
| 86 | |
| 87 | void updateDevice(Device device) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 88 | if (device == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 89 | throw new IllegalArgumentException("Device cannot be null"); |
| 90 | } |
| 91 | // TODO Auto-generated method stub |
| 92 | |
| 93 | } |
| 94 | |
| 95 | void removeDevice(Device device) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 96 | if (device == null) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 97 | throw new IllegalArgumentException("Device cannot be null"); |
| 98 | } |
| 99 | // TODO Auto-generated method stub |
| 100 | |
| 101 | } |
| 102 | |
| 103 | private SwitchImpl getSwitchImpl(Switch sw) { |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 104 | if (sw instanceof SwitchImpl) { |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 105 | return (SwitchImpl) sw; |
| 106 | } |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 107 | throw new ClassCastException("SwitchImpl expected, but found:" |
| 108 | + sw.getClass().getName()); |
| 109 | } |
| 110 | |
| 111 | public void loadWholeTopologyFromDB() { |
| 112 | // XXX clear everything first? |
| 113 | |
| 114 | for (RCSwitch sw : RCSwitch.getAllSwitches()) { |
| 115 | try { |
| 116 | sw.read(); |
| 117 | // TODO SwitchImpl probably should have a constructor from |
| 118 | // RCSwitch |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 119 | SwitchImpl memSw = new SwitchImpl(this, sw.getDpid()); |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 120 | |
| 121 | addSwitch(memSw); |
| 122 | } catch (ObjectDoesntExistException e) { |
| 123 | log.error("Read Switch Failed, skipping", e); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | for (RCPort p : RCPort.getAllPorts()) { |
| 128 | try { |
| 129 | p.read(); |
| 130 | |
| 131 | // TODO PortImpl probably should have a constructor from RCPort |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 132 | Switch sw = this.getSwitch(p.getDpid()); |
| 133 | if (sw == null) { |
| 134 | log.error("Switch {} missing when adding Port {}", |
| 135 | new Dpid(p.getDpid()), p); |
| 136 | continue; |
| 137 | } |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 138 | PortImpl memPort = new PortImpl(this, sw, p.getNumber()); |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 139 | |
| 140 | addPort(memPort); |
| 141 | } catch (ObjectDoesntExistException e) { |
| 142 | log.error("Read Port Failed, skipping", e); |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | // TODO Is Device going to be in DB? If so, read from DB. |
| 147 | // for (RCDevice d : RCDevice.getAllDevices()) { |
| 148 | // try { |
| 149 | // d.read(); |
| 150 | // |
| 151 | // } catch (ObjectDoesntExistException e) { |
| 152 | // log.debug("Read Device Failed, skipping", e); |
| 153 | // } |
| 154 | // } |
| 155 | |
| 156 | for (RCLink l : RCLink.getAllLinks()) { |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 157 | try { |
| 158 | l.read(); |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 159 | |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 160 | |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 161 | Switch srcSw = this.getSwitch(l.getSrc().dpid); |
| 162 | if (srcSw == null) { |
| 163 | log.error("Switch {} missing when adding Link {}", |
| 164 | new Dpid(l.getSrc().dpid), l); |
| 165 | continue; |
| 166 | } |
| 167 | |
| 168 | Switch dstSw = this.getSwitch(l.getDst().dpid); |
| 169 | if (dstSw == null) { |
| 170 | log.error("Switch {} missing when adding Link {}", |
| 171 | new Dpid(l.getDst().dpid), l); |
| 172 | continue; |
| 173 | } |
| 174 | |
| 175 | LinkImpl memLink = new LinkImpl(this, |
| 176 | srcSw.getPort(l.getSrc().number), |
| 177 | dstSw.getPort(l.getDst().number)); |
| 178 | |
| 179 | addLink(memLink); |
| 180 | } catch (ObjectDoesntExistException e) { |
| 181 | log.debug("Delete Link Failed", e); |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 182 | } |
Yuta HIGUCHI | 765cd0d | 2014-02-06 12:46:41 -0800 | [diff] [blame] | 183 | } |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | // FIXME To be removed later this class should never read from DB. |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 187 | public void readSwitchFromTopology(Long dpid) { |
| 188 | SwitchImpl sw = new SwitchImpl(this, dpid); |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 189 | |
| 190 | RCSwitch rcSwitch = new RCSwitch(dpid); |
| 191 | try { |
| 192 | rcSwitch.read(); |
| 193 | } catch (ObjectDoesntExistException e) { |
| 194 | log.warn("Tried to get a switch that doesn't exist {}", dpid); |
| 195 | return; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 196 | } |
| 197 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 198 | addSwitch(sw); |
| 199 | |
| 200 | for (byte[] portId : rcSwitch.getAllPortIds()) { |
| 201 | RCPort rcPort = RCPort.createFromKey(portId); |
| 202 | try { |
| 203 | rcPort.read(); |
| 204 | |
Toshio Koide | 2f570c1 | 2014-02-06 16:55:32 -0800 | [diff] [blame] | 205 | PortImpl port = new PortImpl(this, sw, rcPort.getNumber()); |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 206 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 207 | sw.addPort(port); |
| 208 | |
| 209 | addPort(port); |
| 210 | |
| 211 | } catch (ObjectDoesntExistException e) { |
| 212 | log.warn("Tried to read port that doesn't exist", rcPort); |
| 213 | } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 214 | } |
| 215 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 216 | } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 217 | |
| 218 | } |