You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "Gershaw, Geoffrey" <ge...@credit-suisse.com> on 2013/01/18 18:01:11 UTC

JPA Component Behavior

Hello once more,

 

 

So I read in the documentation that the jpa component polls the db.
Kinda a poor man's queue. I had hoped that this behavior would be
configurable. I don't want to poll. I just want to retrieve the entities
1 time. I would think the jpa component could do this.

 

It doesn't appear so. Am I correct? 

 

I guess I shall create a custom bean to do the retrieval?

 

Thanks


=============================================================================== 
Please access the attached hyperlink for an important electronic communications disclaimer: 
http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html 
=============================================================================== 


Re: JPA Component Behavior

Posted by Chris Wolf <cw...@gmail.com>.
On Fri, Jan 18, 2013 at 12:01 PM, Gershaw, Geoffrey
<ge...@credit-suisse.com> wrote:
> Hello once more,
>
>
>
>
>
> So I read in the documentation that the jpa component polls the db.
> Kinda a poor man's queue. I had hoped that this behavior would be
> configurable. I don't want to poll. I just want to retrieve the entities
> 1 time. I would think the jpa component could do this.
>
>
>
> It doesn't appear so. Am I correct?
>
>
>
> I guess I shall create a custom bean to do the retrieval?
>
>
>
> Thanks


I will definitely need this as well.  I looked into it a little bit
and I understand one possible approach
would be to implement a custom polling strategy that performs the
query once, then stops.

I skimmed through my copy of "Camel In Action" (great book, BTW), but
didn't find anything about this.

I then read this page:

http://camel.apache.org/polling-consumer.html

There, it talks about an interface named
"org.apache.camel.PollingConsumerPollStrategy",
with methods begin, commit and rollback.   Unfortunately, I don't see
any such interface in the
camel-core-2.10.0.jar.  I can only find,
"org.apache.camel.PollingConsumerPollingStrategy"
with methods onInit, beforePoll and afterPoll.

I then looked at the source for DefaultPollingConsumerPollStrategy,
and noticed that the
interface with begin/commit/rollback is actually in different package:

org.apache.camel.spi.PollingConsumerPollStrategy;

...and I'm wondering if it's appropriate for end-developers to create
concrete implementations of spi
interfaces?

Thanks,

   -Chris

Re: JPA Component Behavior

Posted by Chris Wolf <cw...@gmail.com>.
If you look back at the entire thread:

http://camel.465427.n5.nabble.com/JPA-Component-Behavior-td5725781.html#a5731377

You can see that I solved this requirement by implementing a custom
PollingConsumerPollStrategy
called you use that plus configure the JPA consumer with "startScheduler=false"

Then, from your actionPerformed button code, or whatever code needs to trigger
the JPA poll, call a function with this code:

        JpaConsumer jpaConsumer = null;

        Route route = ctx.getRoute(routeId);
        if (route == null) {
            log.error("No route found with id \"{}\"", routeId);
            return;
        }

        if ( ! (route.getConsumer() instanceof JpaConsumer)) {
            log.error("Consumer must be of type JpaConsumer, the
configured consumer is of type {}",
                route.getConsumer().getClass().getName());
            return;
        }

        try {
            if (jpaConsumer.isSuspended() || jpaConsumer.isSuspending()) {
                jpaConsumer.resume();
            } else {
                // first time here - need to start scheduler
                // why is startScheduler() "protected" - can't it be "public"?
                Class<?> superClass = jpaConsumer.getClass().getSuperclass();
                superClass = superClass.getSuperclass();
                Method m = superClass.getDeclaredMethod("startScheduler",
                        (Class<?>[]) null);
                m.setAccessible(true);
                m.invoke(jpaConsumer, (Object[]) null);
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }


This is working fine for my use-case which is the same as yours...

Regards,

Chris

On Tue, Apr 23, 2013 at 5:10 PM, Christian Jacob <cj...@aol.com> wrote:
> Hi Claus,I'm very eager to get that feature, too. My requirements for a new
> project are:
> run on every 1st of a month (or some other Quartz clause) and then select
> all objects with status = 0
> have a user interface for an administrator in which he/she can customize
> some search arguments such as a time range in which a JPA object was
> created, different values for the status field, and so on. I'm surely fit
> enough to deliver such a UI, e.g. as JEE2. From that UI, I can produce a
> route with customized query criteria. But the point is: how do I make the
> JPA consumer run on a button click?
> In my opinion, scheduled poll consuming is not the only sceanrio in which
> database or JPA retrieval is required. Do you see a way with which I can
> achieve that? Or do I have to wait?
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/JPA-Component-Behavior-tp5725781p5731377.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JPA Component Behavior

Posted by Christian Jacob <cj...@aol.com>.
Hi Claus,I'm very eager to get that feature, too. My requirements for a new
project are:
run on every 1st of a month (or some other Quartz clause) and then select
all objects with status = 0
have a user interface for an administrator in which he/she can customize
some search arguments such as a time range in which a JPA object was
created, different values for the status field, and so on. I'm surely fit
enough to deliver such a UI, e.g. as JEE2. From that UI, I can produce a
route with customized query criteria. But the point is: how do I make the
JPA consumer run on a button click?
In my opinion, scheduled poll consuming is not the only sceanrio in which
database or JPA retrieval is required. Do you see a way with which I can
achieve that? Or do I have to wait?



--
View this message in context: http://camel.465427.n5.nabble.com/JPA-Component-Behavior-tp5725781p5731377.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JPA Component Behavior

Posted by Chris Wolf <cw...@gmail.com>.
On Sat, Jan 19, 2013 at 3:09 AM, Claus Ibsen <cl...@gmail.com> wrote:
> Hi
>
> We could possible enhance scheduled poll consumer to allow people to
> set a max number of polls
> http://camel.apache.org/polling-consumer.html
>
> The timer component has a "repeatCount" option for that kind of use-case.
> This will though still let the consumer be started and running, it
> just prevents any further polling.
>

The thing is, you don't want the scheduler to start, initially,
otherwise, it will poll once, find no data, then nothing.
You want it to poll when the data has been inserted into the database,
so you need the other route to signal that
fact, which is why I implemented that custom
PollingConsumerPollStrategy the way I did, although, now that I
think about it, a better way to signal the JPA consumer would be via a
message rather then explicit
method calls on the JpaConsumer.

It's kind of a hack because we're trying to use the EIP pattern,
"Polling Consumer",  but kludging it
to behave as EIP pattern "Even Driven Consumer", which is really what
we need in this use case.

There are some other details that need to be addressed to make this
fully flexible, if you don't want to consume-delete, nor
update a field to "mark as processed"  via @Consumed.  For example,
you may want a separate table to keep a tally of
primary keys of consumed entities, or maybe you want to just indicate
that a timestamp field value older then some value
means the entity is consumed, or too old to be a candidate for
consumption, etc.  E.g. maybe have some sort of pluggable
IndicateConsumedStrategy and provide a few strategies, per the
suggestions, above.

   -Chris

>
> On Sat, Jan 19, 2013 at 1:42 AM, Chris Wolf <cw...@gmail.com> wrote:
>> On Fri, Jan 18, 2013 at 12:01 PM, Gershaw, Geoffrey
>> <ge...@credit-suisse.com> wrote:
>>> Hello once more,
>>>
>>>
>>>
>>>
>>>
>>> So I read in the documentation that the jpa component polls the db.
>>> Kinda a poor man's queue. I had hoped that this behavior would be
>>> configurable. I don't want to poll. I just want to retrieve the entities
>>> 1 time. I would think the jpa component could do this.
>>>
>>>
>>>
>>> It doesn't appear so. Am I correct?
>>>
>>>
>>>
>>> I guess I shall create a custom bean to do the retrieval?
>>>
>>
>> You don't need to.  I created an alternative
>> PollingConsumerPollStrategy implementation,
>> "OneShotPollingConsumerStrategy" (attached).
>>
>> The way it works is that you configure your JPA consumer endpoint with
>> the options,
>> "pollStrategy=#oneshotPoller&startScheduler=false" and make sure this
>> route has it's
>> id set.  When you create an instance of
>> OneShotPollingConsumerStrategy, pass this
>> route id string in the singel arg constructor, or call
>> setDefaultRouteId(id) on the instance.
>>
>> To signal the JPA consumer route to perform it's
>> one-time reading of the DB, change the route you want to drive this,
>> by appending:
>>
>> .beanRef("oneshotPoller", "resumeJpaConsumer");
>>
>> ...to the end, so that when that route's processing completes, it will
>> signal the
>> JPA consuming route to read once.  This works by
>> OneShotPollingConsumerStrategy.commit
>> calling JpaConsumer.suspend().
>>
>> Upon the very first invocation of
>> OneShotPollingConsumerStrategy.resumeJpaConsumer(), it
>> will actually merely just start the scheduler, which stays running
>> from then, on.  The second
>> ans subsequent invocations of
>> OneShotPollingConsumerStrategy.resumeJpaConsumer() will
>> just call JpaConsumer.resume() and do nothing with the scheduler.
>>
>> There could be unintended consequences of calling
>> JpaConsumer.suspend(), so I can't guarantee
>> this solution is robust at this point.
>>
>> Sorry for the rough and lazy explanation.   If anyone finds it useful,
>> I can document it better.
>>
>> Regards,
>>
>>     -Chris.
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> FuseSource is now part of Red Hat
> Email: cibsen@redhat.com
> Web: http://fusesource.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen

Re: JPA Component Behavior

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

We could possible enhance scheduled poll consumer to allow people to
set a max number of polls
http://camel.apache.org/polling-consumer.html

The timer component has a "repeatCount" option for that kind of use-case.
This will though still let the consumer be started and running, it
just prevents any further polling.


On Sat, Jan 19, 2013 at 1:42 AM, Chris Wolf <cw...@gmail.com> wrote:
> On Fri, Jan 18, 2013 at 12:01 PM, Gershaw, Geoffrey
> <ge...@credit-suisse.com> wrote:
>> Hello once more,
>>
>>
>>
>>
>>
>> So I read in the documentation that the jpa component polls the db.
>> Kinda a poor man's queue. I had hoped that this behavior would be
>> configurable. I don't want to poll. I just want to retrieve the entities
>> 1 time. I would think the jpa component could do this.
>>
>>
>>
>> It doesn't appear so. Am I correct?
>>
>>
>>
>> I guess I shall create a custom bean to do the retrieval?
>>
>
> You don't need to.  I created an alternative
> PollingConsumerPollStrategy implementation,
> "OneShotPollingConsumerStrategy" (attached).
>
> The way it works is that you configure your JPA consumer endpoint with
> the options,
> "pollStrategy=#oneshotPoller&startScheduler=false" and make sure this
> route has it's
> id set.  When you create an instance of
> OneShotPollingConsumerStrategy, pass this
> route id string in the singel arg constructor, or call
> setDefaultRouteId(id) on the instance.
>
> To signal the JPA consumer route to perform it's
> one-time reading of the DB, change the route you want to drive this,
> by appending:
>
> .beanRef("oneshotPoller", "resumeJpaConsumer");
>
> ...to the end, so that when that route's processing completes, it will
> signal the
> JPA consuming route to read once.  This works by
> OneShotPollingConsumerStrategy.commit
> calling JpaConsumer.suspend().
>
> Upon the very first invocation of
> OneShotPollingConsumerStrategy.resumeJpaConsumer(), it
> will actually merely just start the scheduler, which stays running
> from then, on.  The second
> ans subsequent invocations of
> OneShotPollingConsumerStrategy.resumeJpaConsumer() will
> just call JpaConsumer.resume() and do nothing with the scheduler.
>
> There could be unintended consequences of calling
> JpaConsumer.suspend(), so I can't guarantee
> this solution is robust at this point.
>
> Sorry for the rough and lazy explanation.   If anyone finds it useful,
> I can document it better.
>
> Regards,
>
>     -Chris.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
FuseSource is now part of Red Hat
Email: cibsen@redhat.com
Web: http://fusesource.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: JPA Component Behavior

Posted by Chris Wolf <cw...@gmail.com>.
On Fri, Jan 18, 2013 at 12:01 PM, Gershaw, Geoffrey
<ge...@credit-suisse.com> wrote:
> Hello once more,
>
>
>
>
>
> So I read in the documentation that the jpa component polls the db.
> Kinda a poor man's queue. I had hoped that this behavior would be
> configurable. I don't want to poll. I just want to retrieve the entities
> 1 time. I would think the jpa component could do this.
>
>
>
> It doesn't appear so. Am I correct?
>
>
>
> I guess I shall create a custom bean to do the retrieval?
>

You don't need to.  I created an alternative
PollingConsumerPollStrategy implementation,
"OneShotPollingConsumerStrategy" (attached).

The way it works is that you configure your JPA consumer endpoint with
the options,
"pollStrategy=#oneshotPoller&startScheduler=false" and make sure this
route has it's
id set.  When you create an instance of
OneShotPollingConsumerStrategy, pass this
route id string in the singel arg constructor, or call
setDefaultRouteId(id) on the instance.

To signal the JPA consumer route to perform it's
one-time reading of the DB, change the route you want to drive this,
by appending:

.beanRef("oneshotPoller", "resumeJpaConsumer");

...to the end, so that when that route's processing completes, it will
signal the
JPA consuming route to read once.  This works by
OneShotPollingConsumerStrategy.commit
calling JpaConsumer.suspend().

Upon the very first invocation of
OneShotPollingConsumerStrategy.resumeJpaConsumer(), it
will actually merely just start the scheduler, which stays running
from then, on.  The second
ans subsequent invocations of
OneShotPollingConsumerStrategy.resumeJpaConsumer() will
just call JpaConsumer.resume() and do nothing with the scheduler.

There could be unintended consequences of calling
JpaConsumer.suspend(), so I can't guarantee
this solution is robust at this point.

Sorry for the rough and lazy explanation.   If anyone finds it useful,
I can document it better.

Regards,

    -Chris.