Skip to content
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

Provide a mechanism for retrieving non-wrapped ObjectMapper instance #352

Open
ash-sykes-acn opened this issue Jun 28, 2022 · 3 comments
Open

Comments

@ash-sykes-acn
Copy link

Hi, attempting to use Spring Cloud for an AWS lambda. Spring cloud looks for an instance of com.fasterxml.jackson.databind.ObjectMapper. However, the serialisation library only provides a mechanism (as far as I can see) to return a wrapped instance of the configured mapper (i.e. com.amazonaws.thirdparty...).

Is there a way to get the expected ObjectMapper instance that I've missed? Or an appetite to expose the appropriately typed instance?

@ash-sykes-acn ash-sykes-acn changed the title Provide a mechanism for retrieving non-wrapper ObjectMapper instance Provide a mechanism for retrieving non-wrapped ObjectMapper instance Jun 28, 2022
@msailes
Copy link
Collaborator

msailes commented Jun 28, 2022

Hi @ash-sykes-acn, is there a particular reason why you want to access that instance of ObjectMapper?

Thanks

Mark

@ash-sykes-acn
Copy link
Author

ash-sykes-acn commented Jun 29, 2022

@msailes Yes, when using Spring Cloud, the function handler that attempts to deserialise the incoming AWS event (in this instance a ScheduledEvent) fails as the input has an unexpected version property. This is despite the fact that the aws serialisation library has been added (see below log). It appears that Spring Cloud attempts to use the unwrapped ObjectMapper from Jackson. I was hoping that I would be able to add this dependency and then register it as the primary ObjectMapper bean:

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        return JacksonFactory.getInstance().getMapper();
    }

Which would work if the Mapper returned was of type com.fasterxml.jackson.databind.ObjectMapper

If I use the above and change other ObjectMapper imports to com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectMapper; deserialization still fails as a Spring Cloud Function doesn't use a mapper of that type during deserialisation.

10170 [main] WARN  o.s.c.f.c.c.JsonMessageConverter - Failed to convert value: {"version": "0", "id": "6bcff830-bc14-4e75-2559-1baf402bbd80", "detail-type": "Scheduled Event", "source": "aws.events", "account": "cccc", "time": "2022-06-27T14:10:00Z", "region": "eu-west-1", "resources": ["arn:aws:events:eu-west-1:XXXX:rule/ddddd"], "detail": {}}
java.lang.IllegalStateException: Failed to convert. Possible bug as the conversion probably shouldn't have been attampted here
	at org.springframework.cloud.function.json.JacksonMapper.doFromJson(JacksonMapper.java:70)
	at org.springframework.cloud.function.json.JsonMapper.fromJson(JsonMapper.java:94)
	at org.springframework.cloud.function.context.config.JsonMessageConverter.convertFromInternal(JsonMessageConverter.java:84)
	at org.springframework.messaging.converter.AbstractMessageConverter.fromMessage(AbstractMessageConverter.java:185)
	at org.springframework.messaging.converter.AbstractMessageConverter.fromMessage(AbstractMessageConverter.java:176)
	at org.springframework.cloud.function.context.config.SmartCompositeMessageConverter.fromMessage(SmartCompositeMessageConverter.java:57)
	at org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry$FunctionInvocationWrapper.convertInputMessageIfNecessary(SimpleFunctionRegistry.java:1302)
	at org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry$FunctionInvocationWrapper.convertInputIfNecessary(SimpleFunctionRegistry.java:1068)
	at org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry$FunctionInvocationWrapper.doApply(SimpleFunctionRegistry.java:707)
	at org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry$FunctionInvocationWrapper.apply(SimpleFunctionRegistry.java:562)
	at org.springframework.cloud.function.adapter.aws.FunctionInvoker.handleRequest(FunctionInvoker.java:113)
	at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:899)
	at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:258)
	at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:192)
	at lambdainternal.AWSLambda.main(AWSLambda.java:187)
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "version" (class com.amazonaws.services.lambda.runtime.events.ScheduledEvent), not marked as ignorable (8 known properties: "detail", "region", "resources", "detailType", "account", "source", "time", "id"])

I can lift and shift your mapper config into a bean that is of type com.fasterxml.jackson.databind.ObjectMapper and everything works as expected. However, I would prefer not to do this incase further changes are made to the mapping config.

Hopefully I managed to explain the reason for wanting this sufficiently :D

@msailes
Copy link
Collaborator

msailes commented Jun 29, 2022

@olegz is there anything else that can be done in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants