|
|
|
@ -16,8 +16,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.web.context.request; |
|
|
|
package org.springframework.web.context.request; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
import java.util.concurrent.atomic.AtomicReference; |
|
|
|
import java.util.concurrent.atomic.AtomicReference; |
|
|
|
import java.util.stream.Stream; |
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
|
|
|
@ -25,13 +23,10 @@ import io.micrometer.context.ContextRegistry; |
|
|
|
import io.micrometer.context.ContextSnapshot; |
|
|
|
import io.micrometer.context.ContextSnapshot; |
|
|
|
import io.micrometer.context.ContextSnapshot.Scope; |
|
|
|
import io.micrometer.context.ContextSnapshot.Scope; |
|
|
|
import io.micrometer.context.ContextSnapshotFactory; |
|
|
|
import io.micrometer.context.ContextSnapshotFactory; |
|
|
|
import org.junit.jupiter.api.AfterEach; |
|
|
|
|
|
|
|
import org.junit.jupiter.params.ParameterizedTest; |
|
|
|
import org.junit.jupiter.params.ParameterizedTest; |
|
|
|
import org.junit.jupiter.params.provider.Arguments; |
|
|
|
import org.junit.jupiter.params.provider.Arguments; |
|
|
|
import org.junit.jupiter.params.provider.MethodSource; |
|
|
|
import org.junit.jupiter.params.provider.MethodSource; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
|
|
|
|
|
|
|
|
@ -39,52 +34,55 @@ import static org.mockito.Mockito.mock; |
|
|
|
* Tests for {@link RequestAttributesThreadLocalAccessor}. |
|
|
|
* Tests for {@link RequestAttributesThreadLocalAccessor}. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Tadaya Tsuyukubo |
|
|
|
* @author Tadaya Tsuyukubo |
|
|
|
|
|
|
|
* @author Rossen Stoyanchev |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class RequestAttributesThreadLocalAccessorTests { |
|
|
|
class RequestAttributesThreadLocalAccessorTests { |
|
|
|
|
|
|
|
|
|
|
|
private final ContextRegistry registry = new ContextRegistry() |
|
|
|
private final ContextRegistry registry = |
|
|
|
.registerThreadLocalAccessor(new RequestAttributesThreadLocalAccessor()); |
|
|
|
new ContextRegistry().registerThreadLocalAccessor(new RequestAttributesThreadLocalAccessor()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@AfterEach |
|
|
|
private static Stream<Arguments> propagation() { |
|
|
|
void cleanUp() { |
|
|
|
RequestAttributes previous = mock(RequestAttributes.class); |
|
|
|
RequestContextHolder.resetRequestAttributes(); |
|
|
|
RequestAttributes current = mock(RequestAttributes.class); |
|
|
|
|
|
|
|
return Stream.of(Arguments.of(null, current), Arguments.of(previous, current)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ParameterizedTest |
|
|
|
@ParameterizedTest |
|
|
|
@MethodSource |
|
|
|
@MethodSource |
|
|
|
@SuppressWarnings({ "try", "unused" }) |
|
|
|
@SuppressWarnings({ "try", "unused" }) |
|
|
|
void propagation(@Nullable RequestAttributes previous, RequestAttributes current) throws Exception { |
|
|
|
void propagation(RequestAttributes previousRequest, RequestAttributes currentRequest) throws Exception { |
|
|
|
RequestContextHolder.setRequestAttributes(current); |
|
|
|
|
|
|
|
ContextSnapshot snapshot = ContextSnapshotFactory.builder() |
|
|
|
ContextSnapshot snapshot = getSnapshotFor(currentRequest); |
|
|
|
.contextRegistry(this.registry) |
|
|
|
|
|
|
|
.clearMissing(true) |
|
|
|
AtomicReference<RequestAttributes> requestInScope = new AtomicReference<>(); |
|
|
|
.build() |
|
|
|
AtomicReference<RequestAttributes> requestAfterScope = new AtomicReference<>(); |
|
|
|
.captureAll(); |
|
|
|
|
|
|
|
|
|
|
|
Thread thread = new Thread(() -> { |
|
|
|
AtomicReference<RequestAttributes> previousHolder = new AtomicReference<>(); |
|
|
|
RequestContextHolder.setRequestAttributes(previousRequest); |
|
|
|
AtomicReference<RequestAttributes> currentHolder = new AtomicReference<>(); |
|
|
|
|
|
|
|
CountDownLatch latch = new CountDownLatch(1); |
|
|
|
|
|
|
|
new Thread(() -> { |
|
|
|
|
|
|
|
RequestContextHolder.setRequestAttributes(previous); |
|
|
|
|
|
|
|
try (Scope scope = snapshot.setThreadLocals()) { |
|
|
|
try (Scope scope = snapshot.setThreadLocals()) { |
|
|
|
currentHolder.set(RequestContextHolder.getRequestAttributes()); |
|
|
|
requestInScope.set(RequestContextHolder.getRequestAttributes()); |
|
|
|
} |
|
|
|
} |
|
|
|
previousHolder.set(RequestContextHolder.getRequestAttributes()); |
|
|
|
requestAfterScope.set(RequestContextHolder.getRequestAttributes()); |
|
|
|
latch.countDown(); |
|
|
|
}); |
|
|
|
}).start(); |
|
|
|
|
|
|
|
|
|
|
|
thread.start(); |
|
|
|
|
|
|
|
thread.join(1000); |
|
|
|
|
|
|
|
|
|
|
|
latch.await(1, TimeUnit.SECONDS); |
|
|
|
assertThat(requestInScope).hasValueSatisfying(value -> assertThat(value).isSameAs(currentRequest)); |
|
|
|
assertThat(previousHolder).hasValueSatisfying(value -> assertThat(value).isSameAs(previous)); |
|
|
|
assertThat(requestAfterScope).hasValueSatisfying(value -> assertThat(value).isSameAs(previousRequest)); |
|
|
|
assertThat(currentHolder).hasValueSatisfying(value -> assertThat(value).isSameAs(current)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static Stream<Arguments> propagation() { |
|
|
|
private ContextSnapshot getSnapshotFor(RequestAttributes request) { |
|
|
|
RequestAttributes previous = mock(RequestAttributes.class); |
|
|
|
RequestContextHolder.setRequestAttributes(request); |
|
|
|
RequestAttributes current = mock(RequestAttributes.class); |
|
|
|
try { |
|
|
|
return Stream.of( |
|
|
|
return ContextSnapshotFactory.builder() |
|
|
|
Arguments.of(null, current), |
|
|
|
.contextRegistry(this.registry).clearMissing(true).build() |
|
|
|
Arguments.of(previous, current) |
|
|
|
.captureAll(); |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
finally { |
|
|
|
|
|
|
|
RequestContextHolder.resetRequestAttributes(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|