Skip to content

Commit

Permalink
Task: Add IfAbsent to LinkPhysicalAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
N-o-Z committed Feb 20, 2024
1 parent b9ddb4f commit 625c07a
Show file tree
Hide file tree
Showing 19 changed files with 155 additions and 10 deletions.
3 changes: 3 additions & 0 deletions api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,9 @@ components:
force:
type: boolean
default: false
if_absent:
type: boolean
default: false
required:
- staging
- checksum
Expand Down
4 changes: 4 additions & 0 deletions clients/java-legacy/api/openapi.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/java-legacy/docs/StagingMetadata.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions clients/java/api/openapi.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/java/docs/StagingMetadata.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/python-legacy/docs/StagingApi.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/python-legacy/docs/StagingMetadata.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions clients/python-legacy/lakefs_client/model/staging_metadata.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions clients/python/docs/StagingMetadata.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions clients/python/lakefs_sdk/models/staging_metadata.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion clients/python/test/test_staging_metadata.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions docs/assets/js/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,9 @@ components:
force:
type: boolean
default: false
if_absent:
type: boolean
default: false
required:
- staging
- checksum
Expand Down
3 changes: 1 addition & 2 deletions pkg/api/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,7 @@ func (c *Controller) LinkPhysicalAddress(w http.ResponseWriter, r *http.Request,
entryBuilder.Metadata(body.UserMetadata.AdditionalProperties)
}
entry := entryBuilder.Build()

err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry, graveler.WithForce(swag.BoolValue(body.Force)))
err = c.Catalog.CreateEntry(ctx, repo.Name, branch, entry, graveler.WithForce(swag.BoolValue(body.Force)), graveler.WithIfAbsent(swag.BoolValue(body.IfAbsent)))
if c.handleAPIError(ctx, w, r, err) {
return
}
Expand Down
44 changes: 44 additions & 0 deletions pkg/api/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3007,6 +3007,50 @@ func TestController_LinkPhysicalAddressHandler(t *testing.T) {
}
})

t.Run("link physical address twice if absent", func(t *testing.T) {
linkResp, err := clt.GetPhysicalAddressWithResponse(ctx, repo, "main", &apigen.GetPhysicalAddressParams{Path: "foo/bar2"})
verifyResponseOK(t, linkResp, err)
if linkResp.JSON200 == nil {
t.Fatalf("GetPhysicalAddress non 200 response - status code %d", linkResp.StatusCode())
}
const expectedSizeBytes = 38
ifAbsent := false
resp, err := clt.LinkPhysicalAddressWithResponse(ctx, repo, "main", &apigen.LinkPhysicalAddressParams{
Path: "foo/bar2",
}, apigen.LinkPhysicalAddressJSONRequestBody{
Checksum: "afb0689fe58b82c5f762991453edbbec",
SizeBytes: expectedSizeBytes,
Staging: apigen.StagingLocation{
PhysicalAddress: linkResp.JSON200.PhysicalAddress,
},
IfAbsent: &ifAbsent,
})
verifyResponseOK(t, resp, err)

// Try again with ifAbsent == true and expect failure
linkResp, err = clt.GetPhysicalAddressWithResponse(ctx, repo, "main", &apigen.GetPhysicalAddressParams{Path: "foo/bar2"})
verifyResponseOK(t, linkResp, err)
if linkResp.JSON200 == nil {
t.Fatalf("GetPhysicalAddress non 200 response - status code %d", linkResp.StatusCode())
}
ifAbsent = true
resp, err = clt.LinkPhysicalAddressWithResponse(ctx, repo, "main", &apigen.LinkPhysicalAddressParams{
Path: "foo/bar2",
}, apigen.LinkPhysicalAddressJSONRequestBody{
Checksum: "afb0689fe58b82c5f762991453edbbec",
SizeBytes: expectedSizeBytes,
Staging: apigen.StagingLocation{
PhysicalAddress: linkResp.JSON200.PhysicalAddress,
},
IfAbsent: &ifAbsent,
})
testutil.Must(t, err)
expectedStatusCode := http.StatusPreconditionFailed
if resp.HTTPResponse.StatusCode != expectedStatusCode {
t.Fatalf("LinkPhysicalAddress status code: %d, expected: %d", resp.HTTPResponse.StatusCode, expectedStatusCode)
}
})

t.Run("link physical address without getting it first", func(t *testing.T) {
const expectedSizeBytes = 38
resp, err := clt.LinkPhysicalAddressWithResponse(ctx, repo, "main", &apigen.LinkPhysicalAddressParams{
Expand Down
5 changes: 4 additions & 1 deletion pkg/graveler/graveler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,10 @@ func (g *Graveler) Set(ctx context.Context, repository *RepositoryRecord, branch

// verify the key not found
_, err := g.Get(ctx, repository, Ref(branchID), key)
if err == nil || !errors.Is(err, ErrNotFound) {
if err == nil { // Entry found, return precondition failed
err = ErrPreconditionFailed
}
if !errors.Is(err, ErrNotFound) {
return err
}

Expand Down

0 comments on commit 625c07a

Please sign in to comment.