Skip to content

Instantly share code, notes, and snippets.

@Marthym
Last active October 15, 2022 21:11
Show Gist options
  • Save Marthym/b75a7d43c2490744319265630b5eb084 to your computer and use it in GitHub Desktop.
Save Marthym/b75a7d43c2490744319265630b5eb084 to your computer and use it in GitHub Desktop.
package fr.ght1pc9kc.baywatch.notify.infra;
import fr.ght1pc9kc.baywatch.notify.api.NotifyManager;
import fr.ght1pc9kc.baywatch.notify.api.model.BasicEvent;
import fr.ght1pc9kc.baywatch.notify.api.model.EventType;
import fr.ght1pc9kc.baywatch.notify.api.model.ReactiveEvent;
import fr.ght1pc9kc.baywatch.notify.api.model.ServerEventVisitor;
import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
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 reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Slf4j
@RestController
@RequiredArgsConstructor
@PreAuthorize("hasAnyRole('USER', 'MANAGER', 'ADMIN')")
@RequestMapping("${baywatch.base-route}/sse")
public class NotificationController {
private final NotifyManager notifyManager;
private final AuthenticationFacade facade;
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Object>> sse() {
return notifyManager.subscribe().flatMap(evt ->
evt.accept(new ServerEventVisitor<Mono<?>>() {
@Override
public <T> Mono<T> visit(BasicEvent<T> event) {
return Mono.just(event.message());
}
@Override
public <T> Mono<T> visit(ReactiveEvent<T> event) {
return event.message();
}
})
.map(msg -> ServerSentEvent.builder()
.id(evt.id())
.event(evt.type().getName()).data(msg)
.build()));
}
@DeleteMapping
public Mono<ResponseEntity<Object>> disposeSse() {
return notifyManager.unsubscribe()
.map(ignore -> ResponseEntity.noContent().build())
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment