I'm new to Spring Cloud Function and came across it as one of best solution for developing FaaS based solution. I am specifically writing application for AWS Lambda Service which is back-end of API Gateway. I ran into very interesting problem with My test application and it is around Handler. My test application works well with Custom Handler written as -
public class UserProfileHandler extends SpringBootRequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
}
which works well when configured as Handler in the AWS Lambda. Then I came across org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler
which is available in Spring Cloud Function dependency, so I wanted to get rid of UserProfileHandler
hence I changed Handler configuration in AWS Lambda to org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler
instead of ...UserProfileHandler
and now lambda fails with following error message. Has anyone run into this problem?
{
"errorMessage": "java.util.Optional cannot be cast to com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent",
"errorType": "java.lang.ClassCastException",
"stackTrace": [
"com.transformco.hs.css.userprofile.function.UserProfileFunction.apply(UserProfileFunction.java:16)",
"org.springframework.cloud.function.context.catalog.BeanFactoryAwareFunctionRegistry$FunctionInvocationWrapper.invokeFunction(BeanFactoryAwareFunctionRegistry.java:499)",
"org.springframework.cloud.function.context.catalog.BeanFactoryAwareFunctionRegistry$FunctionInvocationWrapper.lambda$doApply$1(BeanFactoryAwareFunctionRegistry.java:543)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)",
"reactor.core.publisher.FluxJust$WeakScalarSubscription.request(FluxJust.java:99)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)",
"reactor.core.publisher.BlockingIterable$SubscriberIterator.onSubscribe(BlockingIterable.java:218)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)",
"reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)",
"reactor.core.publisher.FluxJust.subscribe(FluxJust.java:70)",
"reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:53)",
"reactor.core.publisher.BlockingIterable.iterator(BlockingIterable.java:80)",
"org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler.result(SpringBootRequestHandler.java:59)",
"org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler.handleRequest(SpringBootRequestHandler.java:52)",
"org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler.handleRequest(SpringBootApiGatewayRequestHandler.java:140)",
"org.springframework.cloud.function.adapter.aws.SpringBootApiGatewayRequestHandler.handleRequest(SpringBootApiGatewayRequestHandler.java:43)"
]
}
Ganesh, I believe you have already raise the issue in Github of SCF. So as I stated there, we have recently did several enhancements, polished the sample and modified documentation by adding a Getting Started guide.
That said, with new generic request handler you no longer need to provide implementation of AWS request handler including SpringBootApiGatewayRequestHandler
.
Simply write your boot application to contain function bean
@SpringBootApplication
public class FunctionConfiguration {
public static void main(String[] args) {
SpringApplication.run(FunctionConfiguration.class, args);
}
@Bean
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
}
. . . and specify org.springframework.cloud.function.adapter.aws.FunctionInvoker
as a handler in AWS dashboard. We'll do the rest for you.