Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#754 delete with outbox #758

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;

import hanglog.expense.domain.repository.ExpenseRepository;
import hanglog.login.domain.repository.RefreshTokenRepository;
import hanglog.member.domain.MemberDeleteEvent;
import hanglog.outbox.domain.repository.OutBoxRepository;
import hanglog.trip.domain.TripDeleteEvent;
import hanglog.trip.domain.repository.CustomDayLogRepository;
import hanglog.trip.domain.repository.CustomItemRepository;
Expand Down Expand Up @@ -35,7 +35,7 @@ public class DeleteEventListener {
private final DayLogRepository dayLogRepository;
private final TripCityRepository tripCityRepository;
private final TripRepository tripRepository;
private final RefreshTokenRepository refreshTokenRepository;
private final OutBoxRepository outBoxRepository;

@Async
@Transactional(propagation = REQUIRES_NEW)
Expand All @@ -50,6 +50,7 @@ public void deleteMember(final MemberDeleteEvent event) {

dayLogRepository.deleteByIds(dayLogIds);
tripRepository.deleteByMemberId(event.getMemberId());
outBoxRepository.deleteByTargetId(event.getMemberId());
}

@Async
Expand All @@ -65,6 +66,7 @@ public void deleteTrip(final TripDeleteEvent event) {

dayLogRepository.deleteByIds(dayLogIds);
tripCityRepository.deleteAllByTripId(event.getTripId());
outBoxRepository.deleteByTargetId(event.getTripId());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetIdκ°€ κ²ΉμΉ μˆ˜λ„ μžˆμœΌλ‹ˆ typeμ •λ³΄κΉŒμ§€ ν•¨κ»˜ λ„£μ–΄μ€˜μ•Όκ² κ΅°μš”

}

private void deletePlaces(final List<ItemElement> itemElements) {
Expand Down
5 changes: 5 additions & 0 deletions backend/src/main/java/hanglog/login/service/LoginService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import hanglog.member.domain.Member;
import hanglog.member.domain.MemberDeleteEvent;
import hanglog.member.domain.repository.MemberRepository;
import hanglog.outbox.domain.OutBox;
import hanglog.outbox.domain.type.TargetType;
import hanglog.trip.domain.repository.CustomTripRepository;
import hanglog.trip.domain.repository.SharedTripRepository;
import hanglog.outbox.domain.repository.OutBoxRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
Expand All @@ -41,6 +44,7 @@ public class LoginService {
private final OauthProviders oauthProviders;
private final JwtProvider jwtProvider;
private final BearerAuthorizationExtractor bearerExtractor;
private final OutBoxRepository outBoxRepository;
private final ApplicationEventPublisher publisher;

public MemberTokens login(final String providerName, final String code) {
Expand Down Expand Up @@ -101,6 +105,7 @@ public void deleteAccount(final Long memberId) {
publishedTripRepository.deleteByTripIds(tripIds);
sharedTripRepository.deleteByTripIds(tripIds);
memberRepository.deleteByMemberId(memberId);
outBoxRepository.save(new OutBox(memberId, TargetType.MEMBER));
publisher.publishEvent(new MemberDeleteEvent(tripIds, memberId));
}
}
51 changes: 51 additions & 0 deletions backend/src/main/java/hanglog/outbox/domain/OutBox.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package hanglog.outbox.domain;

import static hanglog.outbox.domain.type.TargetType.MEMBER;
import static hanglog.outbox.domain.type.TargetType.TRIP;
import static jakarta.persistence.EnumType.STRING;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

import hanglog.global.BaseEntity;
import hanglog.outbox.domain.type.TargetType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

@Getter
@Entity
@NoArgsConstructor(access = PROTECTED)
@SQLDelete(sql = "UPDATE trip_outbox SET status = 'DELETED' WHERE id = ?")
@Where(clause = "status = 'USABLE'")
public class OutBox extends BaseEntity {

@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;

@Column(nullable = false)
private Long targetId;

@Column(nullable = false)
@Enumerated(value = STRING)
private TargetType targetType;

public OutBox(final Long targetId, final TargetType targetType) {
this.targetId = targetId;
this.targetType = targetType;
}

public boolean isMember() {
return this.targetType.equals(MEMBER);
}

public boolean isTrip() {
return this.targetType.equals(TRIP);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package hanglog.outbox.domain.repository;

import hanglog.outbox.domain.OutBox;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface OutBoxRepository extends JpaRepository<OutBox, Long> {

@Modifying
@Query("""
UPDATE OutBox outBox
SET outBox.status = 'DELETED'
WHERE outBox.targetId = :targetId
""")
void deleteByTargetId(@Param("targetId") final Long targetId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hanglog.outbox.domain.type;

public enum TargetType {

MEMBER,
TRIP
}
37 changes: 37 additions & 0 deletions backend/src/main/java/hanglog/outbox/service/OutBoxExecutor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package hanglog.outbox.service;

import hanglog.member.domain.MemberDeleteEvent;
import hanglog.outbox.domain.OutBox;
import hanglog.outbox.domain.repository.OutBoxRepository;
import hanglog.trip.domain.TripDeleteEvent;
import hanglog.trip.domain.repository.CustomTripRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class OutBoxExecutor {

private final OutBoxRepository outBoxRepository;
private final CustomTripRepository customTripRepository;
private final ApplicationEventPublisher publisher;

@Scheduled(cron = "*/2 * * * * *")
public void execute() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

큐없이 μŠ€μΌ€μ€„λ§μ—μ„œ λ°”λ‘œ λ°œν–‰ν•˜λŠ”κ΅°μš”! ν™•μ‹€νžˆ μ§€κΈˆμ€ μˆœμ„œκ°€ μ€‘μš”ν•œ μ΄λ²€νŠΈκ°€ μ—†μœΌλ‹ˆ λ””λ…Έλ§λŒ€λ‘œ 이 방식이 더 λͺ…λ£Œν•΄λ³΄μž…λ‹ˆλ‹€

final List<OutBox> outBoxes = outBoxRepository.findAll();
outBoxes.forEach(outBox -> {
if (outBox.isMember()) {
final List<Long> tripIds = customTripRepository.findTripIdsByMemberId(outBox.getTargetId());
Comment on lines +28 to +29
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outbox에 λͺ¨λ“  정보λ₯Ό μ €μž₯ν•˜λŠ” λŒ€μ‹  νƒ€κ²Ÿ λ„λ©”μΈμ˜ μ•„μ΄λ””λ§Œ μ €μž₯ν•˜κ³ , λ‚˜λ¨Έμ§€ μ •λ³΄λŠ” λ‹€μ‹œ μ‘°νšŒν•΄μ„œ κ°€μ Έμ˜€λŠ”κ΅°μš”!
μ „ ν•„μš”ν•œ 값을 μ „λΆ€ outbox에 μ €μž₯ν•˜λŠ” μˆ˜λ°–μ— μ—†λ‹€κ³  μƒκ°ν–ˆλŠ”λ°, μƒκ°ν•΄λ³΄λ‹ˆ μ΄λ ‡κ²Œ λ‹€μ‹œ 가져와도 λ˜λŠ” κ±°μ˜€λ„€μš”γ…‹γ…‹γ…‹ λ„˜ μ’‹μŠ΅λ‹ˆλ‹€ 무리가 λ˜λŠ” 쿼리도 μ•„λ‹Œ 것 κ°™λ„€μš”!

outbox에 μ§λ ¬ν™”λœ κ°’μœΌλ‘œ 정보 λ‹€ μ €μž₯ν•  λ•Œ, 이거 λ¦¬μŠ€νŠΈλŠ” μ§„μ§œ 콀마둜 κ΅¬λΆ„ν•΄μ„œ μ €μž₯ν•΄μ•Όν•˜λ‚˜... rdbλŒ€μ‹  λ‹€λ₯Έ dbλ₯Ό κ³ λ €ν•΄λ΄μ•Όν•˜λ‚˜ν•˜κ³  혼자 μ‹¬κ°ν•œ κ³ λ―Όν•˜κ³  μžˆμ—ˆλŠ”λ° κ·Έλƒ₯.......μ΄λ ‡κ²Œ μ°Ύμ•„μ˜€λ©΄ λ˜λŠ”κ±°μ˜€λ„€μš” μ „ λŒ€μ°¬μ„±μž…λ‹ˆλ‹€

publisher.publishEvent(new MemberDeleteEvent(tripIds, outBox.getTargetId()));
}
if (outBox.isTrip()) {
publisher.publishEvent(new TripDeleteEvent(outBox.getTargetId()));
}
});
}
}
7 changes: 6 additions & 1 deletion backend/src/main/java/hanglog/trip/service/TripService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import hanglog.image.domain.S3ImageEvent;
import hanglog.member.domain.Member;
import hanglog.member.domain.repository.MemberRepository;
import hanglog.outbox.domain.OutBox;
import hanglog.outbox.domain.type.TargetType;
import hanglog.trip.domain.DayLog;
import hanglog.trip.domain.PublishDeleteEvent;
import hanglog.trip.domain.PublishEvent;
Expand All @@ -22,6 +24,7 @@
import hanglog.trip.domain.repository.CustomTripCityRepository;
import hanglog.trip.domain.repository.SharedTripRepository;
import hanglog.trip.domain.repository.TripCityRepository;
import hanglog.outbox.domain.repository.OutBoxRepository;
import hanglog.trip.domain.repository.TripRepository;
import hanglog.trip.domain.type.PublishedStatusType;
import hanglog.trip.dto.request.PublishedStatusRequest;
Expand Down Expand Up @@ -55,6 +58,7 @@ public class TripService {
private final SharedTripRepository sharedTripRepository;
private final CustomDayLogRepository customDayLogRepository;
private final CustomTripCityRepository customTripCityRepository;
private final OutBoxRepository outBoxRepository;
private final ApplicationEventPublisher publisher;

public void validateTripByMember(final Long memberId, final Long tripId) {
Expand Down Expand Up @@ -107,7 +111,7 @@ private TripResponse getTripResponse(final Trip trip) {
final List<City> cities = cityRepository.findCitiesByTripId(trip.getId());
return TripResponse.of(trip, cities);
}

@Transactional(readOnly = true)
public TripDetailResponse getTripDetail(final Long tripId) {
final Trip trip = tripRepository.findById(tripId)
Expand Down Expand Up @@ -194,6 +198,7 @@ public void delete(final Long tripId) {
publisher.publishEvent(new PublishDeleteEvent(tripId));
sharedTripRepository.deleteByTripId(tripId);
tripRepository.deleteById(tripId);
outBoxRepository.save(new OutBox(tripId, TargetType.TRIP));
publisher.publishEvent(new TripDeleteEvent(tripId));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import hanglog.trip.domain.repository.ItemRepository;
import hanglog.trip.domain.repository.PlaceRepository;
import hanglog.trip.domain.repository.TripCityRepository;
import hanglog.outbox.domain.repository.OutBoxRepository;
import hanglog.trip.domain.repository.TripRepository;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -52,6 +53,8 @@ class DeleteEventListenerTest {
private RefreshTokenRepository refreshTokenRepository;
@Mock
private TripCityRepository tripCityRepository;
@Mock
private OutBoxRepository outBoxRepository;
@InjectMocks
private DeleteEventListener listener;

Expand Down Expand Up @@ -98,6 +101,7 @@ void deleteTrip() {
doNothing().when(itemRepository).deleteByIds(anyList());
doNothing().when(dayLogRepository).deleteByIds(anyList());
doNothing().when(tripCityRepository).deleteAllByTripId(anyLong());
doNothing().when(outBoxRepository).deleteByTargetId(anyLong());

// when
listener.deleteTrip(event);
Expand All @@ -111,5 +115,6 @@ void deleteTrip() {
verify(itemRepository, times(1)).deleteByIds(anyList());
verify(dayLogRepository, times(1)).deleteByIds(anyList());
verify(tripCityRepository, times(1)).deleteAllByTripId(anyLong());
verify(outBoxRepository, times(1)).deleteByTargetId(anyLong());
}
}