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