diff --git a/Homework/pom.xml b/Homework/pom.xml
deleted file mode 100644
index c051b94..0000000
--- a/Homework/pom.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
- 4.0.0
- ru.project.iakov
- Homework
- 1.0-SNAPSHOT
-
- 24
- 24
- UTF-8
-
-
-
- org.hibernate.orm
- hibernate-core
- 6.6.15.Final
-
-
- org.postgresql
- postgresql
- 42.7.5
-
-
- org.slf4j
- slf4j-api
- 2.0.13
-
-
- org.projectlombok
- lombok
- 1.18.38
- provided
-
-
- ch.qos.logback
- logback-classic
- 1.5.18
- compile
-
-
- org.junit.jupiter
- junit-jupiter
- 5.10.0
- test
-
-
- org.testcontainers
- postgresql
- 1.19.0
- test
-
-
- org.testcontainers
- junit-jupiter
- 1.21.1
- test
-
-
- org.slf4j
- slf4j-log4j12
- 2.1.0-alpha1
- pom
-
-
- org.mockito
- mockito-core
- 5.8.0
- test
-
-
- org.assertj
- assertj-core
- 3.25.1
- test
-
-
- org.springframework.boot
- spring-boot
- 3.5.0
-
-
- org.springframework.boot
- spring-boot-starter-web
- 3.5.0
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
- 3.5.0
-
-
- org.springframework.boot
- spring-boot-starter-test
- 3.5.0
- test
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- 3.0-rc5
-
-
-
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/legacy/HibernateUtil.java b/Homework/src/main/java/ru/project/iakov/homework2/legacy/HibernateUtil.java
deleted file mode 100644
index a6542a9..0000000
--- a/Homework/src/main/java/ru/project/iakov/homework2/legacy/HibernateUtil.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy;
-
-import lombok.Getter;
-import org.hibernate.SessionFactory;
-import org.hibernate.cfg.Configuration;
-import ru.project.iakov.homework2.User;
-
-public class HibernateUtil {
- @Getter
- private static SessionFactory sessionFactory = buildSessionFactory();
-
- private static SessionFactory buildSessionFactory() {
- try {
- Configuration configuration = new Configuration();
- configuration.configure();
- configuration.addAnnotatedClass(User.class);
- return configuration.buildSessionFactory();
- } catch (Exception e) {
- System.err.println(e.getMessage());
- throw new ExceptionInInitializerError(e);
- }
- }
-
- public static void rebuildSessionFactoryForTests() {
- if (sessionFactory != null) {
- sessionFactory.close();
- }
-
- Configuration configuration = new Configuration();
- configuration.configure("hibernate.cfg.xml");
- configuration.setProperty("hibernate.connection.url", System.getProperty("DB_URL"));
- configuration.setProperty("hibernate.connection.username", System.getProperty("DB_USERNAME"));
- configuration.setProperty("hibernate.connection.password", System.getProperty("DB_PASSWORD"));
-
- configuration.addAnnotatedClass(User.class);
-
- sessionFactory = configuration.buildSessionFactory();
- }
-}*/
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/legacy/Runner.java b/Homework/src/main/java/ru/project/iakov/homework2/legacy/Runner.java
deleted file mode 100644
index ae9fe60..0000000
--- a/Homework/src/main/java/ru/project/iakov/homework2/legacy/Runner.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy;
-
-import ru.project.iakov.homework2.User;
-import ru.project.iakov.homework2.dao.UserDaoImpl;
-import ru.project.iakov.homework2.service.UserService;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-import java.util.Scanner;
-
-public class Runner {
- private static final Scanner scanner = new Scanner(System.in);
- private static final UserService userService = new UserService(new UserDaoImpl());
-
- public static void main(String[] args) {
- while (true) {
- printMenu();
- int choice = readInt("Выберите пункт меню: ");
-
- switch (choice) {
- case 1 -> createUser();
- case 2 -> findUserById();
- case 3 -> findAllUsers();
- case 4 -> updateUser();
- case 5 -> deleteUser();
- case 6 -> exitApp();
- default -> System.out.println("Неверный пункт меню. Попробуйте снова.");
- }
- }
- }
-
- private static void printMenu() {
- System.out.println("""
- ===== Меню =====
- 1. Создать пользователя
- 2. Найти пользователя по ID
- 3. Показать всех пользователей
- 4. Обновить пользователя
- 5. Удалить пользователя
- 6. Выход
- """);
- }
-
- private static void createUser() {
- String name = readLine("Имя: ");
- String email = readLine("Email: ");
- int age = readInt("Возраст: ");
-
- User user = User.builder()
- .name(name)
- .email(email)
- .age(age)
- .createdAt(LocalDateTime.now())
- .build();
-
- userService.createUser(user);
- System.out.println("Пользователь создан.");
- }
-
- private static void findUserById() {
- long id = readLong("Введите ID пользователя: ");
- Optional userOpt = userService.findById(id);
- userOpt.ifPresentOrElse(
- System.out::println,
- () -> System.out.println("Пользователь не найден.")
- );
- }
-
- private static void findAllUsers() {
- List users = userService.findAll();
- if (users.isEmpty()) {
- System.out.println("Нет пользователей в базе.");
- } else {
- users.forEach(System.out::println);
- }
- }
-
- private static void updateUser() {
- long id = readLong("ID обновляемого пользователя: ");
- Optional userOpt = userService.findById(id);
-
- if (userOpt.isPresent()) {
- User user = userOpt.get();
- String name = readLine("Новое имя (" + user.getName() + "): ");
- String email = readLine("Новый email (" + user.getEmail() + "): ");
- int age = readInt("Новый возраст (" + user.getAge() + "): ");
-
- user.setName(name.isEmpty() ? user.getName() : name);
- user.setEmail(email.isEmpty() ? user.getEmail() : email);
- user.setAge(age <= 0 ? user.getAge() : age);
-
- userService.update(user);
- System.out.println("Пользователь обновлён.");
- } else {
- System.out.println("Пользователь с таким ID не найден.");
- }
- }
-
- private static void deleteUser() {
- long id = readLong("ID пользователя для удаления: ");
- userService.delete(id);
- System.out.println("Пользователь удалён (если существовал).");
- }
-
- private static void exitApp() {
- System.out.println("Завершение работы.");
- System.exit(0);
- }
-
- private static int readInt(String prompt) {
- System.out.print(prompt);
- while (!scanner.hasNextInt()) {
- scanner.nextLine();
- System.out.print("Введите целое число: ");
- }
- int value = scanner.nextInt();
- scanner.nextLine();
- return value;
- }
-
- private static long readLong(String prompt) {
- System.out.print(prompt);
- while (!scanner.hasNextLong()) {
- scanner.nextLine();
- System.out.print("Введите корректный ID: ");
- }
- long value = scanner.nextLong();
- scanner.nextLine();
- return value;
- }
-
- private static String readLine(String prompt) {
- System.out.print(prompt);
- return scanner.nextLine().trim();
- }
-}*/
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDao.java b/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDao.java
deleted file mode 100644
index 5063c18..0000000
--- a/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDao.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy.dao;
-
-import ru.project.iakov.homework2.User;
-
-import java.util.List;
-import java.util.Optional;
-
-public interface UserDao {
- void create(User user);
- Optional findById(Long id);
- List findAll();
- void update(User user);
- void delete(Long id);
-}*/
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDaoImpl.java b/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDaoImpl.java
deleted file mode 100644
index 251369c..0000000
--- a/Homework/src/main/java/ru/project/iakov/homework2/legacy/dao/UserDaoImpl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy.dao;
-
-import ru.project.iakov.homework2.legacy.HibernateUtil;
-import ru.project.iakov.homework2.User;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-
-import java.util.List;
-import java.util.Optional;
-
-public class UserDaoImpl implements UserDao {
-
- @Override
- public void create(User user) {
- try (Session session = HibernateUtil.getSessionFactory().openSession()) {
- Transaction tx = session.beginTransaction();
- session.persist(user);
- tx.commit();
- }
- }
-
- @Override
- public Optional findById(Long id) {
- try (Session session = HibernateUtil.getSessionFactory().openSession()) {
- return Optional.ofNullable(session.get(User.class, id));
- }
- }
-
- @Override
- public List findAll() {
- try (Session session = HibernateUtil.getSessionFactory().openSession()) {
- return session.createQuery("from User", User.class).list();
- }
- }
-
- @Override
- public void update(User user) {
- try (Session session = HibernateUtil.getSessionFactory().openSession()) {
- Transaction tx = session.beginTransaction();
- session.merge(user);
- tx.commit();
- }
- }
-
- @Override
- public void delete(Long id) {
- try (Session session = HibernateUtil.getSessionFactory().openSession()) {
- Transaction tx = session.beginTransaction();
- User user = session.get(User.class, id);
- if (user != null) {
- session.remove(user);
- }
- tx.commit();
- }
- }
-}*/
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/service/UserService.java b/Homework/src/main/java/ru/project/iakov/homework2/service/UserService.java
deleted file mode 100644
index 5910e1e..0000000
--- a/Homework/src/main/java/ru/project/iakov/homework2/service/UserService.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ru.project.iakov.homework2.service;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import ru.project.iakov.homework2.User;
-import ru.project.iakov.homework2.UserDto;
-import ru.project.iakov.homework2.UserMapper;
-import ru.project.iakov.homework2.UserRepository;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Service
-public class UserService {
- private UserRepository userRepository;
- private UserMapper userMapper;
-
- @Autowired
- public UserService(UserRepository userRepository, UserMapper userMapper) {
- this.userRepository = userRepository;
- this.userMapper = userMapper;
- }
-
- public UserDto createUser(UserDto userDto) {
- User user = userMapper.toEntity(userDto);
- User savedUser = userRepository.save(user);
- return userMapper.toDto(savedUser);
- }
- public UserDto findById(Long id) {
- User user = userRepository.findById(id)
- .orElseThrow(() -> new IllegalArgumentException());
- return userMapper.toDto(user);
- }
- public List findAll() {
- List users = userRepository.findAll();
- return users.stream()
- .map(userMapper::toDto)
- .collect(Collectors.toList());
- }
- public UserDto updateUser(Long id, UserDto userDto) {
- User existingUser = userRepository.findById(id)
- .orElseThrow(() -> new IllegalArgumentException());
- existingUser.setName(userDto.getName());
- existingUser.setEmail(userDto.getEmail());
- User updatedUser = userRepository.save(existingUser);
- return userMapper.toDto(updatedUser);
- }
- public void deleteUser(Long id) {
- if (!userRepository.existsById(id)) {
- throw new IllegalArgumentException();
- }
- userRepository.deleteById(id);
- }
-}
\ No newline at end of file
diff --git a/Homework/src/main/resources/application.yml b/Homework/src/main/resources/application.yml
deleted file mode 100644
index dc80496..0000000
--- a/Homework/src/main/resources/application.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-spring:
- datasource:
- url: jdbc:postgresql://localhost:5432/postgres
- username: postgres
- password: postgres
- jpa:
- hibernate:
- ddl-auto: update
- show-sql: true
- properties:
- hibernate:
- format_sql: true
- jackson:
- serialization:
- INDENT_OUTPUT: true
-
-server:
- port: 8080
\ No newline at end of file
diff --git a/Homework/src/test/java/ru/project/iakov/homework2/legacy/SimpleContainerTest.java b/Homework/src/test/java/ru/project/iakov/homework2/legacy/SimpleContainerTest.java
deleted file mode 100644
index 5769800..0000000
--- a/Homework/src/test/java/ru/project/iakov/homework2/legacy/SimpleContainerTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy;
-
-import jakarta.persistence.PersistenceException;
-import org.junit.jupiter.api.*;
-import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-import ru.project.iakov.homework2.User;
-import ru.project.iakov.homework2.legacy.dao.UserDao;
-import ru.project.iakov.homework2.legacy.dao.UserDaoImpl;
-import ru.project.iakov.homework2.legacy.HibernateUtil;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@Testcontainers
-public class SimpleContainerTest {
- private static UserDao userDao;
- @Container
- public static PostgreSQLContainer> postgres = new PostgreSQLContainer<>("postgres")
- .withDatabaseName("postgres")
- .withUsername("postgres")
- .withPassword("postgres");
-
- @BeforeAll
- static void setUp() {
- postgres.start();
- System.setProperty("DB_URL", postgres.getJdbcUrl());
- System.setProperty("DB_USERNAME", postgres.getUsername());
- System.setProperty("DB_PASSWORD", postgres.getPassword());
-
- HibernateUtil.rebuildSessionFactoryForTests();
- userDao = new UserDaoImpl();
- }
-
- @DisplayName("Создание и поиск по ID")
- @Test
- @Order(1)
- void shouldCreateAndFindUserById() {
- User user = User.builder()
- .name("Iakov")
- .email("lysenko_iakov@yahoo.com")
- .age(25)
- .createdAt(LocalDateTime.now())
- .build();
-
- userDao.create(user);
-
- assertNotNull(user.getId());
-
- Optional saved = userDao.findById(user.getId());
- assertTrue(saved.isPresent());
- assertEquals("Iakov", saved.get().getName());
- }
-
- @DisplayName("Обновление пользователя")
- @Test
- @Order(2)
- void shouldUpdateUser() {
- User user = User.builder()
- .name("Original")
- .email("original@email.com")
- .age(30)
- .createdAt(LocalDateTime.now())
- .build();
-
- userDao.create(user);
- user.setName("Updated");
- user.setEmail("updated@email.com");
-
- userDao.update(user);
-
- Optional updated = userDao.findById(user.getId());
- assertTrue(updated.isPresent());
- assertEquals("Updated", updated.get().getName());
- assertEquals("updated@email.com", updated.get().getEmail());
- }
-
- @DisplayName("Удаление существующего пользователя")
- @Test
- @Order(3)
- void shouldDeleteUser() {
- User user = User.builder()
- .name("ToDelete")
- .email("delete@example.com")
- .age(40)
- .createdAt(LocalDateTime.now())
- .build();
-
- userDao.create(user);
- Long id = user.getId();
-
- userDao.delete(id);
-
- Optional deleted = userDao.findById(id);
- assertFalse(deleted.isPresent());
- }
-
- @DisplayName("Поиск по несуществующему ID")
- @Test
- @Order(4)
- void shouldReturnEmptyForNonExistingUser() {
- Optional user = userDao.findById(99999L);
- assertTrue(user.isEmpty());
- }
-
- @DisplayName("Удаление несуществующего пользователя")
- @Test
- @Order(5)
- void shouldNotThrowWhenDeletingNonExistingUser() {
- assertDoesNotThrow(() -> userDao.delete(99999L));
- }
-
- @DisplayName("Создание пользователя с null-именем должно выбросить исключение")
- @Test
- @Order(6)
- void shouldThrowWhenCreatingUserWithNullName() {
- User user = User.builder()
- .email("nullname@example.com")
- .age(30)
- .createdAt(LocalDateTime.now())
- .build();
-
- assertThrows(PersistenceException.class, () -> userDao.create(user));
- }
-
- @DisplayName("Найти всех пользователей")
- @Test
- @Order(7)
- void shouldFindAllUsers() {
- User user1 = User.builder()
- .name("User1")
- .email("user1@email.com")
- .age(20)
- .createdAt(LocalDateTime.now())
- .build();
-
- User user2 = User.builder()
- .name("User2")
- .email("user2@email.com")
- .age(25)
- .createdAt(LocalDateTime.now())
- .build();
-
- userDao.create(user1);
- userDao.create(user2);
-
- List allUsers = userDao.findAll();
-
- assertTrue(allUsers.size() >= 2);
- }
-
- @AfterAll
- static void stopContainer() {
- postgres.stop();
- }
-}*/
diff --git a/Homework/src/test/java/ru/project/iakov/homework2/legacy/service/UserServiceTest.java b/Homework/src/test/java/ru/project/iakov/homework2/legacy/service/UserServiceTest.java
deleted file mode 100644
index d78267f..0000000
--- a/Homework/src/test/java/ru/project/iakov/homework2/legacy/service/UserServiceTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-package ru.project.iakov.homework2.legacy.service;
-
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.BeforeEach;
-import ru.project.iakov.homework2.User;
-import ru.project.iakov.homework2.legacy.dao.UserDao;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-public class UserServiceTest {
- private UserDao userDao;
- private UserService userService;
-
- @BeforeEach
- void setUp() {
- userDao = mock(UserDao.class);
- userService = new UserService(userDao);
- }
-
- @DisplayName("Создание пользователя")
- @Test
- public void createUser() {
- User user = new User();
- userService.createUser(user);
-
- verify(userDao, times(1)).create(user);
- }
-
- @DisplayName("Пользователь найден по ID")
- @Test
- public void findById_shouldReturnUser_whenUserExist() {
- User user = new User();
- user.setId(1L);
-
- when(userDao.findById(1L)).thenReturn(Optional.of(user));
-
- Optional result = userService.findById(1L);
-
- assertTrue(result.isPresent());
- assertEquals(1L, result.get().getId());
- verify(userDao, times(1)).findById(1L);
- }
-
- @DisplayName("Такого пользователя нет")
- @Test
- public void findById_shouldReturnEmpty_whenUserNotExist() {
- when(userDao.findById(1L)).thenReturn(Optional.empty());
-
- Optional result = userService.findById(1L);
-
- assertFalse(result.isPresent());
- verify(userDao, times(1)).findById(1L);
- }
-
- @DisplayName("Отрицательный ID — выбрасывается исключение")
- @Test
- void findById_shouldThrowException_whenIdIsNegative() {
- assertThrows(IllegalArgumentException.class, () -> userService.findById(-1L));
- verifyNoInteractions(userDao);
- }
-
- @DisplayName("ID равен нулю — выбрасывается исключение")
- @Test
- void findById_shouldThrowException_whenIdIsZero() {
- assertThrows(IllegalArgumentException.class, () -> userService.findById(0L));
- verifyNoInteractions(userDao);
- }
-
- @DisplayName("ID равен null — выбрасывается исключение")
- @Test
- void findById_shouldThrowException_whenIdIsNull() {
- assertThrows(IllegalArgumentException.class, () -> userService.findById(null));
- verifyNoInteractions(userDao);
- }
-
- @DisplayName("Получение списка всех пользователей")
- @Test
- public void testGetAllUsers() {
- List users = Arrays.asList(new User(), new User());
- when(userDao.findAll()).thenReturn(users);
-
- List result = userService.findAll();
-
- assertEquals(2, result.size());
- verify(userDao, times(1)).findAll();
- }
-
- @DisplayName("Обновление данных пользователя")
- @Test
- public void updateUser() {
- User user = new User();
- user.setId(2L);
-
- userService.update(user);
-
- verify(userDao, times(1)).update(user);
- }
-
- @DisplayName("Пользователь успешно удален")
- @Test
- public void deleteUser_whenUserExist() {
- userService.delete(3L);
-
- verify(userDao, times(1)).delete(3L);
- }
-
- @DisplayName("При удалении пользователь не найден")
- @Test
- public void deleteUser_whenUserNotExist() {
- Long noExistId = 999L;
- doThrow(new NoSuchElementException("Пользователь не найден"))
- .when(userDao).delete(noExistId);
-
- assertThrows(NoSuchElementException.class, () -> userService.delete(noExistId));
-
- verify(userDao).delete(noExistId);
- }
-}*/
diff --git a/notification-service/pom.xml b/notification-service/pom.xml
new file mode 100644
index 0000000..b9d3ef4
--- /dev/null
+++ b/notification-service/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+ ru.project.iakov
+ user-service
+ 1.0-SNAPSHOT
+
+ 24
+ 24
+ UTF-8
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.38
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 3.5.0
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ 3.5.0
+ test
+
+
+ org.springframework.kafka
+ spring-kafka
+ 3.3.6
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+ 3.4.6
+
+
+
\ No newline at end of file
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/NotificationServiceApplication.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/NotificationServiceApplication.java
new file mode 100644
index 0000000..c8f0a56
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/NotificationServiceApplication.java
@@ -0,0 +1,13 @@
+package ru.project.iakov.notificationservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class NotificationServiceApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(NotificationServiceApplication.class, args);
+ }
+
+}
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/controller/EmailController.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/controller/EmailController.java
new file mode 100644
index 0000000..adb42d0
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/controller/EmailController.java
@@ -0,0 +1,35 @@
+package ru.project.iakov.notificationservice.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import ru.project.iakov.notificationservice.dto.EmailRequest;
+import ru.project.iakov.notificationservice.model.EventType;
+import ru.project.iakov.notificationservice.service.EmailService;
+
+
+@RestController
+@RequestMapping("/api/v1/email")
+@RequiredArgsConstructor
+public class EmailController {
+
+ private final EmailService emailService;
+
+ @PostMapping("/send")
+ public ResponseEntity sendEmail(@RequestBody EmailRequest request) {
+ try {
+ emailService.sendEmail(request.getEmail(), request.getSubject(), generateText(request.getEventType()));
+ return ResponseEntity.ok("Письмо отправлено");
+ } catch (Exception e) {
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("Ошибка при отправке письма: " + e.getMessage());
+ }
+ }
+ private String generateText(EventType eventType) {
+ return switch (eventType) {
+ case CREATED -> "Здравствуйте! Ваш аккаунт был создан.";
+ case DELETED -> "Здравствуйте! Ваш аккаунт был удалён.";
+ };
+ }
+}
\ No newline at end of file
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/EmailRequest.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/EmailRequest.java
new file mode 100644
index 0000000..ae59c07
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/EmailRequest.java
@@ -0,0 +1,13 @@
+package ru.project.iakov.notificationservice.dto;
+
+import lombok.*;
+import ru.project.iakov.notificationservice.model.EventType;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class EmailRequest {
+ private String email;
+ private String subject;
+ private EventType eventType;
+}
\ No newline at end of file
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/UserEvent.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/UserEvent.java
new file mode 100644
index 0000000..232df3b
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/dto/UserEvent.java
@@ -0,0 +1,15 @@
+package ru.project.iakov.notificationservice.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.*;
+import ru.project.iakov.notificationservice.model.EventType;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Builder
+public class UserEvent {
+ private String email;
+ private EventType eventType;
+}
\ No newline at end of file
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/model/EventType.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/model/EventType.java
new file mode 100644
index 0000000..b34bd25
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/model/EventType.java
@@ -0,0 +1,6 @@
+package ru.project.iakov.notificationservice.model;
+
+public enum EventType {
+ CREATED,
+ DELETED
+}
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/service/EmailService.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/service/EmailService.java
new file mode 100644
index 0000000..c81a712
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/service/EmailService.java
@@ -0,0 +1,36 @@
+package ru.project.iakov.notificationservice.service;
+
+
+import jakarta.mail.internet.MimeMessage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class EmailService {
+
+ private final JavaMailSender mailSender;
+
+ @Value("${spring.mail.username}")
+ private String fromEmail;
+
+ public void sendEmail(String to, String subject, String text) {
+ try {
+ MimeMessage mimeMessage = mailSender.createMimeMessage();
+ MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, false, "utf-8");
+ helper.setFrom(fromEmail);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(text);
+ mailSender.send(mimeMessage);
+ } catch (Exception e) {
+ log.error("Ошибка при отправке email на {}: {}", to, e.getMessage(), e);
+ throw new RuntimeException("Не удалось отправить email", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/notification-service/src/main/java/ru/project/iakov/notificationservice/service/KafkaConsumerService.java b/notification-service/src/main/java/ru/project/iakov/notificationservice/service/KafkaConsumerService.java
new file mode 100644
index 0000000..08de591
--- /dev/null
+++ b/notification-service/src/main/java/ru/project/iakov/notificationservice/service/KafkaConsumerService.java
@@ -0,0 +1,39 @@
+package ru.project.iakov.notificationservice.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+import ru.project.iakov.notificationservice.dto.UserEvent;
+import ru.project.iakov.notificationservice.model.EventType;
+
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class KafkaConsumerService {
+
+ private final EmailService emailService;
+ private final ObjectMapper objectMapper;
+
+ @KafkaListener(topics = "user-events", groupId = "notification-group")
+ public void listen(ConsumerRecord record) {
+ String message = record.value();
+ log.info("Kafka message: {}", message);
+ try {
+ UserEvent event = objectMapper.readValue(message, UserEvent.class);
+ log.info("Получено сообщение из Kafka: {}", event);
+ emailService.sendEmail(event.getEmail(), "Уведомление", generateText(event.getEventType()));
+ } catch (Exception e) {
+ log.error("Ошибка обработки сообщения: {}", e.getMessage(), e);
+ }
+ }
+
+ private String generateText(EventType eventType) {
+ return switch (eventType) {
+ case CREATED -> "Здравствуйте! Ваш аккаунт был создан.";
+ case DELETED -> "Здравствуйте! Ваш аккаунт был удалён.";
+ };
+ }
+}
\ No newline at end of file
diff --git a/notification-service/src/main/resources/application.yml b/notification-service/src/main/resources/application.yml
new file mode 100644
index 0000000..be161d0
--- /dev/null
+++ b/notification-service/src/main/resources/application.yml
@@ -0,0 +1,24 @@
+spring:
+ kafka:
+ bootstrap-servers: localhost:9092
+ consumer:
+ group-id: notification-group
+ auto-offset-reset: earliest
+ key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+ value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+
+ mail:
+ host: smtp.mail.ru
+ port: 587
+ username: ${EMAIL_USERNAME}
+ password: ${EMAIL_PASSWORD}
+ properties:
+ mail.smtp.auth: true
+ mail.smtp.starttls.enable: true
+
+logging:
+ level:
+ root: INFO
+
+server:
+ port: 8081
\ No newline at end of file
diff --git a/user-service/pom.xml b/user-service/pom.xml
new file mode 100644
index 0000000..045cabe
--- /dev/null
+++ b/user-service/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+ ru.project.iakov
+ user-service
+ 1.0-SNAPSHOT
+
+ 24
+ 24
+ UTF-8
+
+
+
+ org.postgresql
+ postgresql
+ 42.7.5
+
+
+ org.projectlombok
+ lombok
+ 1.18.38
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 3.5.0
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ 3.5.0
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ 3.5.0
+ test
+
+
+ org.springframework.kafka
+ spring-kafka
+ 3.3.6
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+ 3.4.6
+
+
+
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/UserServiceApplication.java b/user-service/src/main/java/ru/project/iakov/homework2/UserServiceApplication.java
similarity index 100%
rename from Homework/src/main/java/ru/project/iakov/homework2/UserServiceApplication.java
rename to user-service/src/main/java/ru/project/iakov/homework2/UserServiceApplication.java
diff --git a/user-service/src/main/java/ru/project/iakov/homework2/controller/NotificationController.java b/user-service/src/main/java/ru/project/iakov/homework2/controller/NotificationController.java
new file mode 100644
index 0000000..fe58216
--- /dev/null
+++ b/user-service/src/main/java/ru/project/iakov/homework2/controller/NotificationController.java
@@ -0,0 +1,35 @@
+package ru.project.iakov.homework2.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import ru.project.iakov.homework2.dto.UserEvent;
+import ru.project.iakov.homework2.service.KafkaProducerService;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/v1/kafka")
+@RequiredArgsConstructor
+@Validated
+public class NotificationController {
+
+ private final KafkaProducerService kafkaProducer;
+ private final ObjectMapper objectMapper;
+
+ @PostMapping("/publish")
+ public ResponseEntity send(@RequestBody UserEvent request) {
+ log.info("Получен запрос на публикацию события: {}", request);
+ try {
+ String message = objectMapper.writeValueAsString(request);
+ kafkaProducer.sendUserEvent(message);
+ return ResponseEntity.ok().build();
+ } catch (JsonProcessingException e) {
+ log.error("Ошибка сериализации события: {}", e.getMessage(), e);
+ return ResponseEntity.internalServerError().build();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/UserController.java b/user-service/src/main/java/ru/project/iakov/homework2/controller/UserController.java
similarity index 95%
rename from Homework/src/main/java/ru/project/iakov/homework2/UserController.java
rename to user-service/src/main/java/ru/project/iakov/homework2/controller/UserController.java
index 6c3ca40..6f3833d 100644
--- a/Homework/src/main/java/ru/project/iakov/homework2/UserController.java
+++ b/user-service/src/main/java/ru/project/iakov/homework2/controller/UserController.java
@@ -1,9 +1,10 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import ru.project.iakov.homework2.dto.UserDto;
import ru.project.iakov.homework2.service.UserService;
import java.util.List;
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/UserDto.java b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java
similarity index 78%
rename from Homework/src/main/java/ru/project/iakov/homework2/UserDto.java
rename to user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java
index a789830..7660dce 100644
--- a/Homework/src/main/java/ru/project/iakov/homework2/UserDto.java
+++ b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserDto.java
@@ -1,4 +1,4 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.dto;
import lombok.*;
import java.time.LocalDateTime;
@@ -11,8 +11,11 @@ public class UserDto {
@Getter
@Setter
private Long id;
+ @NonNull
private String name;
+ @NonNull
private String email;
+ @NonNull
private Integer age;
private LocalDateTime createdAt;
}
\ No newline at end of file
diff --git a/user-service/src/main/java/ru/project/iakov/homework2/dto/UserEvent.java b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserEvent.java
new file mode 100644
index 0000000..e610159
--- /dev/null
+++ b/user-service/src/main/java/ru/project/iakov/homework2/dto/UserEvent.java
@@ -0,0 +1,15 @@
+package ru.project.iakov.homework2.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.*;
+import ru.project.iakov.homework2.model.EventType;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class UserEvent {
+ private String email;
+ private EventType eventType;
+}
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/User.java b/user-service/src/main/java/ru/project/iakov/homework2/entity/User.java
similarity index 75%
rename from Homework/src/main/java/ru/project/iakov/homework2/User.java
rename to user-service/src/main/java/ru/project/iakov/homework2/entity/User.java
index d03b7ae..c24753b 100644
--- a/Homework/src/main/java/ru/project/iakov/homework2/User.java
+++ b/user-service/src/main/java/ru/project/iakov/homework2/entity/User.java
@@ -1,4 +1,4 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
@@ -24,4 +24,10 @@ public class User {
@Column(nullable = false)
private int age;
private LocalDateTime createdAt;
+ @PrePersist
+ public void prePersist() {
+ if (createdAt == null) {
+ createdAt = LocalDateTime.now();
+ }
+ }
}
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/UserMapper.java b/user-service/src/main/java/ru/project/iakov/homework2/mapper/UserMapper.java
similarity index 81%
rename from Homework/src/main/java/ru/project/iakov/homework2/UserMapper.java
rename to user-service/src/main/java/ru/project/iakov/homework2/mapper/UserMapper.java
index e3fc5b6..b75741e 100644
--- a/Homework/src/main/java/ru/project/iakov/homework2/UserMapper.java
+++ b/user-service/src/main/java/ru/project/iakov/homework2/mapper/UserMapper.java
@@ -1,5 +1,7 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.mapper;
import org.springframework.stereotype.Component;
+import ru.project.iakov.homework2.entity.User;
+import ru.project.iakov.homework2.dto.UserDto;
@Component
public class UserMapper {
diff --git a/user-service/src/main/java/ru/project/iakov/homework2/model/EventType.java b/user-service/src/main/java/ru/project/iakov/homework2/model/EventType.java
new file mode 100644
index 0000000..897bd29
--- /dev/null
+++ b/user-service/src/main/java/ru/project/iakov/homework2/model/EventType.java
@@ -0,0 +1,6 @@
+package ru.project.iakov.homework2.model;
+
+public enum EventType {
+ CREATED,
+ DELETED
+}
\ No newline at end of file
diff --git a/Homework/src/main/java/ru/project/iakov/homework2/UserRepository.java b/user-service/src/main/java/ru/project/iakov/homework2/repository/UserRepository.java
similarity index 58%
rename from Homework/src/main/java/ru/project/iakov/homework2/UserRepository.java
rename to user-service/src/main/java/ru/project/iakov/homework2/repository/UserRepository.java
index ef9f458..0479fba 100644
--- a/Homework/src/main/java/ru/project/iakov/homework2/UserRepository.java
+++ b/user-service/src/main/java/ru/project/iakov/homework2/repository/UserRepository.java
@@ -1,5 +1,6 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.repository;
import org.springframework.data.jpa.repository.JpaRepository;
+import ru.project.iakov.homework2.entity.User;
public interface UserRepository extends JpaRepository {
}
\ No newline at end of file
diff --git a/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java b/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java
new file mode 100644
index 0000000..8671267
--- /dev/null
+++ b/user-service/src/main/java/ru/project/iakov/homework2/service/KafkaProducerService.java
@@ -0,0 +1,20 @@
+package ru.project.iakov.homework2.service;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class KafkaProducerService {
+
+ private final KafkaTemplate kafkaTemplate;
+ private static final String TOPIC = "user-events";
+
+ public void sendUserEvent(String message) {
+ log.info("Отправка сообщения в Kafka: {}", message);
+ kafkaTemplate.send(TOPIC, message);
+ }
+}
\ No newline at end of file
diff --git a/user-service/src/main/java/ru/project/iakov/homework2/service/UserService.java b/user-service/src/main/java/ru/project/iakov/homework2/service/UserService.java
new file mode 100644
index 0000000..3de3493
--- /dev/null
+++ b/user-service/src/main/java/ru/project/iakov/homework2/service/UserService.java
@@ -0,0 +1,85 @@
+package ru.project.iakov.homework2.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import ru.project.iakov.homework2.dto.UserDto;
+import ru.project.iakov.homework2.dto.UserEvent;
+import ru.project.iakov.homework2.entity.User;
+import ru.project.iakov.homework2.mapper.UserMapper;
+import ru.project.iakov.homework2.model.EventType;
+import ru.project.iakov.homework2.repository.UserRepository;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class UserService {
+
+ private final UserRepository userRepository;
+ private final UserMapper userMapper;
+ private final KafkaProducerService kafkaProducer;
+ private final ObjectMapper objectMapper;
+
+ @Transactional
+ public UserDto createUser(UserDto userDto) {
+ User user = userMapper.toEntity(userDto);
+ User savedUser = userRepository.save(user);
+
+ sendKafkaEvent(savedUser.getEmail(), EventType.CREATED);
+
+ return userMapper.toDto(savedUser);
+ }
+
+ public UserDto findById(Long id) {
+ User user = userRepository.findById(id)
+ .orElseThrow(IllegalArgumentException::new);
+
+ return userMapper.toDto(user);
+ }
+
+ public List findAll() {
+ List users = userRepository.findAll();
+
+ return users.stream()
+ .map(userMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ public UserDto updateUser(Long id, UserDto userDto) {
+ User existingUser = userRepository.findById(id)
+ .orElseThrow(IllegalArgumentException::new);
+
+ existingUser.setName(userDto.getName());
+ existingUser.setEmail(userDto.getEmail());
+
+ User updatedUser = userRepository.save(existingUser);
+
+ return userMapper.toDto(updatedUser);
+ }
+
+ @Transactional
+ public void deleteUser(Long id) {
+ User user = userRepository.findById(id)
+ .orElseThrow(() -> new IllegalArgumentException("Пользователь не найден"));
+
+ userRepository.deleteById(id);
+
+ sendKafkaEvent(user.getEmail(), EventType.DELETED);
+ }
+
+ private void sendKafkaEvent(String email, EventType eventType) {
+ try {
+ UserEvent event = new UserEvent(email, eventType);
+ String json = objectMapper.writeValueAsString(event);
+
+ kafkaProducer.sendUserEvent(json);
+ } catch (JsonProcessingException e) {
+ System.err.println("Ошибка сериализации события Kafka: " + e.getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml
new file mode 100644
index 0000000..39d62b0
--- /dev/null
+++ b/user-service/src/main/resources/application.yml
@@ -0,0 +1,37 @@
+spring:
+ datasource:
+ url: jdbc:postgresql://localhost:5432/postgres
+ username: postgres
+ password: postgres
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ properties:
+ hibernate:
+ format_sql: true
+ jackson:
+ serialization:
+ INDENT_OUTPUT: true
+ mail:
+ host: smtp.mail.ru
+ port: 465
+ username: ${EMAIL_USERNAME}
+ password: ${EMAIL_PASSWORD}
+ protocol: smtps
+ properties:
+ mail.smtp.auth: true
+ mail.smtp.starttls.enable: true
+ mail.smtp.ssl.enable: true
+ kafka:
+ bootstrap-servers: localhost:9092
+ consumer:
+ group-id: notification-group
+ auto-offset-reset: earliest
+ key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+ value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+ producer:
+ key-serializer: org.apache.kafka.common.serialization.StringSerializer
+ value-serializer: org.apache.kafka.common.serialization.StringSerializer
+server:
+ port: 8080
\ No newline at end of file
diff --git a/Homework/src/main/resources/hibernate.cfg.xml b/user-service/src/main/resources/hibernate.cfg.xml
similarity index 93%
rename from Homework/src/main/resources/hibernate.cfg.xml
rename to user-service/src/main/resources/hibernate.cfg.xml
index a49f2af..1515a41 100644
--- a/Homework/src/main/resources/hibernate.cfg.xml
+++ b/user-service/src/main/resources/hibernate.cfg.xml
@@ -20,6 +20,6 @@
true
-
+
-->
\ No newline at end of file
diff --git a/Homework/src/main/resources/log4j.properties b/user-service/src/main/resources/log4j.properties
similarity index 100%
rename from Homework/src/main/resources/log4j.properties
rename to user-service/src/main/resources/log4j.properties
diff --git a/user-service/src/test/java/ru/project/iakov/homework2/controller/EmailControllerTest.java b/user-service/src/test/java/ru/project/iakov/homework2/controller/EmailControllerTest.java
new file mode 100644
index 0000000..ae09553
--- /dev/null
+++ b/user-service/src/test/java/ru/project/iakov/homework2/controller/EmailControllerTest.java
@@ -0,0 +1,39 @@
+package ru.project.iakov.homework2.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+import org.springframework.test.web.servlet.MockMvc;
+import ru.project.iakov.homework2.dto.EmailRequest;
+import ru.project.iakov.homework2.service.EmailService;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+public class EmailControllerTest {
+ @Autowired
+ private MockMvc mockMvc;
+
+ @MockitoBean
+ private EmailService emailService;
+
+ @Test
+ public void testSendEmail_success() throws Exception {
+ EmailRequest request = new EmailRequest("lysenko_iakov@yahoo.com", "Тест", "Тест");
+
+ mockMvc.perform(post("/api/v1/email/send")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(new ObjectMapper().writeValueAsString(request)))
+ .andExpect(status().isOk());
+
+ verify(emailService, times(1)).sendEmail("lysenko_iakov@yahoo.com", "Тест", "Тест");
+ }
+}
\ No newline at end of file
diff --git a/Homework/src/test/java/ru/project/iakov/homework2/UserControllerTest.java b/user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java
similarity index 98%
rename from Homework/src/test/java/ru/project/iakov/homework2/UserControllerTest.java
rename to user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java
index 08b60bf..4873e5d 100644
--- a/Homework/src/test/java/ru/project/iakov/homework2/UserControllerTest.java
+++ b/user-service/src/test/java/ru/project/iakov/homework2/controller/UserControllerTest.java
@@ -1,4 +1,4 @@
-package ru.project.iakov.homework2;
+package ru.project.iakov.homework2.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
@@ -8,6 +8,7 @@
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
+import ru.project.iakov.homework2.dto.UserDto;
import ru.project.iakov.homework2.service.UserService;
import java.time.LocalDateTime;
diff --git a/user-service/src/test/java/ru/project/iakov/homework2/kafka/KafkaConsumerTest.java b/user-service/src/test/java/ru/project/iakov/homework2/kafka/KafkaConsumerTest.java
new file mode 100644
index 0000000..e2854d5
--- /dev/null
+++ b/user-service/src/test/java/ru/project/iakov/homework2/kafka/KafkaConsumerTest.java
@@ -0,0 +1,50 @@
+package ru.project.iakov.homework2.kafka;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+import ru.project.iakov.homework2.dto.UserEvent;
+import ru.project.iakov.homework2.service.EmailService;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@AutoConfigureMockMvc
+@SpringBootTest
+public class KafkaConsumerTest {
+
+ @Autowired
+ private KafkaConsumerService kafkaConsumer;
+
+ @MockitoBean
+ private EmailService emailService;
+
+ @Test
+ public void testKafkaConsumer_sendsEmailOnCreatedEvent() {
+ UserEvent event = UserEvent.builder()
+ .email("lysenko_iakov@yahoo.com")
+ .subject("Тест: создание")
+ .eventType("CREATED")
+ .build();
+
+ kafkaConsumer.listen(event);
+
+ verify(emailService, times(1)).sendEmail(eq("lysenko_iakov@yahoo.com"), anyString(), contains("создан"));
+ }
+
+ @Test
+ public void testKafkaConsumer_sendsEmailOnDeletedEvent() {
+ UserEvent event = UserEvent.builder()
+ .email("lysenko_iakov@yahoo.com")
+ .subject("Тест: удаление")
+ .eventType("DELETED")
+ .build();
+
+ kafkaConsumer.listen(event);
+
+ verify(emailService, times(1)).sendEmail(eq("lysenko_iakov@yahoo.com"), anyString(), contains("удалён"));
+ }
+}
\ No newline at end of file