You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Brad Johnson <br...@mediadriver.com> on 2016/08/04 20:03:09 UTC

Bean injection?

Is there an easy way to inject a bean in the CamelTestSupport that is
required by a RouteBuilder?

Looking at the CBTS example I'll modify it a bit:

public class FilterTest extends CamelTestSupport {

    @EndpointInject(uri = "mock:result")
    protected MockEndpoint resultEndpoint;

    @Produce(uri = "direct:start")
    protected ProducerTemplate template;

    @Override
    public boolean isDumpRouteCoverage() {
        return true;
    }

    @Test
    public void testSendMatchingMessage() throws Exception {
        String expectedBody = "<matched/>";

        resultEndpoint.expectedBodiesReceived(expectedBody);

        template.sendBodyAndHeader(expectedBody, "foo", "bar");

        resultEndpoint.assertIsSatisfied();
    }
 @Override
    protected RouteBuilder createRouteBuilder() {
        return MyRouteBuilder()
    }
}

public class MyRouteBuilder extends RouteBuilder {
public void configure() {

from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result");
            }
        };

}

Re: Bean injection?

Posted by Brad Johnson <br...@mediadriver.com>.
I accidentally wrote CBTS but mean CTS.  I've  been working with Blueprint
for the past 3 years or so but I'm trying to migrate away from it.  With
Camel 2.17 the CDI has become so good that that is definitely the way to go
for the future.  But I'm using Fuse 6.2.1 and it doesn't work with that
version.

I was also experimenting with SCR some.

When I tried using the registry to inject the bean I got
a PropertyPlaceholderDelegateRegistry.  That registry has a getRegistry
method which returns the JNDI registry which I cast.

PropertyPlaceholderDelegateRegistry pRegistry =
(PropertyPlaceholderDelegateRegistry) super.context.getRegistry();
    JndiRegistry jRegistry = (JndiRegistry) pRegistry.getRegistry();
    jRegistry.bind(POFileNameValidator.class.getSimpleName(), new
POFileNameValidator());


But I finally figured it out.  Because I'm currently stuck with Camel 2.15
for the time being I have to bootstrap my routes in blueprint when I
actually use them in Fuse.  Because I've always used the XML to manually
compose and used the @EndpointInject on occasion my understanding of how to
get some of the automated behavior was limited.  With the new CDI it's a
snap.  But until Fuse 6.3 is out I can start working with Java
RouteBuilders and use Blueprint exclusively for bootstrap.


<bean id="fileProcessingRoute" class="foo.FileProcessingRoute" />
<bean id="coupaProcessingRoute" class="fooProcessingRoute" />
<bean id="errorEmailRoute" class="fooEmailErrorRoutes" />

<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<routeBuilder ref="fooErrorEmailRoute" />
<routeBuilder ref="fooFileProcessingRoute" />
<routeBuilder ref="fooProcessingRoute" />
</camelContext>

The trick to it is to not use the String name of the beans in the paths but
to use the .class.  So, for example, the FileProcessingRoute has this:

.filter().method(FileNameValidator.class)

That bean looks like this:

public class FileNameValidator {
@EndpointInject(uri=RouteConstants.NOTIFY_MALFORMED_FILE_ENDPOINT)
private ProducerTemplate producerTemplate;
public Boolean validateFile(@Header("CamelFileNameOnly") String fileName) {

Because I put that in with the class name instead of using the String name
it does the endpoint injection.  This is what Matt and I were talking about
the other day on how to avoid having to throw an exception for standard
error handling.  In this case I'm looking for a file name that does not
have the correct information in it.  Unfortunately the client uses the file
name to convey metadata about the contents of the file.  So it goes.  But
Instead of throwing an exception and trying to handle that up the chain I
just put a filter in and either go/no based on the validity of the file
name.  Then if it isn't valid I fire an error message to an email route.

But testing is always the problem.  CBTS is much better than it used to be
but it still can hang or have race conditions.  And it certainly isn't the
best for quick testing.  I'm sure any of you who have done extensive CBTS
are nodding your heads. When I can switch to CDI the Camel CDI test runner
is fast and wonderful to use.  My question is how to migrate to it.  Since
I now have my routes in Camel Java RouteBuilders I can use the plain
CamelTestSupport without blueprint for testing individual routes.

While I still can't use the newer 1.2 CDI annotations yet this at least
moves me closer so that I'm creating new code that will be easier to
migrate to it once it is out.

public class FileProcessingRouteBuilderTest extends CamelTestSupport{

    @Test
    public void testUnmarshalRoute() throws Exception {

    TestUtil.sendTestFile();

        POBean poBean = (POBean)
context.createConsumerTemplate().receiveBody(RouteConstants.COUPA_PO_ENDPOINT);
        assertNotNull(poBean );
        System.out.println(poBean );
//Whatever other tests...

    }

    @Override
    protected RouteBuilder createRouteBuilder() {

    return new FileProcessingRoute();
    }
    @Override
    protected Properties useOverridePropertiesWithPropertiesComponent() {
    return TestUtil.loadProperties();
    }


On Fri, Aug 5, 2016 at 10:05 PM, Matt Sicker <bo...@gmail.com> wrote:

> Couldn't you use @BeanInject to put the RouteBuilder in your CBTS class,
> then return that bean in the createRouteBuilder() method? Just put the
> RouteBuilder in the blueprint file.
>
> On 5 August 2016 at 21:41, Quinn Stevenson <qu...@pronoia-solutions.com>
> wrote:
>
> > I normally override createRegistry() and add my beans to the registry
> > there - something like this
> > \
> > @Override
> > protected JndiRegistry createRegistry() throws Exception {
> >    JndiRegistry registry = super.createRegistry();
> >
> >    registry.bind( "bean-name", new MyBean());
> >
> >    return registry;
> > }
> >
> >
> > > On Aug 4, 2016, at 2:06 PM, Brad Johnson <brad.johnson@mediadriver.com
> >
> > wrote:
> > >
> > > Fired the email before I finished....Obviously the MyValidator class
> > hasn't
> > > been instantiated or made available as it would be in Spring, CDI or
> > > Blueprint.  So I need to add it to the registry.
> > >
> > > I can get the JndiRegistry from the PPDRegistry and call bind on it
> with
> > > name/bean but don't know if that will really work or if there's an
> easier
> > > way.
> > >
> > >
> > > public class MyRouteBuilder extends RouteBuilder {
> > > public void configure() {
> > >                from("direct:start").filter().method("MyValidator")
> > > .to("mock:result");
> > >            }
> > >        };
> > >
> > > }
> > >
> > > On Thu, Aug 4, 2016 at 3:03 PM, Brad Johnson <
> > brad.johnson@mediadriver.com>
> > > wrote:
> > >
> > >> Is there an easy way to inject a bean in the CamelTestSupport that is
> > >> required by a RouteBuilder?
> > >>
> > >> Looking at the CBTS example I'll modify it a bit:
> > >>
> > >> public class FilterTest extends CamelTestSupport {
> > >>
> > >>    @EndpointInject(uri = "mock:result")
> > >>    protected MockEndpoint resultEndpoint;
> > >>
> > >>    @Produce(uri = "direct:start")
> > >>    protected ProducerTemplate template;
> > >>
> > >>    @Override
> > >>    public boolean isDumpRouteCoverage() {
> > >>        return true;
> > >>    }
> > >>
> > >>    @Test
> > >>    public void testSendMatchingMessage() throws Exception {
> > >>        String expectedBody = "<matched/>";
> > >>
> > >>        resultEndpoint.expectedBodiesReceived(expectedBody);
> > >>
> > >>        template.sendBodyAndHeader(expectedBody, "foo", "bar");
> > >>
> > >>        resultEndpoint.assertIsSatisfied();
> > >>    }
> > >> @Override
> > >>    protected RouteBuilder createRouteBuilder() {
> > >>        return MyRouteBuilder()
> > >>    }
> > >> }
> > >>
> > >> public class MyRouteBuilder extends RouteBuilder {
> > >> public void configure() {
> > >>                from("direct:start").filter(header("foo").
> > >> isEqualTo("bar")).to("mock:result");
> > >>            }
> > >>        };
> > >>
> > >> }
> > >>
> > >>
> >
> >
>
>
> --
> Matt Sicker <bo...@gmail.com>
>

Re: Bean injection?

Posted by Matt Sicker <bo...@gmail.com>.
Couldn't you use @BeanInject to put the RouteBuilder in your CBTS class,
then return that bean in the createRouteBuilder() method? Just put the
RouteBuilder in the blueprint file.

On 5 August 2016 at 21:41, Quinn Stevenson <qu...@pronoia-solutions.com>
wrote:

> I normally override createRegistry() and add my beans to the registry
> there - something like this
> \
> @Override
> protected JndiRegistry createRegistry() throws Exception {
>    JndiRegistry registry = super.createRegistry();
>
>    registry.bind( "bean-name", new MyBean());
>
>    return registry;
> }
>
>
> > On Aug 4, 2016, at 2:06 PM, Brad Johnson <br...@mediadriver.com>
> wrote:
> >
> > Fired the email before I finished....Obviously the MyValidator class
> hasn't
> > been instantiated or made available as it would be in Spring, CDI or
> > Blueprint.  So I need to add it to the registry.
> >
> > I can get the JndiRegistry from the PPDRegistry and call bind on it with
> > name/bean but don't know if that will really work or if there's an easier
> > way.
> >
> >
> > public class MyRouteBuilder extends RouteBuilder {
> > public void configure() {
> >                from("direct:start").filter().method("MyValidator")
> > .to("mock:result");
> >            }
> >        };
> >
> > }
> >
> > On Thu, Aug 4, 2016 at 3:03 PM, Brad Johnson <
> brad.johnson@mediadriver.com>
> > wrote:
> >
> >> Is there an easy way to inject a bean in the CamelTestSupport that is
> >> required by a RouteBuilder?
> >>
> >> Looking at the CBTS example I'll modify it a bit:
> >>
> >> public class FilterTest extends CamelTestSupport {
> >>
> >>    @EndpointInject(uri = "mock:result")
> >>    protected MockEndpoint resultEndpoint;
> >>
> >>    @Produce(uri = "direct:start")
> >>    protected ProducerTemplate template;
> >>
> >>    @Override
> >>    public boolean isDumpRouteCoverage() {
> >>        return true;
> >>    }
> >>
> >>    @Test
> >>    public void testSendMatchingMessage() throws Exception {
> >>        String expectedBody = "<matched/>";
> >>
> >>        resultEndpoint.expectedBodiesReceived(expectedBody);
> >>
> >>        template.sendBodyAndHeader(expectedBody, "foo", "bar");
> >>
> >>        resultEndpoint.assertIsSatisfied();
> >>    }
> >> @Override
> >>    protected RouteBuilder createRouteBuilder() {
> >>        return MyRouteBuilder()
> >>    }
> >> }
> >>
> >> public class MyRouteBuilder extends RouteBuilder {
> >> public void configure() {
> >>                from("direct:start").filter(header("foo").
> >> isEqualTo("bar")).to("mock:result");
> >>            }
> >>        };
> >>
> >> }
> >>
> >>
>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: Bean injection?

Posted by Quinn Stevenson <qu...@pronoia-solutions.com>.
I normally override createRegistry() and add my beans to the registry there - something like this
\
@Override
protected JndiRegistry createRegistry() throws Exception {
   JndiRegistry registry = super.createRegistry();
   
   registry.bind( "bean-name", new MyBean());
   
   return registry;
}


> On Aug 4, 2016, at 2:06 PM, Brad Johnson <br...@mediadriver.com> wrote:
> 
> Fired the email before I finished....Obviously the MyValidator class hasn't
> been instantiated or made available as it would be in Spring, CDI or
> Blueprint.  So I need to add it to the registry.
> 
> I can get the JndiRegistry from the PPDRegistry and call bind on it with
> name/bean but don't know if that will really work or if there's an easier
> way.
> 
> 
> public class MyRouteBuilder extends RouteBuilder {
> public void configure() {
>                from("direct:start").filter().method("MyValidator")
> .to("mock:result");
>            }
>        };
> 
> }
> 
> On Thu, Aug 4, 2016 at 3:03 PM, Brad Johnson <br...@mediadriver.com>
> wrote:
> 
>> Is there an easy way to inject a bean in the CamelTestSupport that is
>> required by a RouteBuilder?
>> 
>> Looking at the CBTS example I'll modify it a bit:
>> 
>> public class FilterTest extends CamelTestSupport {
>> 
>>    @EndpointInject(uri = "mock:result")
>>    protected MockEndpoint resultEndpoint;
>> 
>>    @Produce(uri = "direct:start")
>>    protected ProducerTemplate template;
>> 
>>    @Override
>>    public boolean isDumpRouteCoverage() {
>>        return true;
>>    }
>> 
>>    @Test
>>    public void testSendMatchingMessage() throws Exception {
>>        String expectedBody = "<matched/>";
>> 
>>        resultEndpoint.expectedBodiesReceived(expectedBody);
>> 
>>        template.sendBodyAndHeader(expectedBody, "foo", "bar");
>> 
>>        resultEndpoint.assertIsSatisfied();
>>    }
>> @Override
>>    protected RouteBuilder createRouteBuilder() {
>>        return MyRouteBuilder()
>>    }
>> }
>> 
>> public class MyRouteBuilder extends RouteBuilder {
>> public void configure() {
>>                from("direct:start").filter(header("foo").
>> isEqualTo("bar")).to("mock:result");
>>            }
>>        };
>> 
>> }
>> 
>> 


Re: Bean injection?

Posted by Brad Johnson <br...@mediadriver.com>.
Fired the email before I finished....Obviously the MyValidator class hasn't
been instantiated or made available as it would be in Spring, CDI or
Blueprint.  So I need to add it to the registry.

I can get the JndiRegistry from the PPDRegistry and call bind on it with
name/bean but don't know if that will really work or if there's an easier
way.


public class MyRouteBuilder extends RouteBuilder {
public void configure() {
                from("direct:start").filter().method("MyValidator")
.to("mock:result");
            }
        };

}

On Thu, Aug 4, 2016 at 3:03 PM, Brad Johnson <br...@mediadriver.com>
wrote:

> Is there an easy way to inject a bean in the CamelTestSupport that is
> required by a RouteBuilder?
>
> Looking at the CBTS example I'll modify it a bit:
>
> public class FilterTest extends CamelTestSupport {
>
>     @EndpointInject(uri = "mock:result")
>     protected MockEndpoint resultEndpoint;
>
>     @Produce(uri = "direct:start")
>     protected ProducerTemplate template;
>
>     @Override
>     public boolean isDumpRouteCoverage() {
>         return true;
>     }
>
>     @Test
>     public void testSendMatchingMessage() throws Exception {
>         String expectedBody = "<matched/>";
>
>         resultEndpoint.expectedBodiesReceived(expectedBody);
>
>         template.sendBodyAndHeader(expectedBody, "foo", "bar");
>
>         resultEndpoint.assertIsSatisfied();
>     }
>  @Override
>     protected RouteBuilder createRouteBuilder() {
>         return MyRouteBuilder()
>     }
> }
>
> public class MyRouteBuilder extends RouteBuilder {
> public void configure() {
>                 from("direct:start").filter(header("foo").
> isEqualTo("bar")).to("mock:result");
>             }
>         };
>
> }
>
>