feat: Moved persistence-logic from `ChatHome` into `ChatHomeService`
[demos/kafka/chat] / src / main / java / de / juplo / kafka / chat / backend / api / ChatBackendController.java
1 package de.juplo.kafka.chat.backend.api;
2
3 import de.juplo.kafka.chat.backend.domain.ChatHome;
4 import de.juplo.kafka.chat.backend.domain.ChatRoom;
5 import de.juplo.kafka.chat.backend.persistence.StorageStrategy;
6 import lombok.RequiredArgsConstructor;
7 import org.springframework.http.codec.ServerSentEvent;
8 import org.springframework.web.bind.annotation.*;
9 import reactor.core.publisher.Flux;
10 import reactor.core.publisher.Mono;
11
12 import java.util.UUID;
13
14
15 @RestController
16 @RequiredArgsConstructor
17 public class ChatBackendController
18 {
19   private final ChatHome chatHome;
20   private final StorageStrategy storageStrategy;
21
22
23   @PostMapping("create")
24   public Mono<ChatRoomTo> create(@RequestBody String name)
25   {
26     return chatHome.createChatroom(name).map(ChatRoomTo::from);
27   }
28
29   @GetMapping("list")
30   public Flux<ChatRoomTo> list()
31   {
32     return chatHome.getChatRooms().map(chatroom -> ChatRoomTo.from(chatroom));
33   }
34
35   @GetMapping("list/{chatroomId}")
36   public Flux<MessageTo> list(@PathVariable UUID chatroomId)
37   {
38     return chatHome
39         .getChatRoom(chatroomId)
40         .flatMapMany(chatroom -> chatroom
41             .getMessages()
42             .map(MessageTo::from));
43   }
44
45   @GetMapping("get/{chatroomId}")
46   public Mono<ChatRoomTo> get(@PathVariable UUID chatroomId)
47   {
48     return chatHome.getChatRoom(chatroomId).map(chatroom -> ChatRoomTo.from(chatroom));
49   }
50
51   @PutMapping("put/{chatroomId}/{username}/{messageId}")
52   public Mono<MessageTo> put(
53       @PathVariable UUID chatroomId,
54       @PathVariable String username,
55       @PathVariable Long messageId,
56       @RequestBody String text)
57   {
58     return
59         chatHome
60             .getChatRoom(chatroomId)
61             .flatMap(chatroom -> put(chatroom, username, messageId, text));
62   }
63
64   public Mono<MessageTo> put(
65       ChatRoom chatroom,
66       String username,
67       Long messageId,
68       String text)
69   {
70     return
71         chatroom
72             .addMessage(
73                 messageId,
74                 username,
75                 text)
76             .map(message -> MessageTo.from(message));
77   }
78
79   @GetMapping("get/{chatroomId}/{username}/{messageId}")
80   public Mono<MessageTo> get(
81       @PathVariable UUID chatroomId,
82       @PathVariable String username,
83       @PathVariable Long messageId)
84   {
85     return
86         chatHome
87             .getChatRoom(chatroomId)
88             .flatMap(chatroom -> get(chatroom, username, messageId));
89   }
90
91   private Mono<MessageTo> get(
92       ChatRoom chatroom,
93       String username,
94       Long messageId)
95   {
96     return
97         chatroom
98             .getMessage(username, messageId)
99             .map(message -> MessageTo.from(message));
100   }
101
102   @GetMapping(path = "listen/{chatroomId}")
103   public Flux<ServerSentEvent<MessageTo>> listen(@PathVariable UUID chatroomId)
104   {
105     return chatHome
106         .getChatRoom(chatroomId)
107         .flatMapMany(chatroom -> listen(chatroom));
108   }
109
110   private Flux<ServerSentEvent<MessageTo>> listen(ChatRoom chatroom)
111   {
112     return chatroom
113         .listen()
114         .log()
115         .map(message -> MessageTo.from(message))
116         .map(messageTo ->
117             ServerSentEvent
118                 .builder(messageTo)
119                 .id(messageTo.getSerial().toString())
120                 .event("message")
121                 .build());
122   }
123
124   @PostMapping("/store")
125   public void store()
126   {
127     storageStrategy.writeChatrooms(chatHome.getChatRooms());
128   }
129 }