Oracle BI EE 11g - Action Framework - Java, EJB's and PDF Watermarks
As mentioned in the blog entry yesterday, Action Framework of BI EE 11g opens up direct integration with Java. So, any process that can be called via Java can be directly called from BI EE as well. In 10g, the only way for calling Java Processes was by using Delivers. I have blogged about it in detail here. In 11g, the old method is still supported but is not recommended. The recommended approach is to embed the Java Methods in a EJB session bean and then call it from BI EE. Lets look at how the integration works in this blog entry. To make it interesting, lets look at a method of adding Watermarks to the standard PDF export available in BI EE.
For this example, we will be needing JDeveloper 1113. We start of with creating a simple Generic Application called WaterMark as shown below in JDeveloper
Also create a Generic project without any components in the project.
Now within this project create a new EJB Session Bean.
Use the EJB 3.0 option as i believe only EJB 3 is supported in BI EE.
Create a Stateless Bean as shown below
Note down the Mapped Name as that is what will be used when we create the methods within the EJB. Leave the Bean Class to be with the default value. Also, ensure that the Remote and Client Interfaces are chosen to be implemented within the project
This should create 3 java files within your project as shown below.
For calling EJB's, we need to always include a Jar file called actionframework-common.jar. This is what enables the 2 way communication between BI EE and the EJB's. This jar file is generally present under {MIDDLEWARE_HOM}\user_projects\domains\bifoundation_domain\servers\bi_server1\tmp\_WL_user\bimiddleware_11.1.1\udy1lp\lib folder. The udy1lp folder is a temporary folder. This could be different in your installation.
Also in our example, we are planning to watermark a PDF generated by BI EE. There are different ways of doing this. One way is to use the BI Publisher watermarking feature that we put into use before here. To keep it simple, i will be using the iText package available for download here. Ensure that the project that we created above has both the actionframework-common.jar and the iText-xxx.jar in the Classpath.
For watermarking, in my example here, i will be using the Rittman Mead logo. This logo will be placed in a directory called C:\PDFExport. This logo will be referred in our main Session Bean code.
Open up SessionEJB.java and enter the code below. This declares our method that we will be calling from BI EE.
package watermark; import java.io.FileNotFoundException; import java.io.IOException; import javax.activation.ActivationDataFlavor; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.activation.URLDataSource; import javax.ejb.Remote; import oracle.bi.action.annotation.OBIActionParameter; @Remote public interface SessionEJB { String WatermarkReport( @OBIActionParameter (name = "Enter Filename", prompt = "Enter filename location:") String filename, @OBIActionParameter (name = "Analysis", prompt = "Report to Export:") DataHandler document) throws FileNotFoundException, IOException; }
Open up SessionEJBBean.java and enter the code given below. This is where we will be implementing our method.
package watermark; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.ejb.Local; import javax.ejb.Remote; import javax.ejb.Stateless; import javax.ejb.TransactionManagement; import javax.ejb.TransactionManagementType; @Stateless(name = "SessionEJB", mappedName = "ejb/WaterMark-watermark-SessionEJB") @TransactionManagement(TransactionManagementType.BEAN) @Remote @Local public class SessionEJBBean implements SessionEJB, SessionEJBLocal { public SessionEJBBean() { } public String WatermarkReport (String filename, javax.activation.DataHandler report) throws FileNotFoundException, IOException { File f = new File(filename); FileOutputStream outputStream = new FileOutputStream(f); report.writeTo(outputStream); outputStream.close(); try { PdfReader pdfreadobject = new PdfReader(filename); int no = pdfreadobject.getNumberOfPages(); int cnt = 0; PdfStamper pdfstamp = new PdfStamper(pdfreadobject, new FileOutputStream("C:\\PDFExport\\RMWatermark.pdf")); PdfContentByte pdfcontent; Image image = Image.getInstance("C:\\PDFExport\\RMLogo.png"); image.setAbsolutePosition(300, 400); while (cnt < no) { cnt++; pdfcontent = pdfstamp.getUnderContent(cnt); pdfcontent.addImage(image); } pdfstamp.close(); } catch (Exception ex) { ex.printStackTrace(); } return "Report Exported"; } }
And finally in the SessionEJBLocal.java enter the code given below
package watermark; import java.io.FileNotFoundException; import java.io.IOException; import javax.activation.ActivationDataFlavor; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.activation.URLDataSource; import javax.ejb.Local; @Local public interface SessionEJBLocal { String WatermarkReport(String filename, DataHandler document) throws FileNotFoundException, IOException; }
Now compile this entire project. Create a deployment profile for this project using EJB-JAR option and ensure that the libraries that we have chosen are included properly in the profile.
Create an EAR deployment profile for the Application and refer to the EJB-JAR deployment profile that we created for the project as shown below
Deploy the EAR file to the file system. Then deploy this to weblogic. Ensure that you are deploying this to the same managed server as BI EE.
After deploying and starting up the application, we need to update the ActionFrameworkConfig.xml to enable Java Method calls from BI EE. Open up ActionFrameworkConfig.xml present under {MIDDLEWARE_HOME}/user_projects/domains/bifoundation_domain/config/fmwconfig/biinstances/coreapplication and add the following registry tags.
<registry> <id>reg05</id> <name>WaterMark EJBs</name> <content-type>java</content-type> <provider-class>oracle.bi.action.registry.java.EJBRegistry</provider-class> <description>WaterMark BIEE</description> <location> <path/> </location> <custom-config> <ejb-targets> <appserver> <context-factory>weblogic.jndi.WLInitialContextFactory</context-factory> <jndi-url>t3://localhost:9704</jndi-url> <server-name>localhost</server-name> <account>WLSJNDI</account> <ejb-exclude>mgmt</ejb-exclude> <ejb-exclude>PopulationServiceBean</ejb-exclude> </appserver> <ejb-app> <server>localhost</server> <app-context>watermark</app-context> </ejb-app> </ejb-targets> </custom-config> </registry>
If you look at the registry XML above, there is an accounts tag which is what basically controls the security. So, in order for BI EE to be able to execute a Java process, we need to setup a credential entry that allows the execution. To do that, we log into the Fusion Middleware Control (http://localhost:7001/em) and then right click on bifoundation_domain (under WebLogic Domains) to navigate to the Credentials
If you do not have the Credential Map called oracle.bi.actions already, create it using the Create Map option.
Under this Credential Map, create a new Credential Key called JNDIUser using the Create Key option. The username and password used in this key can be any valid repository username & password
Restart the entire managed server so that the changes can be picked up by BI EE. Now log in to BI EE and create a new Action using the Java Method.
This will show our Java Method that we deployed. Choose the Method and enter the parameters as shown below
As you see, the parameter list shown in BI EE are the parameters that we have specified in the EJB method. So, essentially BI EE looks at the data type of the Java Methods and shows the parameter list accordingly. If we execute the action, you can basically see that a PDF of the report will be saved in the directory specified and the PDF will be watermarked with the Rittman Mead logo.
This might look like a lot of steps but most of it is a one time setup activity.