Rational Publishing Engine

IBM.com Jazz.net Documentation RPE Forum developerWorks How to start
RPE RRDG RRDI

Contents of this page:

  1. Best Practices
  2. REST & OSLC
  3. RPE Settings Tips
  4. RPE Elements
  5. Performance
  6. Other Resources

You need RPE to define your own custom templates to generate the documents based on live data in the Rational Jazz database.

A thought: Having a report will all the thousands of test cases and results in one pdf, would you find the needle you need? Would an interactive dashboard not be more efficient?

All RPE pages are listed below:

Figure: A page from a document generated with the Comprehensive Test Plan Template.

 

Reminder: Many temp files are created in C:\Users\<USER>\AppData\Local\Temp\RPE\temp
Clean this directory once a while!!

Best Practices

Some best proactices and thoughts on document generation and development.

Production

  1. When to run a report
    1. Time-initiated reports - Generate a report on current status of project. E.g. at 04:00 after nightly build and test runs.
      I don't see the use of generating reports after every build requested.
    2. GUI initated reports (RRDG) - On demand generating of reports
  2. ...

Development

  1. Template development is hard. Is not a simple 'user' tasks, but hard work for a developer/tester who has knowledge of the datamodel and what needs to be reported.
  2. Run your template frequently while developing.
  3. Use a large screen! I use external screen to my laptop of 1920x1200.
  4. Use Notepad to store various snippets of URLs and script.
  5. Make versioned backups of your templates (MyTemplate-V01.dta, MyTemplate-V02.dta, MyTemplate-V03.dta). When you are happy with a template you can delete old versions.
  6. If you make use of RRDG to identify a test artifact you might want to skip this.
    Use template variables to define
    • clmProject
      For example: My Project (Quality Management)
    • host
      For example: clm.jkebanking.net
    • port
      For example: 443
      When using the default 9443 you don't need to set this value.
    • userid/password on the Data Source
      One you've configured to be able to access (validate via GUI).
    • Apply inheritance to other Data Sources
      That you've to enter only once your user/pw.
    • Definition of target output (pdf-file)
      For example: directory/sample2.pdf
    Check sample1
    This way you can easily change the target of the reporting.
  7. Use frequently the hyperlink to reference the source of information.
    This is a great feature available in IBM Rational.
  8. Add conditional containers to 'print' variables.

    Figure: Use simple containers to print variables.

  9. Use a debug variable to conditionally activate prints/logic. When true the debug information is printed.

    Figure: By adding condition you can easily switch them on/off leveraging the debug variable.

    Figure: Setting the condition based on the debug variable.

    Personally I give de text printed enabled by the debug switch in a different color/font, eg. red (FF0000).

    At the bottom of this page some RPE logging options are shown.

  10. Print variables in the Console with a simple Javascript statement. This statement must be placed in a script block which is executed.
    java.lang.System.out.println( ">>>> " + testPlanID);
    

    Very good to printout progress of processing...
  11. Use same names for variables etc as in documentation here
  12. Some variables are according to 'standards'
    • TPId
    • TPSummary
    • TPQueryUrl
    • TPLock

    All are in CaMeLcAsE.

  13. Inherit the userid/password from the very first datasource defined. This way you only have to define once the userid/password in the execution template.
  14. Reduce the number of queries
    See Performance chapter below

Rest and OSLC

To understand whats requested by a REST request, you must dig into the actual XML messages. Here two options are described, using the a browser (Firefox) and Poster (a Firefox plugin).

The REST interface is a different one than the OSCL. This is documented on Jazz.net.

Rest using Firefox

An example URL to get the XML of a Work Item.

https://csnext.ibm.com/ccm7/rpt/repository/workitem?fields=workitem/workItem[contextId=_h1ryUHRHEeGZ06KwudyaEQ%20and%20id=61545]/*/*

Figure: You can paste the URL directly in de Firefox addressbar.

When using View Source you see the actual XML.

Rest using Poster

Manually sending/receiving REST requests can be done with the Firefox Poster plugin. This is how I use it:

  1. Login in a normal way using the GUI (and the credentials of the user you use for RPE)
  2. In Poster, add the following header before sending data.
    accept text/xml
    
  3. Enter a URL to interrogate:
    https://business.vanlint5.nl:9443/qm/service/com.ibm.rqm.integration.service.IIntegrationService/resources/Some+Project+%28Quality+Management%29/testplan/urn:com.ibm.rqm:testplan:5
    

    Add the "Quality Management" to the url, the () are replaced with %28 and spaces are + ...
  4. Use the GET button.

RPE Settings tip

Personally I hate it when the Pallete Element Tool remains active. I'm so glad you can switch it off!

Window -> Preferences -> RPE -> Document Desing => Keep current palette element tool **** ==> No 
	

By default, at my installation a IE browser is opened when you select the PDF file in the pop-up. At this moment I don't know a setting to change this to my default FireFox.

RPE Elements

Some examples of interesting RPE Elements.

  1. Table
  2. Hyper link
Elements and properties reference by output format

Table

I experienced the following, but I could not reproduce.

Warning! When you insert a table without any row/cell element in it, the generation of the document will fail. This might happen when you have conditional rows.

Table - Header Row

There are 2 ways to handle a table row. All have their pro-s and con's.

Figure: Table Row Definition in line with the 2nd option.

Suppose you have an source and will give several rows of data. This data must be presented in a table. The table should have a header row. Clearly this header row must be generated once and the following rows should be formatted nicely in 1 table.
If you start a table for every row the cells are formatted according to the contents giving an ugly formatting. This can be solved by a hardcoded width of the columns.

Option 1: Define a variable e.g. TD_HEADER and which is set to true when the table starts and is switched off when a table row is printed.

Option 2: Start the table with the headerrow (no variable needed). IN the table you start the logic to iterate across the data. Advantage is that you don't have an additional variable like TD_HEADER. Disadvantage is that you have a more complex structure. You need such a 'trick' when you want to have a single closing row (e.g. summing). This row should be outsite of the iterating logic.
This is shown in the above image.

There is an option "Once per table:" for a ROW. At this moment I don't see the value of it.

Output exampleexample-table.pdf
example-table.htm
Template Sourceexample-table.dta

Iterate

An example to iterate over an array of names.

Output exampleexample-table.pdf
example-table.htm
Template Sourceexample-table.dta

Hyper link

The hyperlink is very use full in the IBM Rational situation. This because every resource is a URL. So by putting these into the documents (PDF, Word, HTML etc) you give the user the option to open with one click the artifact. The up-to-date information (print is always old), can be viewed. Context is given (e.g. relations) and the information can be adapted.

Fields
Content: the actual link which will be executed.
Specific > Display: What's shown

Figure: The specific attribute set to testPlanURL

Figure: The script getting the ID. Recently I prefer to use a Javascript element to capture the scripting and reference just a variable in these situations. The code is easier to access than hidden in the element.

var p1=TestPlanURL.indexOf(":")+1;
p1=TestPlanURL.indexOf(":",p1)+1;
p2=TestPlanURL.indexOf("/",p1);
java.lang.System.out.println( "p2 >>>> " + p2);
port=TestPlanURL.substring(p1,p2);

To get the last ID from the URL https://business.vanlint5.nl:9443/ccm/resource/itemName/com.ibm.team.workitem.WorkItem/113

href.substring(href.indexOf("WorkItem/")+9);

Logging

As JavaScript you can use the following statements for logging information:

// _sessionLogger methods
_sessionLogger.info( "This will be shown in the console as well as in the rpe.log file");
_sessionLogger.debug( "This will only be shown in the rpe.log file");

// logging docspec information
_sessionLogger.info( "RPE version number: " + _sessionInfo.engineVersion);
_sessionLogger.info( "RPE build number: " + _sessionInfo.buildNumber);

// this property is only populated at runtime. Editing the script and closing the script window will show "" as the result in Studio
_sessionLogger.info( "Template path (requires docgen): " + _sessionInfo.getTemplateProperty( "path",""));

My rpe.log can be found at: C:\Users\IBM_ADMIN\AppData\Local\Temp\RPE

Clean once a while the /output and /temp directory.

Improving Performance

Warning: This section is NOT for novice users!

I found a dramatic improvement by restructuring the template.

	Parent Task
		Child Task
		Child Task
		Child Task

So for every Parent Task we have several Child Tasks.

Like in RPE, the datasource is orange background, comments has a yellow...

Initial Setup

The initial setup was basic, leveraging standard RPE. Child work items don't give a href, so a pre-build url must be created based on the id.

Build Query on the selected Parents
One query gets a single Parent Task
Datasource one Child Task
See samplequery-1
Process one Child Task

So for the parents a query is executed and for each child tasks. We can calulate

TotalNumberOfQueries=1 + NumberOfParentTasks*NumberOfChildTasks

Samplequery-1

https://business.vanlint5.nl/ccm/rpt/repository/workitem?fields=workitem/workItem[id=69979]/(id|summary)

Similar queries are executed for each child task.

Performance Improvement

As a test I collected first all child tasks for a parent tasks. So I had a list of ID's for a parent task.

Build Query on the selected Parents
One query gets a single Parent Task
Collect all Child Tasks
Datasource all Child Task
See samplequery-2
Process one Child Task

So for the parents a query is executed and for each parent if there are child tasks. We can calulate

TotalNumberOfQueries=1 + NumberOfParentTasks

Samplequery-2

https://business.vanlint5.nl/ccm/rpt/repository/workitem?fields=workitem/workItem[id=69979 or id=70008 or id=70167]/(id|summary)

All the child tasks of a parent is queried in 1 query.

Conclusion

In a sample setup each query takes about 3 seconds. Having the first setup having 100 queries took 300 seconds. The second setup reduced the number of queries to 30 and the time to 100 seconds.

RunNumber of queriesSeconds
Each child it's own query100300
All children combined in 1 query30100

In my production template I had a 'double nested' version of this resulting in very long runs. By having a different setup the same result is obtained in minutes instead of hours!!
Basically reduce the number of queries will have a huge impact on the processing of your templates.

A sample template with both options can be found here.

Other Resources

Some sources:

  1. rpeactual.com - The website of the RPE Architect
  2. Authoring Guides - old releases but it's something.
  3. Rational solution for Collaborative Lifecycle Management Traceability Templates with Rational Publishing Engine - Great article.
  4. Complicany Documents