Hitachi Vantara Pentaho Community Forums
Results 1 to 2 of 2

Thread: Pentaho Reporting Desktop, testing session variables on client, not server

  1. #1
    Join Date
    Apr 2008
    Posts
    146

    Question Pentaho Reporting Desktop, testing session variables on client, not server

    I have a simple PRPT report that has a drop down selector for locations. On the server I have a session variable called:
    FACILITY_ASSOCIATION="2, 3, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 27, 30, 31, 33, 35, 36, 37, 40, 43, 44, 45, 46, 47, 49, 50, 52, 53, 55, 63, 65, 66, 67, 73, 79, 81, 82, 94, 95, 96"
    I got my report to work on the server by using a post processing formula on a hidden parameter equaling:
    =CSVARRAY(ENV("session:FACILITY_ASSOCIATION");TRUE())

    -- All of that up there works fine. My question is, how can I introduce the FACILITY_ASSOCIATION variable to the Pentaho Report Designer application and make it easier for testing? I want to be able to use the visual editor and simulate different session variable values. There seems to be this functionality for Mondrian roles.

    Will the same process work for Pentaho Data Integration where I run the report using the Pentaho Reporting Step?

    I've been trying to pursue one possibility by writing lines to the classic-engine.properties file, but I cannot seem to get the variables looked up correctly and handed off to the ENV and CSVARRAY formula in a way that it likes.
    Maybe found a bug where if I have FACILITY_ASSOCIATION-array in the mapper, the property reader looks for FACILITY_ASSOCIATION in the environment line definition. Another potential problem is : vs ::. session:VARIABLE works on the server, but pretty sure session::VARIABLE does not.

    Code:
    org.pentaho.reporting.engine.classic.core.env-mapping.FACILITY_ASSOCIATION=session\:\:FACILITY_ASSOCIATION
    org.pentaho.reporting.engine.classic.core.environment.FACILITY_ASSOCIATION=12,2
    Thanks for your help.

    Brandon
    Last edited by Smoodo; 09-12-2016 at 06:30 PM.

  2. #2
    Join Date
    Mar 2003
    Posts
    8,085

    Default

    You are mixing concepts, and that is tripping you up. Lets talk some code:

    Code:
        String envNameOnServer = "session\\:FACILITY_ASSOCIATION";
    First, lets declare where the data comes from, and how we want to access it later. You have data on the server in a session-variable. The server handles session data via a special prefix ("session:"; one colon!). When you run on the server, the "PentahoReportEnvironment" class will check if a name starts with "session:" and if so, will look up the value for it in the session. It strips out the prefix, so "session:myEntry" searches for a "myEntry" key on the session object.

    Inside PRD and when you run inside Spoon, you wont have a session available - so the global report-configuration will be used to provide a default value so that you can test your code. (Handy trick: You can provide run-time configuration on the fly by setting a system-property with the name and value of your configuration property that you want to configure.)

    Code:
        // the "env::" prefix is just a convention, but avoids clashes with field names returned from the database
        String publishedFieldName = "env::FACILITY_ASSOCIATION";
    To access environment data in as parameter in data-sources and queries (most of which dont support formulas), we now define a field mapping so that the environment entry from above gets published as field on the report. This way the value will be available as if it were a parameter or result of a query itself.

    To avoid clashes with existing queries, I always prefix the fieldname with "env::" - queries are unlikely to ever return such a field (who would be so weird to write that query! )

    Code:
        ClassicEngineBoot.getInstance().start();
        final ModifiableConfiguration config = ClassicEngineBoot.getInstance().getEditableConfig();
        config.setConfigProperty( "org.pentaho.reporting.engine.classic.core.environment." + envNameOnServer, "12,2" );
    Lets just set up the basic configuration. You can do that via the "classic-engine.properties" file, but to demonstrate the flow of names and lookups, I stick to code here.
    With just that single config-property you have a working environment entry. You can access this value from a formula via the "ENV" function:

    Code:
      =ENV("session:FACILITY_ASSOCIATION")
    But formulas are not supported everywhere and are not always convenient to use. Lets map it into a proper report-field instead.

    Code:
        config.setConfigProperty( "org.pentaho.reporting.engine.classic.core.env-mapping." + envNameOnServer, publishedFieldName);
        config.setConfigProperty( "org.pentaho.reporting.engine.classic.core.env-mapping." + envNameOnServer + "-array", publishedFieldName + "-as-parsed-array");
    The setup is simple - for each environment entry you can declare a field name. Make sure the target field names are unique, or funny things may happen.

    Code:
        DefaultReportEnvironment env = new DefaultReportEnvironment( config );
        System.out.println("Querying raw data. " + envNameOnServer + " should return '12,2'");
        final Object rawData = env.getEnvironmentProperty( envNameOnServer );
        System.out.println( rawData );
        assert Objects.equals("12,2", rawData );
    When running outside of the server, we use the DefaultReportEnvironment, which simply takes the property-key and looks it up in the report-configuration. As said before: On the server, a different class handles that lookup and will reroute any lookup that starts with "session:" to the Pentaho/Servlet-Session instead.

    Code:
        // This uses the code as the reporting engine ...
        final DefaultReportEnvironmentMapping reportEnvironmentMapping = new DefaultReportEnvironmentMapping();
        ReportEnvironmentDataRow dr = new ReportEnvironmentDataRow( env, reportEnvironmentMapping );
        final boolean contains = Arrays.asList( dr.getColumnNames() ).contains( publishedFieldName );
        System.out.println( "Published list of fields contains " + publishedFieldName + "? - " + contains);
        assert contains;
    Just demonstrating that you now have the field available.

    Code:
        final Object reportData = dr.get( publishedFieldName );
        System.out.println( "Report data for field " + publishedFieldName + " => " + reportData );
        assert Objects.equals("12,2", reportData );
    ... and that we can get its value ...

    Code:
        config.setConfigProperty( "org.pentaho.reporting.engine.classic.core.env-mapping." + envNameOnServer + "-array", publishedFieldName + "-as-parsed-array");
    Final trick: By adding a "-array" mapping, you can avoid the manual parsing of arrays.

    Code:
        final Object[] reportData2 = (Object[]) dr.get( publishedFieldName + "-as-parsed-array");
        System.out.println( "Report data for field " + publishedFieldName + " => " + Arrays.asList( reportData2 ));
        assert Objects.equals(Arrays.asList( "12", "2" ), Arrays.asList( reportData2 ));
    If you define a lookup to a environment entry ending with "-array", we will strip the "-array" part and will parse the value as CSV array and return you the array. This is most helpful if you have a SQL IN clause, which expects an array to do its multi-value selection.
    Get the latest news and tips and tricks for Pentaho Reporting at the Pentaho Reporting Blog.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Privacy Policy | Legal Notices | Safe Harbor Privacy Policy

Copyright © 2005 - 2019 Hitachi Vantara Corporation. All Rights Reserved.