529be8dfa83eb6b229ceb566deb64909f167bae3
[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.ChatHomeService;
4 import de.juplo.kafka.chat.backend.domain.ChatRoomData;
5 import de.juplo.kafka.chat.backend.implementation.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 ChatHomeService chatHomeService;
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 chatHomeService
28         .createChatRoom(chatRoomId, name)
29         .map(ChatRoomInfoTo::from);
30   }
31
32   @GetMapping("list")
33   public Flux<ChatRoomInfoTo> list()
34   {
35     return chatHomeService
36         .getChatRoomInfo()
37         .map(chatroomInfo -> ChatRoomInfoTo.from(chatroomInfo));
38   }
39
40   @GetMapping("{chatRoomId}/list")
41   public Flux<MessageTo> list(@PathVariable UUID chatRoomId)
42   {
43     return chatHomeService
44         .getChatRoomData(chatRoomId)
45         .flatMapMany(chatRoomData -> chatRoomData
46             .getMessages()
47             .map(MessageTo::from));
48   }
49
50   @GetMapping("{chatRoomId}")
51   public Mono<ChatRoomInfoTo> get(@PathVariable UUID chatRoomId)
52   {
53     return chatHomeService
54         .getChatRoomInfo(chatRoomId)
55         .map(chatRoomInfo -> ChatRoomInfoTo.from(chatRoomInfo));
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         chatHomeService
67             .getChatRoomData(chatRoomId)
68             .flatMap(chatRoomData -> put(chatRoomData, username, messageId, text));
69   }
70
71   private Mono<MessageTo> put(
72       ChatRoomData chatRoomData,
73       String username,
74       Long messageId,
75       String text)
76   {
77     return
78         chatRoomData
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         chatHomeService
94             .getChatRoomData(chatRoomId)
95             .flatMap(chatRoomData -> get(chatRoomData, username, messageId));
96   }
97
98   private Mono<MessageTo> get(
99       ChatRoomData chatRoomData,
100       String username,
101       Long messageId)
102   {
103     return
104         chatRoomData
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 chatHomeService
113         .getChatRoomData(chatRoomId)
114         .flatMapMany(chatRoomData -> listen(chatRoomData));
115   }
116
117   private Flux<ServerSentEvent<MessageTo>> listen(ChatRoomData chatRoomData)
118   {
119     return chatRoomData
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(chatHomeService);
135   }
136 }