Hi Devs,
I've finished (almost) development of a new feature for EL: UDF (User
Defined Functions).
This will add flexibility to EL, reduce complexity of the flows and so on,
and so on...
Example:
${exec('com.example.MyDateUtils', 'minus', ${now()}, '1 year')}
or
${myAttribute:exec('com.example.MyMasker', 'maskCreditCard')}
But while making it more generic and flexible, I've faced some challenges,
which I would like to discuss.
First of all, as per current implementation of EL, any expression should
have output type. Each evaluator needs to specify which type it will return
(STRING, BOOLEAN, WHOLE_NUMBER, DATE, DECIMAL, NUMBER). And, as of now, I
think it is not possible to make it generic without impacting entire EL
framework, which I would like to avoid obviously.
So, first challenge - new EXEC function will always return String type. Or
should I try to introduce new bugs in a core of EL? :)
Second challenge is an interface of this function.
Easiest way is to define new interface
org.apache.nifi.attribute.expression.language.ExecutableUDF with method "
execute" accepting array of Strings. 2 Cons: new class implementation for
each function, and casting from strings into desired data types.
More advanced way: no interface, methods will be looked up by the types
provided in EL itself. This is more opened API, but needs more reflection
and assumptions during error handling. This way is more flexible and
doesn't require implementation of given interface (reduced maven
dependencies, and as a result - less hassle during upgrades, especially if
there are changes in how class loaders are defined, etc). I have it
implemented and it works fine (with some limitations related to mapping of
EL vs Java data types), but not sure if we need to limit to the interface
implementation...
I will appreciate any feedback and comments from community.
Thanks,
Ed.