1717package org .springframework .boot .actuate .endpoint .invoker .cache ;
1818
1919import java .security .Principal ;
20+ import java .util .Arrays ;
2021import java .util .Collections ;
2122import java .util .HashMap ;
2223import java .util .Map ;
2324
2425import org .junit .Test ;
26+ import reactor .core .publisher .Flux ;
27+ import reactor .core .publisher .Mono ;
2528
2629import org .springframework .boot .actuate .endpoint .InvocationContext ;
2730import org .springframework .boot .actuate .endpoint .SecurityContext ;
31+ import org .springframework .boot .actuate .endpoint .invoke .MissingParametersException ;
2832import org .springframework .boot .actuate .endpoint .invoke .OperationInvoker ;
2933
3034import static org .assertj .core .api .Assertions .assertThat ;
3943 * Tests for {@link CachingOperationInvoker}.
4044 *
4145 * @author Stephane Nicoll
46+ * @author Christoph Dreis
47+ * @author Phillip Webb
4248 */
4349public class CachingOperationInvokerTests {
4450
@@ -62,6 +68,30 @@ public void cacheInTtlWithNullParameters() {
6268 assertCacheIsUsed (parameters );
6369 }
6470
71+ @ Test
72+ public void cacheInTtlWithMonoResponse () {
73+ MonoOperationInvoker .invocations = 0 ;
74+ MonoOperationInvoker target = new MonoOperationInvoker ();
75+ InvocationContext context = new InvocationContext (mock (SecurityContext .class ), Collections .emptyMap ());
76+ CachingOperationInvoker invoker = new CachingOperationInvoker (target , 500L );
77+ Object response = ((Mono <?>) invoker .invoke (context )).block ();
78+ Object cachedResponse = ((Mono <?>) invoker .invoke (context )).block ();
79+ assertThat (MonoOperationInvoker .invocations ).isEqualTo (1 );
80+ assertThat (response ).isSameAs (cachedResponse );
81+ }
82+
83+ @ Test
84+ public void cacheInTtlWithFluxResponse () {
85+ FluxOperationInvoker .invocations = 0 ;
86+ FluxOperationInvoker target = new FluxOperationInvoker ();
87+ InvocationContext context = new InvocationContext (mock (SecurityContext .class ), Collections .emptyMap ());
88+ CachingOperationInvoker invoker = new CachingOperationInvoker (target , 500L );
89+ Object response = ((Flux <?>) invoker .invoke (context )).blockLast ();
90+ Object cachedResponse = ((Flux <?>) invoker .invoke (context )).blockLast ();
91+ assertThat (FluxOperationInvoker .invocations ).isEqualTo (1 );
92+ assertThat (response ).isSameAs (cachedResponse );
93+ }
94+
6595 private void assertCacheIsUsed (Map <String , Object > parameters ) {
6696 OperationInvoker target = mock (OperationInvoker .class );
6797 Object expected = new Object ();
@@ -119,4 +149,32 @@ public void targetInvokedWhenCacheExpires() throws InterruptedException {
119149 verify (target , times (2 )).invoke (context );
120150 }
121151
152+ private static class MonoOperationInvoker implements OperationInvoker {
153+
154+ static int invocations ;
155+
156+ @ Override
157+ public Object invoke (InvocationContext context ) throws MissingParametersException {
158+ return Mono .fromCallable (() -> {
159+ invocations ++;
160+ return Mono .just ("test" );
161+ });
162+ }
163+
164+ }
165+
166+ private static class FluxOperationInvoker implements OperationInvoker {
167+
168+ static int invocations ;
169+
170+ @ Override
171+ public Object invoke (InvocationContext context ) throws MissingParametersException {
172+ return Flux .fromIterable (() -> {
173+ invocations ++;
174+ return Arrays .asList ("spring" , "boot" ).iterator ();
175+ });
176+ }
177+
178+ }
179+
122180}
0 commit comments