Main

Bursting Archives

March 11, 2009

Bursting...

During these years with Publisher, I worked with many clients directly/indirectly to resolve there reporting issues and one of the very common requirment is about generate mutilple outputs against the single process/report. Here I am sharing one such requirment...

The company’s billing system generates around 30 thousands invoices/bills for each billing cycle. Each billing cycle correspond to a single process and generate a huge set of data for all the invoices.

The process, further consume this huge data and generate the individual Invoices. i.e. one report and multiple output.

The individual Invoice layout depends upon the recipient’s country and local preference, So it could be multiple templates and multiple local. .

The process should take care of document delivery as well. Delivery type and the destination depend on individual client’s preference. Beside it, a copy of each invoice should be save to specific file location or transferred to content management system. To achieve this, the process should allow to hook custom APIs/Logic before and after individual documents generation.

Beside the individual output, there should be another single consolidated output against the same set of data. i.e. a summary report.

So what do you think, Can we satisfy this requirement against the single process?

Yes, The Bursting take care of such type of requirements where single dataset, multiple conditional layouts/templates, multiple layout, multiple delivery and the listener to hook the custom logic at each stage of process.

There are two type of bursting implementation within BI Publisher. The Control File based bursting, which is well integrated with EBS and JDE and available through Public APIs as well. The other one is Delivery SQL based bursting, which is part of Enterprise Release. We will discuss the first one on this post.

The Bursting Control file holds the Meta Data or the bursting rules in XML format.Lets have a look on following control file and see, how far it satisfies the above requirement.

<?xml version="1.0" encoding="UTF-8"?>
<xapi:requestset xmlns:xapi="http://xmlns.oracle.com/oxp/xapi">
 <xapi:globalData location="stream">
 </xapi:globalData >
    <xapi:request select="/DATA/LIST_DEPT/DEPT/LIST_EMPLOYEE/EMPLOYEE">
 <xapi:delivery>
  <xapi:email server="${EMAIL_SERVER}" port="${EMAIL_PORT}" from="${FROM_EMAIL_ADDRESS}"
    reply-to ="${REPL_TO_ADDRESS}">
 <xapi:message id="123"  to="${TO_EMAIL_ADDRESS}" cc="${CC_EMAIL_ADDRESS}" 
 attachment="true"  content-type="html/text" 
 subject="Employee Report for Empno ${EMPNO}">  Dear ${ENAME}, 
    Please review the attached document.</xapi:message>
  </xapi:email>
  <xapi:print id="printer1"  printer="${PRINT_URL}" copies="2"
   orientation-requested="3" />
 </xapi:delivery>
 <xapi:document key="${EMPNO}"  output="c:\burst\sample\${EMPNO}_${ENAME}.pdf" 
  output-type="pdf" delivery="123">
    <xapi:template type="rtf" location="${EMP_TEMPLATE}">
    </xapi:template>
  </xapi:document>
 </xapi:request>
</xapi:requestset>
A sample control file available here.

This will not exactly satisfy the above requirement but it gives an idea, how we can proceed to achieve the above requirement.

Here is the sample usage of Bursting Engine. We can call bursting engine either directly or through DocumentPrecoessor. Calling directly gives more control over some of the internal methods. API accept the Control file, Data File and Temporary directory path.

Using BurstingProcessorEngine directly..

try {
BurstingProcessorEngine dp = new BurstingProcessorEngine();
dp.deleteTempOutputFile(false);
dp.setTempDirectory("c:\\burst\\sample");//Set the temp file
dp.setXMLAPI("C:\\burst\\sample\\SampleControlFile.xml"); //Set Bursting Control file.
dp.setData("c:\\burst\\sample\\employee.xml"); //Data File
dp.registerListener(this); //Set the listener
Properties prop = new Properties(); //add properties and variables//
prop.put("user-variable:EMAIL_SERVER", "myemailserver.com");
prop.put("user-variable:EMAIL_PORT", "25");
prop.put("user-variable:FROM_EMAIL_ADDRESS", “admin@xyz.com");
prop.put("user-variable:CC_EMAIL_ADDRESS", "cc@xyz.com");
prop.put("user-variable:PRINTER_URL", "ipp://myprintserver:631/printers/printer1");
prop.put("user-variable:EMP_TEMPLATE", "c:\\burst\\sample\\employee.rtf");
dp.setConfig(prop);
dp.process();
dp.deletTemporaryOutputFiles();
} catch (Exception e) {
Logger.log(e);
}

Using DocumentProcessor:

try {
DocumentProcessor dp = new DocumentProcessor("C:\\burst\\sample\\SampleControlFile.xml","c:\\burst\\sample\\employee.xml", "c:\\burst\\sample");
dp.setTempDirectory("c:\\burst\\sample");//Set the temp file
dp.setXMLAPI("C:\\burst\\sample\\SampleControlFile.xml"); //Set Bursting Control file.
dp.setData("c:\\burst\\sample\\employee.xml"); //Data File
dp.registerListener(this); //Set the listener
Properties prop = new Properties(); //add properties and variables//
prop.put("user-variable:EMAIL_SERVER", "myemailserver.com");
prop.put("user-variable:EMAIL_PORT", "25");
prop.put("user-variable:FROM_EMAIL_ADDRESS", “admin@xyz.com");
prop.put("user-variable:CC_EMAIL_ADDRESS", "cc@xyz.com");
prop.put("user-variable:PRINTER_URL", "ipp://myprintserver:631/printers/printer1");
prop.put("user-variable:EMP_TEMPLATE", "c:\\burst\\sample\\employee.rtf");
dp.setConfig(prop);
dp.process();
} catch (Exception e) {
Logger.log(e);
}


A sample test case including sample java application, control file, data file, rtf template is available here. Please make sure you have following libraries in class path
Collection.jar, xdo.jar, Xmlparserv2.jar, mail.jar, Activaton.jar, aolj.jar, i18n, xdoparser.jar,Versioninfo.jar and use 10.1.3.4+ release.

Try it out and let me know your experience. We will see some more interesting example during coming post, so stay tune…

April 8, 2009

Bursting: Conditional delivery

This is in response to arvind’s question on how we can set the conditional delivery based on the user preference available in xml data file. Here is an example.

<?xml version="1.0" encoding="UTF-8"?>
<xapi:requestset xmlns:xapi="http://xmlns.oracle.com/oxp/xapi">
 <xapi:globalData location="stream">
 </xapi:globalData >
    <xapi:request select="/DATA/LIST_DEPT/DEPT/LIST_EMPLOYEE/EMPLOYEE">
 <xapi:delivery>
  <xapi:email server="${EMAIL_SERVER}" port="${EMAIL_PORT}"
 from="${FROM_EMAIL_ADDRESS}" 
   reply-to ="${REPL_TO_ADDRESS}">
   <xapi:message id="email1"  to="${TO_EMAIL_ADDRESS}"  cc="${CC_EMAIL_ADDRESS}"   
 attachment="true" content-type="html/text" 
subject="Employee Report for Empno ${EMPNO}">
   Dear ${ENAME}, Please review the attached document.</xapi:message>
  </xapi:email>
  <xapi:filesystem id="file1"
  output="C:\burst\sample\${EMPNO}_${ENAME}_${MGR}_PRINT.pdf"/>
  <xapi:print id="print1"  printer="${PRINT_URL}" copies="2"
   orientation-requested="3" />
 </xapi:delivery>
 <xapi:document key="${EMPNO}" 
  output-type="pdf" delivery="email1">
    <xapi:template type="rtf" location="${TEMPLATE_LOC}"
    filter=".//EMPLOYEE[DEL_CHANNEL='EMAIL']" >
    </xapi:template>
  </xapi:document>
  <xapi:document key="${EMPNO}"   output-type="pdf" delivery="print1">
    <xapi:template type="rtf" location="${TEMPLATE_LOC}"
    filter=".//EMPLOYEE[DEL_CHANNEL='PRINT']" >
    </xapi:template>
  </xapi:document>
 <xapi:document key="${EMPNO}"   output-type="pdf" delivery="file1">
    <xapi:template type="rtf" location="${TEMPLATE_LOC}"
    filter=".//EMPLOYEE[DEL_CHANNEL='FILE_SYSTEM']" >
    </xapi:template>
  </xapi:document>
 </xapi:request>
</xapi:requestset>  

We need to define multiple document sections corresponding to each delivery channel and the filter condition to deliver the output based on user preference. Here DEL_CHANNEL is the element in xml data file, which define the user delivery preference.

About Bursting

This page contains an archive of all entries posted to A BI Publisher developer's diary... in the Bursting category. They are listed from oldest to newest.

Introduction is the next category.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle