47b46bc5a401637e33aab4d50a7acda66a1e56bb
[demos/kafka/chat] / src / main / java / de / juplo / kafka / chat / backend / api / ChatBackendControllerAdvice.java
1 package de.juplo.kafka.chat.backend.api;
2
3 import de.juplo.kafka.chat.backend.domain.InvalidUsernameException;
4 import de.juplo.kafka.chat.backend.domain.MessageMutationException;
5 import de.juplo.kafka.chat.backend.domain.ShardNotOwnedException;
6 import de.juplo.kafka.chat.backend.domain.UnknownChatroomException;
7 import org.springframework.beans.factory.annotation.Value;
8 import org.springframework.http.HttpStatus;
9 import org.springframework.http.ProblemDetail;
10 import org.springframework.web.bind.annotation.ControllerAdvice;
11 import org.springframework.web.bind.annotation.ExceptionHandler;
12 import org.springframework.web.server.ServerWebExchange;
13 import org.springframework.web.util.UriComponentsBuilder;
14
15 import java.util.Date;
16
17
18 @ControllerAdvice
19 public class ChatBackendControllerAdvice
20 {
21   @Value("${server.context-path:/}")
22   String contextPath;
23
24   @ExceptionHandler(UnknownChatroomException.class)
25   public final ProblemDetail handleException(
26       UnknownChatroomException e,
27       ServerWebExchange exchange,
28       UriComponentsBuilder uriComponentsBuilder)
29   {
30     final HttpStatus status = HttpStatus.NOT_FOUND;
31     ProblemDetail problem = ProblemDetail.forStatus(status);
32
33     problem.setProperty("timestamp", new Date());
34
35     problem.setProperty("requestId", exchange.getRequest().getId());
36
37     problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/unknown-chatroom").build().toUri());
38     StringBuilder stringBuilder = new StringBuilder();
39     stringBuilder.append(status.getReasonPhrase());
40     stringBuilder.append(" - ");
41     stringBuilder.append(e.getMessage());
42     problem.setTitle(stringBuilder.toString());
43
44     stringBuilder.setLength(0);
45     stringBuilder.append("Chatroom unknown: ");
46     stringBuilder.append(e.getChatroomId());
47     problem.setDetail(stringBuilder.toString());
48
49     problem.setProperty("chatroomId", e.getChatroomId());
50     problem.setProperty("shard", e.getShard());
51     problem.setProperty("ownedShards", e.getOwnedShards());
52
53     return problem;
54   }
55
56   @ExceptionHandler(ShardNotOwnedException.class)
57   public final ProblemDetail handleException(
58       ShardNotOwnedException e,
59       ServerWebExchange exchange,
60       UriComponentsBuilder uriComponentsBuilder)
61   {
62     final HttpStatus status = HttpStatus.NOT_FOUND;
63     ProblemDetail problem = ProblemDetail.forStatus(status);
64
65     problem.setProperty("timestamp", new Date());
66
67     problem.setProperty("requestId", exchange.getRequest().getId());
68
69     problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/shard-not-owned").build().toUri());
70     StringBuilder stringBuilder = new StringBuilder();
71     stringBuilder.append(status.getReasonPhrase());
72     stringBuilder.append(" - ");
73     stringBuilder.append(e.getMessage());
74     problem.setTitle(stringBuilder.toString());
75
76     stringBuilder.setLength(0);
77     stringBuilder.append("Shard not owned: ");
78     stringBuilder.append(e.getShard());
79     problem.setDetail(stringBuilder.toString());
80
81     problem.setProperty("shard", e.getShard());
82
83     return problem;
84   }
85
86   @ExceptionHandler(MessageMutationException.class)
87   public final ProblemDetail handleException(
88       MessageMutationException e,
89       ServerWebExchange exchange,
90       UriComponentsBuilder uriComponentsBuilder)
91   {
92     final HttpStatus status = HttpStatus.BAD_REQUEST;
93     ProblemDetail problem = ProblemDetail.forStatus(status);
94
95     problem.setProperty("timestamp", new Date());
96
97     problem.setProperty("requestId", exchange.getRequest().getId());
98
99     problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/message-mutation").build().toUri());
100     StringBuilder stringBuilder = new StringBuilder();
101     stringBuilder.append(status.getReasonPhrase());
102     stringBuilder.append(" - ");
103     stringBuilder.append(e.getMessage());
104     problem.setTitle(stringBuilder.toString());
105
106     stringBuilder.setLength(0);
107     stringBuilder.append("The existing message with user=");
108     stringBuilder.append(e.getExisting().getUsername());
109     stringBuilder.append(" and id=");
110     stringBuilder.append(e.getExisting().getId());
111     stringBuilder.append(" cannot be mutated!");
112     problem.setDetail(stringBuilder.toString());
113
114     problem.setProperty("existingMessage", MessageTo.from(e.getExisting()));
115
116     problem.setProperty("mutatedText", e.getMutatedText());
117
118     return problem;
119   }
120
121   @ExceptionHandler(InvalidUsernameException.class)
122   public final ProblemDetail handleException(
123       InvalidUsernameException e,
124       ServerWebExchange exchange,
125       UriComponentsBuilder uriComponentsBuilder)
126   {
127     final HttpStatus status = HttpStatus.BAD_REQUEST;
128     ProblemDetail problem = ProblemDetail.forStatus(status);
129
130     problem.setProperty("timestamp", new Date());
131
132     problem.setProperty("requestId", exchange.getRequest().getId());
133
134     problem.setType(uriComponentsBuilder.replacePath(contextPath).path("/problem/invalid-username").build().toUri());
135     StringBuilder stringBuilder = new StringBuilder();
136     stringBuilder.append(status.getReasonPhrase());
137     stringBuilder.append(" - ");
138     stringBuilder.append(e.getMessage());
139     problem.setTitle(stringBuilder.toString());
140
141     stringBuilder.setLength(0);
142     stringBuilder.append("Invalid username: ");
143     stringBuilder.append(e.getUsername());
144     stringBuilder.append(
145         "! A valid username must consist of at at least two letters and " +
146         "must only contain lower case letters a-z, numbers and dashes");
147     problem.setDetail(stringBuilder.toString());
148
149     problem.setProperty("username", e.getUsername());
150
151     return problem;
152   }
153 }