Skip to content

Commit

Permalink
Add Integration.Api & Integration.DataLake.
Browse files Browse the repository at this point in the history
  • Loading branch information
eminencegrs committed Jan 8, 2024
1 parent 89d4115 commit 62298e0
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,6 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml
.idea/
global.json
appsettings.Development.json
22 changes: 22 additions & 0 deletions Seneca.Azure.Integration.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "src\Seneca.Azure.Integration.Api", "src\Seneca.Azure.Integration.Api\Seneca.Azure.Integration.Api.csproj", "{43DC551E-4CF1-4B70-A90A-F41B6400734B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Seneca.Azure.Integration.DataLake", "src\Seneca.Azure.Integration.DataLake\Seneca.Azure.Integration.DataLake.csproj", "{F834E082-DC9C-4DE0-8EFC-6CC606556243}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{43DC551E-4CF1-4B70-A90A-F41B6400734B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43DC551E-4CF1-4B70-A90A-F41B6400734B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43DC551E-4CF1-4B70-A90A-F41B6400734B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43DC551E-4CF1-4B70-A90A-F41B6400734B}.Release|Any CPU.Build.0 = Release|Any CPU
{F834E082-DC9C-4DE0-8EFC-6CC606556243}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F834E082-DC9C-4DE0-8EFC-6CC606556243}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F834E082-DC9C-4DE0-8EFC-6CC606556243}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F834E082-DC9C-4DE0-8EFC-6CC606556243}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions src/Seneca.Azure.Integration.Api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["Seneca.Azure.Integration.Api/Seneca.Azure.Integration.Api.csproj", "Seneca.Azure.Integration.Api/"]
RUN dotnet restore "Seneca.Azure.Integration.Api/Seneca.Azure.Integration.Api.csproj"
COPY . .
WORKDIR "/src/Seneca.Azure.Integration.Api"
RUN dotnet build "Seneca.Azure.Integration.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Seneca.Azure.Integration.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Seneca.Azure.Integration.Api.dll"]
22 changes: 22 additions & 0 deletions src/Seneca.Azure.Integration.Api/FoldersController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc;
using Seneca.Azure.Integration.DataLake;

namespace Seneca.Azure.Integration.Api;

[Route("api/[controller]")]
public class FoldersController : ControllerBase
{
private readonly DataLakeService service;

public FoldersController(DataLakeService service)
{
this.service = service;
}

[HttpPost]
public async Task<IActionResult> CreateFolder([FromQuery] string folderName)
{
var result = await this.service.CreateDirectoryWithSas(folderName);
return Ok($"{result.sasUri}");
}
}
27 changes: 27 additions & 0 deletions src/Seneca.Azure.Integration.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Seneca.Azure.Integration.DataLake;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<DataLakeSettings>(builder.Configuration.GetSection(DataLakeSettings.SectionName));

builder.Services.AddScoped<DataLakeService>();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddControllers();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapControllers();

app.Run();
41 changes: 41 additions & 0 deletions src/Seneca.Azure.Integration.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49056",
"sslPort": 44397
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5143",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7081;http://localhost:5143",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<Content Include="..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Seneca.Azure.Integration.DataLake\Seneca.Azure.Integration.DataLake.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@Seneca.Azure.Integration.Api_HostAddress = http://localhost:5143

GET {{Seneca.Azure.Integration.Api_HostAddress}}/weatherforecast/
Accept: application/json

###
9 changes: 9 additions & 0 deletions src/Seneca.Azure.Integration.Api/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
61 changes: 61 additions & 0 deletions src/Seneca.Azure.Integration.DataLake/DataLakeService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Threading.Tasks;
using Azure.Storage;
using Azure.Storage.Files.DataLake;
using Azure.Storage.Files.DataLake.Models;
using Azure.Storage.Sas;
using Microsoft.Extensions.Options;

namespace Seneca.Azure.Integration.DataLake;

public class DataLakeService
{
private const string FileSystemDefaultName = "default-file-system";

private readonly DataLakeServiceClient serviceClient;
private readonly DataLakeSettings settings;

public DataLakeService(IOptions<DataLakeSettings> options)
{
this.settings = options.Value;
var credential = new StorageSharedKeyCredential(this.settings.AccountName, this.settings.AccountKey);
var serviceUri = new Uri($"https://{this.settings.AccountName}.dfs.core.windows.net");
this.serviceClient = new DataLakeServiceClient(serviceUri, credential);
}

public async Task<(DataLakeDirectoryClient directoryClient, Uri sasUri)> CreateDirectoryWithSas(
string directoryName,
string policyName = "mySasPolicy")
{
var fileSystemClient = this.serviceClient.GetFileSystemClient(FileSystemDefaultName);
await fileSystemClient.CreateIfNotExistsAsync();

var directoryClientResponse = await fileSystemClient.CreateDirectoryAsync(directoryName);
var directoryClient = directoryClientResponse.HasValue
? directoryClientResponse.Value
: throw new InvalidOperationException();

var sasBuilder = new DataLakeSasBuilder
{
FileSystemName = fileSystemClient.Name,
Path = directoryClient.Path,
// TODO: move to the settings.
ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
Protocol = SasProtocol.Https,
// TODO: move to the settings?
Resource = "d", // 'd' for directory
StartsOn = DateTimeOffset.UtcNow,
};

// TODO: manage permissions properly.
sasBuilder.SetPermissions(DataLakeSasPermissions.Read | DataLakeSasPermissions.Write);

var sasToken = sasBuilder
.ToSasQueryParameters(new StorageSharedKeyCredential(this.settings.AccountName, this.settings.AccountKey))
.ToString();

var sasUri = new Uri($"{directoryClient.Uri}?{sasToken}");

return (directoryClient, sasUri);
}
}
8 changes: 8 additions & 0 deletions src/Seneca.Azure.Integration.DataLake/DataLakeSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Seneca.Azure.Integration.DataLake;

public class DataLakeSettings
{
public static readonly string SectionName = "DataLakeSettings";
public string AccountName { get; set; } = null!;
public string AccountKey { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Storage.Files.DataLake" Version="12.17.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
</ItemGroup>

</Project>

0 comments on commit 62298e0

Please sign in to comment.