That seems like a good alternative syntax. However the result is the same
(even when setting the argument hardcoded):

No bean could be found in the registry for: MyProcessor-1

The only difference by setting it this way, is that the error shows during
loading, instead of during running the route.

I'm pretty sure that's it's something of the templateBean, because the
templateBean probably wants to register the bean name as something unique.
This behavior should be reproducible, because when I register and bind the
bean manually including the constructor parameter it goes well.

I could for example do this:

@Override
public void configure() throws Exception {

    Registry registry = getCamelContext().getRegistry();
    registry.bind("MyProcessor", new SetHeadersProcessor("myProcessorParam"));

    routeTemplate("setheaders-action")
            .templateParameter("in")
            .from("direct:in")
            .process("MyProcessor")
            .to("{{out}}");
}

Unfortunately one cannot use parameter in the configure method (outside the
routeTemplate) like this:

@Override
public void configure() throws Exception {

    Registry registry = getCamelContext().getRegistry();
    registry.bind("MyProcessor", new
SetHeadersProcessor("{{myProcessorParam}}"));

    routeTemplate("setheaders-action")
            .templateParameter("in")
            .templateParameter("myProcessorParam")
            .from("direct:in")
            .process("MyProcessor")
            .to("{{out}}");
}

Because then the template is outside  it's not parsed.

It's however possible to register the processor one step earlier during
loading of the route like this:

Registry registry = getCamelContext().getRegistry();
registry.bind(processorName, new MyProcessor(processorParameter));

loader = extendedCamelContext.getRoutesLoader();

Resource resource = IntegrationUtil.setResource(routeTemplate);

log.info("Loading routeTemplate" + routeTemplate);

try{
   loader.loadRoutes(resource);
}catch(java.lang.IllegalArgumentException e){
   loader.updateRoutes(resource);
}

The last workaround works, but then I prefer my previous workaround with
setting headers. (because it will put business logic in my loader).

It would be nice to do something like this

loader.loadRoutes(resource, map)

Thus the second parameter is Map<String, Object> that you then can use in
the whole routeBuilder class.

This is at least how I previous called my own 'templates' by passing a map
to the routebuilder with a normal parameterized route.

public ConnectorRoute(final TreeMap<String, String> props){
this.props = props;
}

See:
https://github.com/assimbly/runtime/blob/master/integration/src/main/java/org/assimbly/integration/routes/ConnectorRoute.java

In the route a processor with constructor argument could also be called
this way. With switching to officially routeTemplates I lost this abillity.
Well, sometimes you win, sometimes you learn.

I'll stick to the header workaround for now, thanks for help.

Raymond



On Thu, Sep 8, 2022 at 2:56 PM Claus Ibsen <claus.ib...@gmail.com> wrote:

> Btw there is some details on #class syntax here
>
> https://camel.apache.org/components/3.18.x/others/main.html#_creating_a_custom_bean_with_constructor_parameters
>
> On Thu, Sep 8, 2022 at 2:52 PM Claus Ibsen <claus.ib...@gmail.com> wrote:
>
> >
> >
> > On Thu, Sep 8, 2022 at 2:39 PM ski n <raymondmees...@gmail.com> wrote:
> >
> >> Yes, that was, based on the documentation, the first thing I tried, but
> I
> >> got:
> >>
> >> org.apache.camel.ResolveEndpointFailedException: Failed to resolve
> >> endpoint: bean://MyProcessor-1?method=process) due to: No bean could be
> >> found in the registry for: MyProcessor-1
> >>
> >> That's why I started to register it manually.
> >>
> >> Now I added "-1" the templatedBean name itself but then I got:
> >>
> >> Failed to resolve endpoint: bean:{{MyProcessor}}?method=process) due to:
> >> Property with key [MyProcessor] not found in properties from text:
> >> bean:{{MyProcessor}}?method=process)
> >>
> >> This is logical because now {{MyProcessor-1}} is expected. However when
> I
> >> provide that, it says " No bean could be found in the registry for:
> >> MyProcessor-1-1" . So that's a kind of a deadlock.
> >>
> >> As a side note: From the user point of view wouldn't it by easy if this
> >> was
> >> possible:
> >>
> >> .bean("mybean")
> >>    .parameter("{{first constructor parameter}}")
> >>    .parameter("{{second constructor parameter}}")
> >>    .method("mymethod")
> >>        .parameter("{{first method parameter}}")
> >>        .parameter("{{second method parameter}}")
> >>
> >> And the parameters in a routeTemplate can then be set with a normal
> >> templateParameter.
> >>
> >>
> > No the route template DSL is complex already as-is.
> > See the docs where you can create the bean with inlined groovy or java
> > (via java-joor). There you can use placeholders.
> >
> > You can also try with passing in the parameters as constructor via #class
> > syntax
> >
> >
> >
> .templateBean("MyProcessor").type("#class:com.foo.MyProcessor({{myProperty}})")
> >
> >
> >
> >
> >> Raymond
> >>
> >>
> >> On Thu, Sep 8, 2022 at 1:51 PM Claus Ibsen <claus.ib...@gmail.com>
> wrote:
> >>
> >> > You should NOT register the processor yourself, this is done by the
> >> > template bean thingy automatically
> >> >
> >> > On Thu, Sep 8, 2022 at 1:39 PM ski n <raymondmees...@gmail.com>
> wrote:
> >> >
> >> > > OK, sorry, I actually read the documentation on bindings and did use
> >> > > {{MyProcessor}} as the bean name.
> >> > >
> >> > > But it didn't work.
> >> > >
> >> > > I register my bean/processor as:
> >> > >
> >> > > registry.bind("MyProcessor", new MyProcessor(""));
> >> > >
> >> > > But when I run it, I got:
> >> > >
> >> > > Failed to resolve endpoint: bean://MyProcessor-1?method=process due
> >> to:
> >> > No
> >> > > bean could be found in the registry for: MyProcessor-1
> >> > >
> >> > > Don't know where the "-1" comes from. However when I register it
> with
> >> > that
> >> > >
> >> > > registry.bind("MyProcessor-1", new MyProcessor(""));
> >> > >
> >> > > Then the route works but not with the routetemplate parameter
> (because
> >> > it's
> >> > > already iniaitized. So I tried it with
> >> > >
> >> > > registry.bind("MyProcessor-1", MyProcessor.class);
> >> > >
> >> > >
> >> > > Caused by: org.apache.camel.ResolveEndpointFailedException: Failed
> to
> >> > > resolve endpoint: bean://MyProcessor-1?method=process due to:
> >> > > java.lang.NoSuchMethodException:
> >> > >
> >> > > I also tried it with method parameters, instead of the constructor.
> I
> >> > first
> >> > > tried to put an extra parameter on the process method, but the
> >> interface
> >> > > for Processor doesn't allow that. So I tried to use method
> >> overloading,
> >> > but
> >> > > then it's unclear how to pass the exchange object as a parameter.
> >> > >
> >> > > Raymond
> >> > >
> >> > >
> >> > >
> >> > >
> >> > > On Thu, Sep 8, 2022 at 12:06 PM Claus Ibsen <claus.ib...@gmail.com>
> >> > wrote:
> >> > >
> >> > > > Hi
> >> > > >
> >> > > > No you cannot - you mix standard Java with Camel "parsing" the
> model
> >> > when
> >> > > > it calls the configure() method.
> >> > > > It would be the same in regular Camel route.
> >> > > > You basically do standard Java code with a new constructor and
> pass
> >> in
> >> > a
> >> > > > string literal. Camel is not in use at that point.
> >> > > >
> >> > > > In your template bean example, then you need to use
> {{MyProcessor}}
> >> as
> >> > > the
> >> > > > bean name.
> >> > > > See the IMPORTANT note at:
> >> > > >
> >> > > >
> >> > >
> >> >
> >>
> https://camel.apache.org/manual/route-template.html#_binding_beans_to_route_template
> >> > > >
> >> > > >
> >> > > >
> >> > > > On Thu, Sep 8, 2022 at 11:53 AM ski n <raymondmees...@gmail.com>
> >> > wrote:
> >> > > >
> >> > > > > Hi,
> >> > > > >
> >> > > > > I have a routetemplate as follows:
> >> > > > >
> >> > > > >  routeTemplate("processortemplate")
> >> > > > >          .templateParameter("out")
> >> > > > >          .from("direct:in")
> >> > > > >          .process("MyProcessor")
> >> > > > >          .to("{{out}}");
> >> > > > >
> >> > > > > This works.
> >> > > > >
> >> > > > > The processor is registered an the called by reference. Now I
> >> added a
> >> > > > > constructor argument to the processor and I tried to call it
> like
> >> > this:
> >> > > > >
> >> > > > > routeTemplate("processortemplate")
> >> > > > >         .templateParameter("processerParam")
> >> > > > >         .templateParameter("out")
> >> > > > >         .from("direct:in")
> >> > > > >         .process(new MyProcessor("{{processorParam}}"))
> >> > > > >         .to("{{out}}");
> >> > > > >
> >> > > > > This doesn't work, because the parameter of the processor is
> >> parsed
> >> > > > before
> >> > > > > the template parameter is parsed. Result is that the parameter
> >> > > > > {{myProcessorParam}} is passed as literal param.
> >> > > > >
> >> > > > > I tried to come with up something like this:
> >> > > > >
> >> > > > > routeTemplate("processortemplate")
> >> > > > >         .templateParameter("processerparam")
> >> > > > >         .templateParameter("out")
> >> > > > >         .templateBean("MyProcessor")
> >> > > > >             .typeClass("com.foo.MyProcessor")
> >> > > > >             .property("processerparam", "{{processerparam}}")
> >> > > > >         .end()
> >> > > > >         .from("direct:in")
> >> > > > >         .to("bean:MyProcessor?method=process")
> >> > > > >         .to("{{out}}");
> >> > > > >
> >> > > > > But this didn't pass the parameter as well. As a workaround I
> set
> >> > > > > constructor argument as a header and then get the header within
> >> the
> >> > > > > processor.
> >> > > > >
> >> > > > > Question:
> >> > > > >
> >> > > > > Is there a way to pass constructor arguments to a processor in
> >> > another
> >> > > > way?
> >> > > > > I couldn't find anything at the routeTemplate page on how to
> >> handle
> >> > > > > processors.
> >> > > > >
> >> > > > > Raymond
> >> > > > >
> >> > > >
> >> > > >
> >> > > > --
> >> > > > Claus Ibsen
> >> > > > -----------------
> >> > > > http://davsclaus.com @davsclaus
> >> > > > Camel in Action 2: https://www.manning.com/ibsen2
> >> > > >
> >> > >
> >> >
> >> >
> >> > --
> >> > Claus Ibsen
> >> > -----------------
> >> > http://davsclaus.com @davsclaus
> >> > Camel in Action 2: https://www.manning.com/ibsen2
> >> >
> >>
> >
> >
> > --
> > Claus Ibsen
> > -----------------
> > http://davsclaus.com @davsclaus
> > Camel in Action 2: https://www.manning.com/ibsen2
> >
>
>
> --
> Claus Ibsen
> -----------------
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>

Reply via email to