How to set date format for JsonObjectMapper in Spring Integration - spring-boot

I am converting my Java object to Map using Spring Integration ObjectToMapTransformer's transformPayload().
Everything works fine except that the Instant fields in my object are getting broken into epochSecond and nano, which in turn throws exception while persisting in data-store (MongoDB).
This is the Spring Integration JsonObjectMapper being used to convert the Object to Map:
private final JsonObjectMapper<?, ?> jsonObjectMapper = JsonObjectMapperProvider.newInstance();
My question is how can I configure date format for the above mapper. Just like Jackson's ObjectMapper::configure(), do we have any similar options here?
I cannot find any, neither in source code nor on internet!!
I also tried enabling/disabling spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS in my application.properties, but no joy!
I have jackson-datatype-jsr310 dependency in my pom.xml
How to get the Instant in correct format?

I think we should add support for custom JsonObjectMapper injection. That way you would be able to build Jackson2JsonObjectMapper based on desired ObjectMapper.
Please, raise a JIRA ticket on the matter and don't hesitate with the contribution: https://github.com/spring-projects/spring-integration/blob/master/CONTRIBUTING.adoc
Meanwhile as a workaround I'd suggest a pair of ObjectToJsonTransformer/JsonToObjectTransformer:
.transform(Transformers.toJson(jsonObjectMapper(), ObjectToJsonTransformer.ResultType.NODE))
.transform(Transformers.fromJson(Map.class, jsonObjectMapper()))

Related

Get Jackson ObjectMapper in Quarkus

I am writing a custom OpenApiConfigurator that adds some examples to my api dynamically.
When I add the examples using the value field of io.smallrye.openapi.api.models.examples.ExampleImpl, which is an object, the example is null in swagger-ui. It only works when I added the actual json.
To add the actual json I have to generate it from my response dto using Jackson. But how can I access the quarkus object mapper, for which I have some customisations using ObjectMapperCustomizer, if in the OpenApiConfigurator CDI is not available?
It's actually possible to access the CDI container statically with Arc.container().instance(ObjectMapper::class.java).get()
That solved it for me.

#ConstructorBinding with immutable properties don't work with #Value in Spring Boot Kotlin #ConfigurationProperties

Spring Boot supports Kotlin data classes for #ConfigurationProperties.
#ConstructorBinding
#ConfigurationProperties(prefix = "prefix")
data class AppProperties (
val something: String
)
But val and #ConstructorBinding has some limitations. You cannot alias one variable to another. Let's say you're running in Kubernetes and want to capture the hostname, which is given by the env var HOSTNAME. The easiest way to do this is to apply #Value("\${HOSTNAME}:)" to a property, but it only works for a mutable property and without constructor binding.
The Spring Boot GitHub issue tracker says:
STOP!! Please ask questions about how to use something, or to understand why something isn't
working as you expect it to, on Stack Overflow using the spring-boot tag.
So, is this a known limitation or should I create a ticket for them to fix it?
Edit:
Opened https://github.com/spring-projects/spring-boot/issues/25552
#ConfigurationProperties is an alternative to #Value and the two are not designed to be used together. It may work with JavaBean-style binding but that would be by accident rather than by design and it shouldn't be relied upon.
Instead of using #Value to alias something bound via #ConfigurationProperties, it's recommended that you do so via some other means. For example you could use one of the approaches suggested in this answer that Marcos Barbero linked to in the comments on your question. Alternatively, you could take some inspiration from this example in the documentation and use a placeholder in application.properties:
prefix.something=${hostname}
Another option would be to register via META-INF/spring.factories an implementation of EnvironmentPostProcessor that adds a PropertySource to the environment to set up the desired aliasing. For the time being, this is probably the best approach if you want to do something in a reusable library. There's an open issue to remove some of the ceremony that's currently involved.

How to log MDC with Spring Sleuth 2.0?

referring to quesition/answer in How to log MDC with Spring Sleuth?
I think this has/will change(d) with spring-cloud 2.0 as there is no SpanLogger or Slf4jSpanLogger anymore (or I don't find it)
Wouldn't it be nice if application properties spring.sleuth.baggage-keys and spring.sleuth.propagation-keys if set would also be put in MDC I think inside Slf4jCurrentTraceContext (as this class is currently final I cannot subclass it)
If not, how could I achieve this with spring-cloud 2.0 accordingly?
We don't want to put all entries in MDC (that really doesn't make a lot of sense). You can however either copy the Slf4jCurrentTraceContext and extend it in the way you want to (and register it as a bean) or maybe create your own implementation of CurrentTraceContext that would wrap the existing CurrentTraceContext via a Bean Post Processor and perform additional logic. I guess the first option is more preferable.
In version 2.1.0, Slf4jScopeDecorator was introduced and it will automatically add baggage values to MDC as long as they are whitelisted in the spring.sleuth.log.slf4j.whitelisted-mdc-keys configuration.
For example, if you have the following configuration:
spring.sleuth.baggage-keys=key1,key2
spring.sleuth.log.slf4j.whitelisted-mdc-keys=key2
Only the value of key2 will be automatically added MDC, but not the value of key1.
For more info, see: https://cloud.spring.io/spring-cloud-sleuth/reference/html/#prefixed-fields

NullPointerException com.liferay.portal.spring.util.SpringFactoryImpl.setBeanDefinitions

I'm using springFramework and I try to setBeanDefinitions, the problem is that this methode need a Map beanDefinition as a param... could U tell me plz how I could instantiate this param?
NullPointerException at com.liferay.portal.spring.util.SpringFactoryImpl.setBeanDefinitions(SpringFactoryImpl.java:56)
additional information:
I try to deploy a liferay project without using liferay configuration files (only springFramework libraries), I created my own sessionFactory, my own dataSource ... etc!!
when I run the program, I'm able to create dataBase Schema basing on portlet-hbm.xml information... well now I try to instantiate beans for portal-spring.xml.. (which are xxxxpersistance.java)! those latters told me that they use 'com.liferay.portal.kernel.dao.orm.SessionFactory' as a required type and it can not convert property value of type 'org.hibernate.impl.SessionFactoryImpl'!! so I tried to use the liferay libraries only for those beans and I try to instanciate them manually... but I wasn't able to setBeanDefinitions cause I need a Map beanDefinition as a param... I don't know if there is a way to get them using sessionFactory or not!!
Thanks again
You only mention junit in the tags to your question. I'd recommend to write unit tests without relying on the whole Liferay infrastructure. That will tremendously lower your required setup efforts and simplify your life a lot.

Enunciate validation of Jersey API fails with #POST #FormParam + String data

I'm evaluating enunciate to document our REST APIs and I'm having an issue with the validation step:
Validation result has errors.
my.java: error: [core] An entity parameter must be of type MultivaluedMap<String, String> if there is another parameter annotated with #FormParam.
#FormParam("my-param") String myParam, String data)
This construct of accepting the POST data as a String entity in addition to #FormParam bindings is supported by Jersey, so not sure why enunciate is choking on it? Is this not JAX-RS compliant?
This is a really useful to capture the full post data for auditing purposes if something went wrong. Is there a way to configure enunciate to ignore this argument?
If not, is there some other way to capture the post data in a way that would keep enunciate happy? I'm reluctant to go to MultivaluedMap as the stringification process may not result in exactly the String which was passed in...
Thanks!
It may be that the validation checks Enunciate performs are outdated. You might consider requesting a change by submitting a JIRA issue.
One thing you could try as a workaround is to create your own custom parameter annotation and configure Enunciate consider it as a custom resource parameter.
<enunciate>
...
<services>
<rest>
<custom-resource-parameter-annotation qualifiedName="org.myco.CustomResourceParam"/>
</rest>
</services>
...
</enunciate>
However, if the purpose of the parameter is for auditing, I'd really recommend using a Jersey filter. That way you don't litter your API code with auditing concerns.

Resources