From 0f166572009850f94e578870bffa22f3c247592a Mon Sep 17 00:00:00 2001 From: George Drak Date: Wed, 18 Oct 2023 18:45:47 +0500 Subject: [PATCH] apps(tasks): add tasks to demo app --- .../MudBlazorUnited/MudBlazorUnited.csproj | 1 + apps/Blazor/MudBlazorUnited/Program.cs | 12 ++- .../MudBlazorUnited/Tasks/Demo/LoggingTask.cs | 14 +++ .../Tasks/Demo/LoggingTaskExecutor.cs | 21 +++++ .../Tasks/Demo/LoggingTaskFactory.cs | 12 +++ .../20231018133432_Tasks.Designer.cs | 93 +++++++++++++++++++ .../Tasks/Migrations/20231018133432_Tasks.cs | 45 +++++++++ .../MudBlazorTasksDbContextModelSnapshot.cs | 90 ++++++++++++++++++ .../Tasks/MudBlazorBaseTask.cs | 12 +++ .../Tasks/MudBlazorTasksDbContext.cs | 6 ++ .../appsettings.Development.json | 12 ++- docker-compose.yml | 20 +++- 12 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTask.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskExecutor.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskFactory.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.Designer.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/Migrations/MudBlazorTasksDbContextModelSnapshot.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/MudBlazorBaseTask.cs create mode 100644 apps/Blazor/MudBlazorUnited/Tasks/MudBlazorTasksDbContext.cs diff --git a/apps/Blazor/MudBlazorUnited/MudBlazorUnited.csproj b/apps/Blazor/MudBlazorUnited/MudBlazorUnited.csproj index 5d92cfefe..2951ff0bc 100644 --- a/apps/Blazor/MudBlazorUnited/MudBlazorUnited.csproj +++ b/apps/Blazor/MudBlazorUnited/MudBlazorUnited.csproj @@ -14,6 +14,7 @@ + diff --git a/apps/Blazor/MudBlazorUnited/Program.cs b/apps/Blazor/MudBlazorUnited/Program.cs index 44cf2d534..12e147e75 100644 --- a/apps/Blazor/MudBlazorUnited/Program.cs +++ b/apps/Blazor/MudBlazorUnited/Program.cs @@ -1,6 +1,8 @@ using FluentValidation; using MudBlazorUnited.Components; using MudBlazorUnited.Data; +using MudBlazorUnited.Tasks; +using MudBlazorUnited.Tasks.Demo; using Sitko.Core.App.Localization; using Sitko.Core.App.Web; using Sitko.Core.Blazor.MudBlazor.Server; @@ -11,6 +13,7 @@ using Sitko.Core.Storage.FileSystem; using Sitko.Core.Storage.Metadata.Postgres; using Sitko.Core.Storage.Remote; +using Sitko.Core.Tasks.Kafka; var builder = WebApplication.CreateBuilder(args); @@ -24,7 +27,14 @@ .AddFileSystemStorage() .AddRemoteStorage() .AddPostgresStorageMetadata() - .AddJsonLocalization(); + .AddJsonLocalization() + .AddKafkaTasks(options => + { + options + .AddTask("* * * * *") + .AddExecutorsFromAssemblyOf(); + }, true, + options => options.AutoApplyMigrations = true); builder.Services.AddValidatorsFromAssemblyContaining(); builder.Services.Configure(builder.Configuration.GetSection("MudLayout")); diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTask.cs b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTask.cs new file mode 100644 index 000000000..8e7d22e35 --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTask.cs @@ -0,0 +1,14 @@ +using Sitko.Core.Tasks; +using Sitko.Core.Tasks.Data.Entities; + +namespace MudBlazorUnited.Tasks.Demo; + +[Task("logging")] +public record LoggingTask : MudBlazorBaseTask; + +public record LoggingTaskResult : BaseTaskResult; + +public record LoggingTaskConfig : BaseTaskConfig +{ + public Guid Id { get; set; } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskExecutor.cs b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskExecutor.cs new file mode 100644 index 000000000..7595f9973 --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskExecutor.cs @@ -0,0 +1,21 @@ +using Elastic.Apm.Api; +using Sitko.Core.Repository; +using Sitko.Core.Tasks.Execution; + +namespace MudBlazorUnited.Tasks.Demo; + +[TaskExecutor("Loggers", 10)] +public class LoggingTaskExecutor : BaseTaskExecutor +{ + public LoggingTaskExecutor(ILogger logger, IServiceScopeFactory serviceScopeFactory, + IRepository repository, ITracer? tracer = null) : base(logger, serviceScopeFactory, + repository, tracer) + { + } + + protected override Task ExecuteAsync(LoggingTask task, CancellationToken cancellationToken) + { + Logger.LogInformation("Run Logging Task: {Id}", task.Config.Id); + return Task.FromResult(new LoggingTaskResult()); + } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskFactory.cs b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskFactory.cs new file mode 100644 index 000000000..e78dd991a --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Demo/LoggingTaskFactory.cs @@ -0,0 +1,12 @@ +using Sitko.Core.Tasks.Scheduling; + +namespace MudBlazorUnited.Tasks.Demo; + +public class LoggingTaskFactory : IBaseTaskFactory +{ + public Task GetTasksAsync(CancellationToken cancellationToken) + { + var tasks = new[] { new LoggingTask { Config = new() { Id = Guid.NewGuid() }, Result = new() } }; + return Task.FromResult(tasks); + } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.Designer.cs b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.Designer.cs new file mode 100644 index 000000000..c5a3038a3 --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.Designer.cs @@ -0,0 +1,93 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MudBlazorUnited.Tasks; +using MudBlazorUnited.Tasks.Demo; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MudBlazorUnited.Tasks.Migrations +{ + [DbContext(typeof(MudBlazorTasksDbContext))] + [Migration("20231018133432_Tasks")] + partial class Tasks + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MudBlazorUnited.Tasks.MudBlazorBaseTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DateAdded") + .HasColumnType("timestamp with time zone"); + + b.Property("DateUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("ExecuteDateEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("ExecuteDateStart") + .HasColumnType("timestamp with time zone"); + + b.Property("LastActivityDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ParentId") + .HasColumnType("uuid"); + + b.Property("TaskStatus") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("character varying(21)"); + + b.Property("UserId") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Tasks", (string)null); + + b.HasDiscriminator("Type").HasValue("MudBlazorBaseTask"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("MudBlazorUnited.Tasks.Demo.LoggingTask", b => + { + b.HasBaseType("MudBlazorUnited.Tasks.MudBlazorBaseTask"); + + b.Property("Config") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("Config"); + + b.Property("Result") + .HasColumnType("jsonb") + .HasColumnName("Result"); + + b.ToTable("Tasks", (string)null); + + b.HasDiscriminator().HasValue("LoggingTask"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.cs b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.cs new file mode 100644 index 000000000..e5d4b889f --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/20231018133432_Tasks.cs @@ -0,0 +1,45 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using MudBlazorUnited.Tasks.Demo; + +#nullable disable + +namespace MudBlazorUnited.Tasks.Migrations +{ + /// + public partial class Tasks : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Tasks", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Config = table.Column(type: "jsonb", nullable: true), + Result = table.Column(type: "jsonb", nullable: true), + DateAdded = table.Column(type: "timestamp with time zone", nullable: false), + DateUpdated = table.Column(type: "timestamp with time zone", nullable: false), + TaskStatus = table.Column(type: "integer", nullable: false), + ExecuteDateStart = table.Column(type: "timestamp with time zone", nullable: true), + ExecuteDateEnd = table.Column(type: "timestamp with time zone", nullable: true), + Type = table.Column(type: "character varying(21)", maxLength: 21, nullable: false), + ParentId = table.Column(type: "uuid", nullable: true), + UserId = table.Column(type: "text", nullable: true), + LastActivityDate = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Tasks", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Tasks"); + } + } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/Migrations/MudBlazorTasksDbContextModelSnapshot.cs b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/MudBlazorTasksDbContextModelSnapshot.cs new file mode 100644 index 000000000..de6c2192e --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/Migrations/MudBlazorTasksDbContextModelSnapshot.cs @@ -0,0 +1,90 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MudBlazorUnited.Tasks; +using MudBlazorUnited.Tasks.Demo; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MudBlazorUnited.Tasks.Migrations +{ + [DbContext(typeof(MudBlazorTasksDbContext))] + partial class MudBlazorTasksDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0-rc.2.23480.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MudBlazorUnited.Tasks.MudBlazorBaseTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DateAdded") + .HasColumnType("timestamp with time zone"); + + b.Property("DateUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("ExecuteDateEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("ExecuteDateStart") + .HasColumnType("timestamp with time zone"); + + b.Property("LastActivityDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ParentId") + .HasColumnType("uuid"); + + b.Property("TaskStatus") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("character varying(21)"); + + b.Property("UserId") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Tasks", (string)null); + + b.HasDiscriminator("Type").HasValue("MudBlazorBaseTask"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("MudBlazorUnited.Tasks.Demo.LoggingTask", b => + { + b.HasBaseType("MudBlazorUnited.Tasks.MudBlazorBaseTask"); + + b.Property("Config") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("Config"); + + b.Property("Result") + .HasColumnType("jsonb") + .HasColumnName("Result"); + + b.ToTable("Tasks", (string)null); + + b.HasDiscriminator().HasValue("LoggingTask"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorBaseTask.cs b/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorBaseTask.cs new file mode 100644 index 000000000..e15c026b3 --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorBaseTask.cs @@ -0,0 +1,12 @@ +using Sitko.Core.Tasks.Data.Entities; + +namespace MudBlazorUnited.Tasks; + +public abstract record MudBlazorBaseTask : BaseTask; + +public abstract record MudBlazorBaseTask : MudBlazorBaseTask, IBaseTask + where TConfig : BaseTaskConfig, new() where TResult : BaseTaskResult +{ + public TConfig Config { get; set; } = default!; + public TResult? Result { get; set; } +} diff --git a/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorTasksDbContext.cs b/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorTasksDbContext.cs new file mode 100644 index 000000000..ee8f2737b --- /dev/null +++ b/apps/Blazor/MudBlazorUnited/Tasks/MudBlazorTasksDbContext.cs @@ -0,0 +1,6 @@ +using Microsoft.EntityFrameworkCore; +using Sitko.Core.Tasks.Data; + +namespace MudBlazorUnited.Tasks; + +public class MudBlazorTasksDbContext(DbContextOptions options) : TasksDbContext(options); diff --git a/apps/Blazor/MudBlazorUnited/appsettings.Development.json b/apps/Blazor/MudBlazorUnited/appsettings.Development.json index c475a97f4..1ffcf01b2 100644 --- a/apps/Blazor/MudBlazorUnited/appsettings.Development.json +++ b/apps/Blazor/MudBlazorUnited/appsettings.Development.json @@ -1,6 +1,6 @@ { "DetailedErrors": true, - "Serilog":{ + "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { @@ -8,5 +8,15 @@ "Sitko.Core.Repository": "Debug" } } + }, + "Kafka": { + "Brokers": [ + "127.0.0.1:9092" + ], + "Tasks": { + "MudBlazorBaseTask": { + "TasksTopic": "MudBlazorTasks" + } + } } } diff --git a/docker-compose.yml b/docker-compose.yml index 8ed154692..3b32361e1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,12 +53,30 @@ services: volumes: - "mc:/root/.mc" vault: - image: "vault" + image: hashicorp/vault environment: - VAULT_DEV_ROOT_TOKEN_ID=root cap_add: - IPC_LOCK ports: - "8200:8200" + kafka: + image: docker.io/bitnami/kafka:3.5 + ports: + - "9092:9092" + volumes: + - "kafka_data:/bitnami" + environment: + # KRaft settings + - KAFKA_CFG_NODE_ID=0 + - KAFKA_CFG_PROCESS_ROLES=controller,broker + - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093 + # Listeners + - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 + - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092 + - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT + - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER + - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT volumes: mc: + kafka_data: