On Camel 2.10.1, the following worked:
<camel:bean ref="profilingBean" method="addProfilingContext('TEST')"/>
The method in question takes a String parameter
Migrating to 2.10.6 , this does not work anymore, it tries to call TEST as another class. I have tried wrapping with ${} , trying to use exotic combinations of "& quot;" etc...
The only solution I found was to put the value in a header using constant language then call the header using simple. Obviously, this isn't very clean...
Do you have any ideas how to do this?
Cheers
The behavior/bug still exists in Camel 2.16 and also in latest 2.18.2.
For every string constant that is passed to a bean via Spring DSL a java.lang.ClassNotFoundException is thrown.
It gets more visible by setting logger for org.apache.camel.util.ObjectHelper to TRACE.
This camel behavior also has serious negative performance impact because ClassLoader method (java.lang.ClassLoader.loadClass) is synchronized for a given parameter name.
I wrote a little demo to show this: https://github.com/groundhog2k/camel-dsl-bean-bug
Your solution with the header is fine. The bug you talk about should be fixed in 2.10.7, or 2.11.1 etc.
Related
I have a configuration property that needs to be sent to another system as part of a post body.
lets say for example if have an application.properties file with
my.property.raw=${parameter:some-identifier}
I also have a #ConfigurationProperties annotated class that might look like this
#ConfigurationProperties(prefix = "my.property")
public class Properties {
private String raw;
// getters and such
}
The problem i have is that Spring will see ${parameter:some-identifier} and immediately assumes i want it to be injected with a property names "parameter" and if its not there, put "some-identifier". i have tried to set the property to ${parameter:${parameter:some-identifier}} but Spring seems to have accounted for recursive property injection and it still comes out as "some-identifier".
I know i can write some code around that and replace the ":" with something else and change it back after the fact but i'm trying to make this work without any code change.
So in summation, Spring boot sees this as a configuration property ${parameter:some-identifier} upon injection into the ConfigurationProperties annotated class, the value ends up being some-identifier. What i want to happen is the value in the Properties class after Spring does its variable replacement process is ${parameter:some-identifier} as this injectable format of a value is intended for a down stream system that is expecting that format. Preferably, without changing any code. Maybe there is some special formatting i can use to tell spring to ignore this specific property.
Thanks for your time! and yes i realize this is probably the opposite of what people normally want from Spring.
As stated by #Kayaman this is indeed a duplicate of
Escape property reference in Spring property file
The solution i pulled from there, with some modification, was this:
${dollar:$}{parameter:some-identifier}
https://stackoverflow.com/a/48897422/4621716
I did this because i also don't have control over the process that is generating that application.properties beyond changing existing values.
I hope this helps and i wish i could give #Kayaman credit for pointing me in the right direction but i guess i'll accept my own answer. Thanks.
I am getting started with MapStruct. I am unable to understand when do we use "expression" tag in MapStruct? Why do we have certain mappings where we use "target" tag and "expression" tag? Does it mean that expressions are used when you want to map two or more fields within a bean to a single property/field in the target as mentioned in the documentation "http://mapstruct.org/documentation/stable/reference/html/#expressions"
Expressions are used when you can't map a source - to a target property or when a constant does not apply. MapStruct envisioned that several language could be used to address expressions. However, only plain java is implemented (hence "java(... )" ). EL was envisioned but not yet realised.
A typical use case that I use is generating a UUID. But even there you could try the new #Context to achieve that goal.
Remember, the stuff within the brackets is put directly in the generated code. The IDE can't check its correctness, and you will only spot problems during compilation.
Expressions are IMHO a fallback means / gap filler for stuff that is not yet implemented in MapStruct.
Note: Mapping target-to-source by means of a custom method as suggested in the other answers can be done automatically. MapStruct will recognised the signature (return type, source type) and call your custom method. You can do this in the same interface (default method) or in a used mapper.
In general, MapStruct expressions are used when you simple cannot write a MapStruct mapper. They should be used as a fallback approach when the library doesn't apply to your use-case.
For example, -- as the documentation says -- when a mapping requires more than one source variable, an expression can be used to "inject" them to a mapper method.
Another use case is when the source variable you need to use -- say bar -- is not a part of the source class but a member of one of its variables (here, classVar). You would map it to the target field foo using a custom myCustomMethod method with #Mapping(target="foo", expression="java(myCustomMethod(source.classVar.bar)))".
I'm struggling to upgrade from morphia 1.0.1 to 1.2.1. With 1.0.1 we had to override the morphia calls to equals() and other calls to throw an exception if the value being fetched was null. Doing that prevented a security hole where the first record in the database with a value of null was selected if the calls runs without an exception.
To do this, we overrode morphia.createDatastore() in the Guice module to return a special custom datastore. The special datastore returned a special Query object which returned a special FieldEnd when the Query.field() call was called. This FieldEnd did the exception checking.
That worked, however our special NotAllowingNullsFieldEnd class extended FieldEndImpl which is now private in 1.2.1 and so I have a problem.
We need a way to stop Queries from accepting null as a valid argument in the 1.2.1 world.
One solution would be to move NotAllowingNullsFieldEnd to the same package FieldEndImpl is in (org.mongodb.morphia.query) but that seems really hacky.
I'm NOT a morphia expert and actually I'm fairly new to java, so any expert input would be welcome.
Just FYI, the implementation of this was done before my time, so I don't have a lot to add about the in-depth reasons regarding why this path was chosen, I've just been asked to do the upgrade.
Morphia 1.3.2 the class FieldEndImpl is back to public.
There're few ways one can manipulate the message in Spring Integration. One way is calling a bean's method inside <int:enricher> that will return an object and assign it to the given name, e.g:
<!-- calls getKey method of IdGenerator bean which returns String with some value -->
<int:enricher input-channel="a.channel" output-channel="b.channel" id="preTranslator">
<int:header name="Key" expression="#IdGenerator.getId(payload)"/>
</int:enricher>
Same can be utilized in filtering:
int:filter discard-channel="d.channel" input-channel="b.channel" output-channel="c.channel"
expression="#Cache.hasKey(headers.Key) == false"/>
On the other hand I can call the <int:service-activator> on a class implementing MessageProcessor interface. It would take the original message and return a copy with a new header field. That requires my class's method to always build a new message with MessageBuilder though.
Currently I use the first way for simple field enrichment and service-activator for requesting data from DB/external services. What's the right way of picking the correct approach?
First of all, the <filter> doesn't change message at all. The given name should be read as header, looking to your case.
The <service-activator> always return a new message. Yes, you can populate new headers there as well and right you have to use MessageBuilder.
It is fully unclear what is your problem. If you can achieve the solution with expressions in the config, so be that. But if you do something with the message in the code and would like to add/edit/remove headers you use MessageBuilder.
That's really fine. I think you should just read more documentations and right more code in your application.
Eventually you will find the most convenient style for yourself. Fro example I end up once with expressions and Groovy scripts. No Java code at all. But right now I prefer Spring Integration Java DSL, because it is much faster, cleaner, fluent and lets get rid of any other configs like XML or Groovy. Everything is Java now and that MessageBuilder is still on the horse!
We are facing issue related with making a path parameter optional.
original URL /expire/{token}
What we are trying to do is have the same service work for the URL's below.
1. /expire/{token}
2. /expire
Ex:- #Path("/expire/{token}")
We have already applied other solutions from SO,but no luck so far.
What about adding another method annotated with only:
#Path("/expire")
And let this method pass a null value into the original method.
Logically, it doesn't seem to make sense to have it optional. Your URI should handle the type of request it's supposed to do. But, I came across a post to make the #PathParam to be optional with a small hack using regular expressions.
http://www.nakov.com/blog/2009/07/15/jax-rs-path-pathparam-and-optional-parameters/
I would go with having separate endpoint method in Controller where it can pass the call to your services with optional parameter.
We can use regular expressions,
"#Path("/add/{a:([0-9.]*)}/{b:([0-9.]*)}{p:/?}{c:([0-9.]*)}")"
here path can be
add/2/3
add/2/3/4
my case I am using regular expressions for allowing only numbers