Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Contents
What is an account aware report?.......................................................................3
Background information.................................................................................3
Re-use report templates for accounts..............................................................3
How is this solved in Unified Reporter?............................................................3
Setting up the environment...............................................................................4
iReport........................................................................................................4
Token replacement...........................................................................................8
Creating reports...............................................................................................9
Creating the first test report...........................................................................9
Creating report using stored procedure..........................................................15
Parameters for the stored procedure..............................................................21
Creating a report using dynamic SQL with token.............................................22
Known problems.............................................................................................34
Appendix.......................................................................................................34
Entire xml used in my first account aware report sample using SQL...................34
Entire xml used in my first account aware report sample using nimsoft query
language....................................................................................................37
If you would like to design account aware reports, we recommend you design
them using iReport and add support for our query executor. Then deploy the report
to Unified Reporter and view the results.
First you will need to setup iReport.
iReport
1. Choose Tools -> Options menu
2. Choose classpath tab + click Add Jar button
8. Your window should now look like this (if you expand the columns).
11. Add these values (note that the language is nimsoft with lower case letters
only):
Language:
nimsoft
Factory Class net.sf.jasperreports.engine.query.NimsoftQueryExecuterFactory
Fields
com.jaspersoft.ps.nimsoft.NimsoftFieldsProvider
provider
12. Click OK.
13. Your query executor should now be listed here.
14. Click OK and the query executor should now be ready for use.
Please note, there is not 100% support for query executors in iReport 3.5.0, but the
problems seem to be corrected in 3.6.0.
Token replacement
The query executor is designed to examine the query of each report that is
setup to use the nimsoft query executor. If a know token is found, it will be replaced
with runtime values of the user who is viewing the report on the Unified Reporter
server.
This is the tokens that are currently possible to use in SQL queries for reports
which are using the nimsoft query executor:
token
nimsoft_account_id
nimsoft_account_name
nimsoft_acl
If nimsoft user is
executing
null
null
<acl>
If account/contact user is
executing
<account_id>
<account_name>
Null
Creating reports
Creating the first test report
In this example, we will try to create a basic report which displays some information
depending on whos logged in to Unified Reporter.
This is going to be a very plain example which will try to show you some of the steps
involved.
1.
2.
3.
4.
6. In your report inspector, the node named Fields should now be updated with
your column value(s).
7. Drag this field (myACL in this demo) onto the detail section of your report
pane.
8. Click File -> Save.
9. Connect to your repository using the repository navigator; publish the report
as e.g. acl1 under /public.
10. Login to SDP and view your acl1 report
11. The result should be something like the screenshot
12. Here you can see it is using our hard-coded value of ireport dummy that we
typed in our query in step 4.
13. Go back to iReport and change your query to this: select myACL=nimsoft_acl
14. Change the query language from SQL to nimsoft, but do not click the read
fields button. Just click OK.
15. If your save button is not active, then make a change to your report pane to
trigger the save button.
16. Save the updated report.
17. Find your report unit in the Repository Navigator window. Expand it and right
click the main report definition file (usually main.jrxml) and select replace
with current jrxml.
18. Reopen your report unit in SDP/Unified Reporter and see how the content
changed.
23. Verify that your fields are up to date. If they are not, you may have to go
back into the query and click the Read Fields button one more time.
24. Now, you must change your query language again from SQL to nimsoft,
without clicking the read fields button (this is a know bug in iReport 3.5.0)
25. Drag the account field onto the report page
In this example, we have tried to explain how tokens can be replaced during
runtime, depending on whos viewing the report. To try and ease the use of this
If you were to filter by origin, you would have to filter data on the origin column in
the s_qos_data table.
If we change the query to this:
We have created a stored procedure to help write these types of queries, for use with
iReport and SDP/Unified Reporter, to make account aware queries.
The stored procedure is spn_js_ExecuteAccountAwareReport
It takes several parameters, they are:
@Select
varchar(max) = null,
@Orderby
varchar(max) = null,
@Restriction
varchar(max) = null, /* and d.origin = $placeholder
*/ /* where d.origin = $placeholder */
@AccountId
varchar(max) = null, /* nimsoft_account_id */
@ProcedureTrace int = 5
Argument 5 is used when debugging, so you can ignore that.
The first 3 arguments are very important. Always set the @AccountId parameter to
nimsoft_account_id.
Example:
EXEC
[dbo].[spn_js_ExecuteAccountAwareReport]
@Select = N'SELECT qos.source, qos.target FROM S_QOS_DATA
qos ',
The stored procedure will produce the SQL for us, based on what we pass in and the
token nimsoft_account_id will be replaced by the query executor during runtime if we
use this approach.
5. Drag the fields onto the report. Also drag target to the column header as an
aggregate function.
6. Edit the query again, change language from SQL to nimsoft and click OK.
7. Save report, publish to unified reporter. Try to login as nimsoft user and a
contact to see the result.
8. You may see this dialogue when you publish a new report to unified reporter
from iReport 3.5.0
It is not a problem. Your report should still be published. You will not see this
message if you first publish as SQL language and then update the report from
iReport.
Results:
Using a nimsoft user:
With a contact user you get filtered data based on the origin.
You now have created a sample report, using the stored procedure and Nimsoft
query executor to replace the token nimsoft_account_id during runtime with the
actual account id. It will be used by the stored procedure to filter on the origin.
example
'SELECT qos.source, qos.target FROM
S_QOS_DATA qos '
'WHERE qos.qos = ''QOS_CPU_USAGE'' AND
qos.origin=$origin_place_holder'
'ORDER BY qos.source ASC, qos.target
ASC'
nimsoft_account_id
(In your example, you can pick a different QOS if you like)
For a little overview of which qos you have available, you could run this query on
your SQL server:
select def.description, def.name from s_qos_definition def order by
def.description asc
In this demo database we have 108 different objects. For this example we choose
QOS_LDAP_RESPONSE_TIME.
Next, we start by pulling data from both s_qos_data and the corresponding rn table,
which holds the actual samples. We need to find which rn table to use.
You can use this query to grab the rn table for a given QOS.
declare @qos1 varchar(max)
select @qos1 = 'QOS_LDAP_RESPONSE_TIME'
declare @rntable1 varchar(max)
select @rntable1 = 'RN_QOS_DATA_' + reverse(stuff('0000' , 1,
len(cast(s.qos_def_id as varchar(max))), reverse(cast(s.qos_def_id as
varchar(max))))) from s_qos_definition s where name = @qos1
select qos=@qos1, rn=@rntable1
Result in our demo database:
You can choose to use and hardcode the value for your report, or use this dynamic
approach.
This guide will use the dynamic approach.
Now you have a QOS and the RN table. The SQL to get average last 30 minutes of
ldap response times might have been this if you do not use dynamic SQL:
declare @qos1 varchar(max)
select @qos1 = 'QOS_LDAP_RESPONSE_TIME'
In the example, two of the ldap profiles return NULL data for all rows in the time
span (30 minutes).
You can modify this SQL to be dynamic like this:
declare @qos1 varchar(max)
select @qos1 = 'QOS_LDAP_RESPONSE_TIME'
declare @rntable1 varchar(max)
select @rntable1 = 'RN_QOS_DATA_' + reverse(stuff('0000' , 1,
len(cast(s.qos_def_id as varchar(max))), reverse(cast(s.qos_def_id as
varchar(max))))) from s_qos_definition s where name = @qos1
declare @sql varchar(max)
select @sql = '
declare @dtFrom datetime
declare @dtTo datetime
select @dtFrom = dateadd(minute, -30, getdate())
select @dtTo = getdate()
select s.source, ''ldap profile''=s.target, s.host,
avg=avg(rn.samplevalue) from s_qos_data s
inner join ' + @rntable1 + ' rn
on rn.table_id = s.table_id
where s.qos = ''' + @qos1 + '''
and rn.sampletime between @dtFrom and @dtTo
group by s.source, s.target, s.host
order by ''ldap profile'' asc
'
exec (@sql)
2. In the report inspector, select the report name and name it: my first account
aware report.
3. Edit the query for the report, and copy the query we prepared from the
previous example. Click the Read Fields button. Leave query language for
SQL for now.
4. Design your report. Here is one example of how it might look like:
If you click the XML button, you will get an xml view of the report. You can try to
copy this XML to your report for the purpose of this demo (assuming you used the
same ldap response qos).
The example XML used for this report will be later in this document. See table of
contents.
5. Publish the report to Unified Reporter repository and view the sample report
which currently used normal SQL.
9. Make a change in the report content to trigger the save button, then click
save. Update your report in the repository (right click + replace main.jrxml
with current).
Here is one example of what the report will look like for a contact user who does not
have any qos with ldap_response probe.
In the above screenshot, you see the word acc3; this is the same as you type when
you publish the report to Unified Reporter repository:
In the demo described here, we used acc3 as the display name of the report unit.
This is what the report will look like for a different contact user belonging to an
account that has ldap response records:
Known problems
iReport 3.5.0 does not work 100% with query executors. It fails to read fields
when you click the Read Fields button if the query language is set to
nimsoft.
Publish a new report to Unified Reporter repository using query language
nimsoft also displays a dialogue box. But subsequent updates to a report unit
that already exist in Unified Reporter repository do not show this box. We
recommend first publish as SQL and then republish as nimsoft query language
in order to avoid this dialogue box.
iReport 3.5.0 cant preview reports correctly when using nimsoft query
language.
SQL language does not understand the nimsoft query executor supported
tokens.
Appendix
Entire xml used in my first account aware report
sample using SQL
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports
http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="my first account
aware report" pageWidth="595" pageHeight="842" columnWidth="535"
leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<queryString>
<![CDATA[declare @qos1 varchar(max)
select @qos1 = 'QOS_LDAP_RESPONSE_TIME'
declare @rntable1 varchar(max)
select @rntable1 = 'RN_QOS_DATA_' + reverse(stuff('0000' , 1,
len(cast(s.qos_def_id as varchar(max))), reverse(cast(s.qos_def_id as
varchar(max))))) from s_qos_definition s where name = @qos1
declare @sql varchar(max)
select @sql = '
declare @dtFrom datetime
declare @dtTo datetime
select @dtFrom = dateadd(minute, -30, getdate())
select @dtTo = getdate()
select s.source, ''ldap profile''=s.target, s.host, avg=avg(rn.samplevalue) from
s_qos_data s
inner join ' + @rntable1 + ' rn
on rn.table_id = s.table_id
where s.qos = ''' + @qos1 + '''
and rn.sampletime between @dtFrom and @dtTo
'
/* add room here for account aware token */
--if isnull(nimsoft_account_id, -1) > 0 begin select @sql = @sql + ' and s.origin in
(select origin from cm_account_ownership where account_id = nimsoft_account_id )
' end
select @sql = @sql +
'
group by s.source, s.target, s.host
order by ''ldap profile'' asc
'
exec (@sql)
]]>
</queryString>
<field name="source" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="ldap profile" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="host" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="avg" class="java.math.BigDecimal">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<background>
<band/>
</background>
<title>
<band height="79">
<staticText>
<reportElement x="72" y="14" width="395"
height="48"/>
<textElement textAlignment="Center">
<font size="24"/>
</textElement>
<text><![CDATA[My First account aware
report]]></text>
</staticText>
</band>
</title>
<pageHeader>
<band height="35">
<frame>
<reportElement mode="Opaque" x="0" y="0"
width="555" height="20" backcolor="#6666FF"/>
</frame>
</band>
</pageHeader>
<columnHeader>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="153"
height="20"/>
<textElement/>
<text><![CDATA[Source]]></text>
</staticText>
<staticText>
<reportElement x="153" y="0" width="162"
height="20"/>
<textElement/>
<text><![CDATA[LDAP Profile]]></text>
</staticText>
<staticText>
<reportElement x="422" y="0" width="100"
height="20"/>
<textElement/>
<text><![CDATA[Value]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="20">
<textField>
<reportElement x="0" y="0" width="153"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA[$F{source}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="153" y="0" width="162"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA[$F{ldap profile}]]></textFieldExpression>
</textField>
<textField pattern="###0.00;-###0.00">
<reportElement x="422" y="0" width="100"
height="20"/>
<textElement/>
<textFieldExpression class="java.math.BigDecimal"><!
[CDATA[$F{avg}]]></textFieldExpression>
</textField>
</band>
</detail>
<summary>
<band height="42">
<textField pattern="MMMMM dd, yyyy">
height="20"/>
<textElement/>
<textFieldExpression class="java.util.Date"><!
[CDATA[new java.util.Date()]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="283" y="10" width="117"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA["Total pages: " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</summary>
</jasperReport>
'
/* add room here for account aware token */
if isnull(nimsoft_account_id, -1) > 0 begin select @sql = @sql + ' and s.origin in
(select origin from cm_account_ownership where account_id = nimsoft_account_id )
' end
select @sql = @sql +
'
group by s.source, s.target, s.host
order by ''ldap profile'' asc
'
exec (@sql)]]>
</queryString>
<field name="source" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="ldap profile" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="host" class="java.lang.String">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<field name="avg" class="java.math.BigDecimal">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
<background>
<band/>
</background>
<title>
<band height="79">
<staticText>
<reportElement x="64" y="14" width="395"
height="48"/>
<textElement textAlignment="Center">
<font size="24"/>
</textElement>
<text><![CDATA[My First account aware
report]]></text>
</staticText>
</band>
</title>
<pageHeader>
<band height="35">
<frame>
<reportElement mode="Opaque" x="0" y="0"
width="555" height="20" backcolor="#6666FF"/>
</frame>
</band>
</pageHeader>
<columnHeader>
<band height="20">
<staticText>
<reportElement x="0" y="0" width="153"
height="20"/>
<textElement/>
<text><![CDATA[Source]]></text>
</staticText>
<staticText>
<reportElement x="153" y="0" width="162"
height="20"/>
<textElement/>
<text><![CDATA[LDAP Profile]]></text>
</staticText>
<staticText>
<reportElement x="422" y="0" width="100"
height="20"/>
<textElement/>
<text><![CDATA[Value]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="20">
<textField>
<reportElement x="0" y="0" width="153"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA[$F{source}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="153" y="0" width="162"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA[$F{ldap profile}]]></textFieldExpression>
</textField>
<textField pattern="###0.00;-###0.00">
<reportElement x="422" y="0" width="100"
height="20"/>
<textElement/>
<textFieldExpression class="java.math.BigDecimal"><!
[CDATA[$F{avg}]]></textFieldExpression>
</textField>
</band>
</detail>
<summary>
<band height="42">
<textField pattern="MMMMM dd, yyyy">
<reportElement x="422" y="10" width="100"
height="20"/>
<textElement/>
<textFieldExpression class="java.util.Date"><!
[CDATA[new java.util.Date()]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="283" y="10" width="117"
height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><!
[CDATA["Total pages: " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</summary>
</jasperReport>