Skip to content

Commit

Permalink
Nessie: Bump Nessie and add Namespace support
Browse files Browse the repository at this point in the history
  • Loading branch information
nastra committed Mar 24, 2022
1 parent ea8bbe7 commit f8e92b1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 27 deletions.
76 changes: 55 additions & 21 deletions nessie/src/main/java/org/apache/iceberg/nessie/NessieCatalog.java
Expand Up @@ -38,6 +38,7 @@
import org.apache.iceberg.exceptions.AlreadyExistsException;
import org.apache.iceberg.exceptions.CommitFailedException;
import org.apache.iceberg.exceptions.CommitStateUnknownException;
import org.apache.iceberg.exceptions.NamespaceNotEmptyException;
import org.apache.iceberg.exceptions.NoSuchNamespaceException;
import org.apache.iceberg.exceptions.NoSuchTableException;
import org.apache.iceberg.hadoop.HadoopFileIO;
Expand All @@ -55,10 +56,15 @@
import org.projectnessie.client.http.HttpClientException;
import org.projectnessie.error.BaseNessieClientServerException;
import org.projectnessie.error.NessieConflictException;
import org.projectnessie.error.NessieNamespaceAlreadyExistsException;
import org.projectnessie.error.NessieNamespaceNotEmptyException;
import org.projectnessie.error.NessieNamespaceNotFoundException;
import org.projectnessie.error.NessieNotFoundException;
import org.projectnessie.error.NessieReferenceNotFoundException;
import org.projectnessie.model.Branch;
import org.projectnessie.model.Content;
import org.projectnessie.model.ContentKey;
import org.projectnessie.model.GetNamespacesResponse;
import org.projectnessie.model.IcebergTable;
import org.projectnessie.model.Operation;
import org.projectnessie.model.Reference;
Expand Down Expand Up @@ -281,46 +287,74 @@ public void renameTable(TableIdentifier from, TableIdentifier toOriginal) {
// behavior. So better be safe than sorry.
}

/**
* creating namespaces in nessie is implicit, therefore this is a no-op. Metadata is ignored.
*
* @param namespace a multi-part namespace
* @param metadata a string Map of properties for the given namespace
*/
@Override
public void createNamespace(Namespace namespace, Map<String, String> metadata) {
try {
api.createNamespace()
.refName(reference.getName())
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
.create();
} catch (NessieNamespaceAlreadyExistsException e) {
throw new AlreadyExistsException(e, "Namespace '%s' already exists.", namespace);
} catch (NessieReferenceNotFoundException e) {
LOG.error("Cannot create Namespace '{}': ref is no longer valid.", namespace, e);
}
}

@Override
public List<Namespace> listNamespaces(Namespace namespace) throws NoSuchNamespaceException {
return tableStream(namespace)
.map(TableIdentifier::namespace)
.filter(n -> !n.isEmpty())
.distinct()
.collect(Collectors.toList());
try {
GetNamespacesResponse response = api.getMultipleNamespaces()
.refName(reference.getName())
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
.get();
return response.getNamespaces().stream()
.map(ns -> Namespace.of(ns.getElements().toArray(new String[0])))
.collect(Collectors.toList());
} catch (NessieReferenceNotFoundException e) {
LOG.error("Cannot list Namespaces starting from '{}': ref is no longer valid.", namespace, e);
}
throw new NoSuchNamespaceException("Namespace '%s' does not exist.", namespace);
}

/**
* namespace metadata is not supported in Nessie, thus we return an empty map.
* Load the given namespace but return an empty map because namespace properties are currently not supported.
*
* @param namespace a namespace. {@link Namespace}
* @return an empty map
* @throws NoSuchNamespaceException If the namespace does not exist
*/
@Override
public Map<String, String> loadNamespaceMetadata(Namespace namespace) throws NoSuchNamespaceException {
try {
api.getNamespace()
.refName(reference.getName())
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
.get();
} catch (NessieNamespaceNotFoundException e) {
throw new NoSuchNamespaceException(e, "Namespace '%s' does not exist.", namespace);
} catch (NessieReferenceNotFoundException e) {
LOG.error("Cannot load Namespace '{}': ref is no longer valid.", namespace, e);
}
return ImmutableMap.of();
}

/**
* Namespaces in Nessie are implicit and therefore cannot be dropped
*
* @param namespace The {@link Namespace} to drop.
* @throws UnsupportedOperationException Namespaces in Nessie are implicit and thus cannot be dropped.
*/
@Override
public boolean dropNamespace(Namespace namespace) {
throw new UnsupportedOperationException(
"Cannot drop namespace '" + namespace + "': dropNamespace is not supported by the NessieCatalog");
public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {
try {
api.deleteNamespace()
.refName(reference.getName())
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
.delete();
return true;
} catch (NessieNamespaceNotFoundException e) {
return false;
} catch (NessieReferenceNotFoundException e) {
LOG.error("Cannot drop Namespace '{}': ref is no longer valid.", namespace, e);
return false;
} catch (NessieNamespaceNotEmptyException e) {
throw new NamespaceNotEmptyException(e, "Namespace '%s' is not empty. One or more tables exist.", namespace);
}
}

@Override
Expand Down
Expand Up @@ -55,6 +55,7 @@
import org.projectnessie.model.Branch;
import org.projectnessie.model.Reference;
import org.projectnessie.model.Tag;
import org.projectnessie.server.store.TableCommitMetaStoreWorker;
import org.projectnessie.versioned.persist.adapter.DatabaseAdapter;
import org.projectnessie.versioned.persist.inmem.InmemoryDatabaseAdapterFactory;
import org.projectnessie.versioned.persist.inmem.InmemoryTestConnectionProviderSource;
Expand All @@ -72,7 +73,7 @@
@NessieExternalDatabase(InmemoryTestConnectionProviderSource.class)
public abstract class BaseTestIceberg {

@NessieDbAdapter
@NessieDbAdapter(storeWorker = TableCommitMetaStoreWorker.class)
static DatabaseAdapter databaseAdapter;
@RegisterExtension
static NessieJaxRsExtension server = new NessieJaxRsExtension(() -> databaseAdapter);
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -62,10 +63,12 @@ public void testListNamespaces() {
}

@Test
public void testDroppingNamespace() {
Assertions.assertThatThrownBy(() -> catalog.dropNamespace(Namespace.of("test")))
.isInstanceOf(UnsupportedOperationException.class)
.hasMessage("Cannot drop namespace 'test': dropNamespace is not supported by the NessieCatalog");
public void testCreatingAndDroppingNamespace() {
Namespace namespace = Namespace.of("test");
catalog.createNamespace(namespace, ImmutableMap.of());
Assertions.assertThat(catalog.namespaceExists(namespace)).isTrue();
catalog.dropNamespace(namespace);
Assertions.assertThat(catalog.namespaceExists(namespace)).isFalse();
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion versions.props
Expand Up @@ -23,7 +23,7 @@ javax.xml.bind:jaxb-api = 2.3.1
javax.activation:activation = 1.1.1
org.glassfish.jaxb:jaxb-runtime = 2.3.3
software.amazon.awssdk:* = 2.17.131
org.projectnessie:* = 0.22.0
org.projectnessie:* = 0.23.1
com.google.cloud:libraries-bom = 24.1.0
org.scala-lang.modules:scala-collection-compat_2.12 = 2.6.0
org.scala-lang.modules:scala-collection-compat_2.13 = 2.6.0
Expand Down

0 comments on commit f8e92b1

Please sign in to comment.