mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-23 04:22:17 +00:00
CompositeServerHttpHeadersWriter Executes Sequentially
Fixes gh-7731
This commit is contained in:
parent
1136660518
commit
0f8927b500
@ -15,14 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.security.web.server.header;
|
package org.springframework.security.web.server.header;
|
||||||
|
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines multiple {@link ServerHttpHeadersWriter} instances into a single instance.
|
* Combines multiple {@link ServerHttpHeadersWriter} instances into a single instance.
|
||||||
@ -43,8 +41,9 @@ public class CompositeServerHttpHeadersWriter implements ServerHttpHeadersWriter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
|
public Mono<Void> writeHttpHeaders(ServerWebExchange exchange) {
|
||||||
Stream<Mono<Void>> results = writers.stream().map( writer -> writer.writeHttpHeaders(exchange));
|
return Flux.fromIterable(this.writers)
|
||||||
return Mono.when(results.collect(Collectors.toList()));
|
.concatMap(w -> w.writeHttpHeaders(exchange))
|
||||||
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.security.web.server.header;
|
package org.springframework.security.web.server.header;
|
||||||
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -28,10 +23,19 @@ import org.mockito.junit.MockitoJUnitRunner;
|
|||||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
@ -55,7 +59,6 @@ public class CompositeServerHttpHeadersWriterTests {
|
|||||||
@Test
|
@Test
|
||||||
public void writeHttpHeadersWhenErrorNoErrorThenError() {
|
public void writeHttpHeadersWhenErrorNoErrorThenError() {
|
||||||
when(writer1.writeHttpHeaders(exchange)).thenReturn(Mono.error(new RuntimeException()));
|
when(writer1.writeHttpHeaders(exchange)).thenReturn(Mono.error(new RuntimeException()));
|
||||||
when(writer2.writeHttpHeaders(exchange)).thenReturn(Mono.empty());
|
|
||||||
|
|
||||||
Mono<Void> result = writer.writeHttpHeaders(exchange);
|
Mono<Void> result = writer.writeHttpHeaders(exchange);
|
||||||
|
|
||||||
@ -64,13 +67,11 @@ public class CompositeServerHttpHeadersWriterTests {
|
|||||||
.verify();
|
.verify();
|
||||||
|
|
||||||
verify(writer1).writeHttpHeaders(exchange);
|
verify(writer1).writeHttpHeaders(exchange);
|
||||||
verify(writer2).writeHttpHeaders(exchange);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void writeHttpHeadersWhenErrorErrorThenError() {
|
public void writeHttpHeadersWhenErrorErrorThenError() {
|
||||||
when(writer1.writeHttpHeaders(exchange)).thenReturn(Mono.error(new RuntimeException()));
|
when(writer1.writeHttpHeaders(exchange)).thenReturn(Mono.error(new RuntimeException()));
|
||||||
when(writer2.writeHttpHeaders(exchange)).thenReturn(Mono.error(new RuntimeException()));
|
|
||||||
|
|
||||||
Mono<Void> result = writer.writeHttpHeaders(exchange);
|
Mono<Void> result = writer.writeHttpHeaders(exchange);
|
||||||
|
|
||||||
@ -79,7 +80,6 @@ public class CompositeServerHttpHeadersWriterTests {
|
|||||||
.verify();
|
.verify();
|
||||||
|
|
||||||
verify(writer1).writeHttpHeaders(exchange);
|
verify(writer1).writeHttpHeaders(exchange);
|
||||||
verify(writer2).writeHttpHeaders(exchange);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -96,4 +96,26 @@ public class CompositeServerHttpHeadersWriterTests {
|
|||||||
verify(writer1).writeHttpHeaders(exchange);
|
verify(writer1).writeHttpHeaders(exchange);
|
||||||
verify(writer2).writeHttpHeaders(exchange);
|
verify(writer2).writeHttpHeaders(exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeHttpHeadersSequential() throws Exception {
|
||||||
|
AtomicBoolean slowDone = new AtomicBoolean();
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
ServerHttpHeadersWriter slow = exchange ->
|
||||||
|
Mono.delay(Duration.ofMillis(100))
|
||||||
|
.doOnSuccess(__ -> slowDone.set(true))
|
||||||
|
.then();
|
||||||
|
ServerHttpHeadersWriter second = exchange ->
|
||||||
|
Mono.fromRunnable(() -> {
|
||||||
|
latch.countDown();
|
||||||
|
assertThat(slowDone.get())
|
||||||
|
.describedAs("ServerLogoutHandler should be executed sequentially")
|
||||||
|
.isTrue();
|
||||||
|
});
|
||||||
|
CompositeServerHttpHeadersWriter writer = new CompositeServerHttpHeadersWriter(slow, second);
|
||||||
|
|
||||||
|
writer.writeHttpHeaders(this.exchange).block();
|
||||||
|
|
||||||
|
assertThat(latch.await(3, TimeUnit.SECONDS)).isTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user