spring-cloud / spring-cloud/spring-cloud-stream

spring.cloud.stream.function.autodetect=true (default setting) for spring-webflux app with server.forward-headers-strategy=FRAMEWORK can't work

Open
#3,177 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.1k
Forks
646
Avg merge
2d 3h
Merged PRs (30d)
8

Description

Describe the issue
Using a spring-webflux app with server.forward-headers-strategy=FRAMEWORK, autoconfiguration provides a ForwardedHeaderTransformer bean which breaks all use cases of spring.cloud.stream.function.autodetect :

  • if you have only output-bindings, a queue is createded and a consumer is registered on this queue which noone ever wants. If you send a message to this queue, you get
java.lang.ClassCastException: class [B cannot be cast to class org.springframework.http.server.reactive.ServerHttpRequest ([B is in module java.base of loader 'bootstrap'; org.springframework.http.server.reactive.ServerHttpRequest is in unnamed module of loader 'app')
  • if you had a single java.util.function.* bean and relied on autodetection, it doesn't work.:
17:59:09.253 [main] WARN  org.springframework.cloud.function.context.catalog.BeanFactoryAwareFunctionRegistry - Multiple functional beans were found [forwardedHeaderTransformer, myConsumer], thus can't determine default function definition. Please use 'spring.cloud.function.definition' property to explicitly define it. 

To Reproduce
Steps to reproduce the behavior:
see above
all versions

Additional context
In the docs there is the following note:

In the event you only have single bean of type java.util.function.[Supplier/Function/Consumer], you can skip the spring.cloud.function.definition property, since such functional bean will be auto-discovered. However, it is considered best practice to use such property to avoid any confusion. Some time this auto-discovery can get in the way, since single bean of type java.util.function.[Supplier/Function/Consumer] could be there for purposes other then handling messages, yet being single it is auto-discovered and auto-bound. For these rare scenarios you can disable auto-discovery by providing spring.cloud.stream.function.autodetect property with value set to false.

To me, this would have been a good idea if there were really no easy cases where autodection breaks down. It depends on what "rare" means of course, but just a plain webflux springboot app with a single nonexotic property "server.forward-headers-strategy" doesn't seem to be that rare.

So maybe just make autodetection opt-in ? But then it doesn't make much sense, autodetection is for zero config (onboarding), so it's not interesting to add explicit autodetection=true configuration just to avoid some other configuration..

So maybe just delete autodetection entirely? You would lose the easy zero config onboarding.

Or make the autodection really reliable:

  • maybe the autodetection should only happen when there is zero spring.cloud.stream.bindings or output-bindings configuration ? zeroconfig onboarding would still work (unless the user chose webflux+forward-headers-strategy=FRAMEWORK to try it out) and normal applications with only output-bindings wouldn't get the spurious consumer
  • maybe find a way to exclude all "standard" beans. Based on the package ? Based on the function Signature (who would use Function<HttpServletRequest, HttpServletRequest>) ? Based on something else ?
  • another idea ?

Cheers,
Jon

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No source files or tests are named. Start by reproducing the Spring WebFlux case with server.forward-headers-strategy=FRAMEWORK and spring.cloud.stream.function.autodetect enabled, then trace how ForwardedHeaderTransformer enters functional bean discovery and binding. Done means the described output-only and single-functional-bean scenarios no longer create a spurious consumer or fail autodetection, while the intended zero-configuration behavior remains defined.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.