b98110ef3a9bc72d791e80d0f8e2c3f68f481229
[demos/spring/data-jdbc] / src / main / java / de / juplo / boot / data / jdbc / UserController.java
1 package de.juplo.boot.data.jdbc;
2
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;
13
14 import java.time.Clock;
15 import java.time.LocalDateTime;
16 import java.time.ZonedDateTime;
17
18 import static de.juplo.boot.data.jdbc.UserStatus.CREATED;
19 import static de.juplo.boot.data.jdbc.UserStatus.DELETED;
20
21 @RestController
22 @Transactional
23 @RequestMapping("/users")
24 public class UserController {
25
26     private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
27
28
29     private final UserRepository repository;
30     private final Clock clock;
31     private final ApplicationEventPublisher publisher;
32
33
34     public UserController(
35             UserRepository repository,
36             Clock clock,
37             ApplicationEventPublisher publisher)
38     {
39         this.repository = repository;
40         this.clock = clock;
41         this.publisher = publisher;
42     }
43
44
45     @PostMapping
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);
51
52         LOG.info("Request to create user: {}", user);
53
54         repository.save(user);
55         publisher.publishEvent(
56             new UserEvent(
57                 this,
58                 sanitizedUsername,
59                 CREATED,
60                 ZonedDateTime.now(clock)));
61
62         // Triggers an IncorrectResultSizeDataAccessException, if the user already existed!
63         user = repository.findByUsername(sanitizedUsername);
64
65         UriComponents uri =
66             builder
67                 .fromCurrentRequest()
68                 .pathSegment("{username}")
69                 .buildAndExpand(sanitizedUsername);
70         return ResponseEntity.created(uri.toUri()).build();
71     }
72
73     @GetMapping("{username}")
74     public ResponseEntity<User> getUser(@PathVariable String username) {
75         User user = repository.findByUsername(UserController.sanitize(username));
76
77         if (user == null)
78             return ResponseEntity.notFound().build();
79
80         return ResponseEntity.ok(user);
81     }
82
83     @DeleteMapping("{username}")
84     public ResponseEntity<User> removeUser(@PathVariable String username) {
85         User user = repository.findByUsername(UserController.sanitize(username));
86
87         if (user == null)
88             return ResponseEntity.notFound().build();
89
90         repository.delete(user);
91         publisher.publishEvent(
92             new OutboxEvent(
93                 this,
94                 user.getUsername(),
95                 DELETED,
96                 ZonedDateTime.now(clock)));
97
98         return ResponseEntity.ok(user);
99     }
100
101     @GetMapping()
102     public ResponseEntity<Iterable<User>> getUsers() {
103         return ResponseEntity.ok(repository.findAll());
104     }
105
106
107     private static String sanitize(String string) {
108         if (string == null)
109             return "";
110
111         return string.trim().toLowerCase();
112     }
113
114     @ExceptionHandler
115     public ResponseEntity<?> incorrectResultSizeDataAccessException(
116         IncorrectResultSizeDataAccessException e
117         )
118     {
119       LOG.info("User already exists!");
120       return ResponseEntity.badRequest().build();
121     }
122 }