On Apache Camel, is it possible to setup a second route to consume information from previous route, but at a different schedule? - apache-camel

I'm new to Apache Camel. In my application, I need to consume information from files on a folder, make validations and store that resulting information on an object that is stored inside the exchange, on a property. This process must run every 3 hours a day.
But, I need only once a day at a scheduled time to send an email with the information that is stored on that object. How can I achieve this?
Here's some pseudo code:
.1 from("file:C:/SourceFolder?scheduler.cron=* 3 * * * *).aggregate().process().to(a); //every 3 hours;
.2 from(a).process(); //here, the email must be send at 8pm every day;
Component "Direct" doesn't work, as it doesn't accept scheduling. I just need the information on the exchange from .1, and I need the routing .2 to run only once a day. Suggestions please? Thank you.

Related

How to trigger Messages at specific times?

We have a DB table where every row has a text message and a timestamp. E.g.
Mesg1 09:00
Mesg2 09:01
Mesg3 09:15
Mesg4 09:20
The timings are not at a fixed interval. It is uneven. We would like to read the table as a Source and send the Messages to a Target at the configured timestamps. Components like Quartz do not allow configuring uneven trigger times.
Is there a common pattern that can be followed for such a use case?
Regards,
Yash
Use camel cron component for the trigger events.
from("cron:tab?schedule=0/1+*+*+*+*+?")
.setBody().constant("event")
.log("${body}");
The schedule expression 0/3+10+++*+? can be also written as 0/3 10 * * * ? and triggers an event every three seconds only in the tenth minute of each hour.

AppleScript Calendar automation

I have an AppleScript that runs on loop every two hours to modify a calendar B based on updates from another calendar A.
The script uses the on idle command below to wait 2 hours every loop. What happens if the computer stays idle for 1.5 hours then goes to sleep for 10 hours? Will there be 0.5 hours left when it wakes up? Any other scenarios?
on idle
my_code()
return (120 * minutes)
end idle
The script truly only needs to run if there is an update to calendar A, which is a shared iCloud calendar and can get updates from multiple people. The two hour loop is what I could figure out so far but I feel it is not efficient. Any more robust suggestions? Is there a way I can trigger the script to run only when it detects an update in calendar A? Or, along the same line of thought, is there a way to get the last timestamp the calendar was updated?
Thanks
I can't test following. Not sure it is the best way to solve your problem. Try yourself:
property oldStampDates : {}
on run
tell application "Calendar" to tell calendar "Test Calendar" to set oldStampDates to get stamp date of events
end run
on idle
--> Script retrieves last modified date and time of indicated calendar events.
tell application "Calendar" to tell calendar "Test Calendar" to set newStampDates to get stamp date of events
if newStampDates is not oldStampDates then display notification "The changes was detected"
set oldStampDates to newStampDates
return 30 -- seconds, default setting
end idle
NOTE: 1) you can put instead of display notification call to your handler my_code(), 2) you can put instead of 30 seconds other value, for example, return 10 (checking every 10 seconds).

Generate Sequential Application number

I have a requirement where I need to generate Unique Application Number and in sequential format.
Sample Application Number - APP-Date-0001 the 001 will keep on increasing for entire day and counter should be reset next day. So for next day it should again start from 001 with current date.
The problem will occur when 2 users are creating application at the same time.
Keep counter and last date it was used in custom setting or similar object.
But access that custom setting with normal SOQL, not via the special custom setting methods like getInstance().
Finally - in that SOQL query use FOR UPDATE. https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_for_update.htm
If 2 operations start on same time - 1 will be held until other one finishes or timeout happens

How to organize multiple url fetch calls with GAE?

I should perform thousands of URL fetch calls during the day. All calls are the same, just parameters changes - way and date.
Currently I use multiple cron entries to execute such calls:
- description: get data
url: /admin/getdata?d=way1,way2,way3,way4,...,way12
schedule: every day 8:30
- description: get data
url: /admin/getdata?d=way13,way14,way15,way16,...,way24
schedule: every day 8:40
...
- description: get data
url: /admin/getdata?d=way99,way100,way101,way102,...,way123
schedule: every day 9:20
Then in my getdata handler I parse the d parameter received and perform multiple urlfetches:
for date_ in dates:
for way in d:
response = urlfetch.Fetch('http://example.com?way='+way+'&date='+date_, deadline=60, headers=headers, follow_redirects=True)
But it doesn't help me a lot - still 60 seconds given for the cron job is not enough.
I was thinking about running cron job each ten minutes, but I should store somewhere possible ways and dates, mark already executed requests, then reset it (to be able to execute all again next day).
Is there any better way to do the same?
Or, one cron job which spawns taskqueued jobs for all the other urls. That can be done in the default module, for free. I would set a countdown parameter, to space them out, to not spawn up too many instances. Simplifies app.yaml as well.
A better way is to have just one cron job per day that fetches all urls. All you need to do is to target this cron-job at a backend instance, which does not have a time limit.
Use Modules to create such an instance, and add a "target" setting to your cron job.

Apache Camel - aggregator to space out requests, but not queuing requests

I have route which when sent a message invokes a refresh service
I only want the service to be invoked at most every 1 minute
If the refresh service takes longer than 1 minute (e.g. 11 minutes) I don't want requests for it to queue up
The first part: every 1 minutes is easy, I just create an aggregator with a completionTimeout of 1 mins
The part about stopping requests queueing up is not so easy and I can't figure out how to construct it
e.g.
from( seda_in )
.aggregate( constant(A), blank aggregator )
.completionTimeout( 1000 )
.process( whatever )...
if the process takes 15 seconds then potentially 15 new inoke messages could be waiting for the process when it finishes. I want at most just 1 to be waiting for however long the process takes. (its hard to predict)
how can I avoid this or structure it better to achieve my objectives?
I believe you would be interested in seeing the Throttler pattern, which is documented here http://camel.apache.org/throttler.html
Hope this helps :)
EDIT - If you are wanting to eliminate excess requests, you can also investigate setting a TTL (Time to live) header within JMS and add a concurrent consumer of 1 to your route, which means any excess messages will also be discarded.

Resources