@MessageMapping("flux") public Flux<String> handleFlux() { this.flux = EmitterProcessor.create(); return this.flux; }
@Test public void createDefault() { EmitterProcessor<Integer> processor = EmitterProcessor.create(); assertProcessor(processor, null, null); }
@Test public void createOverrideAutoCancel() { boolean autoCancel = false; EmitterProcessor<Integer> processor = EmitterProcessor.create(autoCancel); assertProcessor(processor, null, autoCancel); }
@Test public void scanMainError() { EmitterProcessor test = EmitterProcessor.create(); test.sink().error(new IllegalStateException("boom")); assertThat(test.scan(Attr.ERROR)).hasMessage("boom"); } }
@Test public void scanMainCancelled() { EmitterProcessor test = EmitterProcessor.create(); test.onSubscribe(Operators.cancelledSubscription()); assertThat(test.scan(CANCELLED)).isTrue(); assertThat(test.isCancelled()).isTrue(); }
@Test public void ignoreDoubleOnSubscribe() { EmitterProcessor<Integer> ep = EmitterProcessor.create(); ep.sink(); assertThat(ep.sink().isCancelled()).isTrue(); }
@Test public void cancel() { final EmitterProcessor<Boolean> pp = EmitterProcessor.create(); StepVerifier.create(Flux.range(1, 5) .filterWhen(v -> pp, 16)) .thenCancel(); assertThat(pp.hasDownstreams()).isFalse(); }
@Test public void deferredResultSubscriberWithMultipleValues() throws Exception { // JSON must be preferred for Flux<String> -> List<String> or else we stream this.servletRequest.addHeader("Accept", "application/json"); Bar bar1 = new Bar("foo"); Bar bar2 = new Bar("bar"); EmitterProcessor<Bar> emitter = EmitterProcessor.create(); testDeferredResultSubscriber(emitter, Flux.class, forClass(Bar.class), () -> { emitter.onNext(bar1); emitter.onNext(bar2); emitter.onComplete(); }, Arrays.asList(bar1, bar2)); }
@Test // SPR-17076 public void responseEntityFluxWithCustomHeader() throws Exception { EmitterProcessor<SimpleBean> processor = EmitterProcessor.create(); ResponseEntity<Flux<SimpleBean>> entity = ResponseEntity.ok().header("x-foo", "bar").body(processor); ResolvableType bodyType = forClassWithGenerics(Flux.class, SimpleBean.class); MethodParameter type = on(TestController.class).resolveReturnType(ResponseEntity.class, bodyType); this.handler.handleReturnValue(entity, type, this.mavContainer, this.webRequest); assertTrue(this.request.isAsyncStarted()); assertEquals(200, this.response.getStatus()); assertEquals("bar", this.response.getHeader("x-foo")); assertFalse(this.response.isCommitted()); }
@Test public void subscribeWithSyncFusionMultiple() { Processor<Integer, Integer> processor = EmitterProcessor.create(16); StepVerifier.create(processor) .then(() -> Flux.range(1, 5).subscribe(processor)) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(Duration.ofSeconds(1)); }
@Test public void responseEntityFlux() throws Exception { EmitterProcessor<String> processor = EmitterProcessor.create(); ResponseEntity<Flux<String>> entity = ResponseEntity.ok().body(processor); ResolvableType bodyType = forClassWithGenerics(Flux.class, String.class); MethodParameter type = on(TestController.class).resolveReturnType(ResponseEntity.class, bodyType); this.handler.handleReturnValue(entity, type, this.mavContainer, this.webRequest); assertTrue(this.request.isAsyncStarted()); assertEquals(200, this.response.getStatus()); assertEquals("text/plain", this.response.getContentType()); processor.onNext("foo"); processor.onNext("bar"); processor.onNext("baz"); processor.onComplete(); assertEquals("foobarbaz", this.response.getContentAsString()); }
@Test public void writeText() throws Exception { EmitterProcessor<String> processor = EmitterProcessor.create(); ResponseBodyEmitter emitter = handleValue(processor, Flux.class, forClass(String.class)); EmitterHandler emitterHandler = new EmitterHandler(); emitter.initialize(emitterHandler); processor.onNext("The quick"); processor.onNext(" brown fox jumps over "); processor.onNext("the lazy dog"); processor.onComplete(); assertEquals("The quick brown fox jumps over the lazy dog", emitterHandler.getValuesAsText()); }
@Test public void testRed() { FluxProcessor<String, String> processor = EmitterProcessor.create(); AssertSubscriber<String> subscriber = AssertSubscriber.create(1); processor.subscribe(subscriber); Flux.fromIterable(DATA) .log() .subscribe(processor); subscriber.awaitAndAssertNextValues("1"); }
@Test public void cancelComposes2() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); EmitterProcessor<Integer> sp = EmitterProcessor.create(); sp.publish(o -> Flux.<Integer>empty()) .subscribe(ts); Assert.assertFalse("Still subscribed?", sp.downstreamCount() == 1); }
@Test public void testGreen() { FluxProcessor<String, String> processor = EmitterProcessor.create(); AssertSubscriber<String> subscriber = AssertSubscriber.create(1); processor.subscribe(subscriber); Flux.fromIterable(DATA) .log() .subscribe(processor); subscriber.awaitAndAssertNextValues("1"); }
@Test public void writeServerSentEvents() throws Exception { this.servletRequest.addHeader("Accept", "text/event-stream"); EmitterProcessor<String> processor = EmitterProcessor.create(); SseEmitter sseEmitter = (SseEmitter) handleValue(processor, Flux.class, forClass(String.class)); EmitterHandler emitterHandler = new EmitterHandler(); sseEmitter.initialize(emitterHandler); processor.onNext("foo"); processor.onNext("bar"); processor.onNext("baz"); processor.onComplete(); assertEquals("data:foo\n\ndata:bar\n\ndata:baz\n\n", emitterHandler.getValuesAsText()); }
@Test public void writeStreamJson() throws Exception { this.servletRequest.addHeader("Accept", "application/stream+json"); EmitterProcessor<Bar> processor = EmitterProcessor.create(); ResponseBodyEmitter emitter = handleValue(processor, Flux.class, forClass(Bar.class)); EmitterHandler emitterHandler = new EmitterHandler(); emitter.initialize(emitterHandler); ServletServerHttpResponse message = new ServletServerHttpResponse(this.servletResponse); emitter.extendResponse(message); Bar bar1 = new Bar("foo"); Bar bar2 = new Bar("bar"); processor.onNext(bar1); processor.onNext(bar2); processor.onComplete(); assertEquals("application/stream+json", message.getHeaders().getContentType().toString()); assertEquals(Arrays.asList(bar1, "\n", bar2, "\n"), emitterHandler.getValues()); }
@Test public void cancelComposes() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); EmitterProcessor<Integer> sp = EmitterProcessor.create(); sp.publish(o -> Flux.<Integer>never()) .subscribe(ts); Assert.assertTrue("Not subscribed?", sp.downstreamCount() != 0); ts.cancel(); Assert.assertTrue("Still subscribed?", sp.downstreamCount() == 0); }
@Test public void responseBodyFlux() throws Exception { this.request.addHeader("Accept", "text/event-stream"); MethodParameter type = on(TestController.class).resolveReturnType(Flux.class, String.class); EmitterProcessor<String> processor = EmitterProcessor.create(); this.handler.handleReturnValue(processor, type, this.mavContainer, this.webRequest); assertTrue(this.request.isAsyncStarted()); assertEquals(200, this.response.getStatus()); assertEquals("text/event-stream;charset=UTF-8", this.response.getContentType()); processor.onNext("foo"); processor.onNext("bar"); processor.onNext("baz"); processor.onComplete(); assertEquals("data:foo\n\ndata:bar\n\ndata:baz\n\n", this.response.getContentAsString()); }
@Test public void writeServerSentEventsWithBuilder() throws Exception { ResolvableType type = ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class); EmitterProcessor<ServerSentEvent<?>> processor = EmitterProcessor.create(); SseEmitter sseEmitter = (SseEmitter) handleValue(processor, Flux.class, type); EmitterHandler emitterHandler = new EmitterHandler(); sseEmitter.initialize(emitterHandler); processor.onNext(ServerSentEvent.builder("foo").id("1").build()); processor.onNext(ServerSentEvent.builder("bar").id("2").build()); processor.onNext(ServerSentEvent.builder("baz").id("3").build()); processor.onComplete(); assertEquals("id:1\ndata:foo\n\nid:2\ndata:bar\n\nid:3\ndata:baz\n\n", emitterHandler.getValuesAsText()); }