1a8711a0f89790437b5eb01db50804cd5532d0fd
[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 import java.util.logging.Level;
14
15
16 @RestController
17 @RequiredArgsConstructor
18 public class ChatBackendController
19 {
20   private final ChatHomeService chatHomeService;
21   private final StorageStrategy storageStrategy;
22
23
24   @PostMapping("create")
25   public Mono<ChatRoomInfoTo> create(@RequestBody String name)
26   {
27     UUID chatRoomId = UUID.randomUUID();
28     return chatHomeService
29         .createChatRoom(chatRoomId, name)
30         .map(ChatRoomInfoTo::from);
31   }
32
33   @GetMapping("list")
34   public Flux<ChatRoomInfoTo> list()
35   {
36     return chatHomeService
37         .getChatRoomInfo()
38         .map(chatroomInfo -> ChatRoomInfoTo.from(chatroomInfo));
39   }
40
41   @GetMapping("{chatRoomId}/list")
42   public Flux<MessageTo> list(@PathVariable UUID chatRoomId)
43   {
44     return chatHomeService
45         .getChatRoomData(chatRoomId)
46         .flatMapMany(chatRoomData -> chatRoomData
47             .getMessages()
48             .map(MessageTo::from));
49   }
50
51   @GetMapping("{chatRoomId}")
52   public Mono<ChatRoomInfoTo> get(@PathVariable UUID chatRoomId)
53   {
54     return chatHomeService
55         .getChatRoomInfo(chatRoomId)
56         .map(chatRoomInfo -> ChatRoomInfoTo.from(chatRoomInfo));
57   }
58
59   @PutMapping("{chatRoomId}/{username}/{messageId}")
60   public Mono<MessageTo> put(
61       @PathVariable UUID chatRoomId,
62       @PathVariable String username,
63       @PathVariable Long messageId,
64       @RequestBody String text)
65   {
66     return
67         chatHomeService
68             .getChatRoomData(chatRoomId)
69             .flatMap(chatRoomData -> put(chatRoomData, username, messageId, text));
70   }
71
72   private Mono<MessageTo> put(
73       ChatRoomData chatRoomData,
74       String username,
75       Long messageId,
76       String text)
77   {
78     return
79         chatRoomData
80             .addMessage(
81                 messageId,
82                 username,
83                 text)
84             .map(message -> MessageTo.from(message));
85   }
86
87   @GetMapping("{chatRoomId}/{username}/{messageId}")
88   public Mono<MessageTo> get(
89       @PathVariable UUID chatRoomId,
90       @PathVariable String username,
91       @PathVariable Long messageId)
92   {
93     return
94         chatHomeService
95             .getChatRoomData(chatRoomId)
96             .flatMap(chatRoomData -> get(chatRoomData, username, messageId));
97   }
98
99   private Mono<MessageTo> get(
100       ChatRoomData chatRoomData,
101       String username,
102       Long messageId)
103   {
104     return
105         chatRoomData
106             .getMessage(username, messageId)
107             .map(message -> MessageTo.from(message));
108   }
109
110   @GetMapping(path = "{chatRoomId}/listen")
111   public Flux<ServerSentEvent<MessageTo>> listen(@PathVariable UUID chatRoomId)
112   {
113     return chatHomeService
114         .getChatRoomData(chatRoomId)
115         .flatMapMany(chatRoomData -> listen(chatRoomData));
116   }
117
118   private Flux<ServerSentEvent<MessageTo>> listen(ChatRoomData chatRoomData)
119   {
120     return chatRoomData
121         .listen()
122         .log(
123             ChatBackendController.class.getSimpleName(),
124             Level.FINE,
125             true)
126         .map(message -> MessageTo.from(message))
127         .map(messageTo ->
128             ServerSentEvent
129                 .builder(messageTo)
130                 .id(messageTo.getSerial().toString())
131                 .event("message")
132                 .build());
133   }
134
135   @GetMapping("/shards")
136   public Mono<String[]> getShardOwners()
137   {
138     return chatHomeService.getShardOwners();
139   }
140
141   @PostMapping("/store")
142   public void store()
143   {
144     storageStrategy
145         .write(chatHomeService)
146         .subscribe();
147   }
148 }