[ 
https://issues.apache.org/jira/browse/CAMEL-12910?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16681037#comment-16681037
 ] 

Cristian Donoiu edited comment on CAMEL-12910 at 11/9/18 8:22 AM:
------------------------------------------------------------------

Thank you [~ancosen]. I will start work on a PR (note: will not be fast since I 
am new to Camel). I am assigning this ticket to myself.

Thanks [~onders]. Where is the dev-list accessible?
 Related to the 12319 which you mentioned, *yes* it is similar but the 
*calling* *is different*. Here is why:
||Options||Description||
|1|Providing the parameters in the route has benefits in that it gives more 
control to the route which is good. E.g. {code:java}
from(X)
.bean(UserService.class, UserService::authenticateUser, body(), 
exchangeProperty("locale"))
.bean(UserService.class, UserService::checkUserPermissions, body(), 
exchangeProperty("locale"))
.bean(UserService.class, UserService::doWork, body(), header("..."))
.to(Y){code}
 |
|2|I would prefer the route to just reference methods on an already 
*instantiated*/wired bean instance(not class like above) and *no parameters* 
specified: {code:java}
@Autowire UserService userService;
...
.bean(userService::authenticateUser)
.bean(userService::checkUserPermissions)
.bean(userService::doWork){code}
Then on the bean instance I use the annotations 
([http://camel.apache.org/parameter-binding-annotations.html]) to let Camel do 
the mapping. Also I learned @Body is *not* needed if automatic matching based 
on type can be done by Camel and there are other smart rules also.  {code:java}
public void validate(@ExchangeProperty("P1") UserRequest request, String 
accountId) {...} // accountId is message body.{code}
Benefits:  # Route DSL is much cleaner.
 # The method being referenced on the object and not on the class allows for 
runtime selection of the method based on the actual type of an interface type. 
The details of what the method takes in or not remain at the choice of the 
target method by using the needed annotations within the method definition/or 
in the target bean class or one of his implemented interfaces. Also in case the 
target method changes signature like adding a new parameter that references an 
existing exchange property then adding the new parameter would not require any 
change in the route dsl. Still someone would prefer to see all the dependencies 
in the route DSL so this is debatable.
 # In case of auto wiring an interface type as we often do, e.g.{code:java}
@Autowire UserService userService;{code}
the target bean you may get may be different depending of the one that is 
injected. You may get a SingleTenantUserServiceImpl or a 
MultiTenantUserServiceImpl and SingleTenantUserServiceImpl#authenticateUser 
would need body and header H1 while MultiTenantUserServiceImpl#authenticateUser 
would need body, header H2. This would be easily possible with using the 
corresponding annotations at the method level and will require some choice 
based on type if we do it in the route DSL. Debatable as the one above.|

 
 *Conclusion.*
 Supporting *both* options could be achieved by using the same ".bean" call 
since we could differentiate based on the number of parameters to the ".bean" 
call.
 But I would implement first only method reference(option 2) in route and have 
in a *later* ticket (if needed) the capability of specifying parameters in 
route(option 1).
   
  
  


was (Author: doncristiano):
Thank you [~ancosen]. I will start work on a PR (note: will not be fast since I 
am new to Camel). I am assigning this ticket to myself.

Thanks [~onders]. Where is the dev-list accessible?
Related to the 12319 which you mentioned, *yes* it is similar but the *calling* 
*is different*. Here is why:
||Options||Description||
|1|Providing the parameters in the route has benefits in that it gives more 
control to the route which is good. E.g.
 {code:java}
from(X)
.bean(UserService.class, UserService::authenticateUser, body(), 
exchangeProperty("locale"))
.bean(UserService.class, UserService::checkUserPermissions, body(), 
exchangeProperty("locale"))
.bean(UserService.class, UserService::doWork, body(), header("..."))
.to(Y){code}
 |
|2|I would prefer the route to just reference methods on an already 
*instantiated*/wired bean instance(not class like above) and *no parameters* 
specified:
 {code:java}
.bean(userService::authenticateUser)
.bean(userService::checkUserPermissions)
.bean(userService::doWork){code}
 
Then on the bean instance I use the annotations 
(http://camel.apache.org/parameter-binding-annotations.html) to let Camel do 
the mapping. Also I learned @Body is *not* needed if automatic matching based 
on type can be done by Camel and there are other smart rules also.  {code:java}
public void validate(@ExchangeProperty("P1") UserRequest request, String 
accountId) {...} // accountId is message body.{code}
Benefits: # Route DSL is much cleaner.
 # The details of what the method takes in or not remain at the choice of the 
target method by using the needed annotations within the method definition/or 
in the target bean class or one of his implemented interfaces. Also in case the 
target method changes signature like adding a new parameter that references an 
existing exchange property then adding the new parameter would not require any 
change in the route dsl. Still someone would prefer to see all the dependencies 
in the route DSL so this is debatable.
 # In case of auto wiring an interface type as we often do, e.g.{code:java}
@Autowire UserService userService;{code}the target bean you may get may be 
different depending of the one that is injected. You may get a 
SingleTenantUserServiceImpl or a MultiTenantUserServiceImpl and 
SingleTenantUserServiceImpl#authenticateUser would need body and header H1 
while MultiTenantUserServiceImpl#authenticateUser would need body, header H2. 
This would be easily possible with using the corresponding annotations at the 
method level and will require some choice based on type if we do it in the 
route DSL. Debatable as the one above.|
 
*Conclusion.*
Supporting *both* options could be achieved by using the same ".bean" call 
since we could differentiate based on the number of parameters to the ".bean" 
call.
But I would implement first only method reference(option 2) in route and have 
in a *later* ticket (if needed) the capability of specifying parameters in 
route(option 1).
  
 
 

> Add support for method references bean::methodName
> --------------------------------------------------
>
>                 Key: CAMEL-12910
>                 URL: https://issues.apache.org/jira/browse/CAMEL-12910
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-core, camel-spring-integration
>            Reporter: Cristian Donoiu
>            Priority: Major
>              Labels: features
>         Attachments: Bean.java
>
>
> Hi
> This is not related only to spring integration.
> I like to be able to use a spring service annotated class or bean directly 
> from route but without using the method name as string, i.e. .bean(instance, 
> "<method name") and instead use a method reference: .bean(instance::method)
> But why?: 
> *1.* not being able to navigate quickly(open) that method from the IDE. Need 
> to do some intermediary steps to reach that method.
> *2.* using of reflection internally by Camel to call that method.
> *3.* not being able to rename the method without breaking the route.
> *4.* not being able to see quickly (Alt+F7) who calls a methods in the IDE.
> *5.* using strings to reference a method when we have method references seems 
> *not right.*
> As a workaround I had to add a helper class to simulate passing of method 
> references and then internally to translate to method.
> In case it helps explaining I am attaching the helper Bean.java class (you 
> can use it for free or to do better).
> You can use the class in any route like this: 
> from (X)
>  .bean(*call*(cancelSubscriptionService::buildSalesforceCase))
>  .to(Y)
>  .routeId(Z);
> As you see I am forced to use the intermediary helper 'call' in order to 
> translate to an Expression.
> I would like to not have to use my helper and have the support built directly 
> into Camel if possible. Let me know if there is a better solution to my 
> problem.
> Thanks



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to