-
Notifications
You must be signed in to change notification settings - Fork 603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RoutingFunction fails with ArrayList to String ClassCastException #1106
Comments
Unfortunately I can not reproduce it. I just tested it with
and everything works as excepted. Please provide a reproducible sample as I can not see how headers for function definition could be given as list |
Hi @olegz, I have stumbled upon the same issue. https://github.com/TamasNeumer/gcf-spring-debug/tree/main/src curl --location --request GET 'http://localhost:8080/' \
--header 'spring.cloud.function.definition: uppercase' \
--header 'Content-Type: text/plain' BR, |
Hi @olegz could you please give some feedback on this? Thank you! |
I tried to run your sample but it doesn't start. Is it GCF specific? |
Hi @olegz, Forgot to mention that you need to use the following Maven command to start:
|
Hey folks, this is occuring basically because of how com.google.cloud.functions.HttpMessage#getHeaders() API is designed. if we refer to the source code: We can see in the javadoc the following:
So, when a new instance of org.springframework.messaging.Message is created in Line 118 in 953217f
Then, in the org.springframework.cloud.function.context.config.RoutingFunction#locateFunctionFromDefinitionOrExpression() we attempt to cast this one-element list to a String which obviously fails. |
As for the solution to the aforementioned problem, I'd like to share some of my findings after a bit of digging:
So we're safe to combine values here in terms of HTTP semantics (not that the RFC matters that much here I guess).
Given my findings, I came to a conclustion that it seems to be possible to add a conditional to org.springframework.cloud.function.context.config.RoutingFunction#locateFunctionFromDefinitionOrExpression() that: Here's a code example to further illustrate my point:
The "spring.cloud.function.routing-expression" will certainly require some special treatment as well, but the same solution as for the header "spring.cloud.function.definition" won't work for it as it's probably nonsensical to combine two (or more) values from duplicate "spring.cloud.function.routing-expression" headers. In this case it's probably fine to simply take the first value from a list and document this behavior as such? So there's that, I guess, @olegz please correct me if I'm wrong. |
…ion.definition" header contains a List value instead of a String value (GCP-specific) Resolves spring-cloud#1106
Describe the bug
Default RoutingFunction fails with:
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.lang.String (java.util.ArrayList and java.lang.String are in module java.base of loader 'bootstrap')
at org.springframework.cloud.function.context.config.RoutingFunction.route(RoutingFunction.java:136)
at org.springframework.cloud.function.context.config.RoutingFunction.apply(RoutingFunction.java:107)
The root cause: message.getHeaders().get(FunctionProperties.FUNCTION_DEFINITION) - returns ArrayList, which is casted to String.
Steps to reproduce
Specify request/message header: spring.cloud.function.definition=uppercase
curl http://localhost:8080
-H "Content-Type: text/plain"
-H "func_name: uppercase"
--data-urlencode "some Txt"
Sample
The text was updated successfully, but these errors were encountered: