1 package de.juplo.kafka.outbox.polling;
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;
14 import javax.servlet.http.HttpServletRequest;
15 import java.io.IOException;
16 import java.nio.charset.Charset;
17 import java.time.LocalDateTime;
19 import static de.juplo.kafka.outbox.polling.UserEvent.Type.CREATED;
20 import static de.juplo.kafka.outbox.polling.UserEvent.Type.DELETED;
25 @RequestMapping("/users")
26 public class UserController {
28 private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
31 private final UserRepository repository;
32 private final ApplicationEventPublisher publisher;
35 public UserController(
36 UserRepository repository,
37 ApplicationEventPublisher publisher)
39 this.repository = repository;
40 this.publisher = publisher;
45 public ResponseEntity<Void> createUser(
46 ServletUriComponentsBuilder builder,
47 @RequestBody String username) {
48 String sanitizedUsername = UserController.sanitize(username);
49 User user = new User(sanitizedUsername, LocalDateTime.now(), false);
51 // Triggering a unique-error for username prevents persistence
52 repository.save(user);
53 publisher.publishEvent(new UserEvent(this, CREATED, sanitizedUsername));
54 user = repository.findByUsername(sanitizedUsername);
59 .pathSegment("{username}")
60 .buildAndExpand(sanitizedUsername);
61 return ResponseEntity.created(uri.toUri()).build();
64 @GetMapping("{username}")
65 public ResponseEntity<User> getUser(@PathVariable String username) {
66 User user = repository.findByUsername(UserController.sanitize(username));
69 return ResponseEntity.notFound().build();
71 return ResponseEntity.ok(user);
74 @DeleteMapping("{username}")
75 public ResponseEntity<User> removeUser(@PathVariable String username) {
76 User user = repository.findByUsername(UserController.sanitize(username));
79 return ResponseEntity.notFound().build();
81 repository.delete(user);
82 publisher.publishEvent(new UserEvent(this, DELETED, username));
84 return ResponseEntity.ok(user);
88 public ResponseEntity<Iterable<User>> getUsers() {
89 return ResponseEntity.ok(repository.findAll());
93 private static String sanitize(String string) {
97 return string.trim().toLowerCase();
101 public ResponseEntity<?> incorrectResultSizeDataAccessException(
102 HttpServletRequest request,
103 IncorrectResultSizeDataAccessException e
108 username = StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset());
110 catch (IOException ioe)
112 username = e.getMessage() + " -> " + ioe.getMessage();
114 LOG.info("User {} already exists!", username);
115 return ResponseEntity.badRequest().build();