Skip to content

Commit

Permalink
feat: Add NewListDirectoryPathsPager for azuredatalake
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbrittain committed Jan 13, 2025
1 parent f33c5da commit bc2318f
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 19 deletions.
6 changes: 6 additions & 0 deletions sdk/storage/azdatalake/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release History

## 1.3.1 (Unreleased)

### Features Added
* Added NewListDirectoryPathPager. Fixes [#23852](https://github.com/Azure/azure-sdk-for-go/issues/23852), [#21083](https://github.com/Azure/azure-sdk-for-go/issues/21083), [#18921](https://github.com/Azure/azure-sdk-for-go/issues/18921)
* Fix compareHeaders custom sorting algorithm for String To Sign.

## 1.3.0-beta.1 (2024-10-23)

### Other Changes
Expand Down
44 changes: 40 additions & 4 deletions sdk/storage/azdatalake/filesystem/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

// FOR FS CLIENT WE STORE THE GENERATED DATALAKE LAYER WITH BLOB ENDPOINT IN ORDER TO USE DELETED PATH LISTING
// FOR FS CLIENT WE STORE THE GENERATED DATALAKE LAYER WITH BLOB ENDPOINT IN ORDER TO USE DELETED/DIRECTORY PATH LISTING

package filesystem

import (
"context"
"net/http"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
Expand All @@ -23,9 +27,6 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/shared"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/sas"
"net/http"
"strings"
"time"
)

// ClientOptions contains the optional parameters when creating a Client.
Expand Down Expand Up @@ -307,6 +308,41 @@ func (fs *Client) NewListPathsPager(recursive bool, options *ListPathsOptions) *
})
}

// NewListDirectoryPathsPager operation returns a pager of the directory paths under the specified filesystem.
func (fs *Client) NewListDirectoryPathsPager(options *ListDirectoryPathsOptions) *runtime.Pager[ListDirectoryPathsSegmentResponse] {
listOptions := options.format()
return runtime.NewPager(runtime.PagingHandler[ListDirectoryPathsSegmentResponse]{
More: func(page ListDeletedPathsSegmentResponse) bool {
return page.NextMarker != nil && len(*page.NextMarker) > 0
},
Fetcher: func(ctx context.Context, page *ListDirectoryPathsSegmentResponse) (ListDirectoryPathsSegmentResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = fs.generatedFSClientWithBlob().ListBlobHierarchySegmentCreateRequest(ctx, &listOptions)
err = exported.ConvertToDFSError(err)
} else {
listOptions.Marker = page.NextMarker
req, err = fs.generatedFSClientWithBlob().ListBlobHierarchySegmentCreateRequest(ctx, &listOptions)
err = exported.ConvertToDFSError(err)
}
if err != nil {
return ListDirectoryPathsSegmentResponse{}, err
}
resp, err := fs.generatedFSClientWithBlob().InternalClient().Pipeline().Do(req)
err = exported.ConvertToDFSError(err)
if err != nil {
return ListDirectoryPathsSegmentResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ListDirectoryPathsSegmentResponse{}, runtime.NewResponseError(resp)
}
newResp, err := fs.generatedFSClientWithBlob().ListBlobHierarchySegmentHandleResponse(resp)
return newResp, exported.ConvertToDFSError(err)
},
})
}

// NewListDeletedPathsPager operation returns a pager of the shares under the specified account.
// For more information, see https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares
func (fs *Client) NewListDeletedPathsPager(options *ListDeletedPathsOptions) *runtime.Pager[ListDeletedPathsSegmentResponse] {
Expand Down
144 changes: 143 additions & 1 deletion sdk/storage/azdatalake/filesystem/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ package filesystem_test

import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file"
"strconv"
"strings"
"testing"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/internal/recording"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/datalakeerror"
Expand Down Expand Up @@ -1730,6 +1731,147 @@ func (s *RecordedTestSuite) TestFilesystemListPathsWithEncryptionContext() {
}
}

func (s *UnrecordedTestSuite) TestFilesystemListDirectoryPaths() {
_require := require.New(s.T())
testName := s.T().Name()

filesystemName := testcommon.GenerateFileSystemName(testName)
fsClient, err := testcommon.GetFileSystemClient(filesystemName, s.T(), testcommon.TestAccountDatalake, nil)
_require.NoError(err)
defer testcommon.DeleteFileSystem(context.Background(), _require, fsClient)

_, err = fsClient.Create(context.Background(), nil)
_require.NoError(err)

dirClient := fsClient.NewDirectoryClient(testName + "dir1")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)
dirClient = fsClient.NewDirectoryClient(testName + "dir2")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)

pager := fsClient.NewListDirectoryPathsPager(nil)
for pager.More() {
resp, err := pager.NextPage(context.Background())
_require.NoError(err)
_require.Equal(3, len(resp.ListPathsHierarchySegmentResponse.Segment.PathItems))
if err != nil {
break
}
}
}

func (s *UnrecordedTestSuite) TestFilesystemListDirectoryPathsMaxResults() {
_require := require.New(s.T())
testName := s.T().Name()

filesystemName := testcommon.GenerateFileSystemName(testName)
fsClient, err := testcommon.GetFileSystemClient(filesystemName, s.T(), testcommon.TestAccountDatalake, nil)
_require.NoError(err)
defer testcommon.DeleteFileSystem(context.Background(), _require, fsClient)

_, err = fsClient.Create(context.Background(), nil)
_require.NoError(err)

dirClient := fsClient.NewDirectoryClient(testName + "dir1")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)
dirClient = fsClient.NewDirectoryClient(testName + "dir2")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)

pages := 3
count := 0
opts := filesystem.ListDirectoryPathsOptions{
MaxResults: to.Ptr(int32(1)),
}

pager := fsClient.NewListDirectoryPathsPager(&opts)
for pager.More() {
_, err := pager.NextPage(context.Background())
_require.NoError(err)
count += 1
if err != nil {
break
}
}
_require.Equal(pages, count)
}

func (s *UnrecordedTestSuite) TestFilesystemListDirectoryPathsWithPrefix() {
_require := require.New(s.T())
testName := s.T().Name()

filesystemName := testcommon.GenerateFileSystemName(testName)
fsClient, err := testcommon.GetFileSystemClient(filesystemName, s.T(), testcommon.TestAccountDatalake, nil)
_require.NoError(err)
defer testcommon.DeleteFileSystem(context.Background(), _require, fsClient)

_, err = fsClient.Create(context.Background(), nil)
_require.NoError(err)

dirClient := fsClient.NewDirectoryClient(testName + "dir1")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)
dirClient = fsClient.NewDirectoryClient(testName + "dir2")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)

opts := filesystem.ListDirectoryPathsOptions{
Prefix: to.Ptr("Test"),
}

pager := fsClient.NewListDirectoryPathsPager(&opts)
for pager.More() {
resp, err := pager.NextPage(context.Background())
_require.NoError(err)
_require.Equal(3, len(resp.ListPathsHierarchySegmentResponse.Segment.PathItems))
if err != nil {
break
}
}
}

func (s *UnrecordedTestSuite) TestFilesystemListDirectoryPathsContinuation() {
_require := require.New(s.T())
testName := s.T().Name()

filesystemName := testcommon.GenerateFileSystemName(testName)
fsClient, err := testcommon.GetFileSystemClient(filesystemName, s.T(), testcommon.TestAccountDatalake, nil)
_require.NoError(err)
defer testcommon.DeleteFileSystem(context.Background(), _require, fsClient)

_, err = fsClient.Create(context.Background(), nil)
_require.NoError(err)

dirClient := fsClient.NewDirectoryClient(testName + "dir1")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)
dirClient = fsClient.NewDirectoryClient(testName + "dir2")
_, err = dirClient.Create(context.Background(), nil)
_require.NoError(err)

opts := filesystem.ListDirectoryPathsOptions{
MaxResults: to.Ptr(int32(2)),
}

pager := fsClient.NewListDirectoryPathsPager(&opts)

resp, err := pager.NextPage(context.Background())
_require.NoError(err)
_require.Equal(2, len(resp.ListPathsHierarchySegmentResponse.Segment.PathItems))
_require.NotNil(resp.NextMarker)

token := resp.NextMarker
pager = fsClient.NewListDeletedPathsPager(&filesystem.ListDeletedPathsOptions{
Marker: token,
})
resp, err = pager.NextPage(context.Background())
_require.NoError(err)
_require.Equal(1, len(resp.ListPathsHierarchySegmentResponse.Segment.PathItems))
_require.Equal("", *resp.NextMarker)
}

func (s *RecordedTestSuite) TestFilesystemListDeletedPaths() {
_require := require.New(s.T())
testName := s.T().Name()
Expand Down
30 changes: 29 additions & 1 deletion sdk/storage/azdatalake/filesystem/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (
"bytes"
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file"
"io"
"log"
"net/http"
"os"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
Expand Down Expand Up @@ -182,6 +183,33 @@ func Example_fs_ClientListPaths() {
}
}

func Example_fs_ClientListDirectoryPaths() {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
fsName := "testfs"
fsURL := fmt.Sprintf("https://%s.dfs.core.windows.net/%s", accountName, fsName)

cred, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

fsClient, err := filesystem.NewClient(fsURL, cred, nil)
handleError(err)

pager := fsClient.NewListDirectoryPathsPager(nil)

for pager.More() {
resp, err := pager.NextPage(context.TODO())
if err != nil {
log.Fatal(err)
}
for _, path := range resp.Segment.PathItems {
fmt.Println(*path.Name)
}
}
}

func Example_fs_ClientListDeletedPaths() {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
Expand Down
30 changes: 28 additions & 2 deletions sdk/storage/azdatalake/filesystem/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
package filesystem

import (
"time"

"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/directory"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/file"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/exported"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated"
"time"
)

// SetAccessPolicyOptions provides set of configurations for FileSystem.SetAccessPolicy operation.
Expand Down Expand Up @@ -158,6 +159,31 @@ func (o *ListPathsOptions) format() generated.FileSystemClientListPathsOptions {
}
}

// ListDirectoryPathsOptions contains the optional parameters from the FileSystem.ListDirectoryPathsOptions.
type ListDirectoryPathsOptions struct {
// Marker contains last continuation token returned from the service for listing.
Marker *string
// MaxResults sets the maximum number of paths that will be returned per page.
MaxResults *int32
// Prefix filters the results to return only paths whose names begin with the specified prefix path.
Prefix *string
}

func (o *ListDirectoryPathsOptions) format() generated.FileSystemClientListBlobHierarchySegmentOptions {
showOnly := generated.ListBlobsShowOnlyDirectories
if o == nil {
return generated.FileSystemClientListBlobHierarchySegmentOptions{
Showonly: &showOnly,
}
}
return generated.FileSystemClientListBlobHierarchySegmentOptions{
Marker: o.Marker,
MaxResults: o.MaxResults,
Prefix: o.Prefix,
Showonly: &showOnly,
}
}

// ListDeletedPathsOptions contains the optional parameters for the FileSystem.ListDeletedPaths operation.
type ListDeletedPathsOptions struct {
// Marker contains last continuation token returned from the service for listing.
Expand All @@ -169,7 +195,7 @@ type ListDeletedPathsOptions struct {
}

func (o *ListDeletedPathsOptions) format() generated.FileSystemClientListBlobHierarchySegmentOptions {
showOnly := "deleted"
showOnly := generated.ListBlobsShowOnlyDeleted
if o == nil {
return generated.FileSystemClientListBlobHierarchySegmentOptions{Showonly: &showOnly}
}
Expand Down
6 changes: 5 additions & 1 deletion sdk/storage/azdatalake/filesystem/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
package filesystem

import (
"time"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake/internal/generated"
"time"
)

// GetAccessPolicyResponse contains the response from method FileSystemClient.GetAccessPolicy.
Expand Down Expand Up @@ -145,6 +146,9 @@ type UndeletePathResponse = generated.PathClientUndeleteResponse
// ListDeletedPathsSegmentResponse contains the response from method FileSystemClient.ListPathsSegment.
type ListDeletedPathsSegmentResponse = generated.FileSystemClientListPathHierarchySegmentResponse

// ListDirectoryPathsSegmentResponse contains the response from method FileSystemClient.ListDirectoryPathsSegmentResponse.
type ListDirectoryPathsSegmentResponse = generated.FileSystemClientListPathHierarchySegmentResponse

// ListPathsHierarchySegmentResponse contains the response from method FileSystemClient.ListPathsHierarchySegment.
type ListPathsHierarchySegmentResponse = generated.ListPathsHierarchySegmentResponse

Expand Down
12 changes: 12 additions & 0 deletions sdk/storage/azdatalake/internal/generated/autorest.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ export-clients: true
use: "@autorest/[email protected]"
```
### Add ListBlobsShowOnly value 'directories'
```yaml
directive:
- from: swagger-document
where: $.parameters.ListBlobsShowOnly
transform: >
if (!$.enum.includes("directories")) {
$.enum.push("directories");
}
```
### Remove FileSystem and PathName from parameter list since they are not needed
``` yaml
directive:
Expand Down
Loading

0 comments on commit bc2318f

Please sign in to comment.