snazy commented on code in PR #8857:
URL: https://github.com/apache/iceberg/pull/8857#discussion_r1365087588


##########
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:
##########
@@ -223,27 +284,57 @@ namespace, getRef().getName()),
   }
 
   public boolean dropNamespace(Namespace namespace) throws 
NamespaceNotEmptyException {
+
+    getRef().checkMutable();
+    ContentKey key = ContentKey.of(namespace.levels());
+
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .deleteNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels())))
-          .delete();
-      refresh();
+
+      CommitMultipleOperationsBuilder commitBuilder =
+          api.commitMultipleOperations()
+              .commitMeta(NessieUtil.buildCommitMetadata("drop namespace " + 
key, catalogOptions))
+              .operation(Operation.Delete.of(key));
+
+      Tasks.foreach(commitBuilder)
+          .retry(5)
+          .stopRetryOn(
+              NessieReferenceNotFoundException.class, 
NessieReferenceConflictException.class)
+          .throwFailureWhenFinished()
+          .onFailure((o, exception) -> refresh())
+          .run(
+              b -> {

Review Comment:
   Rename `b` to `commit`



##########
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:
##########
@@ -181,23 +182,83 @@ public IcebergTable table(TableIdentifier 
tableIdentifier) {
   }
 
   public void createNamespace(Namespace namespace, Map<String, String> 
metadata) {
+    getRef().checkMutable();
+
+    if (namespace.isEmpty()) {
+      throw new IllegalArgumentException("Creating empty namespaces is not 
supported");
+    }
+
+    ContentKey key = ContentKey.of(namespace.levels());
+    org.projectnessie.model.Namespace content =
+        org.projectnessie.model.Namespace.of(key.getElements(), metadata);
+
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .createNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
-                  .properties(metadata))
-          .create();
-      refresh();
-    } catch (NessieNamespaceAlreadyExistsException e) {
-      throw new AlreadyExistsException(e, "Namespace already exists: %s", 
namespace);
+
+      // First, check that the namespace doesn't exist at the current hash;
+      // this will avoid a NessieBadRequestException when committing the 
namespace creation
+      Reference ref = getReference();
+      Map<ContentKey, Content> contentMap = 
api.getContent().reference(ref).key(key).get();

Review Comment:
   You can simplify this one in two (alternative) ways:
   1. check if the returned map is empty (there can only be one element)
   2. use `api.getContent().reference(ref).getSingle(key)` - however this one 
throws a NessieNotFoundException, if the content does not exist or if the ref 
does not exist - so it's probably more code (multiple catch-clauses)



##########
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:
##########
@@ -223,27 +284,57 @@ namespace, getRef().getName()),
   }
 
   public boolean dropNamespace(Namespace namespace) throws 
NamespaceNotEmptyException {
+
+    getRef().checkMutable();
+    ContentKey key = ContentKey.of(namespace.levels());
+
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .deleteNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels())))
-          .delete();
-      refresh();
+
+      CommitMultipleOperationsBuilder commitBuilder =
+          api.commitMultipleOperations()
+              .commitMeta(NessieUtil.buildCommitMetadata("drop namespace " + 
key, catalogOptions))
+              .operation(Operation.Delete.of(key));
+
+      Tasks.foreach(commitBuilder)
+          .retry(5)
+          .stopRetryOn(
+              NessieReferenceNotFoundException.class, 
NessieReferenceConflictException.class)
+          .throwFailureWhenFinished()
+          .onFailure((o, exception) -> refresh())
+          .run(
+              b -> {
+                Branch branch = b.branch((Branch) getReference()).commit();
+                getRef().updateReference(branch);
+              },
+              BaseNessieClientServerException.class);
+
       return true;
-    } catch (NessieNamespaceNotFoundException e) {
-      return false;
-    } catch (NessieNotFoundException e) {
+    } catch (NessieReferenceNotFoundException e) {
       LOG.error(
           "Cannot drop Namespace '{}': ref '{}' is no longer valid.",
           namespace,
           getRef().getName(),
           e);
       return false;
-    } catch (NessieNamespaceNotEmptyException e) {
-      throw new NamespaceNotEmptyException(
-          e, "Namespace '%s' is not empty. One or more tables exist.", 
namespace);
+    } catch (NessieReferenceConflictException e) {
+      List<Conflict> conflicts = e.getErrorDetails().conflicts();

Review Comment:
   Suggestion (also for the conflict handling above):
   
   ```
   Optional<Conflict.ConflictType> conflict = 
e.getErrorDetails().conflicts().stream().filter(c -> 
key.equals(c.key())).map(Conflict::conflictType).findFirst();
   if (conflict.isPresent()) {
     switch (conflict.get()) {
       case KEY_DOES_NOT_EXIST: return false;
       case NAMESPACE_NOT_EMPTY: throw ...;
     }
   }
   ```
   
   Maybe worth to handle all conflicts in one method used for create-ref and 
drop-ref?



##########
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:
##########
@@ -181,23 +182,83 @@ public IcebergTable table(TableIdentifier 
tableIdentifier) {
   }
 
   public void createNamespace(Namespace namespace, Map<String, String> 
metadata) {
+    getRef().checkMutable();
+
+    if (namespace.isEmpty()) {
+      throw new IllegalArgumentException("Creating empty namespaces is not 
supported");
+    }
+
+    ContentKey key = ContentKey.of(namespace.levels());
+    org.projectnessie.model.Namespace content =
+        org.projectnessie.model.Namespace.of(key.getElements(), metadata);
+
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .createNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
-                  .properties(metadata))
-          .create();
-      refresh();
-    } catch (NessieNamespaceAlreadyExistsException e) {
-      throw new AlreadyExistsException(e, "Namespace already exists: %s", 
namespace);
+
+      // First, check that the namespace doesn't exist at the current hash;
+      // this will avoid a NessieBadRequestException when committing the 
namespace creation
+      Reference ref = getReference();
+      Map<ContentKey, Content> contentMap = 
api.getContent().reference(ref).key(key).get();
+      Content existing = contentMap.get(key);
+      if (existing != null) {
+        throwNamespaceAlreadyExists(key, existing);
+      }
+
+      try {
+
+        CommitMultipleOperationsBuilder commitBuilder =
+            api.commitMultipleOperations()
+                .commitMeta(
+                    NessieUtil.buildCommitMetadata("create namespace " + key, 
catalogOptions))
+                .operation(Operation.Put.of(key, content));
+
+        Tasks.foreach(commitBuilder)
+            .retry(5)
+            .stopRetryOn(
+                NessieReferenceNotFoundException.class, 
NessieReferenceConflictException.class)
+            .throwFailureWhenFinished()
+            .onFailure((o, exception) -> refresh())
+            .run(
+                b -> {

Review Comment:
   Nit: rename `b` to `commit` or so (`b` can be associated with a branch)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org
For additional commands, e-mail: issues-h...@iceberg.apache.org

Reply via email to