diff --git a/Directory.Build.props b/Directory.Build.props
index 208b791ca..134b7ea71 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,6 +1,6 @@
- preview
+ 8
diff --git a/HwProj.APIGateway/HwProj.APIGateway.API/Controllers/CoursesController.cs b/HwProj.APIGateway/HwProj.APIGateway.API/Controllers/CoursesController.cs
index 17725e28a..10ded91fa 100644
--- a/HwProj.APIGateway/HwProj.APIGateway.API/Controllers/CoursesController.cs
+++ b/HwProj.APIGateway/HwProj.APIGateway.API/Controllers/CoursesController.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Net;
using System.Threading.Tasks;
+using HwProj.APIGateway.API.Filters;
using HwProj.APIGateway.API.Models;
using HwProj.AuthService.Client;
using HwProj.CoursesService.Client;
@@ -34,6 +35,7 @@ public async Task GetAllCourses()
return result;
}
+ [CourseDataFilter]
[HttpGet("{courseId}")]
[ProducesResponseType(typeof(CourseViewModel), (int)HttpStatusCode.OK)]
public async Task GetCourseData(long courseId)
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Filters/CourseDataFilterAttribute.cs b/HwProj.APIGateway/HwProj.APIGateway.API/Filters/CourseDataFilterAttribute.cs
similarity index 60%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Filters/CourseDataFilterAttribute.cs
rename to HwProj.APIGateway/HwProj.APIGateway.API/Filters/CourseDataFilterAttribute.cs
index e584f2a61..92a8db78e 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Filters/CourseDataFilterAttribute.cs
+++ b/HwProj.APIGateway/HwProj.APIGateway.API/Filters/CourseDataFilterAttribute.cs
@@ -1,19 +1,20 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HwProj.Models;
+using HwProj.Models.AuthService.DTO;
using HwProj.Models.CoursesService.ViewModels;
-using HwProj.Utils.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
-namespace HwProj.CoursesService.API.Filters
+namespace HwProj.APIGateway.API.Filters
{
public class CourseDataFilterAttribute : ResultFilterAttribute
{
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
- var userId = context.HttpContext.Request.GetUserIdFromHeader();
+ var userId = context.HttpContext.User.FindFirst("_id").Value;
if (userId == null)
{
@@ -22,21 +23,18 @@ public override async Task OnResultExecutionAsync(ResultExecutingContext context
else
{
var result = context.Result as ObjectResult;
- if (result?.Value is CourseDTO courseDto && !courseDto.MentorIds.Contains(userId))
+ if (result?.Value is CourseViewModel courseViewModel &&
+ courseViewModel.Mentors.All(mentor => mentor.UserId != userId))
{
var currentDate = DateTimeUtils.GetMoscowNow();
- foreach (var homework in courseDto.Homeworks)
+ foreach (var homework in courseViewModel.Homeworks)
{
homework.Tasks =
new List(homework.Tasks.Where(t =>
currentDate >= t.PublicationDate));
}
- courseDto.CourseMates = courseDto.CourseMates
- .Where(t => t.IsAccepted || t.StudentId == userId)
- .ToArray();
-
- courseDto.Groups = courseDto.Groups.Where(g => g.StudentsIds.Contains(userId)).ToArray();
+ courseViewModel.NewStudents = Array.Empty();
}
}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Events/AdminRegisterEvent.cs b/HwProj.AuthService/HwProj.AuthService.API/Events/AdminRegisterEvent.cs
deleted file mode 100644
index 09fc75942..000000000
--- a/HwProj.AuthService/HwProj.AuthService.API/Events/AdminRegisterEvent.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace HwProj.AuthService.API.Events
-{
- public class AdminRegisterEvent : RegisterEvent
- {
- public AdminRegisterEvent(string userId, string email, string name, string surname = "", string middleName = "")
- : base(userId, email, name, surname, middleName)
- {
-
- }
- }
-}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Events/StudentRegisterEvent.cs b/HwProj.AuthService/HwProj.AuthService.API/Events/StudentRegisterEvent.cs
deleted file mode 100644
index 5c894d2b8..000000000
--- a/HwProj.AuthService/HwProj.AuthService.API/Events/StudentRegisterEvent.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace HwProj.AuthService.API.Events
-{
- public class StudentRegisterEvent : RegisterEvent
- {
- public StudentRegisterEvent(string userId, string email, string name, string surname = "", string middleName = "")
- : base(userId, email, name, surname, middleName)
- {
-
- }
- }
-}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs b/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs
index f3bcd0143..dd83433e4 100644
--- a/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs
+++ b/HwProj.AuthService/HwProj.AuthService.API/RoleInitializer.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Identity;
using System.Threading.Tasks;
-using HwProj.AuthService.API.Events;
+using HwProj.Models.Events.AuthEvents;
using HwProj.EventBus.Client.Interfaces;
using HwProj.Models.Roles;
using HwProj.Models.AuthService.ViewModels;
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs b/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs
index f65b5d28c..84ada40a1 100644
--- a/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs
+++ b/HwProj.AuthService/HwProj.AuthService.API/Services/AccountService.cs
@@ -5,7 +5,7 @@
using AutoMapper;
using HwProj.AuthService.API.Extensions;
using HwProj.Models.Roles;
-using HwProj.AuthService.API.Events;
+using HwProj.Models.Events.AuthEvents;
using HwProj.EventBus.Client.Interfaces;
using HwProj.Models.AuthService.DTO;
using HwProj.Models.AuthService.ViewModels;
diff --git a/HwProj.Common/HwProj.Events/HwProj.Events.csproj b/HwProj.Common/HwProj.Events/HwProj.Events.csproj
new file mode 100644
index 000000000..3ae664db1
--- /dev/null
+++ b/HwProj.Common/HwProj.Events/HwProj.Events.csproj
@@ -0,0 +1,13 @@
+
+
+
+ netcoreapp2.2
+ HwProj.Events2
+
+
+
+
+
+
+
+
diff --git a/HwProj.Common/HwProj.HttpUtils/RequestHeaderBuilder.cs b/HwProj.Common/HwProj.HttpUtils/RequestHeaderBuilder.cs
index 5ac4c68e2..cd1e3a995 100644
--- a/HwProj.Common/HwProj.HttpUtils/RequestHeaderBuilder.cs
+++ b/HwProj.Common/HwProj.HttpUtils/RequestHeaderBuilder.cs
@@ -7,7 +7,7 @@ public static class RequestHeaderBuilder
{
public static void TryAddUserId(this HttpRequestMessage request, IHttpContextAccessor httpContextAccessor)
{
- var userId = httpContextAccessor.HttpContext.User.FindFirst("_id");
+ var userId = httpContextAccessor.HttpContext?.User.FindFirst("_id");
if (userId != null) request.Headers.Add("UserId", userId.Value);
}
}
diff --git a/HwProj.Common/HwProj.Models/CoursesService/ViewModels/HomeworkTaskViewModels.cs b/HwProj.Common/HwProj.Models/CoursesService/ViewModels/HomeworkTaskViewModels.cs
index 3535f5b10..d4508c4f2 100644
--- a/HwProj.Common/HwProj.Models/CoursesService/ViewModels/HomeworkTaskViewModels.cs
+++ b/HwProj.Common/HwProj.Models/CoursesService/ViewModels/HomeworkTaskViewModels.cs
@@ -29,6 +29,18 @@ public class HomeworkTaskViewModel
public bool IsDeferred { get; set; }
}
+
+ public class HomeworkTaskDTO
+ {
+ public long Id { get; set; }
+
+ public string Title { get; set; }
+
+ public DateTime PublicationDate { get; set; }
+
+ public DateTime? DeadlineDate { get; set; }
+ }
+
public class CreateTaskViewModel
{
[Required]
diff --git a/HwProj.Common/HwProj.Models/Events/AuthEvents/AdminRegisterEvent.cs b/HwProj.Common/HwProj.Models/Events/AuthEvents/AdminRegisterEvent.cs
new file mode 100644
index 000000000..e13ee52f8
--- /dev/null
+++ b/HwProj.Common/HwProj.Models/Events/AuthEvents/AdminRegisterEvent.cs
@@ -0,0 +1,15 @@
+using HwProj.EventBus.Client;
+
+namespace HwProj.Models.Events.AuthEvents
+{
+ public class AdminRegisterEvent : RegisterEvent
+ {
+ public AdminRegisterEvent(string userId, string email, string name, string surname = "", string middleName = "")
+ : base(userId, email, name, surname, middleName)
+ {
+ }
+
+ public override string EventName => "AdminRegisterEvent";
+ public override EventCategory Category => EventCategory.Users;
+ }
+}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Events/InviteLecturerEvent.cs b/HwProj.Common/HwProj.Models/Events/AuthEvents/InviteLecturerEvent.cs
similarity index 50%
rename from HwProj.AuthService/HwProj.AuthService.API/Events/InviteLecturerEvent.cs
rename to HwProj.Common/HwProj.Models/Events/AuthEvents/InviteLecturerEvent.cs
index 345d6cc40..dcc4a4b0a 100644
--- a/HwProj.AuthService/HwProj.AuthService.API/Events/InviteLecturerEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/AuthEvents/InviteLecturerEvent.cs
@@ -1,10 +1,12 @@
using HwProj.EventBus.Client;
-namespace HwProj.AuthService.API.Events
+namespace HwProj.Models.Events.AuthEvents
{
public class InviteLecturerEvent : Event
{
public string UserId { get; set; }
public string UserEmail { get; set; }
+ public override string EventName => "InviteLecturerEvent";
+ public override EventCategory Category => EventCategory.Users;
}
}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Events/PasswordRecoveryEvent.cs b/HwProj.Common/HwProj.Models/Events/AuthEvents/PasswordRecoveryEvent.cs
similarity index 62%
rename from HwProj.AuthService/HwProj.AuthService.API/Events/PasswordRecoveryEvent.cs
rename to HwProj.Common/HwProj.Models/Events/AuthEvents/PasswordRecoveryEvent.cs
index c751d6521..d394c7616 100644
--- a/HwProj.AuthService/HwProj.AuthService.API/Events/PasswordRecoveryEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/AuthEvents/PasswordRecoveryEvent.cs
@@ -1,6 +1,6 @@
using HwProj.EventBus.Client;
-namespace HwProj.AuthService.API.Events
+namespace HwProj.Models.Events.AuthEvents
{
public class PasswordRecoveryEvent : Event
{
@@ -9,5 +9,7 @@ public class PasswordRecoveryEvent : Event
public string Surname { get; set; }
public string Email { get; set; }
public string Token { get; set; }
+ public override string EventName => "PasswordRecoveryEvent";
+ public override EventCategory Category => EventCategory.Users;
}
}
diff --git a/HwProj.AuthService/HwProj.AuthService.API/Events/RegisterEvent.cs b/HwProj.Common/HwProj.Models/Events/AuthEvents/RegisterEvent.cs
similarity index 93%
rename from HwProj.AuthService/HwProj.AuthService.API/Events/RegisterEvent.cs
rename to HwProj.Common/HwProj.Models/Events/AuthEvents/RegisterEvent.cs
index c2625e5ba..9aba0fac7 100644
--- a/HwProj.AuthService/HwProj.AuthService.API/Events/RegisterEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/AuthEvents/RegisterEvent.cs
@@ -1,6 +1,6 @@
using HwProj.EventBus.Client;
-namespace HwProj.AuthService.API.Events
+namespace HwProj.Models.Events.AuthEvents
{
public abstract class RegisterEvent : Event
{
diff --git a/HwProj.Common/HwProj.Models/Events/AuthEvents/StudentRegisterEvent.cs b/HwProj.Common/HwProj.Models/Events/AuthEvents/StudentRegisterEvent.cs
new file mode 100644
index 000000000..acf4a6c0b
--- /dev/null
+++ b/HwProj.Common/HwProj.Models/Events/AuthEvents/StudentRegisterEvent.cs
@@ -0,0 +1,16 @@
+using HwProj.EventBus.Client;
+
+namespace HwProj.Models.Events.AuthEvents
+{
+ public class StudentRegisterEvent : RegisterEvent
+ {
+ public StudentRegisterEvent(string userId, string email, string name, string surname = "",
+ string middleName = "")
+ : base(userId, email, name, surname, middleName)
+ {
+ }
+
+ public override string EventName => "StudentRegisterEvent";
+ public override EventCategory Category => EventCategory.Users;
+ }
+}
diff --git a/HwProj.Common/HwProj.Models/Events/CourseEvents/AddOrUpdateEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/AddOrUpdateEvent.cs
new file mode 100644
index 000000000..71dc62940
--- /dev/null
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/AddOrUpdateEvent.cs
@@ -0,0 +1,19 @@
+using HwProj.EventBus.Client;
+using HwProj.Models.CoursesService.ViewModels;
+
+namespace HwProj.Models.Events.CourseEvents
+{
+ public class AddOrUpdateTaskEvent : Event
+ {
+ public bool IsUpdate { get; set; }
+ public long TaskId { get; set; }
+ public override string EventName => "UpdateTaskEvent";
+ public override EventCategory Category => EventCategory.Tasks;
+
+ public AddOrUpdateTaskEvent(long taskId, bool isUpdate)
+ {
+ TaskId = taskId;
+ IsUpdate = isUpdate;
+ }
+ }
+}
\ No newline at end of file
diff --git a/HwProj.Common/HwProj.Models/Events/CourseEvents/DeleteTaskEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/DeleteTaskEvent.cs
new file mode 100644
index 000000000..102cc4353
--- /dev/null
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/DeleteTaskEvent.cs
@@ -0,0 +1,16 @@
+using HwProj.EventBus.Client;
+
+namespace HwProj.Models.Events.CourseEvents
+{
+ public class DeleteTaskEvent : Event
+ {
+ public long TaskId { get; set; }
+ public override string EventName => "DeleteTaskEvent";
+ public override EventCategory Category => EventCategory.Tasks;
+
+ public DeleteTaskEvent(long taskId)
+ {
+ TaskId = taskId;
+ }
+ }
+}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerAcceptToCourseEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerAcceptToCourseEvent.cs
similarity index 60%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerAcceptToCourseEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerAcceptToCourseEvent.cs
index 163af8672..6165affa6 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerAcceptToCourseEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerAcceptToCourseEvent.cs
@@ -1,6 +1,6 @@
using HwProj.EventBus.Client;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class LecturerAcceptToCourseEvent : Event
{
@@ -8,5 +8,8 @@ public class LecturerAcceptToCourseEvent : Event
public string CourseName { get; set; }
public string MentorIds { get; set; }
public string StudentId { get; set; }
+
+ public override string EventName => "AcceptToCourseEvent";
+ public override EventCategory Category => EventCategory.Courses;
}
}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerInvitedToCourseEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerInvitedToCourseEvent.cs
similarity index 59%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerInvitedToCourseEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerInvitedToCourseEvent.cs
index 31be36694..2908ef306 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerInvitedToCourseEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerInvitedToCourseEvent.cs
@@ -1,6 +1,6 @@
using HwProj.EventBus.Client;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class LecturerInvitedToCourseEvent : Event
{
@@ -8,5 +8,8 @@ public class LecturerInvitedToCourseEvent : Event
public string CourseName { get; set; }
public string MentorId { get; set; }
public string MentorEmail { get; set; }
+
+ public override string EventName => "LecturerInvitedToCourseEvent";
+ public override EventCategory Category => EventCategory.Courses;
}
}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerRejectToCourseEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerRejectToCourseEvent.cs
similarity index 56%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerRejectToCourseEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerRejectToCourseEvent.cs
index 9386a6cb1..8db607e4f 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/LecturerRejectToCourseEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/LecturerRejectToCourseEvent.cs
@@ -1,12 +1,14 @@
using HwProj.EventBus.Client;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class LecturerRejectToCourseEvent : Event
{
public long CourseId { get; set; }
public string CourseName { get; set; }
- public string MentorIds { get; set; }
public string StudentId { get; set; }
+
+ public override string EventName => "RejectToCourseEvent";
+ public override EventCategory Category => EventCategory.Courses;
}
}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewCourseMateEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/NewCourseMateEvent.cs
similarity index 62%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/NewCourseMateEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/NewCourseMateEvent.cs
index 747917731..b33b6a135 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewCourseMateEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/NewCourseMateEvent.cs
@@ -1,6 +1,6 @@
using HwProj.EventBus.Client;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class NewCourseMateEvent : Event
{
@@ -9,5 +9,8 @@ public class NewCourseMateEvent : Event
public string MentorIds { get; set; }
public string StudentId { get; set; }
public bool IsAccepted { get; set; }
+
+ public override string EventName => "NewCourseMateEvent";
+ public override EventCategory Category => EventCategory.Courses;
}
-}
\ No newline at end of file
+}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/NewHomeworkEvent.cs
similarity index 67%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/NewHomeworkEvent.cs
index b78429c18..f2e80f155 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/NewHomeworkEvent.cs
@@ -1,13 +1,16 @@
using HwProj.EventBus.Client;
using HwProj.Models.CoursesService.ViewModels;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class NewHomeworkEvent : Event
{
public string Homework { get; set; }
public CourseDTO Course { get; set; }
+ public override string EventName => "NewHomeworkEvent";
+ public override EventCategory Category => EventCategory.Homeworks;
+
public NewHomeworkEvent(string homework, CourseDTO course)
{
Homework = homework;
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateHomeworkEvent.cs b/HwProj.Common/HwProj.Models/Events/CourseEvents/UpdateHomeworkEvent.cs
similarity index 68%
rename from HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateHomeworkEvent.cs
rename to HwProj.Common/HwProj.Models/Events/CourseEvents/UpdateHomeworkEvent.cs
index 9045f256d..e867a5e27 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateHomeworkEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/CourseEvents/UpdateHomeworkEvent.cs
@@ -1,13 +1,16 @@
using HwProj.EventBus.Client;
using HwProj.Models.CoursesService.ViewModels;
-namespace HwProj.CoursesService.API.Events
+namespace HwProj.Models.Events.CourseEvents
{
public class UpdateHomeworkEvent : Event
{
public HomeworkViewModel Homework { get; set; }
public CourseDTO Course { get; set; }
+ public override string EventName => "UpdateHomeworkEvent";
+ public override EventCategory Category => EventCategory.Homeworks;
+
public UpdateHomeworkEvent(HomeworkViewModel homework, CourseDTO course)
{
Homework = homework;
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs b/HwProj.Common/HwProj.Models/Events/SolutionEvents/RateEvent.cs
similarity index 71%
rename from HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs
rename to HwProj.Common/HwProj.Models/Events/SolutionEvents/RateEvent.cs
index 9a1d88091..ce041d443 100644
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/RateEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/SolutionEvents/RateEvent.cs
@@ -2,13 +2,16 @@
using HwProj.Models.CoursesService.ViewModels;
using HwProj.Models.SolutionsService;
-namespace HwProj.SolutionsService.API.Events
+namespace HwProj.Models.Events.SolutionEvents
{
public class RateEvent : Event
{
public HomeworkTaskViewModel Task { get; set; }
public SolutionViewModel Solution { get; set; }
+ public override string EventName => "RateEvent";
+ public override EventCategory Category => EventCategory.Solutions;
+
public RateEvent(HomeworkTaskViewModel task, SolutionViewModel solution)
{
Task = task;
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/StudentPassTaskEvent.cs b/HwProj.Common/HwProj.Models/Events/SolutionEvents/StudentPassTaskEvent.cs
similarity index 66%
rename from HwProj.SolutionsService/HwProj.SolutionsService.API/Events/StudentPassTaskEvent.cs
rename to HwProj.Common/HwProj.Models/Events/SolutionEvents/StudentPassTaskEvent.cs
index e9798b28d..438f1195a 100644
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Events/StudentPassTaskEvent.cs
+++ b/HwProj.Common/HwProj.Models/Events/SolutionEvents/StudentPassTaskEvent.cs
@@ -3,7 +3,7 @@
using HwProj.Models.CoursesService.ViewModels;
using HwProj.Models.SolutionsService;
-namespace HwProj.SolutionsService.API.Events
+namespace HwProj.Models.Events.SolutionEvents
{
public class StudentPassTaskEvent : Event
{
@@ -12,11 +12,15 @@ public class StudentPassTaskEvent : Event
public AccountDataDto Student { get; set; }
public HomeworkTaskViewModel Task { get; set; }
- public StudentPassTaskEvent(CourseDTO course, SolutionViewModel solution, AccountDataDto student, HomeworkTaskViewModel task)
+ public override string EventName => "StudentPassTaskEvent";
+ public override EventCategory Category => EventCategory.Solutions;
+
+ public StudentPassTaskEvent(CourseDTO course, SolutionViewModel solution, AccountDataDto student,
+ HomeworkTaskViewModel task)
{
Course = course;
Solution = solution;
- Student= student;
+ Student = student;
Task = task;
}
}
diff --git a/HwProj.Common/HwProj.Models/HwProj.Models.csproj b/HwProj.Common/HwProj.Models/HwProj.Models.csproj
index 0ec3918d8..ecab40b8c 100644
--- a/HwProj.Common/HwProj.Models/HwProj.Models.csproj
+++ b/HwProj.Common/HwProj.Models/HwProj.Models.csproj
@@ -10,15 +10,17 @@
-
+
+
+
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/ApplicationProfile.cs b/HwProj.CoursesService/HwProj.CoursesService.API/ApplicationProfile.cs
index ab3954c03..55247cb2c 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/ApplicationProfile.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/ApplicationProfile.cs
@@ -28,6 +28,7 @@ public ApplicationProfile()
CreateMap()
.ForMember("IsDeferred", cm => cm.MapFrom(g => DateTimeUtils.GetMoscowNow() < g.PublicationDate));
CreateMap().ReverseMap();
+ CreateMap();
}
}
}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/CoursesController.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/CoursesController.cs
index d3c6095f1..5d25c888f 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/CoursesController.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/Controllers/CoursesController.cs
@@ -43,8 +43,7 @@ public async Task GetAll()
var courses = _mapper.Map(coursesFromDb).ToArray();
return courses;
}
-
- [CourseDataFilter]
+
[HttpGet("{courseId}")]
public async Task Get(long courseId)
{
@@ -53,8 +52,7 @@ public async Task Get(long courseId)
return Ok(course);
}
-
- [CourseDataFilter]
+
[HttpGet("getByTask/{taskId}")]
public async Task GetByTask(long taskId)
{
@@ -122,8 +120,7 @@ public async Task RejectStudent(long courseId, [FromQuery] string
? Ok() as IActionResult
: NotFound();
}
-
- [CourseDataFilter]
+
[HttpGet("userCourses")]
public async Task GetUserCourses(string role)
{
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkTaskEvent.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkTaskEvent.cs
deleted file mode 100644
index 3a5ed857a..000000000
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/NewHomeworkTaskEvent.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using HwProj.EventBus.Client;
-using HwProj.Models.CoursesService.ViewModels;
-
-namespace HwProj.CoursesService.API.Events
-{
- public class NewHomeworkTaskEvent : Event
- {
- public NewHomeworkTaskEvent(string taskTitle, long taskId, DateTime? deadline, CourseDTO course)
- {
- TaskTitle = taskTitle;
- TaskId = taskId;
- Deadline = deadline;
- Course = course;
- }
-
- public string TaskTitle { get; set; }
- public long TaskId { get; set; }
- public DateTime? Deadline { get; set; }
- public CourseDTO Course { get; set; }
- }
-}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateSolutionMaxRatingEvent.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateSolutionMaxRatingEvent.cs
deleted file mode 100644
index 59f77ce4c..000000000
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateSolutionMaxRatingEvent.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using HwProj.EventBus.Client;
-
-namespace HwProj.CoursesService.API.Events
-{
- public class UpdateSolutionMaxRatingEvent : Event
- {
- public long TaskId { get; set; }
- public long SolutionId { get; set; }
- public int MaxRating { get; set; }
-
- public UpdateSolutionMaxRatingEvent(long taskId, long solutionId, int rating)
- {
- TaskId = taskId;
- MaxRating = rating;
- SolutionId = solutionId;
- }
- }
-}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateTaskMaxRatingEvent.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateTaskMaxRatingEvent.cs
deleted file mode 100644
index 4f20de847..000000000
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Events/UpdateTaskMaxRatingEvent.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using HwProj.EventBus.Client;
-using HwProj.Models.CoursesService.ViewModels;
-
-namespace HwProj.CoursesService.API.Events
-{
- public class UpdateTaskMaxRatingEvent : Event
- {
- public CourseDTO Course { get; set; }
- public HomeworkTaskViewModel Task { get; set; }
- public int MaxRating { get; set; }
-
- public UpdateTaskMaxRatingEvent(CourseDTO course, HomeworkTaskViewModel task, int rating)
- {
- Course = course;
- Task = task;
- MaxRating = rating;
- }
- }
-}
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Services/CoursesService.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Services/CoursesService.cs
index e7034650b..dd969a283 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Services/CoursesService.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/Services/CoursesService.cs
@@ -3,7 +3,6 @@
using System.Threading.Tasks;
using AutoMapper;
using HwProj.AuthService.Client;
-using HwProj.CoursesService.API.Events;
using HwProj.CoursesService.API.Models;
using HwProj.CoursesService.API.Repositories;
using HwProj.CoursesService.API.Repositories.Groups;
@@ -12,6 +11,7 @@
using HwProj.Models.CoursesService.ViewModels;
using HwProj.Models.Roles;
using Microsoft.EntityFrameworkCore;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.CoursesService.API.Services
{
@@ -189,7 +189,6 @@ public async Task RejectCourseMateAsync(long courseId, string studentId)
{
CourseId = courseId,
CourseName = course.Name,
- MentorIds = course.MentorIds,
StudentId = studentId
});
return true;
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs
index 2558e64fc..242b47744 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/Services/HomeworksService.cs
@@ -3,9 +3,9 @@
using HwProj.CoursesService.API.Models;
using HwProj.CoursesService.API.Repositories;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.CoursesService.API.Events;
using HwProj.Models;
using HwProj.Models.CoursesService.ViewModels;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.CoursesService.API.Services
{
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Services/TasksService.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Services/TasksService.cs
index e99ea1203..20071deaa 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Services/TasksService.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/Services/TasksService.cs
@@ -1,11 +1,10 @@
using System.Threading.Tasks;
using AutoMapper;
-using HwProj.CoursesService.API.Events;
using HwProj.CoursesService.API.Models;
using HwProj.CoursesService.API.Repositories;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.CoursesService.ViewModels;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.CoursesService.API.Services
{
@@ -19,7 +18,8 @@ public class TasksService : ITasksService
private readonly ICoursesService _coursesService;
public TasksService(ITasksRepository tasksRepository, IEventBus eventBus, IMapper mapper,
- ICoursesRepository coursesRepository, IHomeworksRepository homeworksRepository, ICoursesService coursesService)
+ ICoursesRepository coursesRepository, IHomeworksRepository homeworksRepository,
+ ICoursesService coursesService)
{
_tasksRepository = tasksRepository;
_homeworksRepository = homeworksRepository;
@@ -41,28 +41,30 @@ public async Task AddTaskAsync(long homeworkId, HomeworkTask task)
var homework = await _homeworksRepository.GetAsync(task.HomeworkId);
var course = await _coursesRepository.GetWithCourseMatesAsync(homework.CourseId);
var courseModel = _mapper.Map(course);
-
+ var taskModel = _mapper.Map(task);
var taskId = await _tasksRepository.AddAsync(task);
- if (task.PublicationDate <= DateTimeUtils.GetMoscowNow())
- _eventBus.Publish(new NewHomeworkTaskEvent(task.Title, taskId, task.DeadlineDate, courseModel));
+ _eventBus.Publish(new AddOrUpdateTaskEvent(taskId, false));
return taskId;
}
public async Task DeleteTaskAsync(long taskId)
{
+ _eventBus.Publish(new DeleteTaskEvent(taskId));
await _tasksRepository.DeleteAsync(taskId);
}
public async Task UpdateTaskAsync(long taskId, HomeworkTask update)
{
var task = await _tasksRepository.GetAsync(taskId);
- var taskModel = _mapper.Map(task);
var homework = await _homeworksRepository.GetAsync(task.HomeworkId);
var course = await _coursesRepository.GetWithCourseMatesAsync(homework.CourseId);
var courseModel = _mapper.Map(course);
- _eventBus.Publish(new UpdateTaskMaxRatingEvent(courseModel, taskModel, update.MaxRating));
+ var previousTaskModel = _mapper.Map(task);
+ var newTaskModel = _mapper.Map(update);
+
+ _eventBus.Publish(new AddOrUpdateTaskEvent(taskId, true));
await _tasksRepository.UpdateAsync(taskId, t => new HomeworkTask()
{
diff --git a/HwProj.CoursesService/HwProj.CoursesService.API/Startup.cs b/HwProj.CoursesService/HwProj.CoursesService.API/Startup.cs
index 15f05f2cd..a73057041 100644
--- a/HwProj.CoursesService/HwProj.CoursesService.API/Startup.cs
+++ b/HwProj.CoursesService/HwProj.CoursesService.API/Startup.cs
@@ -1,4 +1,6 @@
-using HwProj.AuthService.Client;
+using System;
+using System.Threading.Channels;
+using HwProj.AuthService.Client;
using HwProj.CoursesService.API.Filters;
using HwProj.CoursesService.API.Models;
using HwProj.CoursesService.API.Repositories;
@@ -25,6 +27,7 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
var connectionString = ConnectionString.GetConnectionString(Configuration);
+
services.AddDbContext(options => options.UseSqlServer(connectionString));
services.AddScoped();
services.AddScoped();
diff --git a/HwProj.EventBus/HwProj.EventBus.Client/Event.cs b/HwProj.EventBus/HwProj.EventBus.Client/Event.cs
index 8a62cbd96..0da3278a4 100644
--- a/HwProj.EventBus/HwProj.EventBus.Client/Event.cs
+++ b/HwProj.EventBus/HwProj.EventBus.Client/Event.cs
@@ -3,21 +3,29 @@
namespace HwProj.EventBus.Client
{
- public class Event
+ public enum EventCategory
{
- [JsonProperty]
- public Guid Id { get; set; }
+ Users,
+ Courses,
+ Homeworks,
+ Tasks,
+ Solutions
+ }
- [JsonProperty]
- public DateTime CreationData { get; set; }
+ public abstract class Event
+ {
+ [JsonProperty] public Guid Id { get; set; }
+ [JsonProperty] public DateTime CreationData { get; set; }
+ public abstract string EventName { get; }
+ public abstract EventCategory Category { get; }
- public Event()
+ protected Event()
{
Id = Guid.NewGuid();
CreationData = DateTime.UtcNow;
}
- public Event(Guid id, DateTime data)
+ protected Event(Guid id, DateTime data)
{
Id = id;
CreationData = data;
diff --git a/HwProj.EventBus/HwProj.EventBus.Client/HwProj.EventBus.Client.csproj b/HwProj.EventBus/HwProj.EventBus.Client/HwProj.EventBus.Client.csproj
index 7932fcc9d..01fb17fd8 100644
--- a/HwProj.EventBus/HwProj.EventBus.Client/HwProj.EventBus.Client.csproj
+++ b/HwProj.EventBus/HwProj.EventBus.Client/HwProj.EventBus.Client.csproj
@@ -18,9 +18,6 @@
-
-
-
-
+
diff --git a/HwProj.EventBus/HwProj.EventBus.Tests/TestEvent.cs b/HwProj.EventBus/HwProj.EventBus.Tests/TestEvent.cs
index 62acb15b3..7420174e7 100644
--- a/HwProj.EventBus/HwProj.EventBus.Tests/TestEvent.cs
+++ b/HwProj.EventBus/HwProj.EventBus.Tests/TestEvent.cs
@@ -8,10 +8,13 @@ public class TestEvent : Event
public int NewPrice { get; set; }
- public TestEvent(int newPrice, int oldPrice)
+ public TestEvent(int newPrice, int oldPrice)
{
OldPrice = oldPrice;
NewPrice = newPrice;
}
+
+ public override string EventName => "TestEvent";
+ public override EventCategory Category => EventCategory.Courses;
}
}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Controllers/NotificationSettingsController.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Controllers/NotificationSettingsController.cs
index e916bb5fa..b2e93f502 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Controllers/NotificationSettingsController.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Controllers/NotificationSettingsController.cs
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using HwProj.Models.NotificationsService;
-using HwProj.NotificationsService.API.Models;
using HwProj.NotificationsService.API.Repositories;
using Microsoft.AspNetCore.Mvc;
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/AddOrUpdateTaskEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/AddOrUpdateTaskEventHandler.cs
new file mode 100644
index 000000000..1c404336a
--- /dev/null
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/AddOrUpdateTaskEventHandler.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Diagnostics.Tracing;
+using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper;
+using HwProj.AuthService.Client;
+using HwProj.CoursesService.Client;
+using HwProj.EventBus.Client.Interfaces;
+using HwProj.Models.Events.CourseEvents;
+using HwProj.Models.NotificationsService;
+using HwProj.NotificationsService.API.Jobs;
+using HwProj.NotificationsService.API.Repositories;
+using HwProj.NotificationsService.API.Services;
+using Microsoft.Extensions.Configuration;
+
+namespace HwProj.NotificationsService.API.EventHandlers
+{
+ public class AddOrUpdateTaskEventHandler : EventHandlerBase
+ {
+ private readonly ICoursesServiceClient _coursesServiceClient;
+ private readonly INotificationsRepository _notificationRepository;
+ private readonly IAuthServiceClient _authServiceClient;
+ private readonly IMapper _mapper;
+ private readonly IConfigurationSection _configuration;
+ private readonly IEmailService _emailService;
+ private readonly IScheduleJobsRepository _scheduleJobsRepository;
+
+ public AddOrUpdateTaskEventHandler(
+ ICoursesServiceClient coursesServiceClient,
+ INotificationsRepository notificationRepository,
+ IMapper mapper,
+ IAuthServiceClient authServiceClient,
+ IConfiguration configuration,
+ IEmailService emailService,
+ IScheduleJobsRepository scheduleJobsRepository)
+ {
+ _coursesServiceClient = coursesServiceClient;
+ _notificationRepository = notificationRepository;
+ _mapper = mapper;
+ _authServiceClient = authServiceClient;
+ _emailService = emailService;
+ _configuration = configuration.GetSection("Notification");
+ _scheduleJobsRepository = scheduleJobsRepository;
+ }
+
+ public override async Task HandleAsync(AddOrUpdateTaskEvent @event)
+ {
+ //TODO : ленивость не работает
+ var task = await _coursesServiceClient.GetTask(@event.TaskId);
+
+ if (task.PublicationDate <= DateTime.UtcNow)
+ {
+ await AddNotificationsAsync(@event);
+ }
+ else if (@event.IsUpdate)
+ {
+ await EventHandlerExtensions.UpdateScheduleJobAsync(@event, @event.TaskId,
+ task.PublicationDate, () => AddNotificationsAsync(@event), _scheduleJobsRepository);
+ }
+ else
+ {
+ await EventHandlerExtensions.AddScheduleJobAsync(@event, @event.TaskId,
+ task.PublicationDate, () => AddNotificationsAsync(@event), _scheduleJobsRepository);
+ }
+ }
+
+ public async Task AddNotificationsAsync(AddOrUpdateTaskEvent @event)
+ {
+ var course = await _coursesServiceClient.GetCourseByTask(@event.TaskId);
+ var task = await _coursesServiceClient.GetTask(@event.TaskId);
+ if (course == null) return;
+
+ var studentIds = course.CourseMates.Select(t => t.StudentId).ToArray();
+ var accountsData = await _authServiceClient.GetAccountsData(studentIds);
+
+ var url = _configuration["Url"];
+ var message = task.PublicationDate < DateTime.UtcNow
+ ? $"Задача {task.Title}" +
+ $" из курса {course.Name} обновлена."
+ : $"В курсе {course.Name}" +
+ $" опубликована новая задача {task.Title}." +
+ (task.DeadlineDate is { } deadline ? $"\n\nДедлайн: {deadline:U}" : "");
+
+ foreach (var student in accountsData)
+ {
+ var notification = new Notification
+ {
+ Sender = "CourseService",
+ Body = message,
+ Category = CategoryState.Homeworks,
+ Date = DateTime.UtcNow,
+ Owner = student.UserId
+ };
+
+ var addNotificationTask = _notificationRepository.AddAsync(notification);
+ var sendEmailTask = _emailService.SendEmailAsync(notification, student.Email, "Новая задача");
+
+ await Task.WhenAll(addNotificationTask, sendEmailTask);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/DeleteTaskEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/DeleteTaskEventHandler.cs
new file mode 100644
index 000000000..db8ffa80a
--- /dev/null
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/DeleteTaskEventHandler.cs
@@ -0,0 +1,24 @@
+using System.Threading.Tasks;
+using HwProj.EventBus.Client.Interfaces;
+using HwProj.Models.Events.CourseEvents;
+using HwProj.NotificationsService.API.Jobs;
+using HwProj.NotificationsService.API.Repositories;
+
+namespace HwProj.NotificationsService.API.EventHandlers
+{
+ public class DeleteTaskEventHandler : EventHandlerBase
+ {
+ private readonly IScheduleJobsRepository _scheduleJobsRepository;
+
+ public DeleteTaskEventHandler(IScheduleJobsRepository scheduleJobsRepository)
+ {
+ _scheduleJobsRepository = scheduleJobsRepository;
+ }
+
+ public override async Task HandleAsync(DeleteTaskEvent @event)
+ {
+ await EventHandlerExtensions.DeleteScheduleJobsAsync(@event, @event.TaskId,
+ _scheduleJobsRepository);
+ }
+ }
+}
\ No newline at end of file
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs
index f8ea9fcff..fadfe6144 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/InviteLecturerEventHandler.cs
@@ -1,7 +1,7 @@
+using System;
using System.Threading.Tasks;
-using HwProj.AuthService.API.Events;
+using HwProj.Models.Events.AuthEvents;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
@@ -26,7 +26,7 @@ public override async Task HandleAsync(InviteLecturerEvent @event)
Sender = "AuthService",
Body = "Вас добавили в список лекторов.",
Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
Owner = @event.UserId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs
index 6949e1854..f2e827d26 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerAcceptToCourseEventHandler.cs
@@ -1,12 +1,12 @@
+using System;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
-using HwProj.CoursesService.API.Events;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.NotificationsService.API.EventHandlers
{
@@ -37,7 +37,7 @@ public override async Task HandleAsync(LecturerAcceptToCourseEvent @event)
Body =
$"Вас приняли на курс {@event.CourseName}.",
Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
Owner = @event.StudentId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerInvitedToCourseEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerInvitedToCourseEventHandler.cs
index 22d0bb7a2..0a181fe8e 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerInvitedToCourseEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerInvitedToCourseEventHandler.cs
@@ -1,11 +1,11 @@
+using System;
using System.Threading.Tasks;
-using HwProj.CoursesService.API.Events;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.NotificationsService.API.EventHandlers
{
@@ -33,7 +33,7 @@ public override async Task HandleAsync(LecturerInvitedToCourseEvent @event)
Body =
$"Вас пригласили в качестве преподавателя на курс {@event.CourseName}.",
Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
Owner = @event.MentorId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs
index cd9b28ab9..f7098e474 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/LecturerRejectToCourseEventHandler.cs
@@ -1,12 +1,12 @@
+using System;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
-using HwProj.CoursesService.API.Events;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.NotificationsService.API.EventHandlers
{
@@ -37,7 +37,7 @@ public override async Task HandleAsync(LecturerRejectToCourseEvent @event)
Body =
$"Вас не приняли на курс {@event.CourseName}.",
Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
Owner = @event.StudentId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs
index e9e3b1a55..ddefa9283 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewCourseMateHandler.cs
@@ -1,12 +1,12 @@
+using System;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
-using HwProj.CoursesService.API.Events;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.NotificationsService.API.EventHandlers
{
@@ -44,7 +44,7 @@ public override async Task HandleAsync(NewCourseMateEvent @event)
$"Студент {user.Name} {user.Surname}" +
$" подал заявку на вступление в курс {@event.CourseName}.",
Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = m
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs
index 716374aca..17351de68 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkEventHandler.cs
@@ -1,13 +1,13 @@
+using System;
using System.Linq;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
using HwProj.EventBus.Client.Interfaces;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
-using HwProj.CoursesService.API.Events;
-using HwProj.Models;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
+using HwProj.Models.Events.CourseEvents;
namespace HwProj.NotificationsService.API.EventHandlers
{
@@ -44,9 +44,9 @@ public override async Task HandleAsync(NewHomeworkEvent @event)
$"В курсе {@event.Course.Name}" +
$" опубликована новая домашняя работа {@event.Homework}.",
Category = CategoryState.Homeworks,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
- Owner = student!.UserId
+ Owner = student.UserId
};
var addNotificationTask = _notificationRepository.AddAsync(notification);
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkTaskEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkTaskEventHandler.cs
deleted file mode 100644
index ba832df25..000000000
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/NewHomeworkTaskEventHandler.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Linq;
-using System.Threading.Tasks;
-using HwProj.AuthService.Client;
-using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models.NotificationsService;
-using HwProj.NotificationsService.API.Repositories;
-using HwProj.CoursesService.API.Events;
-using HwProj.Models;
-using HwProj.NotificationsService.API.Services;
-using Microsoft.Extensions.Configuration;
-
-namespace HwProj.NotificationsService.API.EventHandlers
-{
- public class NewHomeworkTaskEventHandler : EventHandlerBase
- {
- private readonly INotificationsRepository _notificationRepository;
- private readonly IAuthServiceClient _authServiceClient;
- private readonly IConfigurationSection _configuration;
- private readonly IEmailService _emailService;
-
- public NewHomeworkTaskEventHandler(
- INotificationsRepository notificationRepository,
- IAuthServiceClient authServiceClient,
- IConfiguration configuration,
- IEmailService emailService)
- {
- _notificationRepository = notificationRepository;
- _authServiceClient = authServiceClient;
- _emailService = emailService;
- _configuration = configuration.GetSection("Notification");
- }
-
- public override async Task HandleAsync(NewHomeworkTaskEvent @event)
- {
- var studentIds = @event.Course.CourseMates.Select(t => t.StudentId).ToArray();
- var accountsData = await _authServiceClient.GetAccountsData(studentIds);
- var url = _configuration["Url"];
-
- foreach (var student in accountsData)
- {
- var notification = new Notification
- {
- Sender = "CourseService",
- Body =
- $"В курсе {@event.Course.Name}" +
- $" опубликована новая задача {@event.TaskTitle}." +
- (@event.Deadline is { } deadline ? $"\n\nДедлайн: {deadline:U}" : ""),
-
- Category = CategoryState.Homeworks,
- Date = DateTimeUtils.GetMoscowNow(),
- Owner = student!.UserId
- };
-
- var addNotificationTask = _notificationRepository.AddAsync(notification);
- var sendEmailTask = _emailService.SendEmailAsync(notification, student.Email, "Новая задача");
-
- await Task.WhenAll(addNotificationTask, sendEmailTask);
- }
- }
- }
-}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/PasswordRecoveryEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/PasswordRecoveryEventHandler.cs
index c77512fb1..b32c5cf93 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/PasswordRecoveryEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/PasswordRecoveryEventHandler.cs
@@ -1,8 +1,8 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using System.Web;
-using HwProj.AuthService.API.Events;
+using HwProj.Models.Events.AuthEvents;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
@@ -36,7 +36,7 @@ public override async Task HandleAsync(PasswordRecoveryEvent @event)
$"Для изменения пароля перейдите по ссылке
Сменить пароль
" +
$"Если вы не запрашивали сброс пароля, проигнорируйте это письмо.",
Category = CategoryState.Profile,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = @event.UserId
};
@@ -45,7 +45,7 @@ public override async Task HandleAsync(PasswordRecoveryEvent @event)
Sender = "AuthService",
Body = $"{@event.Name} {@event.Surname}, был запрошен сброс вашего пароля.",
Category = CategoryState.Profile,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = @event.UserId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs
index 55d83bcf1..638403618 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RateEventHandler.cs
@@ -1,11 +1,11 @@
+using System;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
-using HwProj.SolutionsService.API.Events;
+using HwProj.Models.Events.SolutionEvents;
using Microsoft.Extensions.Configuration;
namespace HwProj.NotificationsService.API.EventHandlers
@@ -44,7 +44,7 @@ public override async Task HandleAsync(RateEvent @event)
$"{@event.Solution.Rating}/{@event.Task.MaxRating}." +
$"{commentBody}",
Category = CategoryState.Homeworks,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = @event.Solution.StudentId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs
index e094fdc05..80bdf138e 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/RegisterEventHandler.cs
@@ -1,7 +1,7 @@
-using System.Threading.Tasks;
-using HwProj.AuthService.API.Events;
+using System;
+using System.Threading.Tasks;
+using HwProj.Models.Events.AuthEvents;
using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
@@ -26,7 +26,7 @@ public override async Task HandleAsync(StudentRegisterEvent @event)
Sender = "AuthService",
Body = $"{@event.Name} {@event.Surname}, Добро Пожаловать в HwProj2.",
Category = CategoryState.Profile,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = @event.UserId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs
index 6af48b207..e995bcb8c 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/StudentPassTaskEventHandler.cs
@@ -5,7 +5,7 @@
using HwProj.NotificationsService.API.Models;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
-using HwProj.SolutionsService.API.Events;
+using HwProj.Models.Events.SolutionEvents;
using Microsoft.Extensions.Configuration;
namespace HwProj.NotificationsService.API.EventHandlers
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs
index d2bbc4de3..2f1496225 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateHomeworkEventHandler.cs
@@ -1,10 +1,10 @@
+using System;
using System.Threading.Tasks;
using HwProj.AuthService.Client;
using HwProj.EventBus.Client.Interfaces;
using HwProj.Models.NotificationsService;
using HwProj.NotificationsService.API.Repositories;
-using HwProj.CoursesService.API.Events;
-using HwProj.Models;
+using HwProj.Models.Events.CourseEvents;
using HwProj.NotificationsService.API.Services;
using Microsoft.Extensions.Configuration;
@@ -40,7 +40,7 @@ public override async Task HandleAsync(UpdateHomeworkEvent @event)
Body =
$"В курсе {@event.Course.Name} домашнее задание {@event.Homework.Title} обновлено.",
Category = CategoryState.Homeworks,
- Date = DateTimeUtils.GetMoscowNow(),
+ Date = DateTime.UtcNow,
HasSeen = false,
Owner = student.StudentId
};
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs
deleted file mode 100644
index 1289a1333..000000000
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/EventHandlers/UpdateTaskMaxRatingEventHandler.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Threading.Tasks;
-using AutoMapper;
-using HwProj.AuthService.Client;
-using HwProj.EventBus.Client.Interfaces;
-using HwProj.Models.NotificationsService;
-using HwProj.NotificationsService.API.Repositories;
-using HwProj.CoursesService.API.Events;
-using HwProj.Models;
-using HwProj.Models.AuthService.DTO;
-using HwProj.NotificationsService.API.Services;
-using Microsoft.Extensions.Configuration;
-
-namespace HwProj.NotificationsService.API.EventHandlers
-{
- public class UpdateTaskMaxRatingEventHandler : EventHandlerBase
- {
- private readonly INotificationsRepository _notificationRepository;
- private readonly IAuthServiceClient _authServiceClient;
- private readonly IMapper _mapper;
- private readonly IConfigurationSection _configuration;
- private readonly IEmailService _emailService;
-
- public UpdateTaskMaxRatingEventHandler(
- INotificationsRepository notificationRepository,
- IMapper mapper,
- IAuthServiceClient authServiceClient,
- IConfiguration configuration,
- IEmailService emailService)
- {
- _notificationRepository = notificationRepository;
- _mapper = mapper;
- _authServiceClient = authServiceClient;
- _emailService = emailService;
- _configuration = configuration.GetSection("Notification");
- }
-
- public override async Task HandleAsync(UpdateTaskMaxRatingEvent @event)
- {
- foreach (var student in @event.Course.CourseMates)
- {
- var studentAccount = await _authServiceClient.GetAccountData(student.StudentId);
- var studentModel = _mapper.Map(studentAccount);
- var notification = new Notification
- {
- Sender = "CourseService",
- Body = $"Задача {@event.Task.Title}" +
- $" из курса {@event.Course.Name} обновлена.",
- Category = CategoryState.Courses,
- Date = DateTimeUtils.GetMoscowNow(),
- HasSeen = false,
- Owner = student.StudentId
- };
-
- var addNotificationTask = _notificationRepository.AddAsync(notification);
- var sendEmailTask = _emailService.SendEmailAsync(notification, studentModel.Email, "Домашняя работа");
-
- await Task.WhenAll(addNotificationTask, sendEmailTask);
- }
- }
- }
-}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj
index 24abc2bd8..7a5b10658 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/HwProj.NotificationsService.API.csproj
@@ -15,6 +15,9 @@
+
+
+
@@ -23,12 +26,10 @@
-
+
-
-
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/EventHandlerExtensions.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/EventHandlerExtensions.cs
new file mode 100644
index 000000000..d17b471ab
--- /dev/null
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/EventHandlerExtensions.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Hangfire;
+using HwProj.EventBus.Client;
+using HwProj.NotificationsService.API.Repositories;
+using Microsoft.Azure.KeyVault.Models;
+
+namespace HwProj.NotificationsService.API.Jobs
+{
+ public static class EventHandlerExtensions where TEvent : Event
+ {
+ public static async Task AddScheduleJobAsync(TEvent @event, long itemId, DateTime publicationDate,
+ Expression> jobFunc, IScheduleJobsRepository jobsRepository)
+ {
+ var jobId = BackgroundJob.Schedule(jobFunc, publicationDate);
+
+ if (jobId == null)
+ throw new InvalidOperationException($"Невозможно создать отложенное событие для {@event.EventName}");
+
+ var scheduleJob = new ScheduleJob(@event, itemId, jobId);
+ await jobsRepository.AddAsync(scheduleJob);
+ BackgroundJob.ContinueJobWith(
+ jobId,
+ () => jobsRepository.DeleteAsync(new[] { scheduleJob }),
+ JobContinuationOptions.OnAnyFinishedState
+ );
+ }
+
+ public static async Task UpdateScheduleJobAsync(TEvent @event, long itemId, DateTime publicationDate,
+ Expression> jobFunc, IScheduleJobsRepository jobsRepository)
+ {
+ var scheduleJob = await jobsRepository.GetAsync(@event.Category, @event.EventName, itemId);
+ if (scheduleJob == null) return;
+
+ BackgroundJob.Reschedule(scheduleJob.JobId, publicationDate);
+ }
+
+ public static async Task DeleteScheduleJobsAsync(TEvent @event, long itemId,
+ IScheduleJobsRepository jobsRepository)
+ {
+ var scheduleJobs = await jobsRepository.FindAllInCategoryAsync(@event.Category, itemId);
+
+ foreach (var scheduleJob in scheduleJobs)
+ {
+ BackgroundJob.Delete(scheduleJob.JobId);
+ }
+ }
+ }
+}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/ScheduleJob.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/ScheduleJob.cs
new file mode 100644
index 000000000..13926fbf3
--- /dev/null
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Jobs/ScheduleJob.cs
@@ -0,0 +1,24 @@
+using HwProj.EventBus.Client;
+
+namespace HwProj.NotificationsService.API.Jobs
+{
+ public class ScheduleJob
+ {
+ public EventCategory Category { get; set; }
+ public string EventName { get; set; }
+ public long ItemId { get; set; }
+ public string JobId { get; set; }
+
+ public ScheduleJob(Event @event, long itemId, string jobId)
+ {
+ Category = @event.Category;
+ EventName = @event.EventName;
+ ItemId = itemId;
+ JobId = jobId;
+ }
+
+ public ScheduleJob()
+ {
+ }
+ }
+}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.Designer.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.Designer.cs
deleted file mode 100644
index 71e04909a..000000000
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.Designer.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-using System;
-using HwProj.NotificationsService.API.Models;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-namespace HwProj.NotificationsService.API.Migrations
-{
- [DbContext(typeof(NotificationsContext))]
- [Migration("20231023000606_NotificationSettings")]
- partial class NotificationSettings
- {
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
- .HasAnnotation("Relational:MaxIdentifierLength", 128)
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- modelBuilder.Entity("HwProj.Models.NotificationsService.Notification", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- b.Property("Body");
-
- b.Property("Category");
-
- b.Property("Date");
-
- b.Property("HasSeen");
-
- b.Property("Owner");
-
- b.Property("Sender");
-
- b.HasKey("Id");
-
- b.ToTable("Notifications");
- });
-
- modelBuilder.Entity("HwProj.NotificationsService.API.Models.NotificationsSetting", b =>
- {
- b.Property("UserId");
-
- b.Property("Category");
-
- b.Property("IsEnabled");
-
- b.HasKey("UserId", "Category");
-
- b.HasIndex("UserId");
-
- b.ToTable("Settings");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.cs
deleted file mode 100644
index 8970dda79..000000000
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/20231023000606_NotificationSettings.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-namespace HwProj.NotificationsService.API.Migrations
-{
- public partial class NotificationSettings : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "Settings",
- columns: table => new
- {
- UserId = table.Column(nullable: false),
- Category = table.Column(nullable: false),
- IsEnabled = table.Column(nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_Settings", x => new { x.UserId, x.Category });
- });
-
- migrationBuilder.CreateIndex(
- name: "IX_Settings_UserId",
- table: "Settings",
- column: "UserId");
- }
- }
-}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/NotificationsContextModelSnapshot.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/NotificationsContextModelSnapshot.cs
deleted file mode 100644
index 2e38006a5..000000000
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Migrations/NotificationsContextModelSnapshot.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-using System;
-using HwProj.NotificationsService.API.Models;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-namespace HwProj.NotificationsService.API.Migrations
-{
- [DbContext(typeof(NotificationsContext))]
- partial class NotificationsContextModelSnapshot : ModelSnapshot
- {
- 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);
-
- modelBuilder.Entity("HwProj.Models.NotificationsService.Notification", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- b.Property("Body");
-
- b.Property("Category");
-
- b.Property("Date");
-
- b.Property("HasSeen");
-
- b.Property("Owner");
-
- b.Property("Sender");
-
- b.HasKey("Id");
-
- b.ToTable("Notifications");
- });
-
- modelBuilder.Entity("HwProj.NotificationsService.API.Models.NotificationsSetting", b =>
- {
- b.Property("UserId");
-
- b.Property("Category");
-
- b.Property("IsEnabled");
-
- b.HasKey("UserId", "Category");
-
- b.HasIndex("UserId");
-
- b.ToTable("Settings");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Models/NotificationsContext.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Models/NotificationsContext.cs
index d5ae11961..bf34110d8 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Models/NotificationsContext.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Models/NotificationsContext.cs
@@ -1,4 +1,5 @@
using HwProj.Models.NotificationsService;
+using HwProj.NotificationsService.API.Jobs;
using Microsoft.EntityFrameworkCore;
namespace HwProj.NotificationsService.API.Models
@@ -7,6 +8,7 @@ public sealed class NotificationsContext : DbContext
{
public DbSet Notifications { get; set; }
public DbSet Settings { get; set; }
+ public DbSet ScheduleJobs { get; set; }
public NotificationsContext(DbContextOptions options)
: base(options)
@@ -17,6 +19,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().HasIndex(n => n.UserId);
modelBuilder.Entity().HasKey(n => new { n.UserId, n.Category });
+ modelBuilder.Entity().HasKey(s => new { s.Category, s.EventName, s.ItemId });
}
}
}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Repositories/ScheduleJobsRepository.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Repositories/ScheduleJobsRepository.cs
new file mode 100644
index 000000000..f1cbe9e43
--- /dev/null
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Repositories/ScheduleJobsRepository.cs
@@ -0,0 +1,71 @@
+using System.Linq;
+using System.Threading.Tasks;
+using HwProj.EventBus.Client;
+using HwProj.NotificationsService.API.Jobs;
+using HwProj.NotificationsService.API.Models;
+using Microsoft.EntityFrameworkCore;
+using Z.EntityFramework.Plus;
+
+namespace HwProj.NotificationsService.API.Repositories
+{
+ public interface IScheduleJobsRepository
+ {
+ public Task AddAsync(ScheduleJob scheduleJob);
+ public Task GetAsync(EventCategory category, string eventName, long itemId);
+ public Task DeleteAsync(ScheduleJob[] jobs);
+ public Task FindAllInCategoryAsync(EventCategory category, long itemId);
+ }
+
+
+ public class ScheduleJobsRepository : IScheduleJobsRepository
+ {
+ private readonly NotificationsContext _context;
+
+ public ScheduleJobsRepository(NotificationsContext context)
+ {
+ _context = context;
+ }
+
+ public async Task AddAsync(ScheduleJob scheduleJob)
+ {
+ await _context.AddAsync(scheduleJob);
+ await _context.SaveChangesAsync();
+ }
+
+ public async Task GetAsync(EventCategory category, string eventName, long itemId)
+ {
+ return await _context.Set().FindAsync(category, eventName, itemId);
+ }
+
+ public async Task DeleteAsync(Event @event, long itemId)
+ {
+ await _context.Set()
+ .Where(scheduleJob =>
+ scheduleJob.Category == @event.Category &&
+ scheduleJob.EventName == @event.EventName &&
+ scheduleJob.ItemId == itemId)
+ .DeleteAsync();
+ }
+
+ public async Task DeleteAsync(ScheduleJob[] jobs)
+ {
+ _context.Set().RemoveRange(jobs);
+ await _context.SaveChangesAsync();
+ }
+
+ public async Task DeleteAllInCategoryByItemIdAsync(Event @event, long itemId)
+ {
+ await _context.Set()
+ .Where(scheduleJob => scheduleJob.Category == @event.Category && scheduleJob.ItemId == itemId)
+ .DeleteAsync();
+ }
+
+ public async Task FindAllInCategoryAsync(EventCategory category, long itemId)
+ {
+ return await _context.Set()
+ .Where(scheduleJob => scheduleJob.Category == category && scheduleJob.ItemId == itemId)
+ .AsNoTracking()
+ .ToArrayAsync();
+ }
+ }
+}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs b/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs
index c6abaddfe..5db040209 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/Startup.cs
@@ -1,19 +1,20 @@
-using HwProj.AuthService.API.Events;
+using Hangfire;
+using HwProj.Models.Events.AuthEvents;
using HwProj.AuthService.Client;
+using HwProj.CoursesService.Client;
using HwProj.EventBus.Client.Interfaces;
+using HwProj.Models.Events.CourseEvents;
using HwProj.NotificationsService.API.EventHandlers;
using HwProj.NotificationsService.API.Models;
using HwProj.NotificationsService.API.Repositories;
using HwProj.NotificationsService.API.Services;
+using HwProj.Models.Events.SolutionEvents;
using HwProj.Utils.Configuration;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using HwProj.CoursesService.API.Events;
-using HwProj.SolutionsService.API.Events;
-using UpdateTaskMaxRatingEvent = HwProj.CoursesService.API.Events.UpdateTaskMaxRatingEvent;
namespace HwProj.NotificationsService.API
{
@@ -29,20 +30,31 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
var connectionString = ConnectionString.GetConnectionString(Configuration);
+
+ // Add Hangfire services.
+ services.AddHangfire(configuration => configuration
+ .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
+ .UseSimpleAssemblyNameTypeSerializer()
+ .UseRecommendedSerializerSettings()
+ .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection")));
+
+ // Add the processing server as IHostedService
+ services.AddHangfireServer();
services.AddDbContext(options => options.UseSqlServer(connectionString));
services.AddScoped();
services.AddScoped();
services.AddEventBus(Configuration);
+ services.AddTransient();
services.AddTransient, RegisterEventHandler>();
services.AddTransient, RateEventHandler>();
services.AddTransient, StudentPassTaskEventHandler>();
services.AddTransient, UpdateHomeworkEventHandler>();
- services.AddTransient, UpdateTaskMaxRatingEventHandler>();
+ services.AddTransient, AddOrUpdateTaskEventHandler>();
+ services.AddTransient, DeleteTaskEventHandler>();
services.AddTransient, LecturerAcceptToCourseEventHandler>();
services.AddTransient, LecturerRejectToCourseEventHandler>();
services.AddTransient, LecturerInvitedToCourseEventHandler>();
services.AddTransient, NewHomeworkEventHandler>();
- services.AddTransient, NewHomeworkTaskEventHandler>();
services.AddTransient, InviteLecturerEventHandler>();
services.AddTransient, NewCourseMateHandler>();
services.AddTransient, PasswordRecoveryEventHandler>();
@@ -50,7 +62,8 @@ public void ConfigureServices(IServiceCollection services)
services.AddHttpClient();
services.AddAuthServiceClient();
-
+ services.AddCoursesServiceClient();
+
services.ConfigureHwProjServices("Notifications API");
}
@@ -63,17 +76,18 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, IEventBu
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
- eventBustSubscriber.Subscribe();
+ eventBustSubscriber.Subscribe();
+ eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
- eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
eventBustSubscriber.Subscribe();
}
-
+
+ app.UseHangfireDashboard();
app.ConfigureHwProj(env, "Notifications API", context);
}
}
diff --git a/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json b/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json
index 6f9707df9..4a4d36366 100644
--- a/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json
+++ b/HwProj.NotificationsService/HwProj.NotificationsService.API/appsettings.json
@@ -1,11 +1,13 @@
{
"ConnectionStrings": {
"DefaultConnectionForWindows": "Server=(localdb)\\mssqllocaldb;Database=NotificationsServiceDB;Trusted_Connection=True;MultipleActiveResultSets=True",
- "DefaultConnectionForLinux": "Server=localhost,1433;Database=NotificationsServiceDB;User ID=SA;Password=password_1234;"
+ "DefaultConnectionForLinux": "Server=localhost,1433;Database=NotificationsServiceDB;User ID=SA;Password=password_1234;",
+ "HangfireConnection": "Server=(localdb)\\mssqllocaldb;Database=HangfireDB;Trusted_Connection=True;"
},
"Logging": {
"LogLevel": {
- "Default": "Warning"
+ "Default": "Warning",
+ "Hangfire": "Information"
}
},
"AllowedHosts": "*",
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.Designer.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.Designer.cs
deleted file mode 100644
index efc89b036..000000000
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.Designer.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-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;
-
-namespace HwProj.SolutionsService.API.Migrations
-{
- [DbContext(typeof(SolutionContext))]
- [Migration("20231025212103_SolutionsIndex")]
- partial class SolutionsIndex
- {
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
- .HasAnnotation("Relational:MaxIdentifierLength", 128)
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- modelBuilder.Entity("HwProj.Models.SolutionsService.Solution", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- b.Property("Comment");
-
- b.Property("GithubUrl");
-
- b.Property("GroupId");
-
- b.Property("LecturerComment");
-
- b.Property("PublicationDate");
-
- b.Property("Rating");
-
- b.Property("State");
-
- b.Property("StudentId");
-
- b.Property("TaskId");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId");
-
- b.ToTable("Solutions");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.cs
deleted file mode 100644
index 4b3e5e7f3..000000000
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/20231025212103_SolutionsIndex.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-namespace HwProj.SolutionsService.API.Migrations
-{
- public partial class SolutionsIndex : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateIndex(
- name: "IX_Solutions_TaskId",
- table: "Solutions",
- column: "TaskId");
- }
- }
-}
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs
deleted file mode 100644
index 2111fe91c..000000000
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Migrations/SolutionContextModelSnapshot.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-using System;
-using HwProj.SolutionsService.API.Models;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-namespace HwProj.SolutionsService.API.Migrations
-{
- [DbContext(typeof(SolutionContext))]
- partial class SolutionContextModelSnapshot : ModelSnapshot
- {
- 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);
-
- modelBuilder.Entity("HwProj.Models.SolutionsService.Solution", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
-
- b.Property("Comment");
-
- b.Property("GithubUrl");
-
- b.Property("GroupId");
-
- b.Property("LecturerComment");
-
- b.Property("PublicationDate");
-
- b.Property("Rating");
-
- b.Property("State");
-
- b.Property("StudentId");
-
- b.Property("TaskId");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId");
-
- b.ToTable("Solutions");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs
index c9f7d1603..92662c645 100644
--- a/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs
+++ b/HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs
@@ -10,7 +10,7 @@
using HwProj.Models.CoursesService.ViewModels;
using HwProj.Models.SolutionsService;
using HwProj.Models.StatisticsService;
-using HwProj.SolutionsService.API.Events;
+using HwProj.Models.Events.SolutionEvents;
using HwProj.SolutionsService.API.Repositories;
using Microsoft.EntityFrameworkCore;