Jonathan Hart | 472062d | 2014-04-03 10:56:48 -0700 | [diff] [blame] | 1 | package net.onrc.onos.core.topology; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 2 | |
| 3 | import java.util.ArrayList; |
Pavlin Radoslavov | 018d533 | 2014-02-19 23:08:35 -0800 | [diff] [blame] | 4 | import java.util.Collection; |
Jonathan Hart | a99ec67 | 2014-04-03 11:30:34 -0700 | [diff] [blame] | 5 | import java.util.List; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 6 | |
Jonathan Hart | 6df9017 | 2014-04-03 10:13:11 -0700 | [diff] [blame] | 7 | import net.onrc.onos.core.datastore.DataStoreClient; |
| 8 | import net.onrc.onos.core.datastore.IKVClient; |
| 9 | import net.onrc.onos.core.datastore.topology.KVDevice; |
| 10 | import net.onrc.onos.core.datastore.topology.KVLink; |
| 11 | import net.onrc.onos.core.datastore.topology.KVPort; |
Jonathan Hart | 6df9017 | 2014-04-03 10:13:11 -0700 | [diff] [blame] | 12 | import net.onrc.onos.core.datastore.topology.KVPort.STATUS; |
Jonathan Hart | a99ec67 | 2014-04-03 11:30:34 -0700 | [diff] [blame] | 13 | import net.onrc.onos.core.datastore.topology.KVSwitch; |
Jonathan Hart | 6df9017 | 2014-04-03 10:13:11 -0700 | [diff] [blame] | 14 | import net.onrc.onos.core.datastore.utils.KVObject; |
| 15 | import net.onrc.onos.core.datastore.utils.KVObject.WriteOp; |
Yuta HIGUCHI | 5c8cbeb | 2014-06-27 11:13:48 -0700 | [diff] [blame] | 16 | import net.onrc.onos.core.util.SwitchPort; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 17 | |
| 18 | import org.slf4j.Logger; |
| 19 | import org.slf4j.LoggerFactory; |
| 20 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 21 | /** |
Jonathan Hart | e37e4e2 | 2014-05-13 19:12:02 -0700 | [diff] [blame] | 22 | * Contains methods which write topology events into the key-value data store. |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 23 | */ |
Jonathan Hart | e37e4e2 | 2014-05-13 19:12:02 -0700 | [diff] [blame] | 24 | public class TopologyDatastore { |
| 25 | private static final Logger log = LoggerFactory.getLogger(TopologyDatastore.class); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 26 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 27 | /** |
| 28 | * Add a switch to the database. |
| 29 | * |
| 30 | * @param sw the switch to add. |
| 31 | * @param portEvents the corresponding switch ports to add. |
| 32 | * @return true on success, otherwise false. |
| 33 | */ |
| 34 | public boolean addSwitch(SwitchEvent sw, |
| 35 | Collection<PortEvent> portEvents) { |
| 36 | log.debug("Adding switch {}", sw); |
| 37 | ArrayList<WriteOp> groupOp = new ArrayList<>(); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 38 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 39 | KVSwitch rcSwitch = new KVSwitch(sw.getDpid()); |
| 40 | rcSwitch.setStatus(KVSwitch.STATUS.ACTIVE); |
Yuta HIGUCHI | 66ca1bf | 2014-03-12 18:34:09 -0700 | [diff] [blame] | 41 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 42 | IKVClient client = DataStoreClient.getClient(); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 43 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 44 | // XXX Is ForceCreating Switch on DB OK here? |
| 45 | // If ForceCreating, who ever is calling this method needs |
| 46 | // to assure that DPID is unique cluster-wide, etc. |
| 47 | groupOp.add(rcSwitch.forceCreateOp(client)); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 48 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 49 | for (PortEvent portEvent : portEvents) { |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 50 | KVPort rcPort = new KVPort(sw.getDpid(), portEvent.getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 51 | rcPort.setStatus(KVPort.STATUS.ACTIVE); |
Jonathan Hart | 69864df | 2014-02-13 10:44:12 -0800 | [diff] [blame] | 52 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 53 | groupOp.add(rcPort.forceCreateOp(client)); |
| 54 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 55 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 56 | boolean failed = KVObject.multiWrite(groupOp); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 57 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 58 | if (failed) { |
| 59 | log.error("Adding Switch {} and its ports failed.", sw.getDpid()); |
| 60 | for (WriteOp op : groupOp) { |
Yuta HIGUCHI | c66073c | 2014-04-25 09:58:57 -0700 | [diff] [blame] | 61 | log.debug("Operation:{} for {} - Result:{}", op.getOperation(), op.getObject(), op.getStatus()); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 62 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 63 | // If we changed the operation from ForceCreate to |
| 64 | // Conditional operation (Create/Update) then we should retry here. |
| 65 | } |
| 66 | } |
| 67 | return !failed; |
| 68 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 69 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 70 | /** |
| 71 | * Update a switch as inactive in the database. |
| 72 | * |
| 73 | * @param sw the switch to update. |
| 74 | * @param portEvents the corresponding switch ports to update. |
| 75 | * @return true on success, otherwise false. |
| 76 | */ |
| 77 | public boolean deactivateSwitch(SwitchEvent sw, |
| 78 | Collection<PortEvent> portEvents) { |
| 79 | log.debug("Deactivating switch {}", sw); |
| 80 | KVSwitch rcSwitch = new KVSwitch(sw.getDpid()); |
Yuta HIGUCHI | 66ca1bf | 2014-03-12 18:34:09 -0700 | [diff] [blame] | 81 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 82 | IKVClient client = DataStoreClient.getClient(); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 83 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 84 | List<WriteOp> groupOp = new ArrayList<>(); |
| 85 | rcSwitch.setStatus(KVSwitch.STATUS.INACTIVE); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 86 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 87 | groupOp.add(rcSwitch.forceCreateOp(client)); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 88 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 89 | for (PortEvent portEvent : portEvents) { |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 90 | KVPort rcPort = new KVPort(sw.getDpid(), portEvent.getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 91 | rcPort.setStatus(KVPort.STATUS.INACTIVE); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 92 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 93 | groupOp.add(rcPort.forceCreateOp(client)); |
| 94 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 95 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 96 | boolean failed = KVObject.multiWrite(groupOp); |
Pavlin Radoslavov | 018d533 | 2014-02-19 23:08:35 -0800 | [diff] [blame] | 97 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 98 | return !failed; |
| 99 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 100 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 101 | /** |
| 102 | * Add a port to the database. |
| 103 | * |
| 104 | * @param port the port to add. |
| 105 | * @return true on success, otherwise false. |
| 106 | */ |
| 107 | public boolean addPort(PortEvent port) { |
| 108 | log.debug("Adding port {}", port); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 109 | |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 110 | KVPort rcPort = new KVPort(port.getDpid(), port.getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 111 | rcPort.setStatus(KVPort.STATUS.ACTIVE); |
| 112 | rcPort.forceCreate(); |
| 113 | // TODO add description into KVPort |
| 114 | //rcPort.setDescription(port.getDescription()); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 115 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 116 | return true; |
| 117 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 118 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 119 | /** |
| 120 | * Update a port as inactive in the database. |
| 121 | * |
| 122 | * @param port the port to update. |
| 123 | * @return true on success, otherwise false. |
| 124 | */ |
| 125 | public boolean deactivatePort(PortEvent port) { |
| 126 | log.debug("Deactivating port {}", port); |
Yuta HIGUCHI | 5d2d8d4 | 2014-02-20 22:22:53 -0800 | [diff] [blame] | 127 | |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 128 | KVPort rcPort = new KVPort(port.getDpid(), port.getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 129 | rcPort.setStatus(STATUS.INACTIVE); |
Yuta HIGUCHI | 5d2d8d4 | 2014-02-20 22:22:53 -0800 | [diff] [blame] | 130 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 131 | rcPort.forceCreate(); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 132 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 133 | return true; |
| 134 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 135 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 136 | /** |
| 137 | * Add a link to the database. |
| 138 | * |
| 139 | * @param link the link to add. |
| 140 | * @return true on success, otherwise false. |
| 141 | */ |
| 142 | public boolean addLink(LinkEvent link) { |
| 143 | log.debug("Adding link {}", link); |
Yuta HIGUCHI | 0a4bd19 | 2014-02-17 13:52:34 -0800 | [diff] [blame] | 144 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 145 | KVLink rcLink = new KVLink(link.getSrc().getDpid(), |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 146 | link.getSrc().getPortNumber(), |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 147 | link.getDst().getDpid(), |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 148 | link.getDst().getPortNumber()); |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 149 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 150 | // XXX This method is called only by discovery, |
| 151 | // which means what we are trying to write currently is the truth |
| 152 | // so we can force write here |
| 153 | // |
| 154 | // TODO: We need to check for errors |
| 155 | rcLink.setStatus(KVLink.STATUS.ACTIVE); |
| 156 | rcLink.forceCreate(); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 157 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 158 | return true; // Success |
| 159 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 160 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 161 | public boolean removeLink(LinkEvent linkEvent) { |
| 162 | log.debug("Removing link {}", linkEvent); |
Yuta HIGUCHI | 5d2d8d4 | 2014-02-20 22:22:53 -0800 | [diff] [blame] | 163 | |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 164 | KVLink rcLink = new KVLink(linkEvent.getSrc().getDpid(), linkEvent.getSrc().getPortNumber(), |
| 165 | linkEvent.getDst().getDpid(), linkEvent.getDst().getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 166 | rcLink.forceDelete(); |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 167 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 168 | return true; |
| 169 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 170 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 171 | /** |
| 172 | * Add a device to the database. |
| 173 | * |
| 174 | * @param device the device to add. |
| 175 | * @return true on success, otherwise false. |
| 176 | */ |
Yuta HIGUCHI | bfc77f0 | 2014-07-14 22:50:25 -0700 | [diff] [blame] | 177 | public boolean addHost(HostEvent device) { |
| 178 | log.debug("Adding host into DB. mac {}", device.getMac()); |
TeruU | d1c5b65 | 2014-03-24 13:58:46 -0700 | [diff] [blame] | 179 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 180 | KVDevice rcDevice = new KVDevice(device.getMac().toBytes()); |
TeruU | d1c5b65 | 2014-03-24 13:58:46 -0700 | [diff] [blame] | 181 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 182 | for (SwitchPort sp : device.getAttachmentPoints()) { |
Yuta HIGUCHI | b1e2ab7 | 2014-06-30 11:01:31 -0700 | [diff] [blame] | 183 | byte[] portId = KVPort.getPortID(sp.getDpid(), sp.getPortNumber()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 184 | rcDevice.addPortId(portId); |
| 185 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 186 | |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 187 | rcDevice.forceCreate(); |
| 188 | |
| 189 | return true; |
| 190 | } |
| 191 | |
| 192 | /** |
| 193 | * Remove a device from the database. |
| 194 | * |
| 195 | * @param device the device to remove. |
| 196 | * @return true on success, otherwise false. |
| 197 | */ |
Yuta HIGUCHI | bfc77f0 | 2014-07-14 22:50:25 -0700 | [diff] [blame] | 198 | public boolean removeHost(HostEvent device) { |
| 199 | log.debug("Removing host into DB. mac {}", device.getMac()); |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 200 | |
| 201 | KVDevice rcDevice = new KVDevice(device.getMac().toBytes()); |
| 202 | rcDevice.forceDelete(); |
| 203 | |
| 204 | return true; |
| 205 | } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 206 | } |