From fb731ca16f290c3f07acb87d673fc6990c7cd486 Mon Sep 17 00:00:00 2001 From: stvort Date: Mon, 13 Jan 2020 03:43:32 +0400 Subject: [PATCH] spring-mail-rabbitmq-demo --- examples/README.md | 1 + examples/spring-mail-rabbitmq-demo/README.md | 28 +++++++ .../docker-compose.yml | 5 ++ examples/spring-mail-rabbitmq-demo/pom.xml | 18 +++++ .../.gitignore | 31 ++++++++ .../pom.xml | 69 ++++++++++++++++ .../EmitterMicroServiceApplication.java | 17 ++++ .../rabbitmq/rabbitmq/RabbitMqConfig.java | 25 ++++++ .../repositories/ActivityRepository.java | 9 +++ .../repositories/ActivityTypeRepository.java | 7 ++ .../repositories/AppUserRepository.java | 9 +++ ...ActivityStatCalculationEmitterSerivce.java | 21 +++++ .../services/UserActivityEmitterService.java | 41 ++++++++++ .../src/main/resources/application.yml | 14 ++++ .../src/main/resources/data.sql | 16 ++++ .../src/main/resources/schema.sql | 6 ++ .../user-activity-models/.gitignore | 31 ++++++++ .../user-activity-models/pom.xml | 40 ++++++++++ .../useractivitymodels/ActivityStatElem.java | 38 +++++++++ .../useractivitymodels/ActivityType.java | 22 ++++++ .../example/useractivitymodels/AppUser.java | 25 ++++++ .../useractivitymodels/UserActivity.java | 38 +++++++++ .../.gitignore | 31 ++++++++ .../pom.xml | 79 +++++++++++++++++++ .../ProcessorMicroServiceApplication.java | 17 ++++ .../actuator/ActivityStatEndpoint.java | 23 ++++++ .../example/rabbitmq/config/AppProps.java | 13 +++ .../rabbitmq/rabbitmq/RabbitMqConfig.java | 52 ++++++++++++ .../rabbitmq/rabbitmq/RabbitMqListener.java | 56 +++++++++++++ .../repositories/ActivityRepository.java | 9 +++ .../repositories/ActivityStatRepository.java | 21 +++++ .../UserActivityToEmailTransformer.java | 8 ++ .../UserActivityToEmailTransformerImpl.java | 25 ++++++ .../src/main/resources/application.yml | 40 ++++++++++ .../src/main/resources/data.sql | 16 ++++ .../src/main/resources/schema.sql | 8 ++ 36 files changed, 909 insertions(+) create mode 100644 examples/spring-mail-rabbitmq-demo/README.md create mode 100644 examples/spring-mail-rabbitmq-demo/docker-compose.yml create mode 100644 examples/spring-mail-rabbitmq-demo/pom.xml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/.gitignore create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/pom.xml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/EmitterMicroServiceApplication.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityTypeRepository.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/AppUserRepository.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/ActivityStatCalculationEmitterSerivce.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityEmitterService.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/application.yml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/data.sql create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/schema.sql create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/.gitignore create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/pom.xml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityStatElem.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityType.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/AppUser.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/UserActivity.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/.gitignore create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/pom.xml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/ProcessorMicroServiceApplication.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/actuator/ActivityStatEndpoint.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/config/AppProps.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqListener.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityStatRepository.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformer.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformerImpl.java create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/application.yml create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/data.sql create mode 100644 examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/schema.sql diff --git a/examples/README.md b/examples/README.md index 47719ffe..f967bff1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -11,4 +11,5 @@ * *docker-test-containers* - TestContainers * *spring-cloud-demo-stvort* - Config server, Eureka, Zuul, Feign client * *spring-mail-integration-demo* - SpringMail SpringIntegration +* *spring-mail-rabbitmq-demo* - RabbitMQ * *liquibase-demo* - liquibase diff --git a/examples/spring-mail-rabbitmq-demo/README.md b/examples/spring-mail-rabbitmq-demo/README.md new file mode 100644 index 00000000..6f886513 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/README.md @@ -0,0 +1,28 @@ +## Пример взаимодействия приложений через RabbitMQ + +В примере демонстрируется: +* *использование `@Scheduled` таймера для имитации пользовтельской активности* +* *оправка и прием сообщений между двумя приложениями через RabbitMQ* +* *создание и отправка email сообщений средствами SpringMail* +* *аггрегация данных с помощью SpringData/JPQL* +* *создание кастомного endpoint-а actuator-а для вывода статистики* + +Описание примера: + +user-activity-emitter-microservice: +* *по таймеру `UserActivityEmitterService` достает из БД случайный тип активности и пользователя* +* *после чего формирует из них объект активности (`UserActivity`) и отправляет в очередь сообщений RabbitMQ с помощью `RabbitTemplate` настроенный на работу с "main-exchange"* +* *большее число активностей имеют `routingKey` = "user.activity.message.simple" * +* *активности, у которых в названии типа есть вхождение "Вредн" имееют свой `routingKey` ("user.activity.message.important") * +* *так же приложение по таймеру, с помощью `ActivityStatCalculationEmitterSerivce` инициирует подсчет статистики с помощью отправки сообщения в очередь RabbitMQ c `routingKey` = "user.activity.stat"* + +user-activity-processor-microservice: +* *в приложении для обработки сообщений есть несколько очередей, куда попадают сообщения в зависимости от `routingKey`* +* *их прослушивает компонент `RabbitMqListener`, который содержит по методу на каждую очередь"* +* *в "all-activity-queue" попадают все активности. На выходе из данной очереди активности сохраняются в БД* +* *в "important-activity-queue" попадают важные активности. На выходе из данной очереди активности преобразуются в письма и отправляются на почту администратору* +* *в "stat-calc-commands-queue" попадают команды, которые инициируют рассчет статистики. * +* *в методе-обработчике сообщений данной очереди происходит удаление старых статистических данных, а так же подсчет и сохранение в БД новых* +* *за вывод статистических данных отвечает кастомный endpoint actuator-а `ActivityStatEndpoint`* + +Для работы приложений требуется работающий RabbitMQ. За его запуск отвечает docker-compose.yml. На данный момент приложения настроены для работы с RabbitMQ, поднятым в DockerToolbox. Чтобы это изменить следует задать адрес RabbitMQ в application.yml приложений. \ No newline at end of file diff --git a/examples/spring-mail-rabbitmq-demo/docker-compose.yml b/examples/spring-mail-rabbitmq-demo/docker-compose.yml new file mode 100644 index 00000000..9dbda249 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/docker-compose.yml @@ -0,0 +1,5 @@ +rabbitmq: + image: rabbitmq:management + ports: + - "5672:5672" + - "15672:15672" \ No newline at end of file diff --git a/examples/spring-mail-rabbitmq-demo/pom.xml b/examples/spring-mail-rabbitmq-demo/pom.xml new file mode 100644 index 00000000..ea9fb3d9 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + ru.otus.example + spring-mail-rabbitmq-demo + 1.0 + + pom + + + user-activity-models + user-activity-emiter-microservice + user-activity-processor-microservice + + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/.gitignore b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/.gitignore new file mode 100644 index 00000000..a2a3040a --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/.gitignore @@ -0,0 +1,31 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/pom.xml b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/pom.xml new file mode 100644 index 00000000..e74ee0b1 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + + ru.otus.example + user-activity-emitter-microservice + 0.0.1-SNAPSHOT + user-activity-emitter-microservice + User activity emitter microservice + + + 11 + 11 + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-amqp + + + + ru.otus.example + user-activity-models + 0.0.1-SNAPSHOT + + + + com.h2database + h2 + runtime + + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/EmitterMicroServiceApplication.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/EmitterMicroServiceApplication.java new file mode 100644 index 00000000..24ac6621 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/EmitterMicroServiceApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.rabbitmq; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@EntityScan("ru.otus.example.useractivitymodels") +@SpringBootApplication +public class EmitterMicroServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(EmitterMicroServiceApplication.class, args); + } + +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java new file mode 100644 index 00000000..446ac901 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java @@ -0,0 +1,25 @@ +package ru.otus.example.rabbitmq.rabbitmq; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RabbitMqConfig { + + @Bean + public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { + RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); + rabbitTemplate.setExchange("main-exchange"); + return rabbitTemplate; + } + +/* + @Bean + public TopicExchange topicExchange(){ + return new TopicExchange("main-exchange"); + } +*/ +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java new file mode 100644 index 00000000..ec1a77a6 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java @@ -0,0 +1,9 @@ +package ru.otus.example.rabbitmq.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.useractivitymodels.UserActivity; + +@Transactional +public interface ActivityRepository extends JpaRepository { +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityTypeRepository.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityTypeRepository.java new file mode 100644 index 00000000..b1ab8572 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityTypeRepository.java @@ -0,0 +1,7 @@ +package ru.otus.example.rabbitmq.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.otus.example.useractivitymodels.ActivityType; + +public interface ActivityTypeRepository extends JpaRepository { +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/AppUserRepository.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/AppUserRepository.java new file mode 100644 index 00000000..cb45abc1 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/AppUserRepository.java @@ -0,0 +1,9 @@ +package ru.otus.example.rabbitmq.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.useractivitymodels.AppUser; + +@Transactional +public interface AppUserRepository extends JpaRepository { +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/ActivityStatCalculationEmitterSerivce.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/ActivityStatCalculationEmitterSerivce.java new file mode 100644 index 00000000..6926b280 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/ActivityStatCalculationEmitterSerivce.java @@ -0,0 +1,21 @@ +package ru.otus.example.rabbitmq.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class ActivityStatCalculationEmitterSerivce { + private static final String MAIN_EXCHANGE_NAME = "main-exchange"; + private static final String USER_ACTIVITY_STAT_ROUTING_KEY = "user.activity.stat"; + private static final String CALC_STAT_COMMAND = "{\"command\": \"calc stat now\"}"; + + private final RabbitTemplate rabbitTemplate; + + @Scheduled(initialDelay = 3000, fixedRate = 10000) + public void emitAppUserActivityStatCalculation(){ + rabbitTemplate.convertAndSend(MAIN_EXCHANGE_NAME, USER_ACTIVITY_STAT_ROUTING_KEY, CALC_STAT_COMMAND); + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityEmitterService.java b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityEmitterService.java new file mode 100644 index 00000000..69d4b537 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityEmitterService.java @@ -0,0 +1,41 @@ +package ru.otus.example.rabbitmq.services; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.val; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import ru.otus.example.rabbitmq.repositories.ActivityTypeRepository; +import ru.otus.example.rabbitmq.repositories.AppUserRepository; +import ru.otus.example.useractivitymodels.UserActivity; + +import java.util.Random; + +@RequiredArgsConstructor +@Service +public class UserActivityEmitterService { + private static final String MAIN_EXCHANGE_NAME = "main-exchange"; + + private final ActivityTypeRepository activityTypeRepository; + private final AppUserRepository appUserRepository; + private final RabbitTemplate rabbitTemplate; + private final ObjectMapper objectMapper; + + @SneakyThrows + @Scheduled(initialDelay = 2000, fixedRate = 3000) + public void emitAppUserActivity() { + val random = new Random(); + val activityTypes = activityTypeRepository.findAll(); + val appUsers = appUserRepository.findAll(); + + val activityType = activityTypes.get(random.nextInt(activityTypes.size())); + val appUser = appUsers.get(random.nextInt(appUsers.size())); + val appUserActivity = new UserActivity(activityType, appUser); + val isImportant = activityType.getName().contains("Вредн"); + + val routingKey = String.format("user.activity.message.%s", isImportant? "important": "simple"); + rabbitTemplate.convertAndSend(MAIN_EXCHANGE_NAME, routingKey, objectMapper.writeValueAsString(appUserActivity)); + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/application.yml b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/application.yml new file mode 100644 index 00000000..00e977d8 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/application.yml @@ -0,0 +1,14 @@ +server: + port: 9090 +spring: + datasource: + initialization-mode: always + + jpa: + generate-ddl: false + hibernate: + ddl-auto: none + show-sql: false + + rabbitmq: + addresses: "192.168.99.100" \ No newline at end of file diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/data.sql b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/data.sql new file mode 100644 index 00000000..6ab9b209 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/data.sql @@ -0,0 +1,16 @@ +insert into app_users(name, email) values ('Рафаель Губерманович Тыгыдым', 'test@mail.ru') +insert into app_users(name, email) values ('Артем Демосфенович Шмяк', 'test@mail.ru') +insert into app_users(name, email) values ('Ифигения Бореславовна Фуфелшмерц', 'test@mail.ru') + +insert into activity_types(name) values ('Очень полезное дело №4') +insert into activity_types(name) values ('Очень полезное дело №13') +insert into activity_types(name) values ('Очень полезное дело №34') +insert into activity_types(name) values ('Очень полезное дело №48') +insert into activity_types(name) values ('Очень полезное дело №53') +insert into activity_types(name) values ('Вредное дело №11') +insert into activity_types(name) values ('Вредное дело №12') +insert into activity_types(name) values ('Вредное дело №13') +insert into activity_types(name) values ('Вредное дело №14') +insert into activity_types(name) values ('Вредное дело №15') +insert into activity_types(name) values ('Вредное дело №16') + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/schema.sql b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/schema.sql new file mode 100644 index 00000000..76e96603 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-emitter-microservice/src/main/resources/schema.sql @@ -0,0 +1,6 @@ +create table activity_types (id bigint auto_increment, name varchar(255), primary key (id)) +create table app_users (id bigint auto_increment, email varchar(255), name varchar(255), primary key (id)) + +create table app_users_activity (id bigint auto_increment, activity_time timestamp, app_user_id bigint, activity_type_id bigint, primary key (id)) +alter table app_users_activity add constraint app_users_activity_user_id_fk foreign key (app_user_id) references app_users +alter table app_users_activity add constraint app_users_activity_activity_type_id_fk foreign key (activity_type_id) references activity_types diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/.gitignore b/examples/spring-mail-rabbitmq-demo/user-activity-models/.gitignore new file mode 100644 index 00000000..a2a3040a --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/.gitignore @@ -0,0 +1,31 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/pom.xml b/examples/spring-mail-rabbitmq-demo/user-activity-models/pom.xml new file mode 100644 index 00000000..840cec44 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + ru.otus.example + user-activity-models + 0.0.1-SNAPSHOT + user-activity-models + Models for spring mail rabbitmq demo project + + + 11 + 11 + 11 + + + + + com.fasterxml.jackson.core + jackson-annotations + 2.10.1 + + + + javax.persistence + persistence-api + 1.0.2 + + + + + org.projectlombok + lombok + 1.18.8 + true + + + + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityStatElem.java b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityStatElem.java new file mode 100644 index 00000000..d4949876 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityStatElem.java @@ -0,0 +1,38 @@ +package ru.otus.example.useractivitymodels; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@Entity +@Table(name = "activity_stat") +public class ActivityStatElem { + + @JsonIgnore + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @JsonProperty("Имя пользователя") + @Column(name = "app_user_name") + private String appUserName; + + @JsonProperty("Тип активности") + @Column(name = "activity_type") + private String activityType; + + @JsonProperty("Количество") + @Column(name = "activities_count") + private long activitiesCount; + + public ActivityStatElem(String appUserName, String activityType, long activitiesCount) { + this.appUserName = appUserName; + this.activityType = activityType; + this.activitiesCount = activitiesCount; + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityType.java b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityType.java new file mode 100644 index 00000000..289bb64d --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/ActivityType.java @@ -0,0 +1,22 @@ +package ru.otus.example.useractivitymodels; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "activity_types") +public class ActivityType { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "name") + private String name; +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/AppUser.java b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/AppUser.java new file mode 100644 index 00000000..794421a6 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/AppUser.java @@ -0,0 +1,25 @@ +package ru.otus.example.useractivitymodels; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "app_users") +public class AppUser { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "email") + private String email; + + @Column(name = "name") + private String name; +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/UserActivity.java b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/UserActivity.java new file mode 100644 index 00000000..4992f877 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-models/src/main/java/ru/otus/example/useractivitymodels/UserActivity.java @@ -0,0 +1,38 @@ +package ru.otus.example.useractivitymodels; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "app_users_activity") +public class UserActivity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "activity_time") + private LocalDateTime activityTime; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "activity_type_id") + private ActivityType type; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "app_user_id") + private AppUser appUser; + + public UserActivity(ActivityType type, AppUser appUser) { + this.id = id; + this.type = type; + this.appUser = appUser; + this.activityTime = LocalDateTime.now(); + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/.gitignore b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/.gitignore new file mode 100644 index 00000000..a2a3040a --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/.gitignore @@ -0,0 +1,31 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/** +!**/src/test/** + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ + +### VS Code ### +.vscode/ diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/pom.xml b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/pom.xml new file mode 100644 index 00000000..5645bf88 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + + ru.otus.example + user-activity-processor-microservice + 0.0.1-SNAPSHOT + user-activity-processor-microservice + User activity processor microservice + + + 11 + 11 + 11 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-amqp + + + + org.springframework.boot + spring-boot-starter-mail + + + + ru.otus.example + user-activity-models + 0.0.1-SNAPSHOT + + + + com.h2database + h2 + runtime + + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/ProcessorMicroServiceApplication.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/ProcessorMicroServiceApplication.java new file mode 100644 index 00000000..12b2af42 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/ProcessorMicroServiceApplication.java @@ -0,0 +1,17 @@ +package ru.otus.example.rabbitmq; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@EntityScan("ru.otus.example.useractivitymodels") +@SpringBootApplication +public class ProcessorMicroServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProcessorMicroServiceApplication.class, args); + } + +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/actuator/ActivityStatEndpoint.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/actuator/ActivityStatEndpoint.java new file mode 100644 index 00000000..a6170e07 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/actuator/ActivityStatEndpoint.java @@ -0,0 +1,23 @@ +package ru.otus.example.rabbitmq.actuator; + +import lombok.RequiredArgsConstructor; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.stereotype.Component; +import ru.otus.example.rabbitmq.repositories.ActivityStatRepository; +import ru.otus.example.useractivitymodels.ActivityStatElem; + +import java.util.List; + +@RequiredArgsConstructor +@Component +@Endpoint(id = "activity-stat") +public class ActivityStatEndpoint { + + private final ActivityStatRepository activityStatRepository; + + @ReadOperation + public List getAppUsersActivityStat() { + return activityStatRepository.findAll(); + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/config/AppProps.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/config/AppProps.java new file mode 100644 index 00000000..473d175e --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/config/AppProps.java @@ -0,0 +1,13 @@ +package ru.otus.example.rabbitmq.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties("app") +public class AppProps { + private String serverEmail; + private String adminEmail; +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java new file mode 100644 index 00000000..014313dc --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqConfig.java @@ -0,0 +1,52 @@ +package ru.otus.example.rabbitmq.rabbitmq; + +import org.springframework.amqp.core.*; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RabbitMqConfig { + + @Bean + public Queue allActivityQueue() { + return new Queue("all-activity-queue"); + } + + @Bean + public Queue importantActivityQueue() { + return new Queue("important-activity-queue"); + } + + @Bean + public Queue statCalcCommandsQueue() { + return new Queue("stat-calc-commands-queue"); + } + + @Bean + public TopicExchange topicExchange(){ + return new TopicExchange("main-exchange"); + } + + @Bean + public Binding allActivityBinding(){ + return BindingBuilder.bind(allActivityQueue()) + .to(topicExchange()) + .with("user.activity.message.*"); + } + + @Bean + public Binding importantActivityBinding(){ + return BindingBuilder.bind(importantActivityQueue()) + .to(topicExchange()) + .with("user.activity.message.important"); + } + + @Bean + public Binding statCalcCommandsBinding(){ + return BindingBuilder.bind(statCalcCommandsQueue()) + .to(topicExchange()) + .with("user.activity.stat"); + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqListener.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqListener.java new file mode 100644 index 00000000..4e390d31 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/rabbitmq/RabbitMqListener.java @@ -0,0 +1,56 @@ +package ru.otus.example.rabbitmq.rabbitmq; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; +import ru.otus.example.rabbitmq.repositories.ActivityRepository; +import ru.otus.example.rabbitmq.repositories.ActivityStatRepository; +import ru.otus.example.rabbitmq.services.UserActivityToEmailTransformer; +import ru.otus.example.useractivitymodels.UserActivity; + +@RequiredArgsConstructor +@Service +public class RabbitMqListener { + + private final ActivityRepository activityRepository; + private final ActivityStatRepository activityStatRepository; + private final UserActivityToEmailTransformer messageTransformer; + private final JavaMailSender mailSender; + private final ObjectMapper objectMapper; + + @RabbitListener(queues = "important-activity-queue") + public void processImportantMessages(String message) throws JsonProcessingException { + System.out.println("RECEIVED FROM important-activity-queue: " + message); + + val userActivity = objectMapper.readValue(message, UserActivity.class); + val mailMessage = messageTransformer.transform(userActivity); + //System.out.println("Как будто посылаем письмо: " + mailMessage); + //mailSender.send(mailMessage); + } + + @RabbitListener(queues = "all-activity-queue") + public void processAllMessages(String message) throws JsonProcessingException { + System.out.println("RECEIVED FROM all-activity-queue: " + message); + + try { + val userActivity = objectMapper.readValue(message, UserActivity.class); + activityRepository.save(userActivity); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @RabbitListener(queues = "stat-calc-commands-queue") + public void processStatCalcCommandsMessages(String message) { + //System.out.println("RECEIVED FROM stat-calc-commands-queue: " + message); + + activityStatRepository.deleteAll(); + val activityStat = activityStatRepository.calcActivityStat(); + activityStatRepository.saveAll(activityStat); + + } +} \ No newline at end of file diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java new file mode 100644 index 00000000..ec1a77a6 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityRepository.java @@ -0,0 +1,9 @@ +package ru.otus.example.rabbitmq.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.useractivitymodels.UserActivity; + +@Transactional +public interface ActivityRepository extends JpaRepository { +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityStatRepository.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityStatRepository.java new file mode 100644 index 00000000..cde54ceb --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/repositories/ActivityStatRepository.java @@ -0,0 +1,21 @@ +package ru.otus.example.rabbitmq.repositories; + + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.example.useractivitymodels.ActivityStatElem; + +import java.util.List; + +@Transactional +public interface ActivityStatRepository extends JpaRepository { + + @Transactional(readOnly = true) + @Query("select new ru.otus.example.useractivitymodels.ActivityStatElem(u.name, t.name, count(a)) " + + "from UserActivity a left join a.appUser u left join a.type t " + + "group by u.name, t.name " + + "order by count(a) desc, u.name, t.name") + List calcActivityStat(); + +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformer.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformer.java new file mode 100644 index 00000000..8a61b36f --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformer.java @@ -0,0 +1,8 @@ +package ru.otus.example.rabbitmq.services; + +import org.springframework.mail.SimpleMailMessage; +import ru.otus.example.useractivitymodels.UserActivity; + +public interface UserActivityToEmailTransformer { + SimpleMailMessage transform(UserActivity activity); +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformerImpl.java b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformerImpl.java new file mode 100644 index 00000000..d5dc0c08 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/java/ru/otus/example/rabbitmq/services/UserActivityToEmailTransformerImpl.java @@ -0,0 +1,25 @@ +package ru.otus.example.rabbitmq.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.stereotype.Service; +import ru.otus.example.rabbitmq.config.AppProps; +import ru.otus.example.useractivitymodels.UserActivity; + +@RequiredArgsConstructor +@Service +public class UserActivityToEmailTransformerImpl implements UserActivityToEmailTransformer { + + private final AppProps appProps; + + @Override + public SimpleMailMessage transform(UserActivity activity) { + SimpleMailMessage mailMessage = new SimpleMailMessage(); + mailMessage.setTo(appProps.getAdminEmail()); + mailMessage.setFrom(appProps.getServerEmail()); + mailMessage.setSubject("Обнаружена вредная активность"); + mailMessage.setText(String.format("Внимание!!! Обнаружена вредная активность! Время: %s, пользователь: %s, тип активности: %s", + activity.getActivityTime(), activity.getAppUser().getName(), activity.getType().getName())); + return mailMessage; + } +} diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/application.yml b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/application.yml new file mode 100644 index 00000000..5f611b88 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/application.yml @@ -0,0 +1,40 @@ +app: + # адрес почты, через которую сервер отправляет письма + server-email: ${server.email} + # адрес почты администратора, на которую сервер отправляет письма + admin-email: ${admin.email} + +spring: + datasource: + initialization-mode: always + + jpa: + generate-ddl: false + hibernate: + ddl-auto: none + show-sql: true + + rabbitmq: + addresses: "192.168.99.100" + + mail: + host: smtp.mail.ru + port: 465 + # логин и пароль для почты, через которую сервер отправляет письма + username: ${email.server.user} + password: ${email.server.password} + protocol: smtps + properties: + mail: + smtp: + auth: true + starttls.enable: true + +management: + endpoints: + web: + exposure: + include: health, info, activity-stat + endpoint: + health: + show-details: always \ No newline at end of file diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/data.sql b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/data.sql new file mode 100644 index 00000000..6ab9b209 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/data.sql @@ -0,0 +1,16 @@ +insert into app_users(name, email) values ('Рафаель Губерманович Тыгыдым', 'test@mail.ru') +insert into app_users(name, email) values ('Артем Демосфенович Шмяк', 'test@mail.ru') +insert into app_users(name, email) values ('Ифигения Бореславовна Фуфелшмерц', 'test@mail.ru') + +insert into activity_types(name) values ('Очень полезное дело №4') +insert into activity_types(name) values ('Очень полезное дело №13') +insert into activity_types(name) values ('Очень полезное дело №34') +insert into activity_types(name) values ('Очень полезное дело №48') +insert into activity_types(name) values ('Очень полезное дело №53') +insert into activity_types(name) values ('Вредное дело №11') +insert into activity_types(name) values ('Вредное дело №12') +insert into activity_types(name) values ('Вредное дело №13') +insert into activity_types(name) values ('Вредное дело №14') +insert into activity_types(name) values ('Вредное дело №15') +insert into activity_types(name) values ('Вредное дело №16') + diff --git a/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/schema.sql b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/schema.sql new file mode 100644 index 00000000..c0f9ebe8 --- /dev/null +++ b/examples/spring-mail-rabbitmq-demo/user-activity-processor-microservice/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +create table activity_types (id bigint auto_increment, name varchar(255), primary key (id)) +create table app_users (id bigint auto_increment, email varchar(255), name varchar(255), primary key (id)) + +create table app_users_activity (id bigint auto_increment, activity_time timestamp, app_user_id bigint, activity_type_id bigint, primary key (id)) +alter table app_users_activity add constraint app_users_activity_user_id_fk foreign key (app_user_id) references app_users +alter table app_users_activity add constraint app_users_activity_activity_type_id_fk foreign key (activity_type_id) references activity_types + +create table activity_stat (id bigint auto_increment, app_user_name varchar(255), activity_type varchar(255), activities_count bigint, primary key (id))