In org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.MappingDescriptionVisitor#attributes there's a TODO and a throw new UnsupportedOperationException("Auto-generated method stub");.

We should either remove the TODO or implement this method. We're missing a test for a router function with an attribute, too.

Some context on the attributes can be found here.

Comment From: wilkinsona

I guess we should treat this is a bug. A router function with attributes results in a 500 response when calling the mappings endpoint:

2022-07-18 18:36:58.529 ERROR 67619 --- [oundedElastic-1] a.w.r.e.AbstractErrorWebExceptionHandler : [f64947c3-1]  500 Server Error for HTTP GET "/actuator/mappings"

java.lang.UnsupportedOperationException: Auto-generated method stub
    at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider$MappingDescriptionVisitor.attributes(DispatcherHandlersMappingDescriptionProvider.java:188) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping$ReadOperationHandler#handle(ServerWebExchange) [DispatcherHandler]
    *__checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ HTTP GET "/actuator/mappings" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider$MappingDescriptionVisitor.attributes(DispatcherHandlersMappingDescriptionProvider.java:188) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.web.reactive.function.server.RouterFunctions$AttributesRouterFunction.accept(RouterFunctions.java:1189) ~[spring-webflux-5.3.21.jar:5.3.21]
        at org.springframework.web.reactive.function.server.RouterFunctionBuilder$BuiltRouterFunction.lambda$accept$1(RouterFunctionBuilder.java:405) ~[spring-webflux-5.3.21.jar:5.3.21]
        at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_252]
        at org.springframework.web.reactive.function.server.RouterFunctionBuilder$BuiltRouterFunction.accept(RouterFunctionBuilder.java:405) ~[spring-webflux-5.3.21.jar:5.3.21]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider$RouterFunctionMappingDescriptionProvider.describe(DispatcherHandlersMappingDescriptionProvider.java:154) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider$RouterFunctionMappingDescriptionProvider.describe(DispatcherHandlersMappingDescriptionProvider.java:141) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.describe(DispatcherHandlersMappingDescriptionProvider.java:83) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:269) ~[na:1.8.0_252]
        at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[na:1.8.0_252]
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_252]
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_252]
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_252]
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_252]
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) ~[na:1.8.0_252]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.describeMappings(DispatcherHandlersMappingDescriptionProvider.java:76) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.lambda$describeMappings$0(DispatcherHandlersMappingDescriptionProvider.java:71) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_252]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.describeMappings(DispatcherHandlersMappingDescriptionProvider.java:71) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.describeMappings(DispatcherHandlersMappingDescriptionProvider.java:56) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.lambda$mappingsForContext$0(MappingsEndpoint.java:59) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_252]
        at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.mappingsForContext(MappingsEndpoint.java:58) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.web.mappings.MappingsEndpoint.mappings(MappingsEndpoint.java:50) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_252]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_252]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_252]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_252]
        at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.3.21.jar:5.3.21]
        at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping$ElasticSchedulerInvoker.lambda$invoke$0(AbstractWebFluxEndpointHandlerMapping.java:240) ~[spring-boot-actuator-2.6.9.jar:2.6.9]
        at reactor.core.publisher.MonoCallable.call(MonoCallable.java:92) ~[reactor-core-3.4.19.jar:3.4.19]
        at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:227) ~[reactor-core-3.4.19.jar:3.4.19]
        at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) ~[reactor-core-3.4.19.jar:3.4.19]
        at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) ~[reactor-core-3.4.19.jar:3.4.19]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_252]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_252]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_252]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_252]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_252]
        at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_252]