diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 77f2b71f..8e0315ec 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -51,6 +51,13 @@ services:
ports:
- "5106:80"
+ attendance.api:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=http://0.0.0.0:80
+ ports:
+ - "5108:80"
+
webstatus:
environment:
- ASPNETCORE_ENVIRONMENT=Development
diff --git a/docker-compose.yml b/docker-compose.yml
index f3570497..38e50671 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -47,6 +47,14 @@ services:
depends_on:
- sql.data
+ attendance.api:
+ image: ${REGISTRY:-eschool}/attendance.api:${TAG:-latest}
+ build:
+ context: .
+ dockerfile: src/Services/Attendance/Attendance.API/Dockerfile
+ depends_on:
+ - sql.data
+
webstatus:
image: ${REGISTRY:-eschool}/webstatus:${TAG:-latest}
build:
diff --git a/eSchool.sln b/eSchool.sln
index 7f349905..d9c6114e 100644
--- a/eSchool.sln
+++ b/eSchool.sln
@@ -62,6 +62,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ResultProcessing", "ResultP
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResultProcessing.API", "src\Services\ResultProcessing\ResultProcessing.API\ResultProcessing.API.csproj", "{B9816645-F349-434D-A67D-98861B32249C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Attendance", "Attendance", "{C2F37C86-3190-4261-AB1D-AC911B24CF2A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Attendance.API", "src\Services\Attendance\Attendance.API\Attendance.API.csproj", "{7B48DB8F-C668-4510-90A8-13B6170C262F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -264,6 +268,18 @@ Global
{B9816645-F349-434D-A67D-98861B32249C}.Release|x64.Build.0 = Release|Any CPU
{B9816645-F349-434D-A67D-98861B32249C}.Release|x86.ActiveCfg = Release|Any CPU
{B9816645-F349-434D-A67D-98861B32249C}.Release|x86.Build.0 = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|x64.Build.0 = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Debug|x86.Build.0 = Debug|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|x64.ActiveCfg = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|x64.Build.0 = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|x86.ActiveCfg = Release|Any CPU
+ {7B48DB8F-C668-4510-90A8-13B6170C262F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -294,6 +310,8 @@ Global
{6B655445-4A8B-465E-82C8-A3C9CF3D983E} = {C06D4DA8-7465-4D00-BC85-D594CB4996D2}
{D9A25D85-43C9-4F05-876B-12A146E85447} = {1C120673-72F4-4679-AC4C-68286E9091A5}
{B9816645-F349-434D-A67D-98861B32249C} = {D9A25D85-43C9-4F05-876B-12A146E85447}
+ {C2F37C86-3190-4261-AB1D-AC911B24CF2A} = {1C120673-72F4-4679-AC4C-68286E9091A5}
+ {7B48DB8F-C668-4510-90A8-13B6170C262F} = {C2F37C86-3190-4261-AB1D-AC911B24CF2A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E418719F-3193-403E-AF58-9BE9F94FD8BE}
diff --git a/src/Services/Attendance/Attendance.API/Attendance.API.csproj b/src/Services/Attendance/Attendance.API/Attendance.API.csproj
new file mode 100644
index 00000000..bbb5f5cb
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/Attendance.API.csproj
@@ -0,0 +1,13 @@
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Attendance/Attendance.API/Controllers/HelloWorldController.cs b/src/Services/Attendance/Attendance.API/Controllers/HelloWorldController.cs
new file mode 100644
index 00000000..c6898046
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/Controllers/HelloWorldController.cs
@@ -0,0 +1,15 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace Attendance.API.Controllers
+{
+ [ApiController]
+ [Route("[controller]")]
+ public class HelloWorldController : ControllerBase
+ {
+ [HttpGet]
+ public ActionResult Ping()
+ {
+ return Ok("Pong");
+ }
+ }
+}
diff --git a/src/Services/Attendance/Attendance.API/Dockerfile b/src/Services/Attendance/Attendance.API/Dockerfile
new file mode 100644
index 00000000..35fd23d4
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/Dockerfile
@@ -0,0 +1,24 @@
+#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
+WORKDIR /app
+EXPOSE 80
+
+FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
+WORKDIR /src
+
+COPY ["src/Services/Attendance/Attendance.API/Attendance.API.csproj", "src/Services/Attendance/Attendance.API/"]
+
+RUN dotnet restore "src/Services/Attendance/Attendance.API/Attendance.API.csproj"
+
+COPY . .
+WORKDIR "/src/src/Services/Attendance/Attendance.API"
+RUN dotnet build "Attendance.API.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "Attendance.API.csproj" -c Release -o /app/publish
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Attendance.API.dll"]
diff --git a/src/Services/Attendance/Attendance.API/Program.cs b/src/Services/Attendance/Attendance.API/Program.cs
new file mode 100644
index 00000000..e1acdd26
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/Program.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+using Serilog.Enrichers.Span;
+
+namespace Attendance.API
+{
+ public static class Program
+ {
+ public static readonly string Namespace = typeof(Program).Namespace!;
+ public static readonly string AppName = Namespace[(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1)..];
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage(
+ "Design",
+ "CA1031:Do not catch general exception types",
+ Justification = "Top level all exception catcher")]
+ public static int Main(string[] args)
+ {
+ Activity.DefaultIdFormat = ActivityIdFormat.W3C;
+
+ var configuration = GetConfiguration();
+ Log.Logger = CreateSerilogLogger(configuration);
+
+ try
+ {
+ Log.Information("Configuring web host ({ApplicationContext})...", AppName);
+ var host = CreateHostBuilder(configuration, args).Build();
+
+ Log.Information("Starting web host ({ApplicationContext})...", AppName);
+ host.Run();
+
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Log.Fatal(ex, "Host terminated unexpectedly");
+ return 1;
+ }
+ finally
+ {
+ Log.CloseAndFlush();
+ }
+ }
+
+ public static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ webBuilder.UseConfiguration(configuration);
+ webBuilder.UseSerilog();
+ });
+
+ private static ILogger CreateSerilogLogger(IConfiguration configuration)
+ {
+ return new LoggerConfiguration()
+ .MinimumLevel.Verbose()
+ .Enrich.WithProperty("ApplicationContext", AppName)
+ .Enrich.FromLogContext()
+ .Enrich.WithSpan()
+ .WriteTo.Console()
+ .WriteTo.Seq("http://seq")
+ .ReadFrom.Configuration(configuration)
+ .CreateLogger();
+ }
+
+ private static IConfiguration GetConfiguration()
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
+ .AddEnvironmentVariables();
+
+ return builder.Build();
+ }
+ }
+}
diff --git a/src/Services/Attendance/Attendance.API/Startup.cs b/src/Services/Attendance/Attendance.API/Startup.cs
new file mode 100644
index 00000000..37cf6f91
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/Startup.cs
@@ -0,0 +1,56 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.OpenApi.Models;
+
+namespace Attendance.API
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllers();
+ services.AddSwaggerGen(c =>
+ {
+ c.SwaggerDoc(
+ "v1",
+ new OpenApiInfo
+ {
+ Title = "Attendance.API",
+ Version = "v1",
+ });
+ });
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseSwagger();
+ app.UseSwaggerUI(
+ c => c.SwaggerEndpoint(
+ "/swagger/v1/swagger.json", "Attendance.API v1"));
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+ }
+ }
+}
diff --git a/src/Services/Attendance/Attendance.API/appsettings.Development.json b/src/Services/Attendance/Attendance.API/appsettings.Development.json
new file mode 100644
index 00000000..8983e0fc
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/src/Services/Attendance/Attendance.API/appsettings.json b/src/Services/Attendance/Attendance.API/appsettings.json
new file mode 100644
index 00000000..d9d9a9bf
--- /dev/null
+++ b/src/Services/Attendance/Attendance.API/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}