The other day a colleague and myself were working on a BPEL process that should wait for a certain period of time for a message to arrive. When the time was up, a time out occurs and an alternative action should be taken. Using the BPEL Pick activity, this is very easy to accomplish. Usually the time out period is fixed, specified through the BPEL editor in terms of seconds, minutes, hours and even days, months and years. However, in our particular case, we wanted to dynamically determine the time out period: depending on a certain condition, the time to wait for the incoming message could vary. This made us wonder exactly what type of expression we needed to create. Enter xsd:duration.
It turns out that along with more familiar data types such as string, integer, date and dateTime there is a specific XSD type called duration that is used to express time and date intervals – similar for example to INTERVAL in the Oracle Database and Period in the (new) Java 7 Date and Time API (see http://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html#durations).
Values for elements of type xsd:duration represent a period using a specific format. Some examples are:
P1D PT10H5s P5Y11M P2M4DT10M5.23S
The P is the mandatory first character of a duration value and there should be at least one integer as well as at least one of the following characters: Y, M, D (for year, month, day) or H, M, S (for hour, minute, second). Note that when you specify hour, minute or second in the duration, you also need to have a T – to separate the YMD part of the duration from the Time part. Note that the seconds can be expressed down to nanoseconds by using a digital fraction:
PT0.001S
which expresses a duration of 1 milisecond.
There is one situation where the P is not the first character of the duration value and that is in the case of a negative duration, such as
-P2M
The exact meaning of a negative duration is up to you to determine. However, since durations are frequently used in date and time arithmetic where durations are added to date and dateTime values (or even subtracted from them) this may make more sense to you.
Even though durations appear very straightforward, there is room for some inconsistency or unclarity. This is caused by the fact that one month is not necessarily equally long as the next month. The same applies to years – think leap years and all. The Oracle Database caters for this by specifying two different interval data types: Year to Month and Day to Second. XSD:duration does not make this distinction, so you need to be aware of this twilight zone yourself:
As long as you stick to Hours, Minutes and Seconds, there should be no unclarity. Note that durations with more than 24 hours or more than 60 minutes are quite valid. For example:
PT168H120M
to express a 7 day and 2 hour period.
Dynamically deriving the BPEL OnAlarm duration
Let’s briefly return to the original situation in which I found myself – setting the duration for the OnAlarm branch for the BPEL Pick activity:
When you double click the OnAlarm icon, the following editor appears.
It allows us to enter a fixed value for the duration, or specify an expression for this.
In our case, the duration was defined as a number of hours that was held in a BPEL variable – timeoutPeriod. So the expression we needed to define here was:
concat('PT',bpws:getVariableData('timeoutPeriod'),'H')
This concatenates the number held in the variable timeoutPeriod to the string PT, appending H in the process and producing values like PT58H and PT2H.
Resources
W3C definition of the XSD:duration element – http://www.w3.org/TR/xmlschema-2/#duration