A very common use case for using an SLA (Service Level Agreement) is when there is a start date-time (not necessarily the current date-time) and an end date-time and you want to use the time difference between those two dates as your SLA in your BPM process. In the good old BPM 10g days you could do that easily. You could take the two dates and subtract one from the other and the result could be used as a SLA value. Unfortunately, the same cannot be done in BPM 11g as easily but we do have a solution.

The following will demonstrate how the above scenario can be achieved in BPM 11g. Since the SLA calculation itself is just a few lines of Java code, we will use a BPEL component called ‘Java Embedding’ for it. It does exactly what the name suggests; it embeds Java code into a BPEL process. In this blog, we will kill two birds with one stone and will look at the Java code to calculate the SLA value and also look at how to embed that into a reusable BPEL process. The BPEL process can then be referenced or invoked from any client, including a BPM process.

  1. Create a very simple reusable synchronous BPEL process. This BPEL process will be the SLA calculation utility. The input payload will have the two date-times (start date-time and end date-time) as strings. The output payload will have the calculated SLA value as string.

     

  2. We will set the output variable in the ‘Java Embedding’ component later, but for it to work the output variable has to have already been initialized. Therefore, let’s initialize the output variable. Drag the ‘Assign’ component and give it an appropriate name and assign a default value to the output variable. I have assigned it ‘PT60M’, which translates to 60 minutes Duration. Here are some examples of Duration code:

    PT5M – five minutes

    P1D – a day

    P1M – a month

    P1Y1DT1H1S – one year, one day, one hour, and one second

     

  3. Now we will write the Java code to calculate the SLA value. Drag the ‘Java Embedding’ component under the ‘Oracle Extensions’ onto your BPEL process and give it an appropriate name.

  4. This component works like a plain text editor. It does not offer any coding functionality like code completion, typo warnings, etc. so you have to be very careful of what you type. Fortunately for you, we have the code you need, so just copy/paste it.

    The input1 and input2 variables will be assigned with your start date-time and end date-time input variables respectively. The output1 variable will be assigned with your SLA output variable. Those are the only changes you will have to make.


    try {
    addAuditTrailEntry("Executing DateDiff.JavaEmbeddingSLACalculation.");
    SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    String diffDatePeriod = "P";

    XMLElement input1 =
    (XMLElement) getVariableData(“inputVariable”, “payload”, “/ns1:purchaseOrderUS/ns1:orderDateStart”);
    XMLElement input2 =
    (XMLElement) getVariableData(“inputVariable”, “payload”, “/ns1:purchaseOrderUS/ns1:orderDateEnd”);

    Date d1 = format.parse(input1.getTextContent());
    Date d2 = format.parse(input2.getTextContent());
    addAuditTrailEntry(d1 + ” ” + d2);

    long diff = d2.getTime() – d1.getTime();
    long diffSeconds = diff / 1000 % 60;
    long diffMinutes = diff / (60 * 1000) % 60;
    long diffHours = diff / (60 * 60 * 1000) % 24;
    long diffDays = diff / (24 * 60 * 60 * 1000);

    diffDatePeriod = diffDatePeriod + diffDays + “DT”;
    diffDatePeriod = diffDatePeriod + diffHours + “H”;
    diffDatePeriod = diffDatePeriod + diffMinutes + “M”;
    diffDatePeriod = diffDatePeriod + diffSeconds + “S”;

    setVariableData(“outputVariable”, “payload”, “/ns2:OrderAudit/ns2:ActivitySLA”, diffDatePeriod);
    XMLElement output1 =
    (XMLElement) getVariableData(“outputVariable”, “payload”, “/ns2:OrderAudit/ns2:ActivitySLA”);
    addAuditTrailEntry(“ActivitySLA: ” + output1.getTextContent());

    addAuditTrailEntry(“Finished DateDiff.JavaEmbeddingSLACalculation.”);

    } catch (Exception e) {
    System.out.println(“exception “+e.getMessage());
    addAuditTrailEntry(e);
    }

    Big thanks to Oracle Ace Dan Atwood for providing some of this code to me. You can check out his amazing training material here.

     

  5. Since we are writing Java code, we need to import a few classes for the Java code to work. Click on the ‘Source’ tab of your BPEL process and add the following import statements after the <process> tag. These import statements work with BPEL 2.0 Specification. The import syntax is different for BPEL 1.1 Specification.

     

    <import location="oracle.xml.parser.v2.XMLElement" importType="http://schemas.oracle.com/bpel/extension/java"/>
    <import location="java.text.SimpleDateFormat" importType="http://schemas.oracle.com/bpel/extension/java"/>
    <import location="java.util.Date" importType="http://schemas.oracle.com/bpel/extension/java"/>
  6. You are now done creating your utility. Your completed reusable synchronous BPEL process should look similar to this and will be available (as a SOAP service) to be used from anywhere.

  7. Create a client (a BPM process in this example) to use this utility. Below, the ‘Call DateDiff’ makes a service call to the BPEL process with the two dates as input variables and gets back a SLA value to be used in the BPM process. The Catch Timer Event ‘CatchEvent1’ uses this SLA value.

  8. Deploy your composite(s) and test it out from your client.

    In the example below we provided the input dates, as shown below.

    Based on the two input dates, the SLA calculated is 1 minute, as shown below.

    The SLA is set and then fired after 1 minute, as shown below.

The above example used the Catch Timer Event, but this SLA can be used and set on other BPM components like Start Timer Event, Human Task Boundary Event, and Human Task Deadlines. Please feel free to leave me your questions and comments.