Skip to content

Commit

Permalink
Initial creation of filesystem scanner for DMLib (#21492)
Browse files Browse the repository at this point in the history
  • Loading branch information
rnpmsft authored and amnguye committed Dec 6, 2021
1 parent ac2bba2 commit 7a61e69
Show file tree
Hide file tree
Showing 11 changed files with 350 additions and 22 deletions.
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)
{
// 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;
}

// 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

0 comments on commit 7a61e69

Please sign in to comment.