From 576944ac1ab724ee0bd76b908ec418b8ab17a518 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Sat, 31 Oct 2026 23:52:29 +0300 Subject: [PATCH] wip --- .../HwProj.APIGateway.API/Dockerfile | 1 - .../HwProj.AuthService.API/Dockerfile | 2 + .../HwProj.AuthService.API.csproj | 10 +- .../AuthServiceTests.cs | 1 - ...HwProj.AuthService.IntegrationTests.csproj | 1 - .../HwProj.Common.Net8.csproj | 13 +- .../UserIdAuthentication.cs | 50 +++++++ .../HwProj.Repositories.Net8.csproj | 8 +- .../HwProj.Repositories/CrudRepository.cs | 51 ------- .../HwProj.Repositories.csproj | 11 -- .../HwProj.Repositories/ICrudRepository.cs | 17 --- HwProj.Common/HwProj.Repositories/IEntity.cs | 10 -- .../IReadOnlyRepository.cs | 17 --- .../HwProj.Repositories/ReadOnlyRepository.cs | 40 ------ .../HwProj.Utils/Auth/AuthExtensions.cs | 31 ---- .../Auth/UserIdAuthenticationHandler.cs | 48 ------- .../Configuration/ConnectionString.cs | 20 --- .../Middleware/NoApiGatewayMiddleware.cs | 26 ---- .../Configuration/StartupExtensions.cs | 135 ------------------ .../HwProj.Utils/HwProj.Utils.csproj | 44 ------ .../Controllers/FilesController.cs | 2 +- .../HwProj.ContentService.API/Dockerfile | 4 +- .../Extensions/ConfigurationExtensions.cs | 2 +- .../HwProj.ContentService.API.csproj | 10 +- .../HwProj.CoursesService.API/Dockerfile | 3 +- .../HwProj.CoursesService.API.csproj | 19 +-- .../Dockerfile | 2 + .../HwProj.NotificationsService.API.csproj | 13 +- .../Controllers/SolutionsController.cs | 3 +- .../HwProj.SolutionsService.API/Dockerfile | 11 +- .../HwProj.SolutionsService.API.csproj | 31 +--- .../20261031203929_Net8Update.Designer.cs | 94 ++++++++++++ .../Migrations/20261031203929_Net8Update.cs | 22 +++ .../SolutionContextModelSnapshot.cs | 73 ++++++---- .../Models/Github/GithubSolutionCommit.cs | 2 +- .../Models/Solution.cs | 2 +- .../HwProj.SolutionsService.API/Program.cs | 2 +- .../Properties/launchSettings.json | 7 - .../GithubSolutionCommitsRepository.cs | 2 +- .../IGithubSolutionCommitsRepository.cs | 2 +- .../Repositories/ISolutionsRepository.cs | 2 +- .../Repositories/SolutionsRepository.cs | 2 +- .../Services/SolutionsService.cs | 38 ++--- .../HwProj.SolutionsService.API/Startup.cs | 40 ++++-- ...j.SolutionsService.IntegrationTests.csproj | 22 ++- HwProj.sln | 20 --- Net8.Service.props | 24 ++++ Net8.props | 13 ++ docker-compose.override.yml | 4 +- 49 files changed, 362 insertions(+), 645 deletions(-) create mode 100644 HwProj.Common/HwProj.Common.Net8/UserIdAuthentication.cs delete mode 100644 HwProj.Common/HwProj.Repositories/CrudRepository.cs delete mode 100644 HwProj.Common/HwProj.Repositories/HwProj.Repositories.csproj delete mode 100644 HwProj.Common/HwProj.Repositories/ICrudRepository.cs delete mode 100644 HwProj.Common/HwProj.Repositories/IEntity.cs delete mode 100644 HwProj.Common/HwProj.Repositories/IReadOnlyRepository.cs delete mode 100644 HwProj.Common/HwProj.Repositories/ReadOnlyRepository.cs delete mode 100644 HwProj.Common/HwProj.Utils/Auth/AuthExtensions.cs delete mode 100644 HwProj.Common/HwProj.Utils/Auth/UserIdAuthenticationHandler.cs delete mode 100644 HwProj.Common/HwProj.Utils/Configuration/ConnectionString.cs delete mode 100644 HwProj.Common/HwProj.Utils/Configuration/Middleware/NoApiGatewayMiddleware.cs delete mode 100644 HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs delete mode 100644 HwProj.Common/HwProj.Utils/HwProj.Utils.csproj create mode 100644 HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.Designer.cs create mode 100644 HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.cs create mode 100644 Net8.Service.props create mode 100644 Net8.props diff --git a/HwProj.APIGateway/HwProj.APIGateway.API/Dockerfile b/HwProj.APIGateway/HwProj.APIGateway.API/Dockerfile index c288fdbd0..5afbab060 100644 --- a/HwProj.APIGateway/HwProj.APIGateway.API/Dockerfile +++ b/HwProj.APIGateway/HwProj.APIGateway.API/Dockerfile @@ -7,7 +7,6 @@ COPY ["HwProj.APIGateway/HwProj.APIGateway.API/", "HwProj.APIGateway/HwProj.APIG COPY ["HwProj.NotificationsService/HwProj.NotificationsService.Client/", "HwProj.NotificationsService/HwProj.NotificationsService.Client/"] COPY ["HwProj.Common/HwProj.Models/", "HwProj.Common/HwProj.Models/"] COPY ["HwProj.Common/HwProj.HttpUtils/", "HwProj.Common/HwProj.HttpUtils/"] -COPY ["HwProj.Common/HwProj.Utils/", "HwProj.Common/HwProj.Utils/"] COPY ["HwProj.EventBus/HwProj.EventBus.Client/", "HwProj.EventBus/HwProj.EventBus.Client/"] COPY ["HwProj.CoursesService/HwProj.CoursesService.Client/", "HwProj.CoursesService/HwProj.CoursesService.Client/"] COPY ["HwProj.AuthService/HwProj.AuthService.Client/", "HwProj.AuthService/HwProj.AuthService.Client/"] diff --git a/HwProj.AuthService/HwProj.AuthService.API/Dockerfile b/HwProj.AuthService/HwProj.AuthService.API/Dockerfile index 1847054b3..1aa553224 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/Dockerfile +++ b/HwProj.AuthService/HwProj.AuthService.API/Dockerfile @@ -2,6 +2,8 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Directory.Build.props", "Directory.Build.props"] +COPY ["Net8.props", "Net8.props"] +COPY ["Net8.Service.props", "Net8.Service.props"] COPY ["HwProj.AuthService/HwProj.AuthService.API/", "HwProj.AuthService/HwProj.AuthService.API/"] COPY ["HwProj.Common/HwProj.Common.Net8/", "HwProj.Common/HwProj.Common.Net8/"] diff --git a/HwProj.AuthService/HwProj.AuthService.API/HwProj.AuthService.API.csproj b/HwProj.AuthService/HwProj.AuthService.API/HwProj.AuthService.API.csproj index 1eaa0766d..ad045973f 100644 --- a/HwProj.AuthService/HwProj.AuthService.API/HwProj.AuthService.API.csproj +++ b/HwProj.AuthService/HwProj.AuthService.API/HwProj.AuthService.API.csproj @@ -1,27 +1,19 @@  + - net8.0 - Linux - ..\..\docker-compose.dcproj - ..\.. - $(CSharpLanguageVersion) 603911e4-ace8-4439-96f8-1705a0dae761 - disable - - - diff --git a/HwProj.AuthService/HwProj.AuthService.IntegrationTests/AuthServiceTests.cs b/HwProj.AuthService/HwProj.AuthService.IntegrationTests/AuthServiceTests.cs index 404e38e43..c4a9fe8d7 100644 --- a/HwProj.AuthService/HwProj.AuthService.IntegrationTests/AuthServiceTests.cs +++ b/HwProj.AuthService/HwProj.AuthService.IntegrationTests/AuthServiceTests.cs @@ -18,7 +18,6 @@ using HwProj.Models.AuthService.DTO; using HwProj.Models.Result; using HwProj.Models.Roles; -using HwProj.Utils.Auth; namespace HwProj.AuthService.IntegrationTests { diff --git a/HwProj.AuthService/HwProj.AuthService.IntegrationTests/HwProj.AuthService.IntegrationTests.csproj b/HwProj.AuthService/HwProj.AuthService.IntegrationTests/HwProj.AuthService.IntegrationTests.csproj index 5aacb1b26..0fb2fb92b 100644 --- a/HwProj.AuthService/HwProj.AuthService.IntegrationTests/HwProj.AuthService.IntegrationTests.csproj +++ b/HwProj.AuthService/HwProj.AuthService.IntegrationTests/HwProj.AuthService.IntegrationTests.csproj @@ -18,7 +18,6 @@ - diff --git a/HwProj.Common/HwProj.Common.Net8/HwProj.Common.Net8.csproj b/HwProj.Common/HwProj.Common.Net8/HwProj.Common.Net8.csproj index 63ae51c26..08708506f 100644 --- a/HwProj.Common/HwProj.Common.Net8/HwProj.Common.Net8.csproj +++ b/HwProj.Common/HwProj.Common.Net8/HwProj.Common.Net8.csproj @@ -1,14 +1,17 @@  + + - net8.0 enable enable - - - - + + + + + + diff --git a/HwProj.Common/HwProj.Common.Net8/UserIdAuthentication.cs b/HwProj.Common/HwProj.Common.Net8/UserIdAuthentication.cs new file mode 100644 index 000000000..0736d4f8e --- /dev/null +++ b/HwProj.Common/HwProj.Common.Net8/UserIdAuthentication.cs @@ -0,0 +1,50 @@ +using System.Security.Claims; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace HwProj.Common.Net8; + +public static class AuthSchemeConstants +{ + public const string UserIdAuthentication = "UserIdAuth"; +} + +public class UserIdAuthenticationOptions : AuthenticationSchemeOptions +{ +} + +/// +/// Аутентифицирует запрос по заголовку UserId, который проставляет API Gateway +/// +public class UserIdAuthenticationHandler( + IOptionsMonitor options, + ILoggerFactory logger, + UrlEncoder encoder) + : AuthenticationHandler(options, logger, encoder) +{ + protected override Task HandleAuthenticateAsync() + { + var userId = Request.GetUserIdFromHeader(); + if (userId == null) return Task.FromResult(AuthenticateResult.Fail("Unauthorized")); + + var identity = new ClaimsIdentity([new Claim("_id", userId)], Scheme.Name); + var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), Scheme.Name); + return Task.FromResult(AuthenticateResult.Success(ticket)); + } +} + +public static class UserIdAuthenticationExtensions +{ + public static IServiceCollection AddUserIdAuthentication(this IServiceCollection services) + { + services + .AddAuthentication(AuthSchemeConstants.UserIdAuthentication) + .AddScheme( + AuthSchemeConstants.UserIdAuthentication, null); + + return services; + } +} diff --git a/HwProj.Common/HwProj.Repositories.Net8/HwProj.Repositories.Net8.csproj b/HwProj.Common/HwProj.Repositories.Net8/HwProj.Repositories.Net8.csproj index 07c4efcd8..cf10835c4 100644 --- a/HwProj.Common/HwProj.Repositories.Net8/HwProj.Repositories.Net8.csproj +++ b/HwProj.Common/HwProj.Repositories.Net8/HwProj.Repositories.Net8.csproj @@ -1,11 +1,13 @@  + + - net8.0 12 disable + - - + + diff --git a/HwProj.Common/HwProj.Repositories/CrudRepository.cs b/HwProj.Common/HwProj.Repositories/CrudRepository.cs deleted file mode 100644 index ea23293b2..000000000 --- a/HwProj.Common/HwProj.Repositories/CrudRepository.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore; -using Z.EntityFramework.Plus; - -namespace HwProj.Repositories -{ - public class CrudRepository : ReadOnlyRepository, ICrudRepository - where TEntity : class, IEntity - where TKey : IEquatable - { - public CrudRepository(DbContext context) - : base(context) - { - } - - public async Task AddAsync(TEntity item) - { - await Context.AddAsync(item).ConfigureAwait(false); - await Context.SaveChangesAsync().ConfigureAwait(false); - return item.Id; - } - - public async Task> AddRangeAsync(IEnumerable items) - { - items = items.ToList(); - await Context.AddRangeAsync(items); - await Context.SaveChangesAsync(); - return items.Select(item => item.Id).ToList(); - } - - public async Task DeleteAsync(TKey id) - { - await Context.Set() - .Where(entity => entity.Id.Equals(id)) - .DeleteAsync() - .ConfigureAwait(false); - } - - public async Task UpdateAsync(TKey id, Expression> updateFactory) - { - await Context.Set() - .Where(entity => entity.Id.Equals(id)) - .UpdateAsync(updateFactory) - .ConfigureAwait(false); - } - } -} diff --git a/HwProj.Common/HwProj.Repositories/HwProj.Repositories.csproj b/HwProj.Common/HwProj.Repositories/HwProj.Repositories.csproj deleted file mode 100644 index 2cbd043ea..000000000 --- a/HwProj.Common/HwProj.Repositories/HwProj.Repositories.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - netstandard2.0 - $(CSharpLanguageVersion) - $(NullableReferenceTypes) - - - - - - \ No newline at end of file diff --git a/HwProj.Common/HwProj.Repositories/ICrudRepository.cs b/HwProj.Common/HwProj.Repositories/ICrudRepository.cs deleted file mode 100644 index 1f1992e74..000000000 --- a/HwProj.Common/HwProj.Repositories/ICrudRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; -using System.Collections.Generic; - -namespace HwProj.Repositories -{ - public interface ICrudRepository : IReadOnlyRepository - where TEntity : IEntity - where TKey : IEquatable - { - Task AddAsync(TEntity item); - Task> AddRangeAsync(IEnumerable items); - Task DeleteAsync(TKey id); - Task UpdateAsync(TKey id, Expression> updateFactory); - } -} diff --git a/HwProj.Common/HwProj.Repositories/IEntity.cs b/HwProj.Common/HwProj.Repositories/IEntity.cs deleted file mode 100644 index 3a9ebbad0..000000000 --- a/HwProj.Common/HwProj.Repositories/IEntity.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace HwProj.Repositories -{ - public interface IEntity - where TKey : IEquatable - { - TKey Id { get; set; } - } -} diff --git a/HwProj.Common/HwProj.Repositories/IReadOnlyRepository.cs b/HwProj.Common/HwProj.Repositories/IReadOnlyRepository.cs deleted file mode 100644 index f9b556e78..000000000 --- a/HwProj.Common/HwProj.Repositories/IReadOnlyRepository.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace HwProj.Repositories -{ - public interface IReadOnlyRepository - where TEntity : IEntity - where TKey : IEquatable - { - IQueryable GetAll(); - IQueryable FindAll(Expression> predicate); - Task GetAsync(TKey id); - Task FindAsync(Expression> predicate); - } -} diff --git a/HwProj.Common/HwProj.Repositories/ReadOnlyRepository.cs b/HwProj.Common/HwProj.Repositories/ReadOnlyRepository.cs deleted file mode 100644 index 677914ba6..000000000 --- a/HwProj.Common/HwProj.Repositories/ReadOnlyRepository.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; - -namespace HwProj.Repositories -{ - public class ReadOnlyRepository : IReadOnlyRepository - where TEntity : class, IEntity - where TKey : IEquatable - { - protected readonly DbContext Context; - - public ReadOnlyRepository(DbContext context) - { - Context = context; - } - - public IQueryable GetAll() - { - return Context.Set().AsNoTracking(); - } - - public IQueryable FindAll(Expression> predicate) - { - return Context.Set().AsNoTracking().Where(predicate); - } - - public async Task GetAsync(TKey id) - { - return await Context.FindAsync(id).ConfigureAwait(false); - } - - public async Task FindAsync(Expression> predicate) - { - return await Context.Set().AsNoTracking().FirstOrDefaultAsync(predicate).ConfigureAwait(false); - } - } -} diff --git a/HwProj.Common/HwProj.Utils/Auth/AuthExtensions.cs b/HwProj.Common/HwProj.Utils/Auth/AuthExtensions.cs deleted file mode 100644 index fde5ca45a..000000000 --- a/HwProj.Common/HwProj.Utils/Auth/AuthExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Linq; -using HwProj.Models.Roles; -using Microsoft.AspNetCore.Http; - -namespace HwProj.Utils.Authorization -{ - public static class AuthExtensions - { - public static string? GetUserIdFromHeader(this HttpRequest request) => - request.Headers.TryGetValue("UserId", out var id) ? id.FirstOrDefault() : null; - - public static string GetUserName(this HttpRequest request) - { - return request.Query.First(x => x.Key == "_userName").Value.ToString(); - } - - public static string GetUserRole(this HttpRequest request) - { - var claimRole = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"; - var role = request.HttpContext.User.Claims.FirstOrDefault(claim => claim.Type.ToString() == claimRole); - return role == null - ? null - : role.Value; - } - - public static bool IsLecturer(this string role) - { - return role == Roles.LecturerRole; - } - } -} diff --git a/HwProj.Common/HwProj.Utils/Auth/UserIdAuthenticationHandler.cs b/HwProj.Common/HwProj.Utils/Auth/UserIdAuthenticationHandler.cs deleted file mode 100644 index b76f96560..000000000 --- a/HwProj.Common/HwProj.Utils/Auth/UserIdAuthenticationHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections.Generic; -using System.Security.Claims; -using System.Text.Encodings.Web; -using System.Threading.Tasks; -using HwProj.Utils.Authorization; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace HwProj.Utils.Auth -{ - public static class AuthSchemeConstants - { - public const string UserIdAuthentication = "UserIdAuth"; - } - - public class UserIdAuthenticationOptions : AuthenticationSchemeOptions - { - } - - public class UserIdAuthenticationHandler : AuthenticationHandler - { - public UserIdAuthenticationHandler( - IOptionsMonitor options, - ILoggerFactory logger, - UrlEncoder encoder, - ISystemClock clock) - : base(options, logger, encoder, clock) - { - } - - protected override Task HandleAuthenticateAsync() - { - var userId = Request.GetUserIdFromHeader(); - if (userId == null) return Task.FromResult(AuthenticateResult.Fail("Unauthorized")); - - var claims = new List - { - new Claim("_id", userId) - }; - - var identity = new ClaimsIdentity(claims, Scheme.Name); - var principal = new System.Security.Principal.GenericPrincipal(identity, null); - var ticket = new AuthenticationTicket(principal, Scheme.Name); - return Task.FromResult(AuthenticateResult.Success(ticket)); - } - } -} diff --git a/HwProj.Common/HwProj.Utils/Configuration/ConnectionString.cs b/HwProj.Common/HwProj.Utils/Configuration/ConnectionString.cs deleted file mode 100644 index 3e130809a..000000000 --- a/HwProj.Common/HwProj.Utils/Configuration/ConnectionString.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Runtime.InteropServices; -using Microsoft.Extensions.Configuration; -using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration; - -namespace HwProj.Utils.Configuration -{ - public static class ConnectionString - { - public static string GetConnectionString(IConfiguration configuration) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || - RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return configuration.GetConnectionString("DefaultConnectionForLinux"); - } - - return configuration.GetConnectionString("DefaultConnectionForWindows"); - } - } -} \ No newline at end of file diff --git a/HwProj.Common/HwProj.Utils/Configuration/Middleware/NoApiGatewayMiddleware.cs b/HwProj.Common/HwProj.Utils/Configuration/Middleware/NoApiGatewayMiddleware.cs deleted file mode 100644 index 57a1d506e..000000000 --- a/HwProj.Common/HwProj.Utils/Configuration/Middleware/NoApiGatewayMiddleware.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using HwProj.Models.Roles; -using Microsoft.AspNetCore.Http; - -namespace HwProj.Utils.Configuration.Middleware -{ - public class NoApiGatewayMiddleware : IMiddleware - { - public async Task InvokeAsync(HttpContext context, RequestDelegate next) - { - var request = context.Request; - - if (!request.Query.ContainsKey("_id")) - { - request.QueryString = request.QueryString.Add("_id", "hwprojDevUser"); - } - - if (!request.Query.ContainsKey("_role")) - { - request.QueryString = request.QueryString.Add("_role", Roles.LecturerRole); - } - - await next.Invoke(context); - } - } -} \ No newline at end of file diff --git a/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs b/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs deleted file mode 100644 index 920b10f97..000000000 --- a/HwProj.Common/HwProj.Utils/Configuration/StartupExtensions.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using AutoMapper; -using HwProj.Utils.Auth; -using HwProj.Utils.Configuration.Middleware; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.OpenApi.Models; -using Newtonsoft.Json; - -namespace HwProj.Utils.Configuration -{ - public static class StartupExtensions - { - public static IServiceCollection ConfigureHwProjServices(this IServiceCollection services, string serviceName) - { - services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()) - .AddCors() - .AddMvc() - .AddJsonOptions(options => - options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore) - .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - - services.ConfigureHwProjServiceSwaggerGen(serviceName); - services.AddTransient(); - services.AddHttpContextAccessor(); - - return services; - } - - private static void ConfigureHwProjServiceSwaggerGen(this IServiceCollection services, string serviceName) - { - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = serviceName, Version = "v1" }); - c.CustomOperationIds(apiDesc => - { - var controllerName = apiDesc.ActionDescriptor.RouteValues["controller"]; - var actionName = apiDesc.ActionDescriptor.RouteValues["action"]; - return $"{controllerName}{actionName}"; - }); - if (serviceName == "API Gateway") - { - c.AddSecurityDefinition("Bearer", - new OpenApiSecurityScheme() - { - In = ParameterLocation.Header, - Description = "Please enter into field the word 'Bearer' following by space and JWT", - Name = "Authorization", - Type = SecuritySchemeType.ApiKey - }); - c.AddSecurityRequirement( - new OpenApiSecurityRequirement - { - { new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { - Id = "Bearer", - Type = ReferenceType.SecurityScheme - } - }, - new List() - } - }); - } - }); - } - - public static IApplicationBuilder ConfigureHwProj(this IApplicationBuilder app, IHostingEnvironment env, - string serviceName, DbContext? context = null) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage() - .UseSwagger() - .UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", serviceName); }); - } - else - { - app.UseHsts(); - } - - app.UseAuthentication(); - app.UseCors(x => x - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed(origin => true) - .AllowCredentials()); - app.UseMvc(); - - if (context != null) - { - if (env.IsDevelopment()) - { - context.Database.EnsureCreated(); - return app; - } - - var logger = app.ApplicationServices - .GetService() - .CreateLogger(typeof(StartupExtensions)); - - var tries = 0; - const int maxTries = 100; - - while (!context.Database.CanConnect() && ++tries <= maxTries) - { - logger.LogWarning($"Can't connect to database. Try {tries}."); - Thread.Sleep(5000); - } - - if (tries > maxTries) throw new Exception("Can't connect to database"); - context.Database.Migrate(); - } - - return app; - } - - public static IServiceCollection AddUserIdAuthentication(this IServiceCollection services) - { - services - .AddAuthentication(AuthSchemeConstants.UserIdAuthentication) - .AddScheme( - AuthSchemeConstants.UserIdAuthentication, null); - - return services; - } - } -} \ No newline at end of file diff --git a/HwProj.Common/HwProj.Utils/HwProj.Utils.csproj b/HwProj.Common/HwProj.Utils/HwProj.Utils.csproj deleted file mode 100644 index 9ade49d89..000000000 --- a/HwProj.Common/HwProj.Utils/HwProj.Utils.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - netcoreapp2.2 - $(CSharpLanguageVersion) - $(NullableReferenceTypes) - - - - - - - - - - - - - - - - - - - C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.hosting.abstractions\2.1.1\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.Abstractions.dll - - - C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.http.abstractions\2.1.1\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll - - - C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.mvc.core\2.1.1\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll - - - C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.dependencyinjection.abstractions\2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll - - - C:\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\11.0.2\lib\netstandard2.0\Newtonsoft.Json.dll - - - C:\Users\Alex Berezhnyh\.nuget\packages\swashbuckle.aspnetcore.swagger\4.0.1\lib\netstandard2.0\Swashbuckle.AspNetCore.Swagger.dll - - - - diff --git a/HwProj.ContentService/HwProj.ContentService.API/Controllers/FilesController.cs b/HwProj.ContentService/HwProj.ContentService.API/Controllers/FilesController.cs index 85b0db5c5..a228380ed 100644 --- a/HwProj.ContentService/HwProj.ContentService.API/Controllers/FilesController.cs +++ b/HwProj.ContentService/HwProj.ContentService.API/Controllers/FilesController.cs @@ -1,11 +1,11 @@ using System.Net; +using HwProj.Common.Net8; using HwProj.ContentService.API.Extensions; using HwProj.ContentService.API.Models.Enums; using HwProj.ContentService.API.Models.Messages; using HwProj.ContentService.API.Services.Interfaces; using HwProj.Models.ContentService.DTO; using HwProj.Models.Result; -using HwProj.Utils.Authorization; using Microsoft.AspNetCore.Mvc; namespace HwProj.ContentService.API.Controllers; diff --git a/HwProj.ContentService/HwProj.ContentService.API/Dockerfile b/HwProj.ContentService/HwProj.ContentService.API/Dockerfile index 6f1c713c7..edededcbf 100644 --- a/HwProj.ContentService/HwProj.ContentService.API/Dockerfile +++ b/HwProj.ContentService/HwProj.ContentService.API/Dockerfile @@ -2,10 +2,10 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Directory.Build.props", "Directory.Build.props"] +COPY ["Net8.props", "Net8.props"] COPY ["HwProj.ContentService/HwProj.ContentService.API/", "HwProj.ContentService/HwProj.ContentService.API/"] -COPY ["HwProj.Common/HwProj.Utils/", "HwProj.Common/HwProj.Utils/"] -COPY ["HwProj.EventBus/HwProj.EventBus.Client/", "HwProj.EventBus/HwProj.EventBus.Client/"] +COPY ["HwProj.Common/HwProj.Common.Net8/", "HwProj.Common/HwProj.Common.Net8/"] COPY ["HwProj.Common/HwProj.Models/", "HwProj.Common/HwProj.Models/"] WORKDIR "/src/HwProj.ContentService/HwProj.ContentService.API" diff --git a/HwProj.ContentService/HwProj.ContentService.API/Extensions/ConfigurationExtensions.cs b/HwProj.ContentService/HwProj.ContentService.API/Extensions/ConfigurationExtensions.cs index f332e4e8d..35524c641 100644 --- a/HwProj.ContentService/HwProj.ContentService.API/Extensions/ConfigurationExtensions.cs +++ b/HwProj.ContentService/HwProj.ContentService.API/Extensions/ConfigurationExtensions.cs @@ -3,13 +3,13 @@ using Amazon.Extensions.NETCore.Setup; using Amazon.Runtime; using Amazon.S3; +using HwProj.Common.Net8; using HwProj.ContentService.API.Configuration; using HwProj.ContentService.API.Models.Database; using HwProj.ContentService.API.Models.Messages; using HwProj.ContentService.API.Repositories; using HwProj.ContentService.API.Services; using HwProj.ContentService.API.Services.Interfaces; -using HwProj.Utils.Configuration; using Microsoft.AspNetCore.Http.Features; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; diff --git a/HwProj.ContentService/HwProj.ContentService.API/HwProj.ContentService.API.csproj b/HwProj.ContentService/HwProj.ContentService.API/HwProj.ContentService.API.csproj index 6b7af8f7a..657e40d8a 100644 --- a/HwProj.ContentService/HwProj.ContentService.API/HwProj.ContentService.API.csproj +++ b/HwProj.ContentService/HwProj.ContentService.API/HwProj.ContentService.API.csproj @@ -1,7 +1,7 @@ + - net8.0 enable enable Linux @@ -14,19 +14,19 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + + - diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Dockerfile b/HwProj.CoursesService/HwProj.CoursesService.API/Dockerfile index 461e481c6..56da113e8 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/Dockerfile +++ b/HwProj.CoursesService/HwProj.CoursesService.API/Dockerfile @@ -2,9 +2,10 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Directory.Build.props", "Directory.Build.props"] +COPY ["Net8.props", "Net8.props"] +COPY ["Net8.Service.props", "Net8.Service.props"] COPY ["HwProj.CoursesService/HwProj.CoursesService.API/", "HwProj.CoursesService/HwProj.CoursesService.API/"] -COPY ["HwProj.Common/HwProj.Utils/", "HwProj.Common/HwProj.Utils/"] COPY ["HwProj.Common/HwProj.Models/", "HwProj.Common/HwProj.Models/"] COPY ["HwProj.Common/HwProj.Exceptions/", "HwProj.Common/HwProj.Exceptions/"] COPY ["HwProj.EventBus/HwProj.EventBus.Client/", "HwProj.EventBus/HwProj.EventBus.Client/"] diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/HwProj.CoursesService.API.csproj b/HwProj.CoursesService/HwProj.CoursesService.API/HwProj.CoursesService.API.csproj index 94759d1be..d3869af23 100644 --- a/HwProj.CoursesService/HwProj.CoursesService.API/HwProj.CoursesService.API.csproj +++ b/HwProj.CoursesService/HwProj.CoursesService.API/HwProj.CoursesService.API.csproj @@ -1,23 +1,10 @@  - - net8.0 - $(CSharpLanguageVersion) - disable - + + - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - \ No newline at end of file + diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Dockerfile b/HwProj.NotificationsService/HwProj.NotificationsService.API/Dockerfile index 2eb9b0a51..21328145f 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Dockerfile +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Dockerfile @@ -2,6 +2,8 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Directory.Build.props", "Directory.Build.props"] +COPY ["Net8.props", "Net8.props"] +COPY ["Net8.Service.props", "Net8.Service.props"] COPY ["HwProj.NotificationsService/HwProj.NotificationsService.API/", "HwProj.NotificationsService/HwProj.NotificationsService.API/"] COPY ["HwProj.NotificationsService/HwProj.NotificationService.Events/", "HwProj.NotificationsService/HwProj.NotificationService.Events/"] diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj index cf6d0176c..810e211b2 100644 --- a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj +++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj @@ -1,24 +1,13 @@  - - - net8.0 - ..\..\docker-compose.dcproj - Linux - ..\.. - $(CSharpLanguageVersion) - disable - + - - - diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Controllers/SolutionsController.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Controllers/SolutionsController.cs index 9c4e0554b..367b440ee 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Controllers/SolutionsController.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Controllers/SolutionsController.cs @@ -4,6 +4,7 @@ using System.Net; using System.Threading.Tasks; using AutoMapper; +using HwProj.Common.Net8; using HwProj.CoursesService.Client; using HwProj.Models.CoursesService; using HwProj.Models.SolutionsService; @@ -12,8 +13,6 @@ using HwProj.SolutionsService.API.Models; using HwProj.SolutionsService.API.Repositories; using HwProj.SolutionsService.API.Services; -using HwProj.Utils.Auth; -using HwProj.Utils.Authorization; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Dockerfile b/HwProj.SolutionsService/HwProj.SolutionsService.API/Dockerfile index 3a1c33e91..f2b3c06be 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Dockerfile +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Dockerfile @@ -1,15 +1,16 @@ -FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Directory.Build.props", "Directory.Build.props"] +COPY ["Net8.props", "Net8.props"] +COPY ["Net8.Service.props", "Net8.Service.props"] COPY ["HwProj.SolutionsService/HwProj.SolutionsService.API/", "HwProj.SolutionsService/HwProj.SolutionsService.API/"] -COPY ["HwProj.SolutionsService/HwProj.SolutionsService.Client/", "HwProj.SolutionsService/HwProj.SolutionsService.Client/"] +COPY ["HwProj.Common/HwProj.Common.Net8/", "HwProj.Common/HwProj.Common.Net8/"] +COPY ["HwProj.Common/HwProj.Repositories.Net8/", "HwProj.Common/HwProj.Repositories.Net8/"] COPY ["HwProj.Common/HwProj.Models/", "HwProj.Common/HwProj.Models/"] -COPY ["HwProj.Common/HwProj.Repositories/", "HwProj.Common/HwProj.Repositories/"] COPY ["HwProj.Common/HwProj.Exceptions/", "HwProj.Common/HwProj.Exceptions/"] COPY ["HwProj.Common/HwProj.HttpUtils/", "HwProj.Common/HwProj.HttpUtils/"] -COPY ["HwProj.Common/HwProj.Utils/", "HwProj.Common/HwProj.Utils/"] COPY ["HwProj.EventBus/HwProj.EventBus.Client/", "HwProj.EventBus/HwProj.EventBus.Client/"] COPY ["HwProj.CoursesService/HwProj.CoursesService.Client/", "HwProj.CoursesService/HwProj.CoursesService.Client/"] COPY ["HwProj.AuthService/HwProj.AuthService.Client/", "HwProj.AuthService/HwProj.AuthService.Client/"] @@ -18,7 +19,7 @@ COPY ["HwProj.NotificationsService/HwProj.NotificationService.Events/", "HwProj. WORKDIR "/src/HwProj.SolutionsService/HwProj.SolutionsService.API" RUN dotnet publish "HwProj.SolutionsService.API.csproj" -c Release -o /app/publish -FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS final +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app COPY --from=build /app/publish . diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/HwProj.SolutionsService.API.csproj b/HwProj.SolutionsService/HwProj.SolutionsService.API/HwProj.SolutionsService.API.csproj index fe78204a2..4bd094e61 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/HwProj.SolutionsService.API.csproj +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/HwProj.SolutionsService.API.csproj @@ -1,38 +1,17 @@  + + - netcoreapp2.2 - Linux - ..\..\docker-compose.dcproj - ..\.. - $(CSharpLanguageVersion) - $(NullableReferenceTypes) 467aaa56-ee17-4f11-b2da-7d9a74c68753 + - - - - - - - - - - - - - - - - + - - - - \ No newline at end of file + diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.Designer.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.Designer.cs new file mode 100644 index 000000000..6b83e2ee9 --- /dev/null +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.Designer.cs @@ -0,0 +1,94 @@ +// +using System; +using HwProj.SolutionsService.API.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace HwProj.SolutionsService.API.Migrations +{ + [DbContext(typeof(SolutionContext))] + [Migration("20261031203929_Net8Update")] + partial class Net8Update + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("HwProj.SolutionsService.API.Models.GithubSolutionCommit", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("CommitHash") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LastGithubSolutionCommits"); + }); + + modelBuilder.Entity("HwProj.SolutionsService.API.Models.Solution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("nvarchar(max)"); + + b.Property("GithubUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("GroupId") + .HasColumnType("bigint"); + + b.Property("IsModified") + .HasColumnType("bit"); + + b.Property("LecturerComment") + .HasColumnType("nvarchar(max)"); + + b.Property("LecturerId") + .HasColumnType("nvarchar(max)"); + + b.Property("PublicationDate") + .HasColumnType("datetime2"); + + b.Property("Rating") + .HasColumnType("int"); + + b.Property("RatingDate") + .HasColumnType("datetime2"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("StudentId") + .HasColumnType("nvarchar(max)"); + + b.Property("TaskId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("Solutions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.cs new file mode 100644 index 000000000..88c358f8b --- /dev/null +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20261031203929_Net8Update.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace HwProj.SolutionsService.API.Migrations +{ + /// + public partial class Net8Update : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs index 8a4e07014..a636e81d0 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +#nullable disable + namespace HwProj.SolutionsService.API.Migrations { [DbContext(typeof(SolutionContext))] @@ -15,56 +17,73 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.2.6-servicing-10079") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasAnnotation("ProductVersion", "9.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("HwProj.Models.SolutionsService.Solution", b => + modelBuilder.Entity("HwProj.SolutionsService.API.Models.GithubSolutionCommit", b => { b.Property("Id") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasColumnType("bigint"); - b.Property("Comment"); + b.Property("CommitHash") + .HasColumnType("nvarchar(max)"); - b.Property("GithubUrl"); + b.HasKey("Id"); - b.Property("GroupId"); + b.ToTable("LastGithubSolutionCommits"); + }); - b.Property("IsModified"); + modelBuilder.Entity("HwProj.SolutionsService.API.Models.Solution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); - b.Property("LecturerComment"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.Property("LecturerId"); + b.Property("Comment") + .HasColumnType("nvarchar(max)"); - b.Property("PublicationDate"); + b.Property("GithubUrl") + .HasColumnType("nvarchar(max)"); - b.Property("Rating"); + b.Property("GroupId") + .HasColumnType("bigint"); - b.Property("RatingDate"); + b.Property("IsModified") + .HasColumnType("bit"); - b.Property("State"); + b.Property("LecturerComment") + .HasColumnType("nvarchar(max)"); - b.Property("StudentId"); + b.Property("LecturerId") + .HasColumnType("nvarchar(max)"); - b.Property("TaskId"); + b.Property("PublicationDate") + .HasColumnType("datetime2"); - b.HasKey("Id"); + b.Property("Rating") + .HasColumnType("int"); - b.HasIndex("TaskId"); + b.Property("RatingDate") + .HasColumnType("datetime2"); - b.ToTable("Solutions"); - }); + b.Property("State") + .HasColumnType("int"); - modelBuilder.Entity("HwProj.SolutionsService.API.Models.GithubSolutionCommit", b => - { - b.Property("Id"); + b.Property("StudentId") + .HasColumnType("nvarchar(max)"); - b.Property("CommitHash"); + b.Property("TaskId") + .HasColumnType("bigint"); b.HasKey("Id"); - b.ToTable("LastGithubSolutionCommits"); + b.HasIndex("TaskId"); + + b.ToTable("Solutions"); }); #pragma warning restore 612, 618 } diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Github/GithubSolutionCommit.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Github/GithubSolutionCommit.cs index 494b6805a..cf9279745 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Github/GithubSolutionCommit.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Github/GithubSolutionCommit.cs @@ -1,5 +1,5 @@ using System.ComponentModel.DataAnnotations.Schema; -using HwProj.Repositories; +using HwProj.Repositories.Net8; namespace HwProj.SolutionsService.API.Models { diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Solution.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Solution.cs index 064a5c083..8ad068909 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Solution.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Models/Solution.cs @@ -1,6 +1,6 @@ using System; using HwProj.Models.SolutionsService; -using HwProj.Repositories; +using HwProj.Repositories.Net8; namespace HwProj.SolutionsService.API.Models { diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Program.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Program.cs index 264172f93..3c26e3a34 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Program.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Program.cs @@ -3,7 +3,7 @@ namespace HwProj.SolutionsService.API { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Properties/launchSettings.json b/HwProj.SolutionsService/HwProj.SolutionsService.API/Properties/launchSettings.json index b4956d025..a3ea27fbf 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Properties/launchSettings.json +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Properties/launchSettings.json @@ -7,13 +7,6 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5007" - }, - "Docker": { - "commandName": "Docker", - "launchBrowser": true, - "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", - "publishAllPorts": true, - "useSSL": true } } } diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/GithubSolutionCommitsRepository.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/GithubSolutionCommitsRepository.cs index 6a290262e..f1aeaa46f 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/GithubSolutionCommitsRepository.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/GithubSolutionCommitsRepository.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using HwProj.Repositories; +using HwProj.Repositories.Net8; using HwProj.SolutionsService.API.Models; namespace HwProj.SolutionsService.API.Repositories diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/IGithubSolutionCommitsRepository.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/IGithubSolutionCommitsRepository.cs index 3b56a406d..dbee3f812 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/IGithubSolutionCommitsRepository.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/IGithubSolutionCommitsRepository.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using HwProj.Repositories; +using HwProj.Repositories.Net8; using HwProj.SolutionsService.API.Models; namespace HwProj.SolutionsService.API.Repositories diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/ISolutionsRepository.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/ISolutionsRepository.cs index 907a19f23..d227686f9 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/ISolutionsRepository.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/ISolutionsRepository.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; using HwProj.Models.SolutionsService; -using HwProj.Repositories; +using HwProj.Repositories.Net8; using HwProj.SolutionsService.API.Models; namespace HwProj.SolutionsService.API.Repositories diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/SolutionsRepository.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/SolutionsRepository.cs index 999760b67..0b6c3b260 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/SolutionsRepository.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Repositories/SolutionsRepository.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Threading.Tasks; using HwProj.Models.SolutionsService; -using HwProj.Repositories; +using HwProj.Repositories.Net8; using HwProj.SolutionsService.API.Models; using Microsoft.EntityFrameworkCore; diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs index 18d336a04..9fe768524 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs @@ -5,7 +5,6 @@ using HwProj.AuthService.Client; using HwProj.CoursesService.Client; using HwProj.EventBus.Client.Interfaces; -using HwProj.Models.AuthService.DTO; using HwProj.Models.CoursesService; using HwProj.Models.SolutionsService; using HwProj.Models.StatisticsService; @@ -137,8 +136,7 @@ await _solutionsRepository var solutionModel = _mapper.Map(solution); var course = await _coursesServiceClient.GetCourseByTask(solution.TaskId); var student = await _authServiceClient.GetAccountData(solutionModel.StudentId); - var studentModel = _mapper.Map(student); - _eventBus.Publish(new StudentPassTaskEvent(course, solutionModel, studentModel, task)); + _eventBus.Publish(new StudentPassTaskEvent(course, solutionModel, student, task)); } if (task.Tags.Contains(HomeworkTags.Test)) @@ -242,25 +240,27 @@ public async Task GetAllUnratedSolutions(GetTasksSolutions .ToArray(); } - return await getSolutionsQuery.GroupBy(t => new { t.TaskId, t.StudentId }) - .Select(t => t.OrderByDescending(x => x.PublicationDate)) - .Select(t => new - { - LastSolution = t.FirstOrDefault(), - IsFirstTry = t.Skip(1).All(s => s.State == SolutionState.Posted) - }) - .Where(t => t.LastSolution != null && t.LastSolution.State == SolutionState.Posted) - .OrderBy(t => t.LastSolution!.PublicationDate) + // EF Core не транслирует в SQL выборку последнего решения из группы, + // поэтому достаем из БД только нужные столбцы и группируем в памяти + var solutions = await getSolutionsQuery + .Select(s => new { s.Id, s.TaskId, s.StudentId, s.GroupId, s.State, s.PublicationDate }) + .ToArrayAsync(); + + return solutions + .GroupBy(t => new { t.TaskId, t.StudentId }) + .Select(t => t.OrderByDescending(x => x.PublicationDate).ToArray()) + .Where(t => t[0].State == SolutionState.Posted) + .OrderBy(t => t[0].PublicationDate) .Select(t => new SolutionPreviewDto { - StudentId = t.LastSolution!.StudentId, - SolutionId = t.LastSolution.Id, - GroupId = t.LastSolution.GroupId, - TaskId = t.LastSolution.TaskId, - PublicationDate = t.LastSolution.PublicationDate, - IsFirstTry = t.IsFirstTry + StudentId = t[0].StudentId, + SolutionId = t[0].Id, + GroupId = t[0].GroupId, + TaskId = t[0].TaskId, + PublicationDate = t[0].PublicationDate, + IsFirstTry = t.Skip(1).All(s => s.State == SolutionState.Posted) }) - .ToArrayAsync(); + .ToArray(); } public async Task GetTaskSolutionsStats(GetTasksSolutionsModel tasksSolutionsModel) diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Startup.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Startup.cs index 752f0fba4..fcc6113dd 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Startup.cs +++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Startup.cs @@ -1,16 +1,16 @@ +using System.Text.Json.Serialization; using HwProj.AuthService.Client; +using HwProj.Common.Net8; using HwProj.CoursesService.Client; using HwProj.EventBus.Client; -using HwProj.EventBus.Client.Interfaces; using HwProj.SolutionsService.API.Models; using HwProj.SolutionsService.API.Repositories; using HwProj.SolutionsService.API.Services; -using HwProj.Utils.Configuration; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; namespace HwProj.SolutionsService.API { @@ -21,7 +21,7 @@ public Startup(IConfiguration configuration) Configuration = configuration; } - public IConfiguration Configuration { get; } + private IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { @@ -38,13 +38,37 @@ public void ConfigureServices(IServiceCollection services) services.AddCoursesServiceClient(); services.AddEventBus(Configuration); - services.ConfigureHwProjServices("Solutions API"); + + services + .AddCors() + .AddControllers(options => + // Модели из HwProj.Models собраны с nullable, без этого их string-свойства + // без '?' стали бы обязательными, и запросы с null отклонялись бы с 400 + options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true) + .AddJsonOptions(options => + options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles); + + services.AddAutoMapper(x => x.AddProfile()); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, IEventBus eventBus, - SolutionContext context) + public void Configure(IApplicationBuilder app, IHostEnvironment env, SolutionContext context) { - app.ConfigureHwProj(env, "Solutions API", context); + app.UseDatabase(env, context); + + if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); + else app.UseHsts(); + + app.UseRouting(); + app.UseCors(x => x + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed(_ => true) + .AllowCredentials()); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseEndpoints(x => x.MapControllers()); } } } diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.IntegrationTests/HwProj.SolutionsService.IntegrationTests.csproj b/HwProj.SolutionsService/HwProj.SolutionsService.IntegrationTests/HwProj.SolutionsService.IntegrationTests.csproj index 0ec55f117..254e9b5d4 100644 --- a/HwProj.SolutionsService/HwProj.SolutionsService.IntegrationTests/HwProj.SolutionsService.IntegrationTests.csproj +++ b/HwProj.SolutionsService/HwProj.SolutionsService.IntegrationTests/HwProj.SolutionsService.IntegrationTests.csproj @@ -1,7 +1,7 @@ + - netcoreapp2.2 enable false @@ -10,13 +10,13 @@ - - - - - - - + + + + + + + @@ -27,10 +27,4 @@ - - - ..\..\..\..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.2.2\Microsoft.Extensions.Configuration.Abstractions.dll - - - diff --git a/HwProj.sln b/HwProj.sln index 6b9064aec..e639e2948 100644 --- a/HwProj.sln +++ b/HwProj.sln @@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29001.49 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.Repositories", "HwProj.Common\HwProj.Repositories\HwProj.Repositories.csproj", "{4E5191DC-EC8B-44C8-BD85-198D2C0C16F7}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HwProj.SolutionsService", "HwProj.SolutionsService", "{A85A3030-2878-4923-B450-9683832CDAC1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.SolutionsService.API", "HwProj.SolutionsService\HwProj.SolutionsService.API\HwProj.SolutionsService.API.csproj", "{D59EB6F0-8220-417A-AB3E-6960E9A15459}" @@ -20,23 +18,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.NotificationsService EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HwProj.Common", "HwProj.Common", "{77D857A8-45C6-4432-B4BF-A2F2C9ECA7FE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.Utils", "HwProj.Common\HwProj.Utils\HwProj.Utils.csproj", "{F584B68E-B6A8-46F1-A692-CB87DE9996BE}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.NotificationsService.Tests", "HwProj.NotificationsService\HwProj.NotificationsService.Tests\HwProj.NotificationsService.Tests.csproj", "{2B4D695D-1BAA-4BCC-AE5A-C1CDD4ACCCCA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HwProj.AuthService", "HwProj.AuthService", "{D7F8BC73-A6CB-4E07-984D-2D65B740BC69}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.AuthService.API", "HwProj.AuthService\HwProj.AuthService.API\HwProj.AuthService.API.csproj", "{7ECE830B-68EA-4BA3-BDEC-0D1E9FACB19A}" - ProjectSection(ProjectDependencies) = postProject - {F584B68E-B6A8-46F1-A692-CB87DE9996BE} = {F584B68E-B6A8-46F1-A692-CB87DE9996BE} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HwProj.APIGateway", "HwProj.APIGateway", "{DC0D1EE7-D2F8-4D15-8CC6-69A0A0A938D9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.APIGateway.API", "HwProj.APIGateway\HwProj.APIGateway.API\HwProj.APIGateway.API.csproj", "{1407B364-9938-42C3-B061-30BE3F96FE02}" - ProjectSection(ProjectDependencies) = postProject - {F584B68E-B6A8-46F1-A692-CB87DE9996BE} = {F584B68E-B6A8-46F1-A692-CB87DE9996BE} - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HwProj.Models", "HwProj.Common\HwProj.Models\HwProj.Models.csproj", "{ECFA80DA-E0F5-4613-A15E-55FC8B9C8401}" EndProject @@ -88,10 +78,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4E5191DC-EC8B-44C8-BD85-198D2C0C16F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4E5191DC-EC8B-44C8-BD85-198D2C0C16F7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4E5191DC-EC8B-44C8-BD85-198D2C0C16F7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4E5191DC-EC8B-44C8-BD85-198D2C0C16F7}.Release|Any CPU.Build.0 = Release|Any CPU {D59EB6F0-8220-417A-AB3E-6960E9A15459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D59EB6F0-8220-417A-AB3E-6960E9A15459}.Debug|Any CPU.Build.0 = Debug|Any CPU {D59EB6F0-8220-417A-AB3E-6960E9A15459}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -108,10 +94,6 @@ Global {45304D33-6A6C-4C02-95C5-8E213CD8F39C}.Debug|Any CPU.Build.0 = Debug|Any CPU {45304D33-6A6C-4C02-95C5-8E213CD8F39C}.Release|Any CPU.ActiveCfg = Release|Any CPU {45304D33-6A6C-4C02-95C5-8E213CD8F39C}.Release|Any CPU.Build.0 = Release|Any CPU - {F584B68E-B6A8-46F1-A692-CB87DE9996BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F584B68E-B6A8-46F1-A692-CB87DE9996BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F584B68E-B6A8-46F1-A692-CB87DE9996BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F584B68E-B6A8-46F1-A692-CB87DE9996BE}.Release|Any CPU.Build.0 = Release|Any CPU {2B4D695D-1BAA-4BCC-AE5A-C1CDD4ACCCCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2B4D695D-1BAA-4BCC-AE5A-C1CDD4ACCCCA}.Debug|Any CPU.Build.0 = Debug|Any CPU {2B4D695D-1BAA-4BCC-AE5A-C1CDD4ACCCCA}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -205,12 +187,10 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {4E5191DC-EC8B-44C8-BD85-198D2C0C16F7} = {77D857A8-45C6-4432-B4BF-A2F2C9ECA7FE} {D59EB6F0-8220-417A-AB3E-6960E9A15459} = {A85A3030-2878-4923-B450-9683832CDAC1} {EB85EEF8-5860-43A3-AE0D-654DC1325F0F} = {CB37F9AC-88CB-425C-8200-1B40F372F38D} {6AA3505A-04E4-4B4C-90C9-A30393C878C0} = {CB37F9AC-88CB-425C-8200-1B40F372F38D} {45304D33-6A6C-4C02-95C5-8E213CD8F39C} = {1EAEB779-E7C8-4EF9-B9A9-22CB8E3C246D} - {F584B68E-B6A8-46F1-A692-CB87DE9996BE} = {77D857A8-45C6-4432-B4BF-A2F2C9ECA7FE} {2B4D695D-1BAA-4BCC-AE5A-C1CDD4ACCCCA} = {1EAEB779-E7C8-4EF9-B9A9-22CB8E3C246D} {7ECE830B-68EA-4BA3-BDEC-0D1E9FACB19A} = {D7F8BC73-A6CB-4E07-984D-2D65B740BC69} {1407B364-9938-42C3-B061-30BE3F96FE02} = {DC0D1EE7-D2F8-4D15-8CC6-69A0A0A938D9} diff --git a/Net8.Service.props b/Net8.Service.props new file mode 100644 index 000000000..d28e6d75d --- /dev/null +++ b/Net8.Service.props @@ -0,0 +1,24 @@ + + + + + + $(CSharpLanguageVersion) + + disable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/Net8.props b/Net8.props new file mode 100644 index 000000000..1ed622bc3 --- /dev/null +++ b/Net8.props @@ -0,0 +1,13 @@ + + + + net8.0 + + + + 15.0.1 + 9.0.9 + 9.0.9 + 9.104.0 + + diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 10e1ecfee..6be707ea1 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -88,9 +88,9 @@ services: hwproj.solutionsservice.api: environment: - - ConnectionStrings:DefaultConnectionForLinux=Server=mssqllocaldb;Database=SolutionServiceDB;User=sa;Password=Your_password123; + - ConnectionStrings:DefaultConnectionForLinux=Server=mssqllocaldb;Database=SolutionServiceDB;User=sa;Password=Your_password123;TrustServerCertificate=true; - ASPNETCORE_ENVIRONMENT=Production - - ASPNETCORE_HTTP_PORTS=80 + - ASPNETCORE_URLS=http://+:80 - EventBus:EventBusHostName=rabbitmq - Services:Auth=http://hwproj.authservice.api - Services:Courses=http://hwproj.coursesservice.api