From 0fc9256a18f6a894bcb7c09d26bf7f2b530474b1 Mon Sep 17 00:00:00 2001 From: CO0LGIRL Date: Mon, 20 Apr 2026 23:09:33 +0300 Subject: [PATCH 1/4] feat: subnission list controller --- .../submission/SubmissionController.java | 98 +++++++++++++++++++ .../submission/SubmissionPollingService.java | 10 +- .../submission/SubmissionRepository.java | 9 +- .../submission/SubmissionResponseDTO.java | 23 +++++ .../submission/SubmissionUpdatedEvent.java | 5 + 5 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java create mode 100644 src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionResponseDTO.java create mode 100644 src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionUpdatedEvent.java diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java new file mode 100644 index 0000000..2abd18f --- /dev/null +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java @@ -0,0 +1,98 @@ +package com.codzilla.backend.controller.Sandbox.submission; + +import com.codzilla.backend.User.User; +import com.codzilla.backend.User.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; + +import java.security.Principal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/my-submissions") +@RequiredArgsConstructor +public class SubmissionController { + + private final SubmissionRepository submissionRepository; + private final UserRepository userRepository; + + private final Map>>>> waiters = new ConcurrentHashMap<>(); + + @GetMapping + public DeferredResult>> getUserSubmissions( + Principal principal, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime lastUpdate) { + + DeferredResult>> output = new DeferredResult<>(20000L); + + if (principal == null) { + output.setResult(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()); + return output; + } + + User user = userRepository.findByEmail(principal.getName()) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + + UUID userId = user.getId(); + + output.onTimeout(() -> output.setResult(ResponseEntity.status(HttpStatus.NOT_MODIFIED).build())); + + Optional latestSub = submissionRepository.findFirstByUserIdOrderByUpdatedAtDesc(userId); + boolean hasUpdates = lastUpdate == null || + (latestSub.isPresent() && latestSub.get().getUpdatedAt().isAfter(lastUpdate)); + + if (hasUpdates) { + output.setResult(ResponseEntity.ok(fetchUserSubmissions(userId))); + return output; + } + + waiters.computeIfAbsent(userId, k -> new ConcurrentLinkedQueue<>()).add(output); + + output.onCompletion(() -> { + ConcurrentLinkedQueue>>> queue = waiters.get(userId); + if (queue != null) { + queue.remove(output); + } + }); + + return output; + } + + @EventListener + public void onSubmissionUpdated(SubmissionUpdatedEvent event) { + ConcurrentLinkedQueue>>> queue = waiters.get(event.userId()); + + if (queue != null && !queue.isEmpty()) { + List freshData = fetchUserSubmissions(event.userId()); + + DeferredResult>> result; + while ((result = queue.poll()) != null) { + result.setResult(ResponseEntity.ok(freshData)); + } + } + } + + private List fetchUserSubmissions(UUID userId) { + return submissionRepository + .findAllByUserIdOrderByCreatedAtDesc(userId) + .stream() + .map(SubmissionResponseDTO::fromEntity) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java index dc51dd1..9b2a0a3 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java @@ -6,6 +6,11 @@ import com.codzilla.backend.controller.Sandbox.problem.ProblemRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; + +import com.codzilla.backend.controller.Sandbox.submission.SubmissionUpdatedEvent; + +import org.springframework.context.ApplicationEventPublisher; + import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -22,6 +27,8 @@ public class SubmissionPollingService { final private PolygonProblemService polygonProblemService; final private ProblemRepository problemRepository; + private final ApplicationEventPublisher eventPublisher; + @Scheduled(fixedDelay = 2000) public void pollStatuses() { List pending = submissionRepository.findAllByStatus(Submission.Status.IN_QUEUE); @@ -51,7 +58,6 @@ private void updateSubmissionStatus(Submission sub, Judge0Client.SubmissionRespo log.info("Submission {} finished with verdict: {}", sub.getId(), description); - - + eventPublisher.publishEvent(new SubmissionUpdatedEvent(sub.getUserId())); } } \ No newline at end of file diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionRepository.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionRepository.java index e9cce27..f168331 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionRepository.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionRepository.java @@ -1,11 +1,16 @@ package com.codzilla.backend.controller.Sandbox.submission; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; - @Repository public interface SubmissionRepository extends JpaRepository { List findAllByStatus(Submission.Status status); + + List findAllByUserIdOrderByCreatedAtDesc(UUID userId); + Optional findFirstByUserIdOrderByUpdatedAtDesc(UUID userId); } diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionResponseDTO.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionResponseDTO.java new file mode 100644 index 0000000..b974a4e --- /dev/null +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionResponseDTO.java @@ -0,0 +1,23 @@ +package com.codzilla.backend.controller.Sandbox.submission; + +import java.time.LocalDateTime; + +public record SubmissionResponseDTO( + Long id, + Long problemId, + Integer languageId, + String status, + LocalDateTime createdAt, + LocalDateTime updatedAt +) { + public static SubmissionResponseDTO fromEntity(Submission submission) { + return new SubmissionResponseDTO( + submission.getId(), + submission.getProblemId(), + submission.getLanguageId(), + submission.getStatus().name(), + submission.getCreatedAt(), + submission.getUpdatedAt() + ); + } +} \ No newline at end of file diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionUpdatedEvent.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionUpdatedEvent.java new file mode 100644 index 0000000..3938746 --- /dev/null +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionUpdatedEvent.java @@ -0,0 +1,5 @@ +package com.codzilla.backend.controller.Sandbox.submission; + +import java.util.UUID; + +public record SubmissionUpdatedEvent(UUID userId) {} \ No newline at end of file From 9b61294faae8952505f9672aed8fb55bd51c7552 Mon Sep 17 00:00:00 2001 From: CO0LGIRL Date: Tue, 21 Apr 2026 03:25:26 +0300 Subject: [PATCH 2/4] fix: long polling auth and connection pool leak --- .../JWTRequestFilter/JWTRequestFilter.java | 9 ++++--- .../Authentication/config/SecurityConfig.java | 3 ++- .../Sandbox/submission/Submission.java | 10 +++++--- .../submission/SubmissionController.java | 25 ++++++++----------- .../submission/SubmissionPollingService.java | 11 ++++++-- 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java b/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java index 45ad909..2e892d7 100644 --- a/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java +++ b/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java @@ -1,5 +1,6 @@ package com.codzilla.backend.Authentication.JWTRequestFilter; +import com.codzilla.backend.Authentication.RepositoryUserDetailsService; import com.codzilla.backend.User.User; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; @@ -21,9 +22,11 @@ @Component public class JWTRequestFilter extends OncePerRequestFilter { JWTUtils jwtUtils; + RepositoryUserDetailsService userDetailsService; - public JWTRequestFilter(JWTUtils jwtUtils) { + public JWTRequestFilter(JWTUtils jwtUtils, RepositoryUserDetailsService userDetailsService) { this.jwtUtils = jwtUtils; + this.userDetailsService = userDetailsService; } @Override @@ -51,8 +54,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse .map(SimpleGrantedAuthority::new) .toList(); - User user = User.builder() - .email(email).build(); + User user = (User) userDetailsService.loadUserByUsername(email); + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( user, null, diff --git a/src/main/java/com/codzilla/backend/Authentication/config/SecurityConfig.java b/src/main/java/com/codzilla/backend/Authentication/config/SecurityConfig.java index 5c1353d..4bf1654 100644 --- a/src/main/java/com/codzilla/backend/Authentication/config/SecurityConfig.java +++ b/src/main/java/com/codzilla/backend/Authentication/config/SecurityConfig.java @@ -3,6 +3,7 @@ import com.codzilla.backend.Authentication.AdminAccessDeniedHandler; import com.codzilla.backend.Authentication.HttpStatusEntryPoint; import com.codzilla.backend.Authentication.JWTRequestFilter.JWTRequestFilter; +import jakarta.servlet.DispatcherType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; @@ -49,7 +50,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, JWTRequestFilter filte .accessDeniedHandler(adminAccessDeniedHandler) ) .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .authorizeHttpRequests(auth -> auth.requestMatchers(WHITELIST).permitAll().anyRequest().authenticated()) + .authorizeHttpRequests(auth -> auth.dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll().requestMatchers(WHITELIST).permitAll().anyRequest().authenticated()) .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class).build(); } diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/Submission.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/Submission.java index 377f9be..0885f78 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/Submission.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/Submission.java @@ -3,25 +3,29 @@ import jakarta.persistence.*; import lombok.Data; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.time.LocalDateTime; import java.util.List; +import java.util.UUID; @Entity @Table(name = "submissions") @Data public class Submission { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private int retryCount = 0; private Long problemId; - private Long userId; + + @JdbcTypeCode(SqlTypes.UUID) + private UUID userId; @Column(columnDefinition = "TEXT") private String sourceCode; diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java index 2abd18f..e0fc357 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java @@ -1,20 +1,19 @@ package com.codzilla.backend.controller.Sandbox.submission; import com.codzilla.backend.User.User; -import com.codzilla.backend.User.UserRepository; +// UserRepository удален за ненадобностью import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.core.annotation.AuthenticationPrincipal; // Добавлен импорт import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; -import java.security.Principal; import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -30,31 +29,29 @@ public class SubmissionController { private final SubmissionRepository submissionRepository; - private final UserRepository userRepository; private final Map>>>> waiters = new ConcurrentHashMap<>(); @GetMapping public DeferredResult>> getUserSubmissions( - Principal principal, + @AuthenticationPrincipal User user, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime lastUpdate) { DeferredResult>> output = new DeferredResult<>(20000L); - if (principal == null) { - output.setResult(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()); - return output; + if (user != null) { + System.out.println("Principal class: " + user.getClass().getName()); + System.out.println("::" + user.getId()); + } else { + System.out.println("Principal is NULL"); } - User user = userRepository.findByEmail(principal.getName()) - .orElseThrow(() -> new UsernameNotFoundException("User not found")); - UUID userId = user.getId(); output.onTimeout(() -> output.setResult(ResponseEntity.status(HttpStatus.NOT_MODIFIED).build())); Optional latestSub = submissionRepository.findFirstByUserIdOrderByUpdatedAtDesc(userId); - boolean hasUpdates = lastUpdate == null || + boolean hasUpdates = lastUpdate == null || (latestSub.isPresent() && latestSub.get().getUpdatedAt().isAfter(lastUpdate)); if (hasUpdates) { @@ -77,10 +74,10 @@ public DeferredResult>> getUserSubmis @EventListener public void onSubmissionUpdated(SubmissionUpdatedEvent event) { ConcurrentLinkedQueue>>> queue = waiters.get(event.userId()); - + if (queue != null && !queue.isEmpty()) { List freshData = fetchUserSubmissions(event.userId()); - + DeferredResult>> result; while ((result = queue.poll()) != null) { result.setResult(ResponseEntity.ok(freshData)); diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java index 9b2a0a3..ff906a3 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java @@ -13,6 +13,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; @@ -29,10 +30,16 @@ public class SubmissionPollingService { private final ApplicationEventPublisher eventPublisher; + @Transactional(readOnly = true) + public List getPendingSubmissions() { + return submissionRepository.findAllByStatus(Submission.Status.IN_QUEUE); + } + @Scheduled(fixedDelay = 2000) public void pollStatuses() { - List pending = submissionRepository.findAllByStatus(Submission.Status.IN_QUEUE); - for (Submission sub : pending) { + List pending = getPendingSubmissions(); // транзакция закрылась здесь + + for (Submission sub : pending) { // Judge0 вызывается уже без открытой транзакции var response = judge0Client.getSubmissionStatus(sub.getJudge0Token()); if (response != null && response.getStatus() != null && response.getStatus().getId() > 2) { updateSubmissionStatus(sub, response); From 161e2cb0de7328dd3ac86b328c951f9fae067c51 Mon Sep 17 00:00:00 2001 From: CO0LGIRL Date: Tue, 21 Apr 2026 03:34:09 +0300 Subject: [PATCH 3/4] refactor: remove comment --- .../Sandbox/submission/SubmissionController.java | 11 ++++------- .../Sandbox/submission/SubmissionPollingService.java | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java index e0fc357..9680f20 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java @@ -1,13 +1,12 @@ package com.codzilla.backend.controller.Sandbox.submission; import com.codzilla.backend.User.User; -// UserRepository удален за ненадобностью import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; // Добавлен импорт +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -39,11 +38,9 @@ public DeferredResult>> getUserSubmis DeferredResult>> output = new DeferredResult<>(20000L); - if (user != null) { - System.out.println("Principal class: " + user.getClass().getName()); - System.out.println("::" + user.getId()); - } else { - System.out.println("Principal is NULL"); + if (user == null) { + output.setResult(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build()); + return output; } UUID userId = user.getId(); diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java index ff906a3..f3a6555 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionPollingService.java @@ -37,9 +37,9 @@ public List getPendingSubmissions() { @Scheduled(fixedDelay = 2000) public void pollStatuses() { - List pending = getPendingSubmissions(); // транзакция закрылась здесь + List pending = getPendingSubmissions(); - for (Submission sub : pending) { // Judge0 вызывается уже без открытой транзакции + for (Submission sub : pending) { var response = judge0Client.getSubmissionStatus(sub.getJudge0Token()); if (response != null && response.getStatus() != null && response.getStatus().getId() > 2) { updateSubmissionStatus(sub, response); From 8cc038a8f47b7de68e6d3b7e39a41a31e8a0ba2b Mon Sep 17 00:00:00 2001 From: CO0LGIRL Date: Tue, 21 Apr 2026 17:16:22 +0300 Subject: [PATCH 4/4] refactor: resolve full user from db in controller instead of filter --- .../JWTRequestFilter/JWTRequestFilter.java | 9 +++------ .../Sandbox/submission/SubmissionController.java | 7 ++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java b/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java index 2e892d7..45ad909 100644 --- a/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java +++ b/src/main/java/com/codzilla/backend/Authentication/JWTRequestFilter/JWTRequestFilter.java @@ -1,6 +1,5 @@ package com.codzilla.backend.Authentication.JWTRequestFilter; -import com.codzilla.backend.Authentication.RepositoryUserDetailsService; import com.codzilla.backend.User.User; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; @@ -22,11 +21,9 @@ @Component public class JWTRequestFilter extends OncePerRequestFilter { JWTUtils jwtUtils; - RepositoryUserDetailsService userDetailsService; - public JWTRequestFilter(JWTUtils jwtUtils, RepositoryUserDetailsService userDetailsService) { + public JWTRequestFilter(JWTUtils jwtUtils) { this.jwtUtils = jwtUtils; - this.userDetailsService = userDetailsService; } @Override @@ -54,8 +51,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse .map(SimpleGrantedAuthority::new) .toList(); - User user = (User) userDetailsService.loadUserByUsername(email); - + User user = User.builder() + .email(email).build(); UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( user, null, diff --git a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java index 9680f20..d73133a 100644 --- a/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java +++ b/src/main/java/com/codzilla/backend/controller/Sandbox/submission/SubmissionController.java @@ -1,12 +1,14 @@ package com.codzilla.backend.controller.Sandbox.submission; import com.codzilla.backend.User.User; +import com.codzilla.backend.User.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -30,6 +32,7 @@ public class SubmissionController { private final SubmissionRepository submissionRepository; private final Map>>>> waiters = new ConcurrentHashMap<>(); + private final UserRepository userRepository; @GetMapping public DeferredResult>> getUserSubmissions( @@ -43,7 +46,9 @@ public DeferredResult>> getUserSubmis return output; } - UUID userId = user.getId(); + User fullUser = userRepository.findByEmail(user.getEmail()) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + UUID userId = fullUser.getId(); output.onTimeout(() -> output.setResult(ResponseEntity.status(HttpStatus.NOT_MODIFIED).build()));