mirror of
https://github.com/OtusTeam/Spring.git
synced 2026-05-30 10:50:42 +00:00
spring-mail-integration-demo example gas been added
This commit is contained in:
@@ -8,3 +8,4 @@
|
||||
* *mongo-db-demo* - демонстрация подходов к хранению вложенных сущностенй в MongoDB, работы с MongoEventListener, агрегациями и инструментом миграций Mongock
|
||||
* *docker-test-containers* - пример настройки TestContainers для монги
|
||||
* *spring-cloud-demo-stvort* - пример работы двух микросевисов с использованием Config server, Eureka, Zuul, Feign client
|
||||
* *spring-mail-integration-demo* - пример работы с SpringMail через SpringIntegration
|
||||
@@ -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/
|
||||
@@ -0,0 +1,17 @@
|
||||
## Пример работы с SpringMail через SpringIntegration
|
||||
|
||||
В примере демонстрируется:
|
||||
* *использование `@Scheduled` таймера для имитации пользовтельской активности*
|
||||
* *обработка доменных сущностей средствами SpringIntegration (`@MessagingGateway`, `IntegrationFlow`) с использованием `route` и `subFlowMapping`*
|
||||
* *создание и отправка email сообщений средствами SpringMail*
|
||||
* *аггрегация данных с помощью SpringData/JPQL*
|
||||
* *создание кастомного endpoint-а actuator-а для вывода статистики*
|
||||
|
||||
Описание примера:
|
||||
* *по таймеру `UserActivityEmitterService` достает из БД случайный тип активности и пользователя*
|
||||
* *после чего формирует из них объект активности (`UserActivity`) и отправляет в поток обработки с помощью `UserActivityGateway`. Активности,*
|
||||
* *активности, у которых в названии типа есть вхождение "Вредн" помечаются, как важные соответствующим заголовком отправляемого сообщения*
|
||||
* *в потоке обработки (`appUserActivityFlow`) объект активности сохраняется в БД, а важные сообщения преобразуются в письма и отправляются на почту администратору*
|
||||
* *по таймеру `ActivityStatCalculationEmitterSerivce` инициирует подсчет статистики с помощью отправки сообщения в `activityStatFlow` через `ActivityStatGateway`*
|
||||
* *в данном потоке происходит удаление старых статистических данных, а так же подсчет и сохранение в БД новых*
|
||||
* *за вывод статистических данных отвечает кастомный endpoint actuator-а `ActivityStatEndpoint`*
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.9.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>ru.otus.example</groupId>
|
||||
<artifactId>spring-mail-integration-demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-integration-mail-demo</name>
|
||||
<description>Spring mail integration demo project</description>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-integration</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package ru.otus.example.springmail_integration_demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
public class SpringMailIntegrationDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringMailIntegrationDemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package ru.otus.example.springmail_integration_demo.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.springmail_integration_demo.models.ActivityStatElem;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.ActivityStatRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Endpoint(id = "activity-stat")
|
||||
public class ActivityStatEndpoint {
|
||||
|
||||
private final ActivityStatRepository activityStatRepository;
|
||||
|
||||
@ReadOperation
|
||||
public List<ActivityStatElem> getAppUsersActivityStat() {
|
||||
return activityStatRepository.findAll();
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package ru.otus.example.springmail_integration_demo.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;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package ru.otus.example.springmail_integration_demo.integration;
|
||||
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
@MessagingGateway
|
||||
public interface ActivityStatGateway {
|
||||
|
||||
@Gateway(requestChannel = "activityStatInChanel")
|
||||
void calcActivityStat(@Payload String extInfo);
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package ru.otus.example.springmail_integration_demo.integration;
|
||||
|
||||
import lombok.val;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.annotation.IntegrationComponentScan;
|
||||
import org.springframework.integration.dsl.IntegrationFlow;
|
||||
import org.springframework.integration.dsl.IntegrationFlowDefinition;
|
||||
import org.springframework.integration.dsl.MessageChannels;
|
||||
import org.springframework.integration.dsl.Pollers;
|
||||
import org.springframework.integration.scheduling.PollerMetadata;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.ActivityRepository;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.ActivityStatRepository;
|
||||
import ru.otus.example.springmail_integration_demo.services.UserActivityToEmailTransformer;
|
||||
|
||||
|
||||
@Configuration
|
||||
@IntegrationComponentScan
|
||||
public class IntegrationConfig {
|
||||
private static final int DEFAULT_QUEUE_CAPACITY = 100;
|
||||
private static final int DEFAULT_POLLER_PERIOD = 1000;
|
||||
|
||||
private static final String IS_IMPORTANT_MESSAGE = "isImportant";
|
||||
private static final String SAVE_METHOD_NAME = "save";
|
||||
private static final String TRANSFORM_METHOD_NAME = "transform";
|
||||
private static final String CALC_ACTIVITY_STAT_METHOD_NAME = "calcActivityStat";
|
||||
private static final String SAVE_ALL_METHOD_NAME = "saveAll";
|
||||
private static final String DELETE_ALL_METHOD_NAME = "deleteAll";
|
||||
|
||||
@Autowired
|
||||
private ActivityRepository activityRepository;
|
||||
|
||||
@Autowired
|
||||
private ActivityStatRepository activityStatRepository;
|
||||
|
||||
@Autowired
|
||||
private UserActivityToEmailTransformer messageTransformer;
|
||||
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@Bean
|
||||
public PollableChannel appUserActivityInChanel() {
|
||||
return MessageChannels.queue("appUserActivityInChanel", DEFAULT_QUEUE_CAPACITY).get();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PollableChannel activityStatInChanel() {
|
||||
return MessageChannels.queue("activityStatInChanel", DEFAULT_QUEUE_CAPACITY).get();
|
||||
}
|
||||
|
||||
@Bean(name = PollerMetadata.DEFAULT_POLLER)
|
||||
public PollerMetadata poller() {
|
||||
return Pollers.fixedRate(DEFAULT_POLLER_PERIOD).get();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow appUserActivityFlow() {
|
||||
return f -> f.channel(appUserActivityInChanel())
|
||||
.handle(activityRepository, SAVE_METHOD_NAME)
|
||||
.route(Message.class, m -> m.getHeaders().get(IS_IMPORTANT_MESSAGE, Boolean.class)
|
||||
, mapping -> mapping.subFlowMapping(true, sub -> sub
|
||||
.transform(messageTransformer, TRANSFORM_METHOD_NAME)
|
||||
.handle(m -> {
|
||||
val isImportant = m.getHeaders().get(IS_IMPORTANT_MESSAGE, Boolean.class);
|
||||
if (isImportant != null && isImportant) {
|
||||
mailSender.send((SimpleMailMessage) m.getPayload());
|
||||
}
|
||||
})
|
||||
)
|
||||
.subFlowMapping(false, IntegrationFlowDefinition::nullChannel)
|
||||
);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow activityStatFlow() {
|
||||
return f -> f.channel(activityStatInChanel())
|
||||
.handle((m, h) -> {
|
||||
activityStatRepository.deleteAll();
|
||||
return true;
|
||||
})
|
||||
.handle(activityStatRepository, CALC_ACTIVITY_STAT_METHOD_NAME)
|
||||
.handle(activityStatRepository, SAVE_ALL_METHOD_NAME)
|
||||
.log();
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package ru.otus.example.springmail_integration_demo.integration;
|
||||
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.MessagingGateway;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import ru.otus.example.springmail_integration_demo.models.UserActivity;
|
||||
|
||||
@MessagingGateway
|
||||
public interface UserActivityGateway {
|
||||
|
||||
@Gateway(requestChannel = "appUserActivityInChanel")
|
||||
void processActivity(@Payload UserActivity activity, @Header(name = "isImportant") boolean isImportant);
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package ru.otus.example.springmail_integration_demo.models;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package ru.otus.example.springmail_integration_demo.models;
|
||||
|
||||
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;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package ru.otus.example.springmail_integration_demo.models;
|
||||
|
||||
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;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package ru.otus.example.springmail_integration_demo.models;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.springmail_integration_demo.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import ru.otus.example.springmail_integration_demo.models.UserActivity;
|
||||
|
||||
@Transactional
|
||||
public interface ActivityRepository extends JpaRepository<UserActivity, Long> {
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package ru.otus.example.springmail_integration_demo.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.springmail_integration_demo.models.ActivityStatElem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Transactional
|
||||
public interface ActivityStatRepository extends JpaRepository<ActivityStatElem, Long> {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Query("select new ru.otus.example.springmail_integration_demo.models.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<ActivityStatElem> calcActivityStat();
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ru.otus.example.springmail_integration_demo.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import ru.otus.example.springmail_integration_demo.models.ActivityType;
|
||||
|
||||
public interface ActivityTypeRepository extends JpaRepository<ActivityType, Long> {
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.springmail_integration_demo.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import ru.otus.example.springmail_integration_demo.models.AppUser;
|
||||
|
||||
@Transactional
|
||||
public interface AppUserRepository extends JpaRepository<AppUser, Long> {
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package ru.otus.example.springmail_integration_demo.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.otus.example.springmail_integration_demo.integration.ActivityStatGateway;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.ActivityTypeRepository;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.AppUserRepository;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class ActivityStatCalculationEmitterSerivce {
|
||||
private static final String EMPTY_EXT_INFO = "none";
|
||||
|
||||
private final ActivityTypeRepository activityTypeRepository;
|
||||
private final AppUserRepository appUserRepository;
|
||||
private final ActivityStatGateway activityStatGateway;
|
||||
|
||||
@Scheduled(initialDelay = 3000, fixedRate = 10000)
|
||||
public void emitAppUserActivityStatCalculation(){
|
||||
activityStatGateway.calcActivityStat(EMPTY_EXT_INFO);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package ru.otus.example.springmail_integration_demo.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.otus.example.springmail_integration_demo.integration.UserActivityGateway;
|
||||
import ru.otus.example.springmail_integration_demo.models.UserActivity;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.ActivityTypeRepository;
|
||||
import ru.otus.example.springmail_integration_demo.repositories.AppUserRepository;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class UserActivityEmitterService {
|
||||
private final ActivityTypeRepository activityTypeRepository;
|
||||
private final AppUserRepository appUserRepository;
|
||||
private final UserActivityGateway userActivityGateway;
|
||||
|
||||
@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);
|
||||
userActivityGateway.processActivity(appUserActivity, activityType.getName().contains("Вредн"));
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package ru.otus.example.springmail_integration_demo.services;
|
||||
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import ru.otus.example.springmail_integration_demo.models.UserActivity;
|
||||
|
||||
public interface UserActivityToEmailTransformer {
|
||||
SimpleMailMessage transform(UserActivity activity);
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package ru.otus.example.springmail_integration_demo.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.otus.example.springmail_integration_demo.config.AppProps;
|
||||
import ru.otus.example.springmail_integration_demo.models.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
app:
|
||||
admin-email: ${admin.email}
|
||||
server-email: ${admin.email}
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
initialization-mode: always
|
||||
|
||||
jpa:
|
||||
generate-ddl: false
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
show-sql: true
|
||||
|
||||
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
|
||||
@@ -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')
|
||||
|
||||
@@ -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))
|
||||
Reference in New Issue
Block a user