feat: `ChatHome` returns an `Optional` for `getChatroom(UUID)`
[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 lombok.RequiredArgsConstructor;
6 import org.springframework.http.MediaType;
7 import org.springframework.web.bind.annotation.*;
8 import reactor.core.publisher.Flux;
9 import reactor.core.publisher.Mono;
10
11 import java.time.Clock;
12 import java.time.LocalDateTime;
13 import java.util.Collection;
14 import java.util.Optional;
15 import java.util.UUID;
16
17
18 @RestController
19 @RequiredArgsConstructor
20 public class ChatBackendController
21 {
22   private final ChatHome chatHome;
23   private final Clock clock;
24
25
26   @PostMapping("create")
27   public Chatroom create(@RequestBody String name)
28   {
29     return chatHome.createChatroom(name);
30   }
31
32   @GetMapping("list")
33   public Collection<Chatroom> list()
34   {
35     return chatHome.list();
36   }
37
38   @GetMapping("get/{chatroomId}")
39   public Optional<Chatroom> get(@PathVariable UUID chatroomId)
40   {
41     return chatHome.getChatroom(chatroomId);
42   }
43
44   @PutMapping("put/{chatroomId}/{username}/{messageId}")
45   public Mono<MessageTo> put(
46       @PathVariable UUID chatroomId,
47       @PathVariable String username,
48       @PathVariable Long messageId,
49       @RequestBody String text)
50   {
51     return
52         chatHome
53             .getChatroom(chatroomId)
54             .map(chatroom -> put(chatroom, username, messageId, text))
55             .orElseThrow(() -> new UnknownChatroomException(chatroomId));
56   }
57
58   public Mono<MessageTo> put(
59       Chatroom chatroom,
60       String username,
61       Long messageId,
62       String text)
63   {
64     return
65         chatroom
66             .addMessage(
67                 messageId,
68                 LocalDateTime.now(clock),
69                 username,
70                 text)
71             .switchIfEmpty(chatroom.getMessage(username, messageId))
72             .map(message -> MessageTo.from(message));
73   }
74
75   @GetMapping("get/{chatroomId}/{username}/{messageId}")
76   public Mono<MessageTo> get(
77       @PathVariable UUID chatroomId,
78       @PathVariable String username,
79       @PathVariable Long messageId)
80   {
81     return
82         chatHome
83             .getChatroom(chatroomId)
84             .map(chatroom -> get(chatroom, username, messageId))
85             .orElseThrow(() -> new UnknownChatroomException(chatroomId));
86   }
87
88   private Mono<MessageTo> get(
89       Chatroom chatroom,
90       String username,
91       Long messageId)
92   {
93     return
94         chatroom
95             .getMessage(username, messageId)
96             .map(message -> MessageTo.from(message));
97   }
98
99   @GetMapping(
100       path = "listen/{chatroomId}",
101       produces = MediaType.TEXT_EVENT_STREAM_VALUE)
102   public Flux<MessageTo> listen(@PathVariable UUID chatroomId)
103   {
104     return chatHome
105         .getChatroom(chatroomId)
106         .map(chatroom -> listen(chatroom))
107         .orElseThrow(() -> new UnknownChatroomException(chatroomId));
108   }
109
110   private Flux<MessageTo> listen(Chatroom chatroom)
111   {
112     return chatroom
113         .listen()
114         .log()
115         .map(message -> MessageTo.from(message));
116   }
117 }