Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial creation of filesystem scanner for DMLib #21492

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions eng/Packages.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
<PackageReference Update="Microsoft.Rest.ClientRuntime.Azure.TestFramework" Version="[1.7.7, 2.0.0)" />
<PackageReference Update="Microsoft.ServiceFabric.Data" Version="3.3.624" />
<PackageReference Update="Microsoft.Spatial" Version="7.5.3" />
<PackageReference Update="Mono.Posix" Version="7.0.0-alpha8.21302.6" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check if we can introduce these dependencies first.
My guess is that we can't as they appear to be 3rd party.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are only for testing we can add them in test project file directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#21715 I took the two dependencies I introduced for testing out of this file and used VersionOverride in the .csproj. The error spooked me and override sounded scary.

I can't tell if the Mono.Posix is/isn't 3rd party, since Microsoft is listed as an owner alongside some other users. There was another package called Mono.Posix.NETStandard with only Microsoft as an owner, but for some reason, that package was searching for the assembly "Mono.Posix". I couldn't think of anything to get that one to properly find the assembly without potentially causing other issues.

Do you think I should drop the dependency and maybe just execute bash + call chmod manually? I fiddled with manually loading the c library for chmod, but I couldn't do it with .NET Core 2.1 as a target.

<PackageReference Update="Moq" Version="4.10.1" />
<PackageReference Update="MSTest.TestAdapter" Version="1.3.2" />
<PackageReference Update="MSTest.TestFramework" Version="1.3.2" />
Expand All @@ -217,6 +218,7 @@
<PackageReference Update="PublicApiGenerator" Version="10.0.1" />
<PackageReference Update="System.Diagnostics.TraceSource" Version="4.3.0" />
<PackageReference Update="System.IO.Compression" Version="4.3.0" />
<PackageReference Update="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Update="System.Net.WebSockets.Client" Version="4.3.2" />
<PackageReference Update="System.Reflection.Emit" Version="4.7.0" />
<PackageReference Update="System.Runtime.InteropServices" Version="4.3.0" />
Expand Down
2 changes: 1 addition & 1 deletion sdk/storage/Azure.Storage.Blobs.DataMovement/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release History

## 3.0.0-preview.1 (Unreleased)
## 12.0.0-preview.1 (Unreleased)
This preview is the first release of a ground-up rewrite of our client
libraries to ensure consistency, idiomatic design, productivity, and an
excellent developer experience. It was created following the Azure SDK Design
Expand Down
4 changes: 4 additions & 0 deletions sdk/storage/Azure.Storage.Blobs.DataMovement/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Here's an example using the Azure CLI:
az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS
```

### Authenticate the Client

Authentication works the same as in [Azure.Storage.Blobs][authenticating_with_blobs].

## Key concepts

Blob storage is designed for:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<AssemblyTitle>Microsoft Azure.Storage.DataMovement.Blobs client library</AssemblyTitle>
<Version>0.1.0-beta.1</Version>
<Version>12.0.0-preview.1</Version>
<DefineConstants>BlobSDK;$(DefineConstants)</DefineConstants>
<PackageTags>Microsoft Azure Storage Blobs DataMovement;Microsoft;Azure;Blobs;Blob;Storage;DataMovement;StorageScalable;$(PackageCommonTags)</PackageTags>
<Description>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<AssemblyTitle>Microsoft Azure.Storage.Common.DataMovement client library tests</AssemblyTitle>
<IsPackable>false</IsPackable>
<RootNamespace>Azure.Storage.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)..\src\Azure.Storage.Blobs.DataMovement.csproj" />
<ProjectReference Include="..\..\Azure.Storage.Common.DataMovement\tests\Azure.Storage.Common.DataMovement.Tests.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Common.DataMovement\tests\Azure.Storage.Common.DataMovement.Tests.csproj" />
</ItemGroup>
<!-- Ensure an empty TestConfigurations.xml is always present so the build can copy it -->
<Target Name="TouchTestConfigurationsFile" BeforeTargets="PreBuildEvent">
<Touch Files="$(MSBuildThisFileDirectory)Shared\TestConfigurations.xml" AlwaysCreate="True" ContinueOnError="WarnAndContinue" />
</Target>
</Project>
<ItemGroup>
<Folder Include="SessionRecords\" />
<None Include="$(AzureStorageSharedTestSources)\*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion sdk/storage/Azure.Storage.Common.DataMovement/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release History

## 3.0.0-preview.1 (Unreleased)
## 12.0.0-preview.1 (Unreleased)
This preview is the first release of a ground-up rewrite of our client
libraries to ensure consistency, idiomatic design, productivity, and an
excellent developer experience. It was created following the Azure SDK Design
Expand Down
4 changes: 4 additions & 0 deletions sdk/storage/Azure.Storage.Common.DataMovement/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Here's an example using the Azure CLI:
az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS
```

### Authenticate the Client

Authentication details to be written.

## Key concepts

The Azure Storage Common client library contains shared infrastructure like
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<AssemblyTitle>Microsoft Azure.Storage.Common.DataMovement client library</AssemblyTitle>
<Version>0.1.0-beta.1</Version>
<Version>12.0.0-preview.1</Version>
<DefineConstants>CommonSDK;$(DefineConstants)</DefineConstants>
<PackageTags>Microsoft Azure Storage Common DataMovement, Microsoft, Azure, StorageScalable, azureofficial</PackageTags>
<Description>
Expand Down
114 changes: 114 additions & 0 deletions sdk/storage/Azure.Storage.Common.DataMovement/src/FilesystemScanner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Azure.Storage.Common.DataMovement
{
/// <summary>
/// FilesystemScanner class.
/// </summary>
public static class FilesystemScanner
{
/// <summary>
/// Enumerates all files pointed to by the provided path, including those in subdirectories (if path is a directory).
/// </summary>
/// <param name="path">Filesystem location.</param>
/// <returns>Enumerable list of absolute paths containing all relevant files the user has permission to access.</returns>
public static IEnumerable<string> ScanLocation(string path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#21715 I refactored the scanner to make it non-static and shift a couple things around, let me know if there's any issues with this implementation.

{
// Path type is ambiguous at start
bool isDirectory = false;

try
{
// Make sure we're dealing with absolute, well-formatted path
path = Path.GetFullPath(path);

// Check if path points to a directory
if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
{
isDirectory = true;
}
}
catch (Exception)
{
// If there's an error here, there aren't any valid entries to scan at the given path;
// the path is either invalid or nonexistant. In this case, throw the resulting exception.
//
// TODO: Logging for invalid path exceptions
throw;
}

// If we're given a directory, parse its children recursively
if (isDirectory)
{
// Create a queue of folders to enumerate files from, starting with provided path
Queue<string> folders = new();
folders.Enqueue(path);

while (folders.Count > 0)
{
// Grab a folder from the queue
string dir = folders.Dequeue();

// Try to enumerate and queue all subdirectories of the current folder
try
{
foreach (string subdir in Directory.EnumerateDirectories(dir))
{
folders.Enqueue(subdir);
}
}
// If we lack permissions to enumerate, skip the folder and continue processing
// the rest of the queue
catch (Exception)
{
// TODO: Logging for missing permissions to enumerate folder
if (dir == path)
{
// If we can't even enumerate the path supplied by the user, throw
// the error
throw;
}

// Otherwise, just log the failed subdirectory and continue to list as many
// files as accessible. Maybe let users decide whether to always throw here?
continue;
amnguye marked this conversation as resolved.
Show resolved Hide resolved
}

// Add all files in the directory to be returned
foreach (string file in Directory.EnumerateFiles(dir))
{
yield return file;
}
}
}
// Otherwise we can just return the original path
else
{
yield return path;
}
}

/// <summary>
/// Enumerates files pointed to by several paths.
/// </summary>
/// <param name="paths">Filesystem locations.</param>
/// <returns>Enumerable list of absolute paths containing all relevant files the user has permission to access.</returns>
public static IEnumerable<string> ScanLocations(string[] paths)
{
// Redirect all paths provided to ScanLocation(), and collect all results together
foreach (string path in paths)
{
foreach (string file in ScanLocation(path))
{
yield return file;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<AssemblyTitle>Microsoft Azure.Storage.Common.DataMovement client library tests</AssemblyTitle>
<IsPackable>false</IsPackable>
<RootNamespace>Azure.Storage.Tests</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Mono.Posix" />
<PackageReference Include="System.IO.FileSystem.AccessControl" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\src\Azure.Storage.Common.DataMovement.csproj" />
<ProjectReference Include="..\..\Azure.Storage.Common\tests\Azure.Storage.Common.Tests.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Azure.Storage.Common\tests\Azure.Storage.Common.Tests.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="SessionRecords\" />
<None Include="$(AzureStorageSharedTestSources)\*.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<!-- Ensure an empty TestConfigurations.xml is always present so the build can copy it -->
<Target Name="TouchTestConfigurationsFile" BeforeTargets="PreBuildEvent">
<Touch Files="$(MSBuildThisFileDirectory)Shared\TestConfigurations.xml" AlwaysCreate="True" ContinueOnError="WarnAndContinue" />
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using NUnit.Framework;
using Azure.Core;
using Azure.Core.Pipeline;
Expand All @@ -21,7 +22,7 @@ namespace Azure.Storage.Tests
public abstract class DataMovementTestBase : CommonTestBase
{
public DataMovementTestBase(bool async, BlobClientOptions.ServiceVersion serviceVersion, RecordedTestMode? mode = null)
: base(async, serviceVersion, null /* RecordedTestMode.Record /* to re-record */)
: base(async, serviceVersion, mode /* RecordedTestMode.Record /* to re-record */)
{
}

Expand Down
Loading