refactor: Simplified implementation - Removed interface `ChatRoomFactory`
[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<ChatRoomInfoTo> create(@RequestBody String name)
25   {
26     UUID chatRoomId = UUID.randomUUID();
27     return chatHome
28         .createChatRoom(chatRoomId, name)
29         .map(ChatRoomInfoTo::from);
30   }
31
32   @GetMapping("list")
33   public Flux<ChatRoomInfoTo> list()
34   {
35     return chatHome
36         .getChatRooms()
37         .map(chatroom -> ChatRoomInfoTo.from(chatroom));
38   }
39
40   @GetMapping("{chatroomId}/list")
41   public Flux<MessageTo> list(@PathVariable UUID chatroomId)
42   {
43     return chatHome
44         .getChatRoom(chatroomId)
45         .flatMapMany(chatroom -> chatroom
46             .getMessages()
47             .map(MessageTo::from));
48   }
49
50   @GetMapping("{chatroomId}")
51   public Mono<ChatRoomInfoTo> get(@PathVariable UUID chatroomId)
52   {
53     return chatHome
54         .getChatRoom(chatroomId)
55         .map(chatroom -> ChatRoomInfoTo.from(chatroom));
56   }
57
58   @PutMapping("{chatroomId}/{username}/{messageId}")
59   public Mono<MessageTo> put(
60       @PathVariable UUID chatroomId,
61       @PathVariable String username,
62       @PathVariable Long messageId,
63       @RequestBody String text)
64   {
65     return
66         chatHome
67             .getChatRoom(chatroomId)
68             .flatMap(chatroom -> put(chatroom, username, messageId, text));
69   }
70
71   private Mono<MessageTo> put(
72       ChatRoom chatroom,
73       String username,
74       Long messageId,
75       String text)
76   {
77     return
78         chatroom
79             .addMessage(
80                 messageId,
81                 username,
82                 text)
83             .map(message -> MessageTo.from(message));
84   }
85
86   @GetMapping("{chatroomId}/{username}/{messageId}")
87   public Mono<MessageTo> get(
88       @PathVariable UUID chatroomId,
89       @PathVariable String username,
90       @PathVariable Long messageId)
91   {
92     return
93         chatHome
94             .getChatRoom(chatroomId)
95             .flatMap(chatroom -> get(chatroom, username, messageId));
96   }
97
98   private Mono<MessageTo> get(
99       ChatRoom chatroom,
100       String username,
101       Long messageId)
102   {
103     return
104         chatroom
105             .getMessage(username, messageId)
106             .map(message -> MessageTo.from(message));
107   }
108
109   @GetMapping(path = "{chatroomId}/listen")
110   public Flux<ServerSentEvent<MessageTo>> listen(@PathVariable UUID chatroomId)
111   {
112     return chatHome
113         .getChatRoom(chatroomId)
114         .flatMapMany(chatroom -> listen(chatroom));
115   }
116
117   private Flux<ServerSentEvent<MessageTo>> listen(ChatRoom chatroom)
118   {
119     return chatroom
120         .listen()
121         .log()
122         .map(message -> MessageTo.from(message))
123         .map(messageTo ->
124             ServerSentEvent
125                 .builder(messageTo)
126                 .id(messageTo.getSerial().toString())
127                 .event("message")
128                 .build());
129   }
130
131   @PostMapping("/store")
132   public void store()
133   {
134     storageStrategy.write(chatHome.getChatRooms());
135   }
136 }