use of org.projectnessie.client.api.CommitMultipleOperationsBuilder in project iceberg by apache.
the class NessieCatalog method renameTable.
@Override
public void renameTable(TableIdentifier from, TableIdentifier toOriginal) {
reference.checkMutable();
TableIdentifier to = NessieUtil.removeCatalogName(toOriginal, name());
IcebergTable existingFromTable = table(from);
if (existingFromTable == null) {
throw new NoSuchTableException("table %s doesn't exists", from.name());
}
IcebergTable existingToTable = table(to);
if (existingToTable != null) {
throw new AlreadyExistsException("table %s already exists", to.name());
}
CommitMultipleOperationsBuilder operations = api.commitMultipleOperations().commitMeta(NessieUtil.buildCommitMetadata(String.format("Iceberg rename table from '%s' to '%s'", from, to), catalogOptions)).operation(Operation.Put.of(NessieUtil.toKey(to), existingFromTable, existingFromTable)).operation(Operation.Delete.of(NessieUtil.toKey(from)));
try {
Tasks.foreach(operations).retry(5).stopRetryOn(NessieNotFoundException.class).throwFailureWhenFinished().onFailure((o, exception) -> refresh()).run(ops -> {
Branch branch = ops.branch(reference.getAsBranch()).commit();
reference.updateReference(branch);
}, BaseNessieClientServerException.class);
} catch (NessieNotFoundException e) {
// and removed by another.
throw new RuntimeException("Failed to drop table as ref is no longer valid.", e);
} catch (BaseNessieClientServerException e) {
throw new CommitFailedException(e, "Failed to rename table: the current reference is not up to date.");
} catch (HttpClientException ex) {
// safe than sorry.
throw new CommitStateUnknownException(ex);
}
// Intentionally just "throw through" Nessie's HttpClientException here and do not "special case"
// just the "timeout" variant to propagate all kinds of network errors (e.g. connection reset).
// Network code implementation details and all kinds of network devices can induce unexpected
// behavior. So better be safe than sorry.
}
use of org.projectnessie.client.api.CommitMultipleOperationsBuilder in project iceberg by apache.
the class NessieCatalog method dropTable.
@Override
public boolean dropTable(TableIdentifier identifier, boolean purge) {
reference.checkMutable();
IcebergTable existingTable = table(identifier);
if (existingTable == null) {
return false;
}
if (purge) {
LOG.info("Purging data for table {} was set to true but is ignored", identifier.toString());
}
CommitMultipleOperationsBuilder commitBuilderBase = api.commitMultipleOperations().commitMeta(NessieUtil.buildCommitMetadata(String.format("Iceberg delete table %s", identifier), catalogOptions)).operation(Operation.Delete.of(NessieUtil.toKey(identifier)));
// We try to drop the table. Simple retry after ref update.
boolean threw = true;
try {
Tasks.foreach(commitBuilderBase).retry(5).stopRetryOn(NessieNotFoundException.class).throwFailureWhenFinished().onFailure((o, exception) -> refresh()).run(commitBuilder -> {
Branch branch = commitBuilder.branch(reference.getAsBranch()).commit();
reference.updateReference(branch);
}, BaseNessieClientServerException.class);
threw = false;
} catch (NessieConflictException e) {
LOG.error("Cannot drop table: failed after retry (update ref and retry)", e);
} catch (NessieNotFoundException e) {
LOG.error("Cannot drop table: ref is no longer valid.", e);
} catch (BaseNessieClientServerException e) {
LOG.error("Cannot drop table: unknown error", e);
}
return !threw;
}
use of org.projectnessie.client.api.CommitMultipleOperationsBuilder in project nessie by projectnessie.
the class GenerateContent method execute.
@Override
public void execute() throws BaseNessieClientServerException {
if (runtimeDuration != null) {
if (runtimeDuration.isZero() || runtimeDuration.isNegative()) {
throw new ParameterException(spec.commandLine(), "Duration must be absent to greater than zero.");
}
}
Duration perCommitDuration = Optional.ofNullable(runtimeDuration).orElse(Duration.ZERO).dividedBy(numCommits);
ThreadLocalRandom random = ThreadLocalRandom.current();
String runStartTime = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss").format(LocalDateTime.now());
List<ContentKey> tableNames = IntStream.range(0, numTables).mapToObj(i -> ContentKey.of(String.format("create-contents-%s", runStartTime), "contents", Integer.toString(i))).collect(Collectors.toList());
try (NessieApiV1 api = createNessieApiInstance()) {
Branch defaultBranch;
if (defaultBranchName == null) {
// Use the server's default branch.
defaultBranch = api.getDefaultBranch();
} else {
// Use the specified default branch.
try {
defaultBranch = (Branch) api.getReference().refName(defaultBranchName).get();
} catch (NessieReferenceNotFoundException e) {
// Create branch if it does not exist.
defaultBranch = api.getDefaultBranch();
defaultBranch = (Branch) api.createReference().reference(Branch.of(defaultBranchName, defaultBranch.getHash())).sourceRefName(defaultBranch.getName()).create();
}
}
List<String> branches = new ArrayList<>();
branches.add(defaultBranch.getName());
while (branches.size() < branchCount) {
// Create a new branch
String newBranchName = "branch-" + runStartTime + "_" + (branches.size() - 1);
Branch branch = Branch.of(newBranchName, defaultBranch.getHash());
spec.commandLine().getOut().printf("Creating branch '%s' from '%s' at %s%n", branch.getName(), defaultBranch.getName(), branch.getHash());
api.createReference().reference(branch).sourceRefName(defaultBranch.getName()).create();
branches.add(newBranchName);
}
spec.commandLine().getOut().printf("Starting contents generation, %d commits...%n", numCommits);
for (int i = 0; i < numCommits; i++) {
// Choose a random branch to commit to
String branchName = branches.get(random.nextInt(branches.size()));
Branch commitToBranch = (Branch) api.getReference().refName(branchName).get();
ContentKey tableName = tableNames.get(random.nextInt(tableNames.size()));
Content tableContents = api.getContent().refName(branchName).key(tableName).get().get(tableName);
Content newContents = createContents(tableContents, random);
spec.commandLine().getOut().printf("Committing content-key '%s' to branch '%s' at %s%n", tableName, commitToBranch.getName(), commitToBranch.getHash());
CommitMultipleOperationsBuilder commit = api.commitMultipleOperations().branch(commitToBranch).commitMeta(CommitMeta.builder().message(String.format("%s table %s on %s, commit #%d of %d", tableContents != null ? "Update" : "Create", tableName, branchName, i, numCommits)).author(System.getProperty("user.name")).authorTime(Instant.now()).build());
if (newContents instanceof IcebergTable || newContents instanceof IcebergView) {
commit.operation(Put.of(tableName, newContents, tableContents));
} else {
commit.operation(Put.of(tableName, newContents));
}
Branch newHead = commit.commit();
if (random.nextDouble() < newTagProbability) {
Tag tag = Tag.of("new-tag-" + random.nextLong(), newHead.getHash());
spec.commandLine().getOut().printf("Creating tag '%s' from '%s' at %s%n", tag.getName(), branchName, tag.getHash());
api.createReference().reference(tag).sourceRefName(branchName).create();
}
try {
TimeUnit.NANOSECONDS.sleep(perCommitDuration.toNanos());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
spec.commandLine().getOut().printf("Done creating contents.%n");
}
use of org.projectnessie.client.api.CommitMultipleOperationsBuilder in project nessie by projectnessie.
the class AbstractRestGC method commitSingleOp.
CommitOutput commitSingleOp(String prefix, Reference branch, String currentHash, long snapshotId, String contentId, String contentKey, String metadataFile, IcebergTable previous, String beforeRename) throws NessieNotFoundException, NessieConflictException {
IcebergTable meta = IcebergTable.of(prefix + "_" + metadataFile, snapshotId, 42, 42, 42, prefix + "_" + contentId);
CommitMultipleOperationsBuilder multiOp = getApi().commitMultipleOperations().branchName(branch.getName()).hash(currentHash).commitMeta(CommitMeta.builder().author("someone").message("some commit").properties(ImmutableMap.of("prop1", "val1", "prop2", "val2")).build()).operation(Put.of(ContentKey.of(prefix + "_" + contentKey), meta, previous));
if (beforeRename != null) {
multiOp.operation(Operation.Delete.of(ContentKey.of(prefix + "_" + beforeRename)));
}
String nextHash = multiOp.commit().getHash();
assertThat(currentHash).isNotEqualTo(nextHash);
return new CommitOutput(nextHash, meta);
}
use of org.projectnessie.client.api.CommitMultipleOperationsBuilder in project nessie by projectnessie.
the class AbstractRestNamespace method testNamespaceDeletion.
@Test
public void testNamespaceDeletion() throws BaseNessieClientServerException {
Branch branch = createBranch("testNamespaceDeletion");
CommitMultipleOperationsBuilder commit = getApi().commitMultipleOperations().branch(branch).commitMeta(CommitMeta.fromMessage("verifyAllContentAndOperationTypes"));
contentAndOperationTypes().flatMap(c -> c.globalOperation == null ? Stream.of(c.operation) : Stream.of(c.operation, c.globalOperation)).forEach(commit::operation);
commit.commit();
List<Entry> entries = contentAndOperationTypes().filter(c -> c.operation instanceof Put).map(c -> Entry.builder().type(c.type).name(c.operation.getKey()).build()).collect(Collectors.toList());
for (Entry e : entries) {
Namespace namespace = e.getName().getNamespace();
assertThat(getApi().getNamespace().refName(branch.getName()).namespace(namespace).get()).isEqualTo(namespace);
assertThatThrownBy(() -> getApi().deleteNamespace().refName(branch.getName()).namespace(namespace).delete()).isInstanceOf(NessieNamespaceNotEmptyException.class).hasMessage(String.format("Namespace '%s' is not empty", namespace));
}
}
Aggregations