Skip to content

Commit ba3fd06

Browse files
committed
이벤트 소싱을 이상하게 구현하던 것을 수정함
요청받았을 때 저장하고 -> 저장된 이벤트를 발송하여, 사후처리를 하던 것을, 저장 요청 -> 커맨드 이벤트 발송으로 변경함
1 parent 008b360 commit ba3fd06

File tree

6 files changed

+43
-43
lines changed

6 files changed

+43
-43
lines changed

profile/src/main/java/com/example/research/profile/entity/cache/Profile.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.example.research.profile.entity.cache;
22

33
import com.example.research.profile.entity.command.ProfileChangedCommand;
4-
import com.example.research.profile.entity.command.ProfileSavedCommand;
4+
import com.example.research.profile.entity.command.CreateProfileCommand;
55
import com.example.research.profile.entity.storage.ProfileEvent;
66

77
import org.springframework.data.annotation.Id;
@@ -36,7 +36,7 @@ public static Profile from(com.example.research.profile.entity.storage.Profile p
3636
}
3737

3838
// 생성 이벤트에서 왔으므로, 항상 active
39-
public static Profile from(ProfileSavedCommand event) {
39+
public static Profile from(CreateProfileCommand event) {
4040
return from(event.getId(), event.getName(), event.getAge(),
4141
event.getSex(), true, Collections.emptySet());
4242
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.example.research.profile.entity.command;
22

3-
import com.example.research.profile.entity.storage.Profile;
3+
import com.example.research.profile.v1.profile.ProfileSaveRequest;
44

55
import java.time.LocalDateTime;
66

@@ -12,20 +12,20 @@
1212
@ToString
1313
@Getter
1414
@RequiredArgsConstructor
15-
public class ProfileSavedCommand extends ProfileCommand {
16-
public static final String TAG = ProfileSavedCommand.class.getSimpleName();
15+
public class CreateProfileCommand extends ProfileCommand {
16+
public static final String TAG = CreateProfileCommand.class.getSimpleName();
1717

1818
@NonNull String id;
1919
@NonNull String name;
2020
@NonNull Integer age;
2121
@NonNull String sex; // man, woman
2222
@NonNull LocalDateTime createdAt;
2323

24-
public static ProfileSavedCommand from(Profile storeProfile) {
25-
return new ProfileSavedCommand(
24+
public static CreateProfileCommand from(ProfileSaveRequest storeProfile) {
25+
return new CreateProfileCommand(
2626
storeProfile.getId(),
2727
storeProfile.getName(), storeProfile.getAge(),
28-
storeProfile.getSex(), storeProfile.getCreatedAt()
28+
storeProfile.getSex(), LocalDateTime.now()
2929
);
3030
}
3131

profile/src/main/java/com/example/research/profile/entity/storage/Profile.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.research.profile.entity.storage;
22

3+
import com.example.research.profile.entity.command.CreateProfileCommand;
34
import com.example.research.profile.v1.profile.ProfileSaveRequest;
45

56
import org.springframework.data.annotation.CreatedDate;
@@ -47,15 +48,15 @@ public class Profile {
4748
@LastModifiedDate
4849
@Column(name = "updated_at") LocalDateTime updatedAt;
4950

50-
public static Profile from(ProfileSaveRequest request) {
51+
public static Profile from(CreateProfileCommand command) {
5152
Profile profile = new Profile();
52-
profile.id = request.getId();
53-
profile.name = request.getName();
54-
profile.age = request.getAge();
55-
profile.sex = request.getSex();
53+
profile.id = command.getId();
54+
profile.name = command.getName();
55+
profile.age = command.getAge();
56+
profile.sex = command.getSex();
5657
profile.active = true;
57-
profile.createdAt = LocalDateTime.now();
58-
profile.updatedAt = LocalDateTime.now();
58+
profile.createdAt = command.getCreatedAt();
59+
profile.updatedAt = command.getCreatedAt();
5960
return profile;
6061
}
6162
}

profile/src/main/java/com/example/research/profile/v1/profile/ProfileEventHandler.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.example.research.profile.v1.profile;
22

3+
import com.example.research.profile.entity.cache.Profile;
4+
import com.example.research.profile.entity.cache.ProfileRepository;
5+
import com.example.research.profile.entity.command.CreateProfileCommand;
36
import com.example.research.profile.entity.command.ProfileCommand;
7+
import com.example.research.profile.entity.command.UpdateProfileCommand;
48
import com.example.research.profile.entity.storage.ProfileEventStoreRepository;
59
import com.example.research.profile.entity.storage.ProfileStorageRepository;
610
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -19,23 +23,27 @@
1923
@Async
2024
@Service
2125
public class ProfileEventHandler {
26+
@Autowired ProfileRepository profileRepository;
2227
@Autowired ProfileStorageRepository profileStorageRepository;
2328
@Autowired ProfileEventStoreRepository profileEventStoreRepository;
2429

2530
@Autowired ObjectMapper objectMapper;
2631

2732
@Async
2833
@Transactional
29-
public CompletableFuture<com.example.research.profile.entity.storage.ProfileEvent> save(ProfileCommand event) {
34+
public CompletableFuture<com.example.research.profile.entity.storage.ProfileEvent> save(CreateProfileCommand command) {
3035
return CompletableFuture.supplyAsync(() -> {
36+
// TODO chaining 이 나을지, 그냥 소비시켜버릴지.
37+
profileRepository.save(Profile.from(command)).subscribe();
38+
profileStorageRepository.save(com.example.research.profile.entity.storage.Profile.from(command));
3139
Long latestVersion = profileEventStoreRepository
32-
.findTopByIdentifierOrderByNoDesc(event.getId())
40+
.findTopByIdentifierOrderByNoDesc(command.getId())
3341
.map(com.example.research.profile.entity.storage.ProfileEvent::getVersion)
3442
.orElse(0L);
35-
String payload = generatePayload(event);
43+
String payload = generatePayload(command);
3644

3745
com.example.research.profile.entity.storage.ProfileEvent profileRawEvent
38-
= com.example.research.profile.entity.storage.ProfileEvent.from(event, latestVersion + 1, payload);
46+
= com.example.research.profile.entity.storage.ProfileEvent.from(command, latestVersion + 1, payload);
3947
return profileEventStoreRepository.save(profileRawEvent);
4048
});
4149
}

profile/src/main/java/com/example/research/profile/v1/profile/ProfileEventListener.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.example.research.profile.entity.cache.Profile;
44
import com.example.research.profile.entity.cache.ProfileRepository;
55
import com.example.research.profile.entity.command.ProfileChangedCommand;
6-
import com.example.research.profile.entity.command.ProfileSavedCommand;
6+
import com.example.research.profile.entity.command.CreateProfileCommand;
77
import com.example.research.profile.entity.storage.ProfileStorageRepository;
88

99
import org.springframework.beans.factory.annotation.Autowired;
@@ -23,12 +23,11 @@ public class ProfileEventListener {
2323
@Autowired ProfileRepository profileRepository;
2424
@Autowired ProfileStorageRepository profileStorageRepository;
2525

26-
@EventListener public void onProfileSavedEventReceived(ProfileSavedCommand event) {
27-
log.info("onProfileSavedEventReceived received : {}" + event);
28-
profileRepository.save(Profile.from(event))
29-
.flatMap(profile -> Mono.fromCompletionStage(profileEventHandler.save(event)))
26+
@EventListener public void onProfileSavedEventReceived(CreateProfileCommand command) {
27+
log.info("onProfileSavedEventReceived received : {}" + command);
28+
Mono.fromCompletionStage(profileEventHandler.save(command))
3029
.doOnError(e -> log.error("onProfileSavedEventReceived error : {}", e))
31-
.onErrorResume(throwable -> profileRepository.deleteById(event.getId()).flatMap(aVoid -> Mono.empty()))
30+
.onErrorResume(throwable -> profileRepository.deleteById(command.getId()).flatMap(aVoid -> Mono.empty()))
3231
.subscribe();
3332
}
3433

profile/src/main/java/com/example/research/profile/v1/profile/ProfileHandler.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.example.research.profile.entity.cache.Profile;
44
import com.example.research.profile.entity.cache.ProfileRepository;
5+
import com.example.research.profile.entity.command.CreateProfileCommand;
56
import com.example.research.profile.entity.command.ProfileChangedCommand;
6-
import com.example.research.profile.entity.command.ProfileSavedCommand;
77
import com.example.research.profile.entity.storage.ProfileStorageRepository;
88

99
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,13 +16,15 @@
1616
import org.springframework.web.reactive.function.server.ServerResponse;
1717

1818
import java.time.LocalDateTime;
19+
import java.util.function.Consumer;
1920
import java.util.function.Function;
2021

2122
import lombok.extern.slf4j.Slf4j;
2223
import reactor.core.publisher.Flux;
2324
import reactor.core.publisher.Mono;
2425

2526
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
27+
import static org.springframework.web.reactive.function.server.ServerResponse.noContent;
2628
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
2729

2830
@Slf4j
@@ -54,24 +56,14 @@ public Mono<ServerResponse> fetch(ServerRequest request) {
5456

5557
@NonNull
5658
public Mono<ServerResponse> save(Mono<ProfileSaveRequest> request) {
57-
Function<ProfileSaveRequest, com.example.research.profile.entity.storage.Profile> mapToProfile
58-
= com.example.research.profile.entity.storage.Profile::from;
59+
// TODO validation
60+
Function<ProfileSaveRequest, CreateProfileCommand> requestToCommand = CreateProfileCommand::from;
61+
Consumer<CreateProfileCommand> sendCommand = command -> applicationEventPublisher.publishEvent(command);
5962

60-
Function<com.example.research.profile.entity.storage.Profile, Mono<com.example.research.profile.entity.storage.Profile>>
61-
saveProfile = profile -> {
62-
log.info("profile is {}", profile);
63-
com.example.research.profile.entity.storage.Profile storeProfile = profileStorageRepository.save(profile);
64-
applicationEventPublisher.publishEvent(ProfileSavedCommand.from(storeProfile));
65-
return Mono.just(storeProfile);
66-
};
67-
68-
Function<com.example.research.profile.entity.storage.Profile, ProfileSaveResponse> mapToResponse =
69-
profile -> new ProfileSaveResponse(profile.getId());
70-
71-
Mono<ProfileSaveResponse> save = request.flatMap(saveProfile.compose(mapToProfile))
72-
.map(mapToResponse); // FIXME throw 처리
73-
74-
return ok().body(save, ProfileSaveResponse.class);
63+
return request.single().flatMap(profile -> {
64+
sendCommand.accept(requestToCommand.apply(profile));
65+
return noContent().build();
66+
});
7567
}
7668

7769
@NonNull

0 commit comments

Comments
 (0)