Connected to Event Collector

This commit is contained in:
2026-01-11 13:33:53 +01:00
parent b18e21d4c7
commit 82af52f15a
5 changed files with 156 additions and 3 deletions

View File

@@ -0,0 +1,19 @@
package dev.mednikov.social.connections.events;
import dev.mednikov.social.connections.models.Follower;
import org.springframework.context.ApplicationEvent;
public final class FollowerCreatedEvent extends ApplicationEvent {
private final Follower follower;
public FollowerCreatedEvent(Object source, Follower follower) {
super(source);
this.follower = follower;
}
public Follower getFollower() {
return follower;
}
}

View File

@@ -0,0 +1,23 @@
package dev.mednikov.social.connections.events;
import org.springframework.context.ApplicationEvent;
public final class FollowerDeletedEvent extends ApplicationEvent {
private final Long followerUserId;
private final Long followedUserId;
public FollowerDeletedEvent(Object source, Long followerUserId, Long followedUserId) {
super(source);
this.followerUserId = followerUserId;
this.followedUserId = followedUserId;
}
public Long getFollowerUserId() {
return followerUserId;
}
public Long getFollowedUserId() {
return followedUserId;
}
}

View File

@@ -0,0 +1,42 @@
package dev.mednikov.social.connections.messaging;
import java.time.LocalDateTime;
final class AnalyticsEvent {
private String userId;
private String eventType;
private String timestamp;
AnalyticsEvent (){}
AnalyticsEvent(Long userId, String eventType){
this.userId = userId.toString();
this.eventType = eventType;
this.timestamp = LocalDateTime.now().toString();
}
String getUserId() {
return userId;
}
void setUserId(String userId) {
this.userId = userId;
}
String getEventType() {
return eventType;
}
void setEventType(String eventType) {
this.eventType = eventType;
}
String getTimestamp() {
return timestamp;
}
void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}

View File

@@ -0,0 +1,54 @@
package dev.mednikov.social.connections.messaging;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.mednikov.social.connections.events.FollowerCreatedEvent;
import dev.mednikov.social.connections.events.FollowerDeletedEvent;
import dev.mednikov.social.connections.models.Follower;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class MessageService {
private final static Logger logger = LoggerFactory.getLogger(MessageService.class);
private final ObjectMapper objectMapper;
private final RabbitTemplate rabbitTemplate;
public MessageService(ObjectMapper objectMapper, RabbitTemplate rabbitTemplate) {
this.objectMapper = objectMapper;
this.rabbitTemplate = rabbitTemplate;
}
@EventListener
@Async
public void onFollowerCreatedEventListener(FollowerCreatedEvent event) {
Follower follower = event.getFollower();
Long userId = follower.getOwner().getId();
AnalyticsEvent analyticsEvent = new AnalyticsEvent(userId, "followers_created");
try {
String payload = this.objectMapper.writeValueAsString(analyticsEvent);
this.rabbitTemplate.convertAndSend("", "social_events", payload);
logger.info("Event collector: follower created event sent");
} catch (Exception ex){
logger.error(ex.getMessage());
}
}
@EventListener
@Async
public void onFollowerDeletedEventListener(FollowerDeletedEvent event) {
AnalyticsEvent analyticsEvent = new AnalyticsEvent(event.getFollowerUserId(), "followers_deleted");
try {
String payload = this.objectMapper.writeValueAsString(analyticsEvent);
this.rabbitTemplate.convertAndSend("", "social_events", payload);
logger.info("Event collector: follower deleted event sent");
} catch (Exception ex){
logger.error(ex.getMessage());
}
}
}

View File

@@ -3,6 +3,8 @@ package dev.mednikov.social.connections.services;
import dev.mednikov.social.connections.domain.CreateFollowerRequestDto; import dev.mednikov.social.connections.domain.CreateFollowerRequestDto;
import dev.mednikov.social.connections.domain.FollowerDto; import dev.mednikov.social.connections.domain.FollowerDto;
import dev.mednikov.social.connections.domain.FollowerDtoMapper; import dev.mednikov.social.connections.domain.FollowerDtoMapper;
import dev.mednikov.social.connections.events.FollowerCreatedEvent;
import dev.mednikov.social.connections.events.FollowerDeletedEvent;
import dev.mednikov.social.connections.exceptions.FollowerAlreadyExistsException; import dev.mednikov.social.connections.exceptions.FollowerAlreadyExistsException;
import dev.mednikov.social.connections.exceptions.UserDoesNotExistException; import dev.mednikov.social.connections.exceptions.UserDoesNotExistException;
import dev.mednikov.social.connections.models.Follower; import dev.mednikov.social.connections.models.Follower;
@@ -10,6 +12,7 @@ import dev.mednikov.social.connections.models.User;
import dev.mednikov.social.connections.repositories.FollowerRepository; import dev.mednikov.social.connections.repositories.FollowerRepository;
import dev.mednikov.social.connections.repositories.IdentifierGenerator; import dev.mednikov.social.connections.repositories.IdentifierGenerator;
import dev.mednikov.social.connections.repositories.UserRepository; import dev.mednikov.social.connections.repositories.UserRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Optional; import java.util.Optional;
@@ -22,14 +25,17 @@ public class FollowerServiceImpl implements FollowerService {
private final FollowerRepository followerRepository; private final FollowerRepository followerRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
private final IdentifierGenerator identifierGenerator; private final IdentifierGenerator identifierGenerator;
private final ApplicationEventPublisher eventPublisher;
public FollowerServiceImpl( public FollowerServiceImpl(
FollowerRepository followerRepository, FollowerRepository followerRepository,
UserRepository userRepository, UserRepository userRepository,
IdentifierGenerator identifierGenerator) { IdentifierGenerator identifierGenerator,
ApplicationEventPublisher eventPublisher) {
this.followerRepository = followerRepository; this.followerRepository = followerRepository;
this.userRepository = userRepository; this.userRepository = userRepository;
this.identifierGenerator = identifierGenerator; this.identifierGenerator = identifierGenerator;
this.eventPublisher = eventPublisher;
} }
@Override @Override
@@ -61,13 +67,22 @@ public class FollowerServiceImpl implements FollowerService {
follower.setId(this.identifierGenerator.getNextId()); follower.setId(this.identifierGenerator.getNextId());
Follower savedFollower = this.followerRepository.save(follower); Follower savedFollower = this.followerRepository.save(follower);
FollowerCreatedEvent event = new FollowerCreatedEvent(this, savedFollower);
this.eventPublisher.publishEvent(event);
return mapper.apply(savedFollower); return mapper.apply(savedFollower);
} }
@Override @Override
public void deleteFollower(Long id) { public void deleteFollower(Long id) {
Optional<Follower> result = this.followerRepository.findById(id);
if (result.isPresent()) {
Follower follower = result.get();
Long followerUserId = follower.getOwner().getId();
Long followedUserId = follower.getFollowedUser().getId();
FollowerDeletedEvent event = new FollowerDeletedEvent(this, followerUserId, followedUserId);
this.eventPublisher.publishEvent(event);
this.followerRepository.deleteById(id); this.followerRepository.deleteById(id);
} }
}
} }