Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 1 | package net.onrc.onos.ofcontroller.networkgraph; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.List; |
| 5 | |
| 6 | import net.onrc.onos.datastore.RCObject; |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 7 | import net.onrc.onos.datastore.RCObject.WriteOp; |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 8 | import net.onrc.onos.datastore.topology.RCLink; |
Jonathan Hart | 69864df | 2014-02-13 10:44:12 -0800 | [diff] [blame] | 9 | import net.onrc.onos.datastore.topology.RCPort; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 10 | import net.onrc.onos.datastore.topology.RCSwitch; |
| 11 | |
| 12 | import org.slf4j.Logger; |
| 13 | import org.slf4j.LoggerFactory; |
| 14 | |
| 15 | import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException; |
| 16 | import edu.stanford.ramcloud.JRamCloud.ObjectExistsException; |
| 17 | import edu.stanford.ramcloud.JRamCloud.WrongVersionException; |
| 18 | |
| 19 | /** |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 20 | * The southbound interface to the network graph which allows clients to |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 21 | * mutate the graph. This class will maintain the invariants of the network |
| 22 | * graph. The southbound discovery modules will use this interface to update |
| 23 | * the network graph as they learn about the state of the network. |
| 24 | * |
Yuta HIGUCHI | 181d34d | 2014-02-05 15:05:46 -0800 | [diff] [blame] | 25 | * Modification to the Network Map by this module will: |
| 26 | * 1. Writes to Cluster-wide DataStore. |
| 27 | * 2. Update ONOS instance In-memory Network Map. |
| 28 | * 3. Send-out Notification. (TBD) |
| 29 | * (XXX: To update other instances In-memory Network Map, |
| 30 | * notification should be triggered here. |
| 31 | * But if we want to aggregate notification to minimize notification, |
| 32 | * It might be better for the caller to trigger notification.) |
| 33 | * |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 34 | */ |
Jonathan Hart | fa01c24 | 2014-02-11 10:03:03 -0800 | [diff] [blame] | 35 | public class NetworkGraphDatastore { |
| 36 | private static final Logger log = LoggerFactory.getLogger(NetworkGraphDatastore.class); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 37 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 38 | private static final int NUM_RETRIES = 10; |
Yuta HIGUCHI | cb95198 | 2014-02-11 13:31:44 -0800 | [diff] [blame] | 39 | |
Pavlin Radoslavov | db7dbb2 | 2014-02-18 14:45:10 -0800 | [diff] [blame] | 40 | private final TopologyManager graph; |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 41 | |
Pavlin Radoslavov | db7dbb2 | 2014-02-18 14:45:10 -0800 | [diff] [blame] | 42 | public NetworkGraphDatastore(TopologyManager graph) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 43 | this.graph = graph; |
| 44 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 45 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 46 | /** |
| 47 | * Add a switch to the database. |
| 48 | * |
| 49 | * @param sw the switch to add. |
| 50 | * @return true on success, otherwise false. |
| 51 | */ |
| 52 | public boolean addSwitch(SwitchEvent sw) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 53 | log.debug("Adding switch {}", sw); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 54 | ArrayList<WriteOp> groupOp = new ArrayList<>(); |
| 55 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 56 | RCSwitch rcSwitch = new RCSwitch(sw.getDpid()); |
| 57 | rcSwitch.setStatus(RCSwitch.STATUS.ACTIVE); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 58 | |
| 59 | // XXX Is ForceCreating Switch on DB OK here? |
| 60 | // If ForceCreating, who ever is calling this method needs |
| 61 | // to assure that DPID is unique cluster-wide, etc. |
| 62 | groupOp.add(WriteOp.ForceCreate(rcSwitch)); |
| 63 | |
Jonathan Hart | 69864df | 2014-02-13 10:44:12 -0800 | [diff] [blame] | 64 | //for (Port port : sw.getPorts()) { |
| 65 | for (PortEvent portEvent : sw.getPorts()) { |
| 66 | RCPort rcPort = new RCPort(sw.getDpid(), portEvent.getNumber()); |
| 67 | rcPort.setStatus(RCPort.STATUS.ACTIVE); |
| 68 | //rcSwitch.addPortId(rcPort.getId()); |
| 69 | |
| 70 | groupOp.add(WriteOp.ForceCreate(rcPort)); |
| 71 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 72 | |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 73 | boolean failed = RCObject.multiWrite(groupOp); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 74 | |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 75 | if (failed) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 76 | log.error("Adding Switch {} and its ports failed.", sw.getDpid()); |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 77 | for (WriteOp op : groupOp) { |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 78 | log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus() ); |
| 79 | |
| 80 | // If we changed the operation from ForceCreate to |
| 81 | // Conditional operation (Create/Update) then we should retry here. |
| 82 | } |
| 83 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 84 | return (! failed); |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 85 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 86 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 87 | /** |
| 88 | * Update a switch as inactive in the database. |
| 89 | * |
| 90 | * @param sw the switch to update. |
| 91 | * @return true on success, otherwise false. |
| 92 | */ |
| 93 | public boolean deactivateSwitch(SwitchEvent sw) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 94 | log.debug("Deactivating switch {}", sw); |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 95 | RCSwitch rcSwitch = new RCSwitch(sw.getDpid()); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 96 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 97 | List<RCObject> objectsToDeactive = new ArrayList<RCObject>(); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 98 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 99 | for (int i = 0; i < NUM_RETRIES; i++) { |
| 100 | try { |
| 101 | rcSwitch.read(); |
| 102 | rcSwitch.setStatus(RCSwitch.STATUS.INACTIVE); |
| 103 | objectsToDeactive.add(rcSwitch); |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 104 | |
Yuta HIGUCHI | cb95198 | 2014-02-11 13:31:44 -0800 | [diff] [blame] | 105 | // for (Port p : sw.getPorts()) { |
| 106 | // RCPort rcPort = new RCPort(sw.getDpid(), (long)p.getNumber()); |
| 107 | // rcPort.read(); |
| 108 | // rcPort.setStatus(RCPort.STATUS.INACTIVE); |
| 109 | // objectsToDeactive.add(rcPort); |
| 110 | // } |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 111 | } catch (ObjectDoesntExistException e) { |
| 112 | log.warn("Trying to deactivate an object that doesn't exist", e); |
| 113 | // We don't care to much if the object wasn't there, it's |
| 114 | // being deactivated anyway |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 115 | return true; // Success: no object in the DB |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 116 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 117 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 118 | try { |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 119 | for (RCObject rcObject : objectsToDeactive) { |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 120 | rcObject.update(); |
| 121 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 122 | return true; // Success |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 123 | } catch (ObjectDoesntExistException e) { |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 124 | // Unlikely, and we don't care anyway. |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 125 | // TODO But, this will cause everything else to fail |
| 126 | log.warn("Trying to deactivate object that doesn't exist", e); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 127 | return true; // Success: no object in the DB |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 128 | } catch (WrongVersionException e) { |
| 129 | // Need to re-read and retry |
| 130 | } |
| 131 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 132 | |
| 133 | return false; // Failure |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 134 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 135 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 136 | /** |
| 137 | * Add a port to the database. |
| 138 | * |
| 139 | * @param port the port to add. |
| 140 | * @return true on success, otherwise false. |
| 141 | */ |
| 142 | public boolean addPort(PortEvent port) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 143 | log.debug("Adding port {}", port); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 144 | //RCSwitch rcSwitch = new RCSwitch(sw.getDpid()); |
| 145 | |
| 146 | //try { |
| 147 | //rcSwitch.read(); |
| 148 | //} catch (ObjectDoesntExistException e) { |
| 149 | //log.warn("Add port failed because switch {} doesn't exist", sw.getDpid(), e); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 150 | //return false; |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 151 | //} |
| 152 | |
| 153 | RCPort rcPort = new RCPort(port.getDpid(), port.getNumber()); |
| 154 | rcPort.setStatus(RCPort.STATUS.ACTIVE); |
| 155 | // TODO add description into RCPort |
| 156 | //rcPort.setDescription(port.getDescription()); |
| 157 | //rcSwitch.addPortId(rcPort.getId()); |
| 158 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 159 | boolean success = writeObject(rcPort); |
| 160 | // success &= writeObject(rcSwitch); |
| 161 | return success; |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 162 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 163 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 164 | /** |
| 165 | * Update a port as inactive in the database. |
| 166 | * |
| 167 | * @param port the port to update. |
| 168 | * @return true on success, otherwise false. |
| 169 | */ |
| 170 | public boolean deactivatePort(PortEvent port) { |
Jonathan Hart | 4b5bbb5 | 2014-02-06 10:09:31 -0800 | [diff] [blame] | 171 | log.debug("Deactivating port {}", port); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 172 | RCPort rcPort = new RCPort(port.getDpid(), port.getNumber()); |
| 173 | |
| 174 | for (int i = 0; i < NUM_RETRIES; i++) { |
| 175 | try { |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 176 | rcPort.read(); |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 177 | } catch (ObjectDoesntExistException e) { |
| 178 | // oh well, we were deactivating anyway |
| 179 | log.warn("Trying to deactivate a port that doesn't exist: {}", port); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 180 | return true; // Success: no object in the DB |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | rcPort.setStatus(RCPort.STATUS.INACTIVE); |
| 184 | |
| 185 | try { |
| 186 | rcPort.update(); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 187 | return true; // Success |
Jonathan Hart | 4c26327 | 2014-02-13 17:41:05 -0800 | [diff] [blame] | 188 | } catch (ObjectDoesntExistException | WrongVersionException e) { |
| 189 | // retry |
| 190 | } |
| 191 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 192 | |
| 193 | return false; // Failure |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 194 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 195 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 196 | /** |
| 197 | * Add a link to the database. |
| 198 | * |
| 199 | * @param link the link to add. |
| 200 | * @return true on success, otherwise false. |
| 201 | */ |
| 202 | public boolean addLink(LinkEvent link) { |
| 203 | log.debug("Adding link {}", link); |
Yuta HIGUCHI | 0a4bd19 | 2014-02-17 13:52:34 -0800 | [diff] [blame] | 204 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 205 | RCLink rcLink = new RCLink(link.getSrc().getDpid(), |
| 206 | link.getSrc().getNumber(), |
| 207 | link.getDst().getDpid(), |
| 208 | link.getDst().getNumber()); |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 209 | |
Yuta HIGUCHI | ef47967 | 2014-02-19 09:14:39 -0800 | [diff] [blame] | 210 | // XXX This method is called only by discovery, |
| 211 | // which means what we are trying to write currently is the truth |
| 212 | // so we can force write here |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 213 | // |
| 214 | // TODO: We need to check for errors |
Yuta HIGUCHI | ef47967 | 2014-02-19 09:14:39 -0800 | [diff] [blame] | 215 | rcLink.setStatus(RCLink.STATUS.ACTIVE); |
| 216 | rcLink.forceCreate(); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 217 | |
| 218 | return true; // Success |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 219 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 220 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 221 | /** |
| 222 | * Remove a link from the database. |
| 223 | * |
| 224 | * @param link the link to remove. |
| 225 | * @return true on success, otherwise false. |
| 226 | */ |
| 227 | public boolean removeLink(LinkEvent link) { |
| 228 | log.debug("Removing link {}", link); |
| 229 | RCLink rcLink = new RCLink(link.getSrc().getDpid(), |
| 230 | link.getSrc().getNumber(), |
| 231 | link.getDst().getDpid(), |
| 232 | link.getDst().getNumber()); |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 233 | |
| 234 | //RCPort rcSrcPort = new RCPort(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber()); |
| 235 | //RCPort rcDstPort = new RCPort(link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber()); |
| 236 | |
| 237 | for (int i = 0; i < NUM_RETRIES; i++) { |
| 238 | try { |
| 239 | //rcSrcPort.read(); |
| 240 | //rcDstPort.read(); |
| 241 | rcLink.read(); |
| 242 | } catch (ObjectDoesntExistException e) { |
Yuta HIGUCHI | 0a4bd19 | 2014-02-17 13:52:34 -0800 | [diff] [blame] | 243 | // XXX Note: This error might be harmless, if triggered by out-dated remove Link event |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 244 | log.error("Remove link failed {}", link, e); |
| 245 | return true; // Success: no object in the DB |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 246 | } |
| 247 | |
| 248 | //rcSrcPort.removeLinkId(rcLink.getId()); |
| 249 | //rcDstPort.removeLinkId(rcLink.getId()); |
| 250 | |
| 251 | try { |
| 252 | //rcSrcPort.update(); |
| 253 | //rcDstPort.update(); |
| 254 | rcLink.delete(); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 255 | return true; // Success |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 256 | } catch (ObjectDoesntExistException e) { |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 257 | log.error("Remove link failed {}", link, e); |
| 258 | return true; // Success: no object in the DB |
Jonathan Hart | 369875b | 2014-02-13 10:00:31 -0800 | [diff] [blame] | 259 | } catch (WrongVersionException e) { |
| 260 | // retry |
| 261 | } |
| 262 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 263 | |
| 264 | return false; // Failure |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 265 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 266 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 267 | /** |
| 268 | * Add a device to the database. |
| 269 | * |
| 270 | * @param device the device to add. |
| 271 | * @return true on success, otherwise false. |
| 272 | */ |
| 273 | public boolean updateDevice(DeviceEvent device) { |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 274 | // TODO implement |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 275 | return false; // Failure: not implemented yet |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 276 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 277 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 278 | /** |
| 279 | * Remove a device from the database. |
| 280 | * |
| 281 | * @param device the device to remove. |
| 282 | * @return true on success, otherwise false. |
| 283 | */ |
| 284 | public boolean removeDevice(DeviceEvent device) { |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 285 | // TODO implement |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 286 | return false; // Failure: not implemented yet |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 287 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 288 | |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 289 | /** |
| 290 | * Write an object to the database. |
| 291 | * |
| 292 | * @param object the object to write. |
| 293 | * @return true on success, otherwise false. |
| 294 | */ |
| 295 | private boolean writeObject(RCObject object) { |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 296 | for (int i = 0; i < NUM_RETRIES; i++) { |
| 297 | try { |
| 298 | object.create(); |
| 299 | } catch (ObjectExistsException e) { |
| 300 | try { |
| 301 | object.read(); |
| 302 | } catch (ObjectDoesntExistException e1) { |
| 303 | // TODO Auto-generated catch block |
| 304 | log.error(" ", e); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 305 | return false; // Failure |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 306 | } |
| 307 | } |
Yuta HIGUCHI | b4335ad | 2014-02-05 09:56:07 -0800 | [diff] [blame] | 308 | |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 309 | try { |
| 310 | // TODO check API for writing without caring what's there |
| 311 | object.update(); |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 312 | return true; // Success |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 313 | } catch (ObjectDoesntExistException | WrongVersionException e) { |
| 314 | log.debug(" ", e); |
| 315 | // re-read and retry |
| 316 | } |
| 317 | } |
Pavlin Radoslavov | ca52907 | 2014-02-19 14:07:52 -0800 | [diff] [blame] | 318 | |
| 319 | return false; // Failure |
Jonathan Hart | 062a2e8 | 2014-02-03 09:41:57 -0800 | [diff] [blame] | 320 | } |
| 321 | } |