Implemented user event listeners
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -96,6 +96,11 @@
|
|||||||
<artifactId>spring-boot-starter-webmvc-test</artifactId>
|
<artifactId>spring-boot-starter-webmvc-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-core</artifactId>
|
||||||
|
<version>5.8.43</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package dev.mednikov.social.connections.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class JdbcTemplateConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
|
||||||
|
return new NamedParameterJdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package dev.mednikov.social.connections.config;
|
package dev.mednikov.social.connections.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -10,6 +12,7 @@ public class ObjectMapperConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public ObjectMapper objectMapper() {
|
public ObjectMapper objectMapper() {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||||
return objectMapper;
|
return objectMapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package dev.mednikov.social.connections.messaging;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import dev.mednikov.social.connections.models.User;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserCreatedListener {
|
||||||
|
|
||||||
|
private final static UserParamsMapper userParamsMapper = new UserParamsMapper();
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(UserCreatedListener.class);
|
||||||
|
|
||||||
|
private final NamedParameterJdbcTemplate jdbcTemplate;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public UserCreatedListener(NamedParameterJdbcTemplate jdbcTemplate, ObjectMapper objectMapper) {
|
||||||
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@RabbitListener(queues = {"social_users_created"})
|
||||||
|
public void onEvent (String payload) {
|
||||||
|
logger.info("User created" + payload);
|
||||||
|
try {
|
||||||
|
UserPayload user = this.objectMapper.readValue(payload, UserPayload.class);
|
||||||
|
String query = """
|
||||||
|
INSERT INTO connections_user (
|
||||||
|
id,
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
email,
|
||||||
|
is_active,
|
||||||
|
is_onboarded,
|
||||||
|
is_email_verified,
|
||||||
|
avatar_url,
|
||||||
|
headline,
|
||||||
|
version
|
||||||
|
) VALUES (
|
||||||
|
:id,
|
||||||
|
:first_name,
|
||||||
|
:last_name,
|
||||||
|
:email,
|
||||||
|
:is_active,
|
||||||
|
:is_onboarded,
|
||||||
|
:is_email_verified,
|
||||||
|
:avatar_url,
|
||||||
|
:headline,
|
||||||
|
:version) ON CONFLICT (id) DO NOTHING
|
||||||
|
""";
|
||||||
|
MapSqlParameterSource sqlParameterSource = userParamsMapper.apply(user);
|
||||||
|
jdbcTemplate.update(query, sqlParameterSource);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package dev.mednikov.social.connections.messaging;
|
||||||
|
|
||||||
|
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
final class UserParamsMapper implements Function<UserPayload, MapSqlParameterSource> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapSqlParameterSource apply(UserPayload user) {
|
||||||
|
MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
|
||||||
|
sqlParameterSource.addValue("id", Long.valueOf(user.getId()));
|
||||||
|
sqlParameterSource.addValue("first_name", user.getFirstName());
|
||||||
|
sqlParameterSource.addValue("last_name", user.getLastName());
|
||||||
|
sqlParameterSource.addValue("email", user.getEmail());
|
||||||
|
sqlParameterSource.addValue("is_active", user.isActive());
|
||||||
|
sqlParameterSource.addValue("is_onboarded", user.isOnboarded());
|
||||||
|
sqlParameterSource.addValue("is_email_verified", user.isEmailVerified());
|
||||||
|
sqlParameterSource.addValue("avatar_url", user.getAvatarUrl());
|
||||||
|
sqlParameterSource.addValue("headline", user.getHeadline());
|
||||||
|
sqlParameterSource.addValue("version", user.getVersion());
|
||||||
|
return sqlParameterSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package dev.mednikov.social.connections.messaging;
|
||||||
|
|
||||||
|
import dev.mednikov.social.connections.models.User;
|
||||||
|
|
||||||
|
final class UserPayload {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String email;
|
||||||
|
private String avatarUrl;
|
||||||
|
private boolean emailVerified;
|
||||||
|
private boolean active;
|
||||||
|
private boolean onboarded;
|
||||||
|
private String headline;
|
||||||
|
private Long version;
|
||||||
|
|
||||||
|
UserPayload() {}
|
||||||
|
|
||||||
|
UserPayload(User user) {
|
||||||
|
this.id = user.getId().toString();
|
||||||
|
this.firstName = user.getFirstName();
|
||||||
|
this.lastName = user.getLastName();
|
||||||
|
this.email = user.getEmail();
|
||||||
|
this.avatarUrl = user.getAvatarUrl();
|
||||||
|
this.emailVerified = user.getEmailVerified();
|
||||||
|
this.active = user.getActive();
|
||||||
|
this.onboarded = user.getOnboarded();
|
||||||
|
this.headline = user.getHeadline();
|
||||||
|
this.version = user.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getAvatarUrl() {
|
||||||
|
return avatarUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isEmailVerified() {
|
||||||
|
return emailVerified;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isOnboarded() {
|
||||||
|
return onboarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getHeadline() {
|
||||||
|
return headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatarUrl(String avatarUrl) {
|
||||||
|
this.avatarUrl = avatarUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailVerified(boolean emailVerified) {
|
||||||
|
this.emailVerified = emailVerified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnboarded(boolean onboarded) {
|
||||||
|
this.onboarded = onboarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadline(String headline) {
|
||||||
|
this.headline = headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(Long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package dev.mednikov.social.connections.messaging;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import dev.mednikov.social.connections.models.User;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserUpdatedListener {
|
||||||
|
|
||||||
|
private final static UserParamsMapper userParamsMapper = new UserParamsMapper();
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(UserUpdatedListener.class);
|
||||||
|
|
||||||
|
private final NamedParameterJdbcTemplate jdbcTemplate;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public UserUpdatedListener(NamedParameterJdbcTemplate jdbcTemplate, ObjectMapper objectMapper) {
|
||||||
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@RabbitListener(queues = {"social_users_updated"})
|
||||||
|
public void onEvent (String payload){
|
||||||
|
logger.info("User updated" + payload);
|
||||||
|
try {
|
||||||
|
UserPayload user = this.objectMapper.readValue(payload, UserPayload.class);
|
||||||
|
String query = """
|
||||||
|
UPDATE connections_user
|
||||||
|
SET first_name = :first_name,
|
||||||
|
last_name = :last_name,
|
||||||
|
email = :email,
|
||||||
|
is_active = :is_active,
|
||||||
|
is_email_verified = :is_email_verified,
|
||||||
|
is_onboarded = :is_onboarded,
|
||||||
|
avatar_url = :avatar_url,
|
||||||
|
headline = :headline,
|
||||||
|
version = :version
|
||||||
|
WHERE id = :id
|
||||||
|
""";
|
||||||
|
MapSqlParameterSource sqlParameterSource = userParamsMapper.apply(user);
|
||||||
|
jdbcTemplate.update(query, sqlParameterSource);
|
||||||
|
} catch (Exception ex){
|
||||||
|
logger.error(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/main/java/dev/mednikov/social/connections/models/User.java
Normal file
117
src/main/java/dev/mednikov/social/connections/models/User.java
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package dev.mednikov.social.connections.models;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "connections_user")
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id private Long id;
|
||||||
|
@Column(nullable = false, name = "email") private String email;
|
||||||
|
@Column(nullable = false, name = "first_name") private String firstName;
|
||||||
|
@Column(nullable = false, name = "last_name") private String lastName;
|
||||||
|
@Column(nullable = false, name = "avatar_url") private String avatarUrl;
|
||||||
|
@Column(nullable = false, name = "headline") private String headline;
|
||||||
|
@Column(nullable = false, name = "is_active") private Boolean active;
|
||||||
|
@Column(nullable = false, name = "is_email_verified") private Boolean emailVerified;
|
||||||
|
@Column(nullable = false, name = "is_onboarded") private Boolean onboarded;
|
||||||
|
@Column(nullable = false, name = "version") private Long version;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object o) {
|
||||||
|
if (!(o instanceof User user)) return false;
|
||||||
|
|
||||||
|
return id.equals(user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(Long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getOnboarded() {
|
||||||
|
return onboarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnboarded(Boolean onboarded) {
|
||||||
|
this.onboarded = onboarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEmailVerified() {
|
||||||
|
return emailVerified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailVerified(Boolean emailVerified) {
|
||||||
|
this.emailVerified = emailVerified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvatarUrl() {
|
||||||
|
return avatarUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatarUrl(String avatarUrl) {
|
||||||
|
this.avatarUrl = avatarUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeadline() {
|
||||||
|
return headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadline(String headline) {
|
||||||
|
this.headline = headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(Boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.mednikov.social.connections.repositories;
|
||||||
|
|
||||||
|
public interface IdentifierGenerator {
|
||||||
|
|
||||||
|
Long getNextId();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package dev.mednikov.social.connections.repositories;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.generator.SnowflakeGenerator;
|
||||||
|
|
||||||
|
public class IdentifierGeneratorImpl implements IdentifierGenerator {
|
||||||
|
|
||||||
|
private final SnowflakeGenerator snowflakeGenerator;
|
||||||
|
|
||||||
|
public IdentifierGeneratorImpl() {
|
||||||
|
this.snowflakeGenerator = new SnowflakeGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getNextId() {
|
||||||
|
return this.snowflakeGenerator.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package dev.mednikov.social.connections.repositories;
|
||||||
|
|
||||||
|
import dev.mednikov.social.connections.models.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
|
||||||
|
}
|
||||||
12
src/main/resources/db/migration/V1__initial.sql
Normal file
12
src/main/resources/db/migration/V1__initial.sql
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS connections_user (
|
||||||
|
id BIGINT PRIMARY KEY,
|
||||||
|
first_name VARCHAR(255) NOT NULL,
|
||||||
|
last_name VARCHAR(255) NOT NULL,
|
||||||
|
email VARCHAR(255) NOT NULL,
|
||||||
|
avatar_url VARCHAR(255) NOT NULL,
|
||||||
|
is_active BOOLEAN NOT NULL,
|
||||||
|
is_onboarded BOOLEAN NOT NULL,
|
||||||
|
is_email_verified BOOLEAN NOT NULL,
|
||||||
|
headline VARCHAR(255) NOT NULL,
|
||||||
|
version BIGINT NOT NULL
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user