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 |
| 119 | SwitchImpl memSw = new SwitchImpl(this); |
| 120 | memSw.setDpid(sw.getDpid()); |
| 121 | |
| 122 | addSwitch(memSw); |
| 123 | } catch (ObjectDoesntExistException e) { |
| 124 | log.error("Read Switch Failed, skipping", e); |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | for (RCPort p : RCPort.getAllPorts()) { |
| 129 | try { |
| 130 | p.read(); |
| 131 | |
| 132 | // TODO PortImpl probably should have a constructor from RCPort |
| 133 | PortImpl memPort = new PortImpl(this); |
| 134 | // FIXME remove shortValue() |
| 135 | memPort.setPortNumber(p.getNumber().shortValue()); |
| 136 | Switch sw = this.getSwitch(p.getDpid()); |
| 137 | if (sw == null) { |
| 138 | log.error("Switch {} missing when adding Port {}", |
| 139 | new Dpid(p.getDpid()), p); |
| 140 | continue; |
| 141 | } |
| 142 | memPort.setSwitch(sw); |
| 143 | |
| 144 | addPort(memPort); |
| 145 | } catch (ObjectDoesntExistException e) { |
| 146 | log.error("Read Port Failed, skipping", e); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // TODO Is Device going to be in DB? If so, read from DB. |
| 151 | // for (RCDevice d : RCDevice.getAllDevices()) { |
| 152 | // try { |
| 153 | // d.read(); |
| 154 | // |
| 155 | // } catch (ObjectDoesntExistException e) { |
| 156 | // log.debug("Read Device Failed, skipping", e); |
| 157 | // } |
| 158 | // } |
| 159 | |
| 160 | for (RCLink l : RCLink.getAllLinks()) { |
| 161 | try { |
| 162 | l.read(); |
| 163 | |
| 164 | LinkImpl memLink = new LinkImpl(this); |
| 165 | |
| 166 | Switch srcSw = this.getSwitch(l.getSrc().dpid); |
| 167 | if (srcSw == null) { |
| 168 | log.error("Switch {} missing when adding Link {}", |
| 169 | new Dpid(l.getSrc().dpid), l); |
| 170 | continue; |
| 171 | } |
| 172 | memLink.setSrcSwitch(srcSw); |
| 173 | // FIXME remove shortValue() |
| 174 | memLink.setSrcPort(srcSw.getPort(l.getSrc().number.shortValue())); |
| 175 | |
| 176 | Switch dstSw = this.getSwitch(l.getDst().dpid); |
| 177 | if (dstSw == null) { |
| 178 | log.error("Switch {} missing when adding Link {}", |
| 179 | new Dpid(l.getDst().dpid), l); |
| 180 | continue; |
| 181 | } |
| 182 | memLink.setDstSwitch(dstSw); |
| 183 | // FIXME remove shortValue() |
| 184 | memLink.setDstPort(srcSw.getPort(l.getDst().number.shortValue())); |
| 185 | |
| 186 | addLink(memLink); |
| 187 | } catch (ObjectDoesntExistException e) { |
| 188 | log.debug("Delete Link Failed", e); |
| 189 | } |
| 190 | } |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | // FIXME To be removed later this class should never read from DB. |
| 194 | public void readSwitchFromTopology(long dpid) { |
| 195 | SwitchImpl sw = new SwitchImpl(this); |
| 196 | |
| 197 | RCSwitch rcSwitch = new RCSwitch(dpid); |
| 198 | try { |
| 199 | rcSwitch.read(); |
| 200 | } catch (ObjectDoesntExistException e) { |
| 201 | log.warn("Tried to get a switch that doesn't exist {}", dpid); |
| 202 | return; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 203 | } |
| 204 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 205 | sw.setDpid(rcSwitch.getDpid()); |
| 206 | |
| 207 | addSwitch(sw); |
| 208 | |
| 209 | for (byte[] portId : rcSwitch.getAllPortIds()) { |
| 210 | RCPort rcPort = RCPort.createFromKey(portId); |
| 211 | try { |
| 212 | rcPort.read(); |
| 213 | |
| 214 | PortImpl port = new PortImpl(this); |
| 215 | // port.setDpid(dpid); |
| 216 | |
| 217 | // TODO why are port numbers long? |
| 218 | // port.setPortNumber((short)rcPort.getNumber()); |
| 219 | |
| 220 | port.setSwitch(sw); |
| 221 | sw.addPort(port); |
| 222 | |
| 223 | addPort(port); |
| 224 | |
| 225 | } catch (ObjectDoesntExistException e) { |
| 226 | log.warn("Tried to read port that doesn't exist", rcPort); |
| 227 | } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 228 | } |
| 229 | |
Yuta HIGUCHI | 80829d1 | 2014-02-05 20:16:56 -0800 | [diff] [blame] | 230 | } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 231 | |
| 232 | } |