The app emitts events for created / deleted users
[demos/spring/data-jdbc] / 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.http.ResponseEntity;
7 import org.springframework.transaction.annotation.Transactional;
8 import org.springframework.web.bind.annotation.*;
9 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
10 import org.springframework.web.util.UriComponents;
11
12 import java.time.Clock;
13 import java.time.LocalDateTime;
14 import java.time.ZonedDateTime;
15
16 import static de.juplo.boot.data.jdbc.UserStatus.CREATED;
17 import static de.juplo.boot.data.jdbc.UserStatus.DELETED;
18
19 @RestController
20 @Transactional
21 @RequestMapping("/users")
22 public class UserController {
23
24     private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
25
26
27     private final UserRepository repository;
28     private final Clock clock;
29     private final ApplicationEventPublisher publisher;
30
31
32     public UserController(
33             UserRepository repository,
34             Clock clock,
35             ApplicationEventPublisher publisher)
36     {
37         this.repository = repository;
38         this.clock = clock;
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         repository.save(user);
50         publisher.publishEvent(
51             new UserEvent(
52                 this,
53                 sanitizedUsername,
54                 CREATED,
55                 ZonedDateTime.now(clock)));
56         UriComponents uri =
57             builder
58                 .fromCurrentRequest()
59                 .pathSegment("{username}")
60                 .buildAndExpand(sanitizedUsername);
61         return ResponseEntity.created(uri.toUri()).build();
62     }
63
64     @GetMapping("{username}")
65     public ResponseEntity<User> getUser(@PathVariable String username) {
66         User user = repository.findByUsername(UserController.sanitize(username));
67
68         if (user == null)
69             return ResponseEntity.notFound().build();
70
71         return ResponseEntity.ok(user);
72     }
73
74     @DeleteMapping("{username}")
75     public ResponseEntity<User> removeUser(@PathVariable String username) {
76         User user = repository.findByUsername(UserController.sanitize(username));
77
78         if (user == null)
79             return ResponseEntity.notFound().build();
80
81         repository.delete(user);
82         publisher.publishEvent(
83             new UserEvent(
84                 this,
85                 user.getUsername(),
86                 DELETED,
87                 ZonedDateTime.now(clock)));
88
89         return ResponseEntity.ok(user);
90     }
91
92     @GetMapping()
93     public ResponseEntity<Iterable<User>> getUsers() {
94         return ResponseEntity.ok(repository.findAll());
95     }
96
97
98     private static String sanitize(String string) {
99         if (string == null)
100             return "";
101
102         return string.trim().toLowerCase();
103     }
104 }