Thursday, February 25, 2010

Customize CDF jfreechart component

I was dealing with CDF Dashboards during these days and I had to set line-width and line-style attributes in my jFreechartComponent's LineChart widget.

Looking at the jFreechartComponent documentation you clearly see that in the standard implementation some attributes, specifics only to some chart types, aren't implemented. This was also for the two attributes line-width and line-style related to the LineChart widget.  But this is not a problem because we can add that missing attibutes very easily and I'll show you how. The interesting thing is that I can manage all the attributes that are available for a specific JFreeChart chart type.

If you need to add support for missed JFreeChart chart's attributes you can follow the steps summarized below. We suppose to add line-width and line-style attributes and to access them from CDF jFreechartComponent as two properties respectively named lineWidth and lineStyle.

1) Go to <biserver-home>/pentaho-solutions/cdf/components and open jfreechart.xaction and open it with your favourite editor.


2) Add two new elements to the inputs section of the .xaction file. Below an example of the file with the two new inputs added. Remember here that the value of the request element (see lines 5 and 11 below)  has to be the same in name and in case as the name of the property we want to put in our CDF jFreechartComponent definition. Then be careful to correctly assign a the default value needed in case that the property isn't provided (see lines 7 and 13) by you CDF component call. This is particularly important when our attribute is a number. If you don't assign it properly you'll get a NumberFormatException.

1:  <inputs>   
2:    <!-- Omitted for brevity -->       
3:       <LINEWIDTH type="string">  
4:            <sources>  
5:                 <request>lineWidth</request>  
6:            </sources>  
7:            <default-value>1.5</default-value>  
8:       </LINEWIDTH>  
9:       <LINESTYLE type="string">  
10:            <sources>  
11:                 <request>lineStyle</request>  
12:            </sources>  
13:            <default-value/>  
14:       </LINESTYLE>  
15:    <!-- Omitted for brevity -->       
16:  </inputs>  

3) Add the new inputs previously defined in the inputs section (see above) to the  action-inputs section of our ChartComponent action-definition (as shown below at lines 7 and 8). Then, use these new fields to populate two new property elements added to the chart-attributes section as shown at line 25-26. Be very careful here because the name of the element you give to every new chart attribute has to be equal to the related attribute for the JFreeChart library. For example: if in JFreeChart library the line width  attribute is named line-width that is the name to be considered as child element of the chart-attributes element. Then the value to be assigne to that new element is the name of the related action input element (for line-width we will assign as value the LINEWIDTH element. See line 25 below).


1:       <action-definition>   
2:            <component-name>ChartComponent</component-name>  
3:            <action-type>Chart</action-type>  
4:            <action-inputs>   
5:                 <chart-data type="result-set" mapping="newResults"/>   
6:                  <!-- Omitted for brevity -->       
7:                 <LINEWIDTH   type="string"/>  
8:                 <LINESTYLE   type="string"/>  
9:                 <!-- Omitted for brevity -->       
10:            </action-inputs>  
11:            <action-resources/>  
12:            <action-outputs>   
13:                 <chart-filename type="string"/>   
14:                 <base-url type="string"/>   
15:                 <chart-mapping type="string"/>   
16:                 <image-tag type="string"/>   
17:                 <chart-output type="content"/>   
18:            </action-outputs>  
19:            <component-definition>   
20:                 <width>{WIDTH}</width>   
21:                 <height>{HEIGHT}</height>   
22:                 <by-row>{BYROW}</by-row>   
23:                 <chart-attributes>   
24:                 <!-- Omitted for brevity -->       
25:                      <line-width>{LINEWIDTH}</line-width>  
26:                      <line-style>{LINESTYLE}</line-style>  
27:                 <!-- Omitted for brevity -->       
28:                 </chart-attributes>   
29:            </component-definition>   
30:       </action-definition>  

Thursday, February 18, 2010

BI Server & MS Active Directory in 10 minutes

Recently I had the need to connect Pentaho to MS Active Directory for user authentication/authorization. Immediately I asked myself how to connect Pentaho BI Server to Microsoft Active directory and I answered "Oh don't worry... it will take no more than 10 minutes!". Then the "look for a how-to document..." discovery process started.

I found a lot of documentation about this issue (wiki articles, forums thread) but there isn't a well done survival guide on this problem (that's my opinion).

So I'll try to summarize in few lines the steps followed and problems encountered to try to build a sort of survival guide for anyone with the same issue to solve

Have a look at spring configuration files

BI Server security architecture is based on Spring Security so the first guide to be read is the Spring documentation where they talk about LDAP configuration. Better, in case you don't know anything about that, if you came a step backward and have a read at the general architecture of Spring security.

Spring security beans wires together through spring application context and in Pentaho all the needed spring application context files are located in <biserver_home>/pentaho-solutions/system. You'll find a lot of them there but the important things to know are:

pentaho-spring-beans.xml contains the list of imported spring bean files that will be loaded when BI Server will start.
We've two important file groups there named applicationContext-spring* and applicationContext-pentaho*. In each group, you have one file for every available authentication method defined in Pentaho. Usually the beans located in files belonging to applicationContext-spring group contains definitions for spring related beans needed to configure the specified authentication/authorization method. The beans located in files belonging to applicationContext-pentaho group contains definitions of Pentaho's beans involved in the authorization/authentication methods for the specific authentication method (LDAP, Hibernate, jdbc).

So how to configure Pentaho to work with MS Active Directory?

The setup to have Pentaho working with MS Active Directory is really simple if you know exactly what to do and to how. Il try to summarize you everything in the following paragraphs. As detailed above all the files we will mention are located in <biserver_home>/pentaho-solutions/system.

1. Setup an MS Active Directory user to let BI Server connect to. You need to define a user in MS Active Directory so that BI Server can connect to and check if the Pentaho's user is going authenticate exists and is valid. The user you're going to define in MS Active Directory doesn't need to have any special right so a normal user is the more appropriate. Remember to check that the "password never expire" flag is not set for this user.

2. Setup Spring Security files needed to enable LDAP Server authentication/authorization. This is a good point, I think the major one. First of all read the guidelines provided here  about some rules to be followed when editing Spring configuration files particularly regarding white spaces and special characters. Then follow the points detailed here.

2.a) Open the applicationContext-security-ldap.properties and change the properties accordingly to your needs. The useful thing about this file is that it contains all the properties needed to configure spring beans so that we doesn't need to look for them in eac xml file. They're all in one single place. Following you'll find an example:

 contextSource.providerUrl=ldap\://ldaphost\:389  
 contextSource.userDn=cn=ldapuser,OU=my_org_unit,dc=my_dc  
 contextSource.password=password  
 userSearch.searchBase=OU=my_org_unit,dc=my_dc  
 userSearch.searchFilter=(sAMAccountName=\{0\})  
 populator.convertToUpperCase=false  
 populator.groupRoleAttribute=cn  
 populator.groupSearchBase=OU=my_org_unit,dc=my_dc  
 populator.groupSearchFilter=(member=\{0\})  
 populator.rolePrefix=  
 populator.searchSubtree=true  
 allAuthoritiesSearch.roleAttribute=cn  
 allAuthoritiesSearch.searchBase=OU=my_org_unit,dc=my_dc  
 allAuthoritiesSearch.searchFilter=(objectClass=group)  

Important things to note here are
  • contextSource.providerUrl - LDAP server url
  • contextSource.userDn - LDAP username. This is the user we've talked about in 1) above
  • contextSource.password - LDAP user password
  • the populator properties are needed by Spring DefaultLdapAuthoritiesPopulator. That object is needed to load the set of authorities the user was granted.
  • the userSearch properties configures the attributes needed to fills up the "users" box when assigning permissions to reports etc.
  • the allAuthorities properties configures the attributes needed to fills up the "roles" portion of the permissions box when setting them for a report etc.
The excerpt I gave above is fully working so you can copy and paste it in your properties file changing only the definitions specific to your installation. At this point you completed almost the 70% of the required configuration to have everything working on your system. Be careful to declare the full DN (domain name) when you work with MS Active Directory because, if not, it's almost sure you'll have an error like this (The first time I tried I had such an error for this reason)

<pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;padding:0px;color:#000000;text-align:left;line-height:20px;"><code style="color:#000000;word-wrap:normal;"> Microsoft Active Directory Error:  
   javax.naming.AuthenticationException:  
   [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09030B, comment:  
                        AcceptSecurityContext error, data 525, v893 ] 
     at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtx.(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source) 
     at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source) 
     at javax.naming.spi.NamingManager.getInitialContext(Unknown Source) 
     at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source) 
     at javax.naming.InitialContext.init(Unknown Source) 
     at javax.naming.InitialContext.(Unknown Source) 
     at javax.naming.directory.InitialDirContext.(Unknown Source) 
</code></pre>

You can find short but useful informations about this issue here

2.b) Two words about the default role. Anytime a user logs into Pentaho, the system assigns the user a default role of "Authenticated". This is a really important point to have all the things working. If that role isn't assigned you're able to connect but mantle witll never show anything to you. My problem was that in my spring LDAP context file the definitions to have that role assigned by default were missed. So I had to add them manually. So be absolutely sure to check that in applicationContext-spring-security-ldap.xml you have the defaultRole property defined with a value of Authenticated in the popolator bean and if missed add it. Below an excerpt of that bean definition with the defaultRole property added so that you can copy and paste if missed in your file.

 <bean id="populator" class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">  
  <!-- omitted -->  
  <property name="defaultRole" value="Authenticated" />  
  <!-- omitted -->  
 </bean>  

3) Rework the imports in pentaho-spring-beans.xml to enable the load of LDAP security beans at startup. Below (at lines 8-9) we disabled the DAO/Hibernate security and (at lines 10-11) we imported the new definitions enabling LDAP security

1:  <beans>  
2:   <import resource="pentahoSystemConfig.xml" />  
3:   <import resource="adminPlugins.xml" />  
4:   <import resource="systemListeners.xml" />  
5:   <import resource="sessionStartupActions.xml" />  
6:   <import resource="applicationContext-spring-security.xml" />  
7:   <import resource="applicationContext-common-authorization.xml" />  
8:   <!-- import resource="applicationContext-spring-security-hibernate.xml" />  
9:   <import resource="applicationContext-pentaho-security-hibernate.xml" / -->  
10:   <import resource="applicationContext-spring-security-ldap.xml" />  
11:   <import resource="applicationContext-pentaho-security-ldap.xml" />  
12:   <import resource="pentahoObjects.spring.xml" />  
13:  </beans>  

4) Now its the time to define a set of groups in your MS Active Directory for your pentaho users (if you don't already have such a groups) depending on your authorization needs. For sure you need to have at least one group to contain pentaho admins. In my system I called that group PentahoAdmin.

5) Declare the new admin group in Pentaho configuration to assign that group the admin grant. To do that rework the acl-voter element in pentaho.xml as shown below.

      <acl-voter>  
           <!-- What role must someone be in to be an ADMIN of Pentaho -->  
           <admin-role>PentahoAdmin</admin-role>  
      </acl-voter>  

6) Rework acl-publisher definitions in pentaho.xml for all the Pentaho's groups defined in the LDAP server. In my system I defined two roles PentahoAdmin and PentahoUser so my configuration looks like this

  <acl-publisher>  
           <!--   
                These acls are used when publishing from the file system. Every folder  
                gets these ACLS. Authenticated is a "default" role that everyone  
                gets when they're authenticated (be sure to setup your bean xml properly  
                for this to work).  
           -->  
           <default-acls>  
                <acl-entry role="PentahoAdmin" acl="FULL_CONTROL" />                    <!-- Admin users get all authorities -->  
                <!-- acl-entry role="cto" acl="FULL_CONTROL" / -->                    <!-- CTO gets everything -->  
                <acl-entry role="PentahoUser" acl="EXECUTE_SUBSCRIBE" />          <!-- PentahoUser gets execute/subscribe -->  
                <acl-entry role="Authenticated" acl="EXECUTE" />          <!-- Authenticated users get execute only -->  
           </default-acls>  
           <!--  
                These acls are overrides to specific file/folders. The above default-acls will  
                be applied and then these overrides. This allows for specific access controls to  
                be loaded when the repository if first populated. Futher changes to acls can be  
                made in the platform GUI tool. Uncomment these and change add or delete to your hearts desire -->                           
           <overrides>  
                <file path="/pentaho-solutions/admin">  
                     <acl-entry role="PentahoAdmin" acl="FULL_CONTROL" />  
                </file>  
           </overrides>  
      </acl-publisher>  

7) Stop and restart you Pentaho server and everything is ready for a try.

I hope I haven't missed anything and that everything is clear enough for everyone who reads these few instructions.  Let me know if you have any problems so that I can keep updated this very brief guide.

Tuesday, February 2, 2010

Pentaho BI Server language files (1/2)

It was a long time of hard work the last month and a half but now I'm able to see a little light at the end of the tunnel and I had the time to be back. This time I have an interesting thing for all the italian friends. I completed:

  1. the italian language files for Mantle GWT Client. The files were already submitted to Pentaho JIRA hoping they will be incorporated in the next release of the product.
  2. the italian language file for JPivot toolbar. This was a minor effort because it is a very little file so it takes really a few minutes to be completed. This language file has been already committed by myself on JPivot's cvs trunk.

I detailed  below the steps to be followed to install the new language on existing BI Server installations. The files are compatible with Pentaho 3.x. A special thanks to my colleague and dear friend Andrea Pasotti who helped (and is helping) me in this work.

How to activate italian language support for Mantle GWT client
  • Download the files messages_it.properties and  MantleLoginMessages_it.properties from the following link to JIRA
  • Stop BI Server
  • Copy the file messages_it.properties to <biserver_home>/webapps/pentaho/mantle/messages
  • Open the file <biserver_home>/webapps/pentaho/mantle/messages/supported_languages.properties
  • Add the following line
  • it=Italiano
    
  • Save and close the file
  • Copy the file MantleLoginMessages_it.properties to <biserver_home>/webapps/pentaho/mantleLogin/messages
  • Open the file <biserver_home>/webapps/pentaho/mantleLogin/messages/supported_languages.properties
  • Add the following line
  • it=Italiano
    
  • Save and close the file 
  • Start BI Server
How to activate Italian language support for JPivot toolbar
  • Dowload the resources_it.properties language file from the following link
  • Go to <biserver_home>/webapps/pentaho/WEB-INF/classes and create the following directory path com/tonbeller/jpivot/toolbar
  • Copy resources_it.properties to <biserver_home>/webapps/pentaho/WEB-INF/classes/com/tonbeller/jpivot/toolbar
  • Start BI Server
I'm going to finalize to complete translation of the GUI so in the next few weeks will follow the italian language files PAC (Pentaho Administration Console) and Ad-Hoc Query Reporting. So what else.... stay tuned!