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

Feature/refactor to dotnet 8 #45

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
04456d6
feat: kubernetes hosting
yongenaelf Oct 20, 2024
3312913
fix: remove statelessworker
yongenaelf Oct 20, 2024
431b0e8
feat: refactor to dotnet 8
yongenaelf Oct 20, 2024
21be072
feat: hello world working example
yongenaelf Oct 21, 2024
31717bf
feat: add background task example
yongenaelf Oct 21, 2024
7358fc2
feat: complete skeleton flow for build
yongenaelf Oct 21, 2024
bb1c857
fix: immutable
yongenaelf Oct 21, 2024
bf309fd
revert: should not affect master
yongenaelf Oct 21, 2024
e14f727
fix: should be guid empty for stateless worker grains
yongenaelf Oct 21, 2024
862b762
feat: build
yongenaelf Oct 21, 2024
4bb56ba
feat: test
yongenaelf Oct 21, 2024
a67bd12
feat: template
yongenaelf Oct 21, 2024
9042d4b
ci: dockerfile
yongenaelf Oct 21, 2024
376cf24
ci: fix dockerfile
yongenaelf Oct 21, 2024
9415411
feat: downgrade orleans to 7
yongenaelf Oct 21, 2024
172a261
fix: docker compose
yongenaelf Oct 21, 2024
375c4e7
feat: add zookeeper clustering
yongenaelf Oct 21, 2024
8a319e6
feat: zookeeper on client
yongenaelf Oct 21, 2024
4811394
fix: add cluster and service id
yongenaelf Oct 21, 2024
eb4426f
fix: client options
yongenaelf Oct 21, 2024
f9e0ae5
feat: add swagger
yongenaelf Oct 21, 2024
a354782
feat: add endpoint to compile code with roslyn
yongenaelf Oct 22, 2024
fbf9505
fix: reference
yongenaelf Oct 22, 2024
734743d
fix: follow hello world example
yongenaelf Oct 22, 2024
5bd5831
feat: add testing page
yongenaelf Oct 22, 2024
2fb464f
feat: display errors
yongenaelf Oct 22, 2024
0779ce4
fix: set run analyzers to false
yongenaelf Oct 24, 2024
df00338
fix: register cancellationtoken
yongenaelf Oct 28, 2024
ce32d47
fix: deactivateonidle
yongenaelf Oct 28, 2024
90e52d4
fix: build errors
yongenaelf Oct 28, 2024
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
19 changes: 9 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ name: Create and publish a Docker image
on:
workflow_dispatch:
push:
branches: [master]
branches: [master, feature/refactor-to-dotnet-8]
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- "v[0-9]+.[0-9]+.[0-9]+"

jobs:
docker:
runs-on: ubuntu-latest
strategy:
matrix:
app: [PlaygroundClient, PlaygroundSilo]
if: github.ref_type != 'tag'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.0'
- run: dotnet publish PlaygroundService -o out
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
Expand All @@ -30,7 +29,7 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ secrets.DOCKER_USERNAME }}/playground-service
images: ${{ secrets.DOCKER_USERNAME }}/orleans-${{ matrix.app }}
tags: |
type=sha
# set latest tag for default branch
Expand All @@ -39,8 +38,8 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.${{ matrix.app }}
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
Expand All @@ -67,11 +66,11 @@ jobs:
await github.rest.actions.createWorkflowDispatch({
owner: 'poc-aaa',
repo: 'devops',
workflow_id: 'playground-deploy.yaml',
workflow_id: 'playground-autoscaler-deploy.yaml',
ref: 'main',
inputs: {
env: '${{ env.ENVIRONMENT }}',
appName: 'playground-service',
appName: 'orleans-playground-service',
commit_sha: 'sha-${{ steps.vars.outputs.short_sha }}',
}
})
19 changes: 19 additions & 0 deletions Dockerfile.PlaygroundClient
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . ./
RUN dotnet publish src/PlaygroundClient -c Release -o out

# Use the official .NET 8 runtime image as a runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime

# Set the working directory
WORKDIR /app

# Copy the built application from the build stage
COPY --from=build /app/out .

# Expose the port the app runs on
EXPOSE 80

# Set the entry point for the application
ENTRYPOINT ["dotnet", "PlaygroundClient.dll"]
22 changes: 22 additions & 0 deletions Dockerfile.PlaygroundSilo
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . ./
RUN dotnet publish src/PlaygroundSilo -c Release -o out

# Use the official .NET 8 sdk image as a runtime stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS runtime

# Set the working directory
WORKDIR /app

# Copy the built application from the build stage
COPY --from=build /app/out .

# Copy dotnet sdk from .NET 6 SDK
COPY --from=mcr.microsoft.com/dotnet/sdk:6.0 /usr/share/dotnet /usr/share/dotnet

# Expose the port the app runs on
EXPOSE 80

# Set the entry point for the application
ENTRYPOINT ["dotnet", "PlaygroundSilo.dll"]
1 change: 1 addition & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ services:
- "3310:3310"
volumes:
- ./temp/clamav:/var/lib/clamav
platform: linux/amd64
mongo:
image: mongo:latest
ports:
Expand Down
23 changes: 23 additions & 0 deletions src/PlaygroundClient/PlaygroundClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

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

<ItemGroup>
<PackageReference Include="ClamAV.Net" Version="0.1.166" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
<PackageReference Include="Microsoft.Orleans.Client" Version="7.0.0" />
<PackageReference Include="Microsoft.Orleans.Clustering.ZooKeeper" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\PlaygroundGrainInterfaces\PlaygroundGrainInterfaces.csproj" />
</ItemGroup>

</Project>
174 changes: 174 additions & 0 deletions src/PlaygroundClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
using Microsoft.Extensions.Hosting;
using Client.Services;
using Microsoft.AspNetCore.Mvc;
using GrainInterfaces;
using Microsoft.Extensions.Logging;
using Orleans.Configuration;
using System.Diagnostics;

var builder = WebApplication.CreateBuilder(args);
builder.Host
.UseOrleansClient((context, clientBuilder) =>
{
clientBuilder.Configure<ClusterOptions>(options =>
{
options.ClusterId = Environment.GetEnvironmentVariable("ORLEANS_CLUSTER_ID") ?? "default";
options.ServiceId = Environment.GetEnvironmentVariable("ORLEANS_SERVICE_ID") ?? "default";
});

clientBuilder.UseZooKeeperClustering(options =>
{
// for development, start services using docker compose.
options.ConnectionString = Environment.GetEnvironmentVariable("ASPNETCORE_ZOOKEEPER_HOST") ?? "localhost:2181";
});
})
.ConfigureLogging(logging => logging.AddConsole());

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddSingleton<IVirusScanService, VirusScanService>();

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

// host index.html file
app.UseDefaultFiles();
app.UseStaticFiles();

// upload zip file and return the extracted files
app.MapPost("/playground/build", async ([FromServices] IClusterClient _client, IFormFile file) =>
{
Console.WriteLine("Build started");

var grain = _client.GetGrain<IBuildGrain>(Guid.Empty); // stateless worker: https://learn.microsoft.com/en-us/dotnet/orleans/grains/stateless-worker-grains
BuildRequestDto request = new BuildRequestDto
{
ZipFile = await file.GetBytesAsync()
};

await grain.StartAsync(request);

var status = await grain.GetStatusAsync();

while (status != TaskStatus.RanToCompletion)
{
await Task.Delay(1000);
status = await grain.GetStatusAsync();
}

Console.WriteLine("Build completed");

var result = await grain.GetResultAsync();

return result;

})
.DisableAntiforgery();

// upload zip file and return the extracted files
app.MapPost("/playground/buildWithRoslyn", async ([FromServices] IClusterClient _client, [FromForm] string code) =>
{
var timer = Stopwatch.StartNew();
Console.WriteLine("Build started at " + DateTime.Now);

var grain = _client.GetGrain<ICodeCompilerGrain>(Guid.NewGuid().ToString());

try
{
var result = await grain.CompileCSharpCode(code);
Console.WriteLine("Build completed at " + DateTime.Now);
return result;
}
catch (Exception e)
{
Console.WriteLine("Build failed at " + DateTime.Now);
return e.Message;
}
})
.DisableAntiforgery();

app.MapPost("/playground/test", async ([FromServices] IClusterClient _client, IFormFile file) =>
{
Console.WriteLine("Test started");

var grain = _client.GetGrain<ITestGrain>(Guid.Empty); // stateless worker: https://learn.microsoft.com/en-us/dotnet/orleans/grains/stateless-worker-grains
TestRequestDto request = new TestRequestDto
{
ZipFile = await file.GetBytesAsync()
};

await grain.StartAsync(request);

var status = await grain.GetStatusAsync();

while (status != TaskStatus.RanToCompletion)
{
await Task.Delay(1000);
status = await grain.GetStatusAsync();
}

Console.WriteLine("Test completed");

var result = await grain.GetResultAsync();

return result;
})
.DisableAntiforgery();

app.MapGet("/playground/templates", () =>
{
return new List<string> { "aelf", "aelf-lottery", "aelf-nft-sale", "aelf-simple-dao" };
});

app.MapGet("/playground/template", async ([FromServices] IClusterClient _client, string template, string templateName) =>
{
Console.WriteLine("Template started");

var grain = _client.GetGrain<ITemplateGrain>(Guid.Empty); // stateless worker: https://learn.microsoft.com/en-us/dotnet/orleans/grains/stateless-worker-grains
TemplateRequestDto request = new TemplateRequestDto
{
Template = template,
TemplateName = templateName
};

await grain.StartAsync(request);

var status = await grain.GetStatusAsync();

while (status != TaskStatus.RanToCompletion)
{
await Task.Delay(1000);
status = await grain.GetStatusAsync();
}

Console.WriteLine("Template completed");

var result = await grain.GetResultAsync();

return result;
});

app.MapPost("/playground/share/create", ([FromServices] IClusterClient _client, IFormFile file) =>
{
// TODO
})
.DisableAntiforgery();

app.Run();

public static class FormFileExtensions
{
public static async Task<byte[]> GetBytesAsync(this IFormFile formFile)
{
await using var memoryStream = new MemoryStream();
await formFile.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
41 changes: 41 additions & 0 deletions src/PlaygroundClient/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:49589",
"sslPort": 44355
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7180;http://localhost:5209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
6 changes: 6 additions & 0 deletions src/PlaygroundClient/Services/IVirusScanService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Client.Services;

public interface IVirusScanService
{
Task<bool> IsFileInfected(byte[] file);
}
28 changes: 28 additions & 0 deletions src/PlaygroundClient/Services/VirusScanService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using ClamAV.Net.Client;
using ClamAV.Net.Client.Results;

namespace Client.Services;

public class VirusScanService : IVirusScanService
{
private readonly IConfiguration _configuration;
private readonly IClamAvClient _clamAvClient;
private readonly ILogger<VirusScanService> _logger;

public VirusScanService(IConfiguration configuration, ILogger<VirusScanService> logger)
{
_configuration = configuration;
_logger = logger;
_clamAvClient = ClamAvClient.Create(new Uri(_configuration.GetSection("ClamAV:ConnectionString").Value));
}

public async Task<bool> IsFileInfected(byte[] file)
{
using var stream = new MemoryStream(file);
ScanResult res = await _clamAvClient.ScanDataAsync(stream).ConfigureAwait(false);

_logger.LogInformation($"Scan result : Infected - {res.Infected} , Virus name {res.VirusName}");

return !res.Infected;
}
}
8 changes: 8 additions & 0 deletions src/PlaygroundClient/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Loading
Loading