Logging the name for create-requests for already existent users
[demos/kafka/outbox] / src / main / java / de / juplo / boot / data / jdbc / UserController.java
1 package de.juplo.boot.data.jdbc;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.springframework.context.ApplicationEventPublisher;
6 import org.springframework.dao.IncorrectResultSizeDataAccessException;
7 import org.springframework.http.ResponseEntity;
8 import org.springframework.transaction.annotation.Transactional;
9 import org.springframework.util.StreamUtils;
10 import org.springframework.web.bind.annotation.*;
11 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
12 import org.springframework.web.util.UriComponents;
13
14 import javax.servlet.http.HttpServletRequest;
15 import java.io.IOException;
16 import java.nio.charset.Charset;
17 import java.time.LocalDateTime;
18
19 import static de.juplo.boot.data.jdbc.UserEvent.Type.CREATED;
20 import static de.juplo.boot.data.jdbc.UserEvent.Type.DELETED;
21
22 @RestController
23 @Transactional
24 @RequestMapping("/users")
25 public class UserController {
26
27     private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
28
29
30     private final UserRepository repository;
31     private final ApplicationEventPublisher publisher;
32
33
34     public UserController(
35             UserRepository repository,
36             ApplicationEventPublisher publisher)
37     {
38         this.repository = repository;
39         this.publisher = publisher;
40     }
41
42
43     @PostMapping
44     public ResponseEntity<Void> createUser(
45             ServletUriComponentsBuilder builder,
46             @RequestBody String username) {
47         String sanitizedUsername = UserController.sanitize(username);
48         User user = new User(sanitizedUsername, LocalDateTime.now(), false);
49
50         // Triggering a unique-error for username prevents persistence
51         repository.save(user);
52         publisher.publishEvent(new UserEvent(this, CREATED, sanitizedUsername));
53         user = repository.findByUsername(sanitizedUsername);
54
55         UriComponents uri =
56             builder
57                 .fromCurrentRequest()
58                 .pathSegment("{username}")
59                 .buildAndExpand(sanitizedUsername);
60         return ResponseEntity.created(uri.toUri()).build();
61     }
62
63     @GetMapping("{username}")
64     public ResponseEntity<User> getUser(@PathVariable String username) {
65         User user = repository.findByUsername(UserController.sanitize(username));
66
67         if (user == null)
68             return ResponseEntity.notFound().build();
69
70         return ResponseEntity.ok(user);
71     }
72
73     @DeleteMapping("{username}")
74     public ResponseEntity<User> removeUser(@PathVariable String username) {
75         User user = repository.findByUsername(UserController.sanitize(username));
76
77         if (user == null)
78             return ResponseEntity.notFound().build();
79
80         repository.delete(user);
81         publisher.publishEvent(new UserEvent(this, DELETED, username));
82
83         return ResponseEntity.ok(user);
84     }
85
86     @GetMapping()
87     public ResponseEntity<Iterable<User>> getUsers() {
88         return ResponseEntity.ok(repository.findAll());
89     }
90
91
92     private static String sanitize(String string) {
93         if (string == null)
94             return "";
95
96         return string.trim().toLowerCase();
97     }
98
99     @ExceptionHandler
100     public ResponseEntity<?> incorrectResultSizeDataAccessException(
101         HttpServletRequest request,
102         IncorrectResultSizeDataAccessException e
103         )
104     {
105       String username;
106       try {
107           username = StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset());
108       }
109       catch (IOException ioe)
110       {
111         username = e.getMessage() + " -> " + ioe.getMessage();
112       }
113       LOG.info("User {} already exists!", username);
114       return ResponseEntity.badRequest().build();
115     }
116 }