Wednesday, October 12, 2005

BIRT Report Server Pt. 2

In my previous article entitled “BIRT Report Server Pt. 1”, I showed how I set up my base server for reporting with BIRT. In this article, I will continue by setting up the components needed to generate scheduled reports--specifically Apache Tomcat and the BIRT report viewer. For demonstration, I will use the report I built in my previous article: “Sguil Event reporting with BIRT”. The completed setup allows users to retrieve completed reports from the exposed Apache server, allow remote administration via SSH, allow only the development machine to have access to Samba and Swat, and deny outside access to the Apache Tomcat service that will be used local to the server to generate reports via the BIRT Java Servlet.

I need the following components before I begin: Apache Tomcat 4.1.30 and the Java Software Development Kit 1.4.2_90. The Java Runtime Environment alone is not enough since Tomcat required the SDK version. For my own purposes, I prefer binary packages rather than the source packages for two reasons: first is the headache of attempting to compile packages and issues involved with that, such as missing libraries; second is that it is easier to demonstrate using binary packages. Apache Tomcat 4.1.30 is available at http://archive.apache.org/dist/jakarta/tomcat-4/v4.1.30/src/jakarta-tomcat-4.1.30.tar.gz. Java SDK 1.4.2_09 is available at http://java.sun.com/j2se/1.4.2/download.html. I downloaded the RPM version of Java to make for an easier install. Both files were downloaded to the /usr/local/src directory. Since I already installed BIRT as indicated in my previous article “Sguil Event reporting with BIRT”, I already have the BIRT Java Servlet to install into Tomcat on my development machine. Also, I already have the report I will use for testing, SguilReport.rptdesign. For reference, the local machine is at IP address 10.10.2.131, and the development machine is at IP address 10.10.2.1.

Since Tomcat is dependent on Java, I need to install the Java SDK first. Even though this is an RPM based download, Sun provides this as a self-extracting executable to force you to go through the EULA. To launch the extracting binary file, I run the following command (Note: my working directory is /usr/local/src):

./j2sdk-1_4_2_09-linux-i586-rpm.bin

This brings up Sun’s EULA. I agree to the terms, which extracts the RPM package. To install the RPM package, I run the following command:

rpm –Uvh j2sdk-1_4_2_09-linux-i586.rpm

The Install goes though the RPM console progress meter, and I have no issues. Although it is not indicated anywhere during the install, the files are installed to the /usr/java/j2sdk1.4.2_09/ directory. I will need to set up an environment variable for Tomcat to find Java, called JAVA_HOME. To setup the environment variable I run the following command:

export JAVA_HOME=/usr/java/j2sdk1.4.2_09

Since I will be rebooting a few times during the installation and testing, I want to make this a global environment variable available on bootup, so I need to add the entry to the /etc/profile file. To add this to /etc/profile I run the following command:

echo “export JAVA_HOME=/usr/java/j2sdk1.4.2_09” >> /etc/profile

Note the use of the >> redirect symbol. This will cause the redirect to append to the end of the file instead of overwriting the contents of the file. Now I am ready to extract Tomcat. From the /usr/local/src directory I run the following command:

tar –zxvf jakarta-tomcat-4.1.30.tar.gz

This is the full package, and I don’t want it to reside in my /usr/local/src directory. I decide the best place for it would be in the /usr/local folder, so I need to move it. I move the extracted directory to reside in the /usr/local directory like so:

mv /usr/local/jakarta-tomcat-4.1.30 /usr/local

Much like the Java setup above, I need an environment variable for Tomcat called CATALINA_HOME. I set up an environment variable to test run Tomcat by running the following command:

export CATALINA_HOME=/usr/local/jakarta-tomcat-4.1.30/bin

Now I need to add the CATALINA_HOME variable to the /etc/profile for future bootups:

echo “export CATALINA_HOME=/usr/local/jakarta-tomcat-4.1.30/bin” >> /etc/profile

Since Tomcat now resides in its permanent home and I have set up my environment variables, I am ready to do a test run to ensure that everything is set up correctly. Tomcat has a nice startup and shutdown script included with it to make it that much easier to run. So to start Tomcat I run the following command:

$CATALINA_HOME/bin/startup.sh

In order to test if Tomcat is running I want to connect from my development machine using a graphical browser, so I need to shutdown IPTables. To do so I run the following command:

/etc/init.d/iptables stop

Now I go to my development instance and open up Internet Explorer to port 8080 on my reports server at 10.10.2.131. I can see by the Tomcat home page that it is running:



Looks like Tomcat is running. I also go into the Examples Links and decided to see if the servlets are running correctly. Below is the Hello World Servelet:



Now we need to get the BIRT applet over to the report server. To accomplish this, I copy from the BIRT installation directory to the report servers webapps directory. I installed BIRT on my development Windows machine at C:\Program Files\ActuateBIRT1.0.1\BRD. The Birt Report Java Applet resides in $BRD_INSTALL_DIR\eclipse\plugins\ org.eclipse.birt.report.viewer_1.0.1\birt. On the server the target directory will be /usr/local/jakarta-tomcat-4.1.30/webapps. Since SSH is installed on my Windows machine via Cygwin for Windows, I copy the files using SCP. Since I am using Cygwin, I will need to replace the C:\ prefix of my directory structure with /cygdrive/c and replace all the \ characters with / characters in my Windows path. Below is the transcript of the commands run to copy this over:

scp -r "/cygdrive/c/Program Files/ActuateBIRT1.0.1/BRD/eclipse/plugins/org.eclipse.birt.report.viewer_1.0.1/birt" root@10.10.2.131:/usr/local/jakarta-tomcat-4.1.30/webapps

Now a bunch of files scroll by. I need to restart Tomcat in order for the changes to take effect, so I run the following commands from the reports server:

$CATALINA_HOME/bin/shutdown.sh
$CATALINA_HOME/bin/startup.sh

Now I need to reconnect to the Tomcat server and log in to the Management Applet to verify my change that the Birt report viewer is installed correctly. On my development box, I connect to the server in Internet Explorer. To check this, I need to go into the Tomcat Manager applet. The manager applet will not allow access to anyone who does not have the manager role assigned to them. So first I will need to create a user in Tomcat and assign them the manager role. The Tomcat users file is located at $CATALINA_HOME/conf/tomecat-user.xml. I modify it like so:

<?xml version='1.0' encoding='utf-8'?>

     <tomcat-users>
          <role rolename="tomcat"/>
          <role rolename="role1"/>
          <role rolename="manager"/>
          <user username="tomcat" password="tomcat" roles="tomcat"/>
          <user username="jward" password="jward" roles="manager"/>
          <user username="both" password="tomcat" roles="tomcat,role1"/>
          <user username="role1" password="tomcat" roles="role1"/>
     </tomcat-users>


Once I restart Tomcat I should be able to access the manager applet as jward. I get into the management window, and I can see that the BIRT report viewer is indeed setup correctly.



To complete the set up of BIRT I need to make the reports viewer aware of the path to the reports folder. Recall from the last article that we created a separate partition called /birt_reports to house reports. To make BIRT aware of this, an entry is added to the $CATALINA_HOME/webapps/birt/WEB-INF/web.xml file. I need to change the following tag to look like this:

<context-param>
     <param-name>BIRT_VIEWER_REPORT_ROOT</param-name>
     <param-value>/birt_reports</param-value>
</context-param>

After this is set up, I want to run a report and test it. We will use the SguilReport.rptdesign that was created previously. To make the server Birt Report Viewer aware of this report, I only need to copy it over to the E: drive share I have on my development box:

C:\Program Files\ActuateBIRT1.0.1\BRD\eclipse\workspace>copy SguilReport.rptdesi
gn e:
1 file(s) copied

Now that the file is copied I need to test run it using the following URL:

http://10.10.2.131:8080/birt/run?__report=SguilReport.rptdesign

The report result looks like below:



Now that the report runs successfully from Tomcat, I would like to set up an automated task with Cron to run the report and retrieve the results. I would like the scheduled report to run weekly, and put the output file in the Apache root web folder for report viewing, with the report name and date the report was run appended to the end. The easiest way to do this is to use Wget in a script and schedule it to retrieve the report. To do this, I will set up a script file in the /etc/cron.weekly directory. My Apache web root directoy is at /var/www/html. To test if this will work I run the following command:

wget http://localhost:8080/birt/run?__report=SguilReport.rptdesign -O /var/www/html/sguil_report_`date +%G-%m-%d`.html

After this is done, I go into my development machine, and try to retrieve the generated report via Internet Explorer. I will access it from the following URL

http://10.10.2.131/sguil_report_2005-10-04.html



I can schedule the job with Cron now that I know my command will work. This will allow the scheduled jobs to run without any intervention from me, and be able to retrieve them from the publicly exposed Apache instance pre-generated. To add this to my weekly Cron schedule I am going to run the following commands:

echo wget http://localhost:8080/birt/run?__report=SguilReport.rptdesign -O /var/www/html/sguil_report_\`date +%G-%m-%d\`.html > /etc/cron.weekly/run-sguil-report
Chmod 755 /etc/cron.weekly/run-sguil-report

Now that this is scheduled, I do not want Tomcat to run as my root user. Instead it should run as the birt_rpt user. I need to make sure the birt_rpt user can access the Tomcat folders, so I will need to change the owner and group of the /usr/local/jakarta folder to birt_rpt. I have already done this for the /birt_report folder. I run the following two commands to recursively change all files and folders for Tomcat to be owned by birt_rpt:

chown –R birt_rpt /usr/local/jakarta
chgrp –R birt_rpt /usr/local/jakarta

Tomcat has to be set up to start automatically on boot as the birt_rpt user. I would like to be able to utilize a SysV style script at startup. I will need an appropriate file in /etc/init.d for Tomcat, and set the process to start correctly in Runlevel 3. After much searching, I came across this article http://gridrm.org/admin/auto-start-tomcat.html that fully explains how to set up Tomcat to start on boot as another user. I had some issues with setting this up, so I was glad to find a article describing how to do this correctly. I tried many different approaches, such as loading in rc.local, and other formats for my init.d script;all of them had issues with context renaming in SELinux. I create a file called /etc/init.d/tomcat with the following contents:

#!/bin/bash
# chkconfig: - 85 15
# description: Tomcat is a servlet container

export JAVA_HOME=/usr/java/j2sdk1.4.2_09/
export CATALINA_HOME=/usr/local/jakarta-tomcat-4.1.30/

start_tomcat=$CATALINA_HOME/bin/startup.sh
stop_tomcat=$CATALINA_HOME/bin/shutdown.sh

start() {
     echo -n "Starting tomcat: "
     su -c ${start_tomcat} - birt_rpt
     echo "done."
}
stop() {
     echo -n "Shutting down tomcat: "
     ${stop_tomcat}
     echo "done."
}

#see how we were called
case "$1" in
start)
     start
     ;;
stop)
     stop
     ;;
restart)
     stop
     sleep 10
     start
     ;;
*)
     echo "Usage: $0 {startstoprestart}"
esac

exit 0

Note the format of su in the start function. For some odd reason SELinux was very particular about this format for su, and threw various errors when this script was run otherwise. Next the permissions of /etc/init.d/tomcat script are modified by running:

chmod 755 /etc/init.d/tomcat

Then I set it up to run in Runlevel 3 using the following command:

chkconfig --level 3 tomcat on

And the final piece of the puzzle is more optional than anything. I decide I want to create a small PHP file that will reside in the /var/www/html directory that will list the contents of that folder to show the report files. Although this script could be cleaned up quite a bit to correct formatting and remove the . directory, the .. directory, the script name itself, and pretty it up, I kept this bare bones for the purpose of this example. The script will basically get a listing of all files in the /var/www/html directory, store in an array, then go through each element in the array and display the file name with an hyperlink to it. (Note: Comments are removed for brevity):

<html>
<body>
<?php

     $my_directory="/var/www/html/";
     $dir = dir($my_directory);

     while ($temp = $dir->read())
          $dirarray[] = $temp;


     for ($x = 0; $x <= count($dirarray); $x++)
          echo '<a href="'.$dirarray[$x].'">'.$dirarray[$x].'</a><br>';
?>
</body>
</html>


The results fo the script are below:

While this is a very basic example, it demonstrates how to set up a full-fledged automated reports server. Although I used the Sguil report environment as my example, it can be set up to report on any database application in your environment. With customization, this setup can be every bit as robust as the commercial offerings out there. It is easy to administer since it uses easily accessible and standard utilities, and makes use of the facilities that the Operating System already offers. Outside of the optional script to display the contents of the Apaches root directory, there was no custom development required. Every single part of this system does one thing and does it very well.

4 comments:

paul said...

Another useful post. Thanks

Vallabh Vaidya said...

Hi,
Read d post.
In d post u hav mentioned tht report viewer should b aware of d reports folder.So set d reports folder path in web.xml.
Can we set this reports folder path @ runtime or without defining it in the web.xml file?
(I m using Eclipse Ganymede and BIRT 2.3.)

Anonymous said...

you have a nice post. thanks for sharing this enormous resources.

Sumant said...

BIRT iServer Express is a BIRT report server that deploys, manages, schedules, secures, runs and distributes BIRT reports. It embeds the Eclipse BIRT Engine and Java APIs. It is compatible with reports developed with any BIRT Designer including BIRT Studio. It also works with the BIRT Viewer and BIRT Interactive Viewer. It can be deployed as a stand-alone report server or as a behind-the-scenes reporting service for other applications.

Recently I just came across a good article on " Windows Server"
Here is its link.