Attempts to write the rule to storage via CompareAndSet, merging changes with an existing rule. Note: If the local object didn't have any fields set by the caller or there weren't any changes, then the data will not be written and an exception will be thrown. Note: This method also val
(final TSDB tsdb,
final boolean overwrite)
| 248 | * @throws JSONException if the object could not be serialized |
| 249 | */ |
| 250 | public Deferred<Boolean> syncToStorage(final TSDB tsdb, |
| 251 | final boolean overwrite) { |
| 252 | if (tree_id < 1 || tree_id > 65535) { |
| 253 | throw new IllegalArgumentException("Invalid Tree ID"); |
| 254 | } |
| 255 | |
| 256 | // if there aren't any changes, save time and bandwidth by not writing to |
| 257 | // storage |
| 258 | boolean has_changes = false; |
| 259 | for (Map.Entry<String, Boolean> entry : changed.entrySet()) { |
| 260 | if (entry.getValue()) { |
| 261 | has_changes = true; |
| 262 | break; |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | if (!has_changes) { |
| 267 | LOG.trace(this + " does not have changes, skipping sync to storage"); |
| 268 | throw new IllegalStateException("No changes detected in the rule"); |
| 269 | } |
| 270 | |
| 271 | /** |
| 272 | * Executes the CAS after retrieving existing rule from storage, if it |
| 273 | * exists. |
| 274 | */ |
| 275 | final class StoreCB implements Callback<Deferred<Boolean>, TreeRule> { |
| 276 | final TreeRule local_rule; |
| 277 | |
| 278 | public StoreCB(final TreeRule local_rule) { |
| 279 | this.local_rule = local_rule; |
| 280 | } |
| 281 | |
| 282 | /** |
| 283 | * @return True if the CAS was successful, false if not |
| 284 | */ |
| 285 | @Override |
| 286 | public Deferred<Boolean> call(final TreeRule fetched_rule) { |
| 287 | |
| 288 | TreeRule stored_rule = fetched_rule; |
| 289 | final byte[] original_rule = stored_rule == null ? new byte[0] : |
| 290 | JSON.serializeToBytes(stored_rule); |
| 291 | if (stored_rule == null) { |
| 292 | stored_rule = local_rule; |
| 293 | } else { |
| 294 | if (!stored_rule.copyChanges(local_rule, overwrite)) { |
| 295 | LOG.debug(this + " does not have changes, skipping sync to storage"); |
| 296 | throw new IllegalStateException("No changes detected in the rule"); |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | // reset the local change map so we don't keep writing on subsequent |
| 301 | // requests |
| 302 | initializeChangedMap(); |
| 303 | |
| 304 | // validate before storing |
| 305 | stored_rule.validateRule(); |
| 306 | |
| 307 | final PutRequest put = new PutRequest(tsdb.treeTable(), |