diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-07-08 10:01:45 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-07-08 10:01:45 +0200 |
commit | 08afd426d391fa66f51be424b1f6b2f593b8e116 (patch) | |
tree | 6740d5d653876d48a1b610fbe8200039b454843a /zkfacade | |
parent | 679ed0d71e2548d4984989f9828dc71c66267ccf (diff) |
Support recursivetransactional delete in zk
Diffstat (limited to 'zkfacade')
4 files changed, 46 insertions, 3 deletions
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java index c037f7e8ae2..4c08924f8de 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java @@ -227,7 +227,7 @@ public class Curator { } /** - * Returns the children at the given path. + * Returns the names of the children at the given path. * If the path does not exist or have no children an empty list (never null) is returned. */ public List<String> getChildren(Path path) { diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorDeleteOperation.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorDeleteOperation.java index e49a4cca9d2..95c8a1b732f 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorDeleteOperation.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorDeleteOperation.java @@ -21,10 +21,17 @@ class CuratorDeleteOperation implements CuratorOperation { public void check(Curator curator, TransactionChanges changes) { if ( ! curator.exists(Path.fromString(path)) && ! changes.create(path)) throw new IllegalStateException("Cannot perform " + this + ": Path does not exist"); - if (curator.getChildren(Path.fromString(path)).size() > 0 || changes.createsChildrenOf(path)) + if (hasNondeletedChildren(Path.fromString(path), curator, changes) || changes.createsChildrenOf(path)) throw new IllegalStateException("Cannot perform " + this + ": Path is not empty"); changes.addDelete(path); } + + private boolean hasNondeletedChildren(Path path, Curator curator, TransactionChanges changes) { + for (String childName : curator.getChildren(path)) + if ( ! changes.delete(path.append(childName).getAbsolute())) + return true; + return false; + } @Override public CuratorTransaction and(CuratorTransaction transaction) throws Exception { diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorOperations.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorOperations.java index f1af85bcb1b..84a98dab7eb 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorOperations.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorOperations.java @@ -1,12 +1,18 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.curator.transaction; +import com.yahoo.path.Path; +import com.yahoo.vespa.curator.Curator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Optional; /** * Factory for transactional ZooKeeper operations. * This mirrors the operations which are actually available in Curator, which unfortunately does not include - * convenient variants that deletes children, creates parents etc. + * variants that deletes children, creates parents etc. in a single operation. * * @author lulf * @author bratseth @@ -49,4 +55,24 @@ public class CuratorOperations { return new CuratorDeleteOperation(path); } + /** + * Returns operations deleting this path and everything below it, in an order where a parent + * is ordered after all its children, + * such that the operations will succeed when executed in the returned order. + * This does not fail, but returns an empty list if the path does not exist. + */ + public static List<CuratorOperation> deleteAll(String path, Curator curator) { + if ( ! curator.exists(Path.fromString(path))) return Collections.emptyList(); + + List<CuratorOperation> operations = new ArrayList<>(); + deleteRecursively(Path.fromString(path), operations, curator); + return operations; + } + + private static void deleteRecursively(Path path, List<CuratorOperation> operations, Curator curator) { + for (String childName : curator.getChildren(path)) + deleteRecursively(path.append(childName), operations, curator); + operations.add(delete(path.getAbsolute())); + } + } diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorTransaction.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorTransaction.java index 1345cabcd40..551fb9c1501 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorTransaction.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/transaction/CuratorTransaction.java @@ -5,6 +5,8 @@ import com.yahoo.transaction.AbstractTransaction; import com.yahoo.vespa.curator.Curator; import org.apache.curator.framework.api.transaction.CuratorTransactionFinal; +import java.util.List; + /** * Transaction implementation against ZooKeeper. * @@ -31,6 +33,14 @@ public class CuratorTransaction extends AbstractTransaction { return transaction; } + /** Returns a curator transaction having a list of operations */ + public static CuratorTransaction from(List<CuratorOperation> operations, Curator curator) { + CuratorTransaction transaction = new CuratorTransaction(curator); + for (Operation operation : operations) + transaction.add(operation); + return transaction; + } + @Override public void prepare() { TransactionChanges changes = new TransactionChanges(); |