Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.projectnessie.services.rest.RestV2TreeResource Maven / Gradle / Ivy
/*
* Copyright (C) 2022 Dremio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.rest;
import static com.google.common.base.Preconditions.checkArgument;
import static org.projectnessie.api.v2.params.ReferenceResolver.resolveReferencePathElement;
import static org.projectnessie.services.impl.RefUtil.toReference;
import static org.projectnessie.services.spi.TreeService.MAX_COMMIT_LOG_ENTRIES;
import com.fasterxml.jackson.annotation.JsonView;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.Path;
import java.util.List;
import java.util.Locale;
import org.projectnessie.api.v2.http.HttpTreeApi;
import org.projectnessie.api.v2.params.CommitLogParams;
import org.projectnessie.api.v2.params.DiffParams;
import org.projectnessie.api.v2.params.EntriesParams;
import org.projectnessie.api.v2.params.GetReferenceParams;
import org.projectnessie.api.v2.params.Merge;
import org.projectnessie.api.v2.params.ParsedReference;
import org.projectnessie.api.v2.params.ReferenceHistoryParams;
import org.projectnessie.api.v2.params.ReferencesParams;
import org.projectnessie.api.v2.params.Transplant;
import org.projectnessie.error.NessieConflictException;
import org.projectnessie.error.NessieNotFoundException;
import org.projectnessie.model.CommitMeta;
import org.projectnessie.model.CommitResponse;
import org.projectnessie.model.ContentKey;
import org.projectnessie.model.ContentResponse;
import org.projectnessie.model.DiffResponse;
import org.projectnessie.model.DiffResponse.DiffEntry;
import org.projectnessie.model.EntriesResponse;
import org.projectnessie.model.GetMultipleContentsRequest;
import org.projectnessie.model.GetMultipleContentsResponse;
import org.projectnessie.model.ImmutableCommitMeta;
import org.projectnessie.model.ImmutableDiffResponse;
import org.projectnessie.model.ImmutableEntriesResponse;
import org.projectnessie.model.ImmutableGetMultipleContentsRequest;
import org.projectnessie.model.ImmutableLogResponse;
import org.projectnessie.model.ImmutableReferencesResponse;
import org.projectnessie.model.LogResponse;
import org.projectnessie.model.LogResponse.LogEntry;
import org.projectnessie.model.MergeResponse;
import org.projectnessie.model.Operations;
import org.projectnessie.model.Reference;
import org.projectnessie.model.ReferenceHistoryResponse;
import org.projectnessie.model.ReferencesResponse;
import org.projectnessie.model.SingleReferenceResponse;
import org.projectnessie.model.ser.Views;
import org.projectnessie.services.spi.ConfigService;
import org.projectnessie.services.spi.ContentService;
import org.projectnessie.services.spi.DiffService;
import org.projectnessie.services.spi.PagedCountingResponseHandler;
import org.projectnessie.services.spi.TreeService;
/** REST endpoint for the tree-API. */
@RequestScoped
@Path("api/v2/trees")
public class RestV2TreeResource implements HttpTreeApi {
private final ConfigService configService;
private final TreeService treeService;
private final ContentService contentService;
private final DiffService diffService;
// Mandated by CDI 2.0
public RestV2TreeResource() {
this(null, null, null, null);
}
@Inject
public RestV2TreeResource(
ConfigService configService,
TreeService treeService,
ContentService contentService,
DiffService diffService) {
this.configService = configService;
this.treeService = treeService;
this.contentService = contentService;
this.diffService = diffService;
}
private ParsedReference parseRefPathString(String refPathString) {
return parseRefPathString(refPathString, Reference.ReferenceType.BRANCH);
}
private ParsedReference parseRefPathString(
String refPathString, Reference.ReferenceType referenceType) {
return resolveReferencePathElement(
refPathString, referenceType, () -> configService.getConfig().getDefaultBranch());
}
private TreeService tree() {
return treeService;
}
private DiffService diff() {
return diffService;
}
private ContentService content() {
return contentService;
}
@JsonView(Views.V2.class)
@Override
public ReferencesResponse getAllReferences(ReferencesParams params) {
Integer maxRecords = params.maxRecords();
return tree()
.getAllReferences(
params.fetchOption(),
params.filter(),
params.pageToken(),
new PagedCountingResponseHandler<>(maxRecords) {
final ImmutableReferencesResponse.Builder builder = ReferencesResponse.builder();
@Override
public ReferencesResponse build() {
return builder.build();
}
@Override
protected boolean doAddEntry(Reference entry) {
builder.addReferences(entry);
return true;
}
@Override
public void hasMore(String pagingToken) {
builder.isHasMore(true).token(pagingToken);
}
});
}
@JsonView(Views.V2.class)
@Override
public SingleReferenceResponse createReference(String name, String type, Reference reference)
throws NessieNotFoundException, NessieConflictException {
Reference.ReferenceType referenceType = parseReferenceType(type);
checkArgument(referenceType != null, "Mandatory reference type missing");
String fromRefName = null;
String fromHash = null;
if (reference != null) {
fromRefName = reference.getName();
fromHash = reference.getHash();
}
Reference created = tree().createReference(name, referenceType, fromHash, fromRefName);
return SingleReferenceResponse.builder().reference(created).build();
}
@JsonView(Views.V2.class)
@Override
public SingleReferenceResponse getReferenceByName(GetReferenceParams params)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(params.getRef());
checkArgument(
reference.hashWithRelativeSpec() == null,
"Hashes are not allowed when fetching a reference by name");
return SingleReferenceResponse.builder()
.reference(tree().getReferenceByName(reference.name(), params.fetchOption()))
.build();
}
@JsonView(Views.V2.class)
@Override
public ReferenceHistoryResponse getReferenceHistory(ReferenceHistoryParams params)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(params.getRef());
checkArgument(
reference.hashWithRelativeSpec() == null,
"Hashes are not allowed when fetching a reference history");
return tree().getReferenceHistory(reference.name(), params.headCommitsToScan());
}
@JsonView(Views.V2.class)
@Override
public EntriesResponse getEntries(String ref, EntriesParams params)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(ref);
Integer maxRecords = params.maxRecords();
ImmutableEntriesResponse.Builder builder = EntriesResponse.builder();
return tree()
.getEntries(
reference.name(),
reference.hashWithRelativeSpec(),
null,
params.filter(),
params.pageToken(),
params.withContent(),
new PagedCountingResponseHandler<>(maxRecords) {
@Override
public EntriesResponse build() {
return builder.build();
}
@Override
protected boolean doAddEntry(EntriesResponse.Entry entry) {
builder.addEntries(entry);
return true;
}
@Override
public void hasMore(String pagingToken) {
builder.isHasMore(true).token(pagingToken);
}
},
h -> builder.effectiveReference(toReference(h)),
params.minKey(),
params.maxKey(),
params.prefixKey(),
params.getRequestedKeys());
}
@JsonView(Views.V2.class)
@Override
public LogResponse getCommitLog(String ref, CommitLogParams params)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(ref);
Integer maxRecords = params.maxRecords();
return tree()
.getCommitLog(
reference.name(),
params.fetchOption(),
params.startHash(),
reference.hashWithRelativeSpec(),
params.filter(),
params.pageToken(),
new PagedCountingResponseHandler<>(maxRecords, MAX_COMMIT_LOG_ENTRIES) {
final ImmutableLogResponse.Builder builder = ImmutableLogResponse.builder();
@Override
public LogResponse build() {
return builder.build();
}
@Override
protected boolean doAddEntry(LogEntry entry) {
builder.addLogEntries(entry);
return true;
}
@Override
public void hasMore(String pagingToken) {
builder.isHasMore(true).token(pagingToken);
}
});
}
@JsonView(Views.V2.class)
@Override
public DiffResponse getDiff(DiffParams params) throws NessieNotFoundException {
Integer maxRecords = params.maxRecords();
ParsedReference from = parseRefPathString(params.getFromRef());
ParsedReference to = parseRefPathString(params.getToRef());
ImmutableDiffResponse.Builder builder = DiffResponse.builder();
return diff()
.getDiff(
from.name(),
from.hashWithRelativeSpec(),
to.name(),
to.hashWithRelativeSpec(),
params.pageToken(),
new PagedCountingResponseHandler<>(maxRecords) {
@Override
public DiffResponse build() {
return builder.build();
}
@Override
protected boolean doAddEntry(DiffEntry entry) {
builder.addDiffs(entry);
return true;
}
@Override
public void hasMore(String pagingToken) {
builder.isHasMore(true).token(pagingToken);
}
},
h -> builder.effectiveFromReference(toReference(h)),
h -> builder.effectiveToReference(toReference(h)),
params.minKey(),
params.maxKey(),
params.prefixKey(),
params.getRequestedKeys(),
params.getFilter());
}
@JsonView(Views.V2.class)
@Override
public SingleReferenceResponse assignReference(String type, String ref, Reference assignTo)
throws NessieNotFoundException, NessieConflictException {
ParsedReference reference = parseRefPathString(ref, parseReferenceType(type));
Reference updated =
tree()
.assignReference(
reference.type(), reference.name(), reference.hashWithRelativeSpec(), assignTo);
return SingleReferenceResponse.builder().reference(updated).build();
}
@JsonView(Views.V2.class)
@Override
public SingleReferenceResponse deleteReference(String type, String ref)
throws NessieConflictException, NessieNotFoundException {
ParsedReference reference = parseRefPathString(ref, parseReferenceType(type));
Reference deleted =
tree()
.deleteReference(reference.type(), reference.name(), reference.hashWithRelativeSpec());
return SingleReferenceResponse.builder().reference(deleted).build();
}
private static Reference.ReferenceType parseReferenceType(String type) {
if (type == null) {
return null;
}
return Reference.ReferenceType.valueOf(type.toUpperCase(Locale.ROOT));
}
@JsonView(Views.V2.class)
@Override
public ContentResponse getContent(
ContentKey key, String ref, boolean withDocumentation, boolean forWrite)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(ref);
return content()
.getContent(
key, reference.name(), reference.hashWithRelativeSpec(), withDocumentation, forWrite);
}
@JsonView(Views.V2.class)
@Override
public GetMultipleContentsResponse getSeveralContents(
String ref, List keys, boolean withDocumentation, boolean forWrite)
throws NessieNotFoundException {
ImmutableGetMultipleContentsRequest.Builder request = GetMultipleContentsRequest.builder();
keys.forEach(k -> request.addRequestedKeys(ContentKey.fromPathString(k)));
return getMultipleContents(ref, request.build(), withDocumentation, forWrite);
}
@JsonView(Views.V2.class)
@Override
public GetMultipleContentsResponse getMultipleContents(
String ref, GetMultipleContentsRequest request, boolean withDocumentation, boolean forWrite)
throws NessieNotFoundException {
ParsedReference reference = parseRefPathString(ref);
return content()
.getMultipleContents(
reference.name(),
reference.hashWithRelativeSpec(),
request.getRequestedKeys(),
withDocumentation,
forWrite);
}
@JsonView(Views.V2.class)
@Override
public MergeResponse transplantCommitsIntoBranch(String branch, Transplant transplant)
throws NessieNotFoundException, NessieConflictException {
ParsedReference ref = parseRefPathString(branch);
String msg = transplant.getMessage();
CommitMeta meta = CommitMeta.fromMessage(msg == null ? "" : msg);
return tree()
.transplantCommitsIntoBranch(
ref.name(),
ref.hashWithRelativeSpec(),
meta,
transplant.getHashesToTransplant(),
transplant.getFromRefName(),
transplant.getKeyMergeModes(),
transplant.getDefaultKeyMergeMode(),
transplant.isDryRun(),
transplant.isFetchAdditionalInfo(),
transplant.isReturnConflictAsResult());
}
@JsonView(Views.V2.class)
@Override
public MergeResponse mergeRefIntoBranch(String branch, Merge merge)
throws NessieNotFoundException, NessieConflictException {
ParsedReference ref = parseRefPathString(branch);
@SuppressWarnings("deprecation")
String msg = merge.getMessage();
ImmutableCommitMeta.Builder meta = CommitMeta.builder();
CommitMeta commitMeta = merge.getCommitMeta();
if (commitMeta != null) {
meta.from(commitMeta);
if (commitMeta.getMessage().isEmpty() && msg != null) {
meta.message(msg);
}
} else {
meta.message(msg == null ? "" : msg);
}
return tree()
.mergeRefIntoBranch(
ref.name(),
ref.hashWithRelativeSpec(),
merge.getFromRefName(),
merge.getFromHash(),
meta.build(),
merge.getKeyMergeModes(),
merge.getDefaultKeyMergeMode(),
merge.isDryRun(),
merge.isFetchAdditionalInfo(),
merge.isReturnConflictAsResult());
}
@JsonView(Views.V2.class)
@Override
public CommitResponse commitMultipleOperations(String branch, Operations operations)
throws NessieNotFoundException, NessieConflictException {
ParsedReference ref = parseRefPathString(branch);
return tree().commitMultipleOperations(ref.name(), ref.hashWithRelativeSpec(), operations);
}
}