1 package de.juplo.boot.data.jdbc;
3 import de.juplo.kafka.outbox.OutboxEvent;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6 import org.springframework.context.ApplicationEventPublisher;
7 import org.springframework.dao.IncorrectResultSizeDataAccessException;
8 import org.springframework.http.ResponseEntity;
9 import org.springframework.transaction.annotation.Transactional;
10 import org.springframework.web.bind.annotation.*;
11 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
12 import org.springframework.web.util.UriComponents;
14 import java.time.Clock;
15 import java.time.LocalDateTime;
16 import java.time.ZonedDateTime;
18 import static de.juplo.boot.data.jdbc.UserStatus.CREATED;
19 import static de.juplo.boot.data.jdbc.UserStatus.DELETED;
23 @RequestMapping("/users")
24 public class UserController {
26 private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
29 private final UserRepository repository;
30 private final Clock clock;
31 private final ApplicationEventPublisher publisher;
34 public UserController(
35 UserRepository repository,
37 ApplicationEventPublisher publisher)
39 this.repository = repository;
41 this.publisher = publisher;
46 public ResponseEntity<Void> createUser(
47 ServletUriComponentsBuilder builder,
48 @RequestBody String username) {
49 String sanitizedUsername = UserController.sanitize(username);
50 User user = new User(sanitizedUsername, LocalDateTime.now(), false);
52 LOG.info("Request to create user: {}", user);
54 repository.save(user);
55 publisher.publishEvent(
60 ZonedDateTime.now(clock)));
62 // Triggers an IncorrectResultSizeDataAccessException, if the user already existed!
63 user = repository.findByUsername(sanitizedUsername);
68 .pathSegment("{username}")
69 .buildAndExpand(sanitizedUsername);
70 return ResponseEntity.created(uri.toUri()).build();
73 @GetMapping("{username}")
74 public ResponseEntity<User> getUser(@PathVariable String username) {
75 User user = repository.findByUsername(UserController.sanitize(username));
78 return ResponseEntity.notFound().build();
80 return ResponseEntity.ok(user);
83 @DeleteMapping("{username}")
84 public ResponseEntity<User> removeUser(@PathVariable String username) {
85 User user = repository.findByUsername(UserController.sanitize(username));
88 return ResponseEntity.notFound().build();
90 repository.delete(user);
91 publisher.publishEvent(
96 ZonedDateTime.now(clock)));
98 return ResponseEntity.ok(user);
102 public ResponseEntity<Iterable<User>> getUsers() {
103 return ResponseEntity.ok(repository.findAll());
107 private static String sanitize(String string) {
111 return string.trim().toLowerCase();
115 public ResponseEntity<?> incorrectResultSizeDataAccessException(
116 IncorrectResultSizeDataAccessException e
119 LOG.info("User already exists!");
120 return ResponseEntity.badRequest().build();