August 25, 2009

Multiple RPDs on one server – Part 2 – Presentation Services

Filed under: hack, obiee, sawserver — rmoff @ 16:13


In this article I plan to get sample and paint repositories hosted on a single server, using one BI Server instance and two Presentation Services instances. This is on both Unix (OEL 4) and Windows, and both OC4J (OBIEE’s “basic installation” option) and OAS (“Advanced Installation”).

Make sure you’ve read and followed part 1 – BI Server first.

Remember that multiple Presentation Services instances on a machine is UNSUPPORTED BY ORACLE!

OBIEE Components

See the deployment guide p.11 for a thorough explanation of the components.

It’s important to understand the components of the OBIEE stack as what we’re doing is unsupported and undocumented in parts, so you need to be able to diagnose and reason through issues you may get:

  • BI Server (nqserver) – the Analytics server. Uses the RPD to build queries to send to the database.
  • Presentation Services (sawserver) – This takes the submission of queries from Answers/Dashboards and sends them by ODBC to the BI Server. It handles the rendering of the returned data.
  • Presentation Services Plug-in (analytics) – This is a J2EE application deployed in on an application server such as Oracle Application Server or OC4J. It handles server-side calls from the Answers or Dashboards webpage.

What we do is deploy a second instance of the Presentation Services Plug-in (analytics) and configure it to talk to a second invocation of Presentation Services (sawserver) which is run with a new configuration.

NB contrary to other posts on this subject that I’ve seen, you don’t need to install a second instance of presentation services – you just fire up your existing one with a different configuration file.

Deploy a second instance of Presentation Services Plug-in (analytics)

This is for OAS and OC4J, with another application server YMMV.

  • Login, at http://:/em/ (common ports are 7777 or 9704) (see here for info on resetting login details it if you don’t know the login)
  • [OAS only] Assuming you’re now on the “Cluster Topology” screen, click through to the OC4J home (under Members click the link where in the Type column it says OC4J)Oracle Enterprise Manager (oc4jadmin) - Cluster Topology_1251187606945
  • Assuming you’re now on OC4J: home click the Applications link. (You should see one instance of analytics already deployed.)
  • Click on the Deploy button oc4jhome
  • For the next step, determine where on your server analytics.war is (by default it will be $OracleBI/web/analytics.war).
  • On the Deploy: Select Archive page tick “Archive is already present on the server where Application Server Control is running.” and enter the full path to analytics.war. Under Deployment Plan leave “Automatically create a new deployment plan” ticked. Click Next.Oracle Enterprise Manager (oc4jadmin) - Deploy- Select Archive_1251188864123
  • On the Deploy: Application Attributes page change Application Name and Context Root to whatever you want to access the new instance by. For example, if you currently go to http://localhost:7777/analytics you could choose http://localhost:7777/analyticsInstanceB. In this example I’m going to use analyticsRNM. Click Next.Oracle Enterprise Manager (oc4jadmin) - Deploy- Application Attributes_1251189838584
  • On the Deploy: Deployment Settings page you shouldn’t need to change anything. Click Deploy.Oracle Enterprise Manager (oc4jadmin) - Deploy- Deployment Settings_1251190127915
  • Hopefully you’ll get a successful deployment:Oracle Enterprise Manager (oc4jadmin) - Confirmation_1251190541184Take note of the path listed as “Copy the archive to” in the output. This gives you the j2ee home, which you’ll need in a minute. In this example:
    [25-Aug-2009 09:51:33] Copy the archive to /app/oracle/product/

    the J2EE home dir is

  • Click Return, and on your OC4J: home you should now have a second analytics listedOracle Enterprise Manager (oc4jadmin) - OC4J- home_1251191169012

Setting up a second Presentation Services

You need to create a second Presentation Services that will have its own web catalog and configuration to use the correct RPD.
In this example I’ll create a new Presenttion Services which will be for samplesales whilst the original default installation will be for paint.

An important note is that we don’t need to install anything new, we simply use the existing installation with separate configurations (instanceconfig.xml) and web catalog. The next steps assume that you already have the web catalog for samplesales and just cover instanceconfig.xml

In $OracleBIData/web/config create a copy of instanceconfig.xml for your new instance, eg. instanceconfigRNM.xml. Edit it as follows:

  • Set the CatalogPath to the web cat for samplesales
  • Set the DSN to the ODBC connection you defined above for samplesales
  • Under the <ServerInstance> tag add <Listener port=”9711” />. Set the listener port to port that is not currently in use. Remember what you set it to, as you’ll need to update the Presentation Services plugin with it (see below). In unix you can’t use below 1024 unless you’re root (which you shouldn’t be running OBIEE as!).

Be aware that instanceconfig.xml is CaSe SENsiTIve. Thanks to Merlin128 for discovering this 🙂 This can lead to problems as you won’t always get an error. If you use catalogpath (instead of CatalogPath) you’ll get an error, but if you use Listener Port (capital P, should be lowercase) you won’t get an error but sawserver will ignore it and default to port 9710.

Your modified file should look something like this:

<?xml version="1.0" encoding="utf-8"?>
   <Listener port="9711"/>

(NB: following the instructions in “Changing the BI Presentation Services Listener Port” in the deployment guide p.141, I got an error when I tried to embed the Listener tag within RPC: “The configuration entry ‘RPC/Listener’ is deprecated. Please refer to the admin guide for more information.” followed by an Assertion failure. Putting it just within ServerIntance worked fine)

Testing the second instance of Presentation Services (sawserver)

sawserver can be started with command line parameters, one of which is to specify the config file (which defaults to $OracleBIdata/web/config/instanceconfig.xml). Ultimately we’ll package this up neatly, but to avoid complications it’s best to run it natively from the commandline first to make sure it’s working and not hide any output which may be helpful.


From the commandline go to $OracleBI\web\bin (eg. C:\OracleBI\web\bin) and enter:
sawserver.exe -c c:\OracleBIData\web\config\instanceconfigRNM.xml
(amend c:\OracleBIData\web\config\instanceconfigRNM.xml as appropriate to point to the new instanceconfig.xml file you created above).
Make sure you get a successful startup:

Type: Information
Oracle BI Presentation Services (Build 090414.1900) are starting up.
Type: Warning
WARNING: The Oracle BI Presentation Server is running on a workstation class machine (Windows 2000 Workstation, Windows XP Professional, etc
.). Number of concurrent users may be severely limited by the operating system.
Type: Information
Oracle BI Presentation Services have started successfully.


From the shell prompt go to $OracleBI/setup and run

. ./sa-init.sh
sawserver -c /data/web/config/instanceconfigRNM.xml

Points to note:

  • common.sh and sa-init.sh are “dot sourced”, i.e. type exactly: dot space dot slash
  • If you’re on 64 bit then run sa-init64.sh and sawserver64 instead of sa-init.sh and sawserver respectively
  • amend /data/web/config/instanceconfigRNM.xml as appropriate to point to the new instanceconfig.xml file you created above

Make sure you get a successful startup:

Type: Information
Oracle BI Presentation Services (Build 090414.1900) are starting up.
Type: Information
Oracle BI Presentation Services have started successfully.

Configuring the new Presentation Services plugin

You need to configure the new Presentation Services plugin (eg analyticsRNM) so that it can communicate with the second instance of Presentation Services.

  • Go to your J2EE home directory (if you didn’t note it down below, in OC4J go logs in the top right corner and then click on View for one of the logs, this should give you the path to j2ee/home). Under applications (not application-deployments) go to whatever you called your new instance (eg analyticsRNM), then analytics, then WEB-INF



  • Make a backup copy of web.xml
  • Open web.xml in your favourite text editor and search for oracle.bi.presentation.sawserver.Port. On the line below there will be the default port of 9710. Change this to the new value that you defined above in Setting up a second Presentation Services (in that example it was 9711). It’s very important to get this bit right!webxm
  • In OC4J Application list restart the new instance (eg analyticsRNM), or restart the whole of OC4J/OAS to make doubly-sure.

Testing the configuration

For good measure, first bounce both BI Server and your web/application server (eg OC4J, OAS) if you haven’t already.

Then start both versions of Presentation Services (either manully or scripted, see below). Check that they’ve started up correctly by checking sawserver.out.log, and check they’re listening on the correct ports (eg 9710 and 9711):


Note about ports: don’t confuse these Presentation Services ports with your web server ports. You will always connect from your web browser to your web server on the same port, eg. 9704 or 7777. You would never enter the ports 9710 etc in your web browser address bar.

Start BI server if it’s not running, and then navigate to http://%5Bweb server]:[web server port]/analytics (eg http://localhost:7777/analytics) and login and ensure that you get paint (or whatever you’ve left your default instanceconfig.xml pointing to).

Now try http://%5Bserver%5D:%5Bport%5D/%5Bnew analytics] eg. http://localhost:7777/analyticsRNM and login and hopefully you’ll get samplesales (or whatever your new instanceconfig.xml points to).

samplesales.rpd in one window, paint.rpd on the other, both running from one server

samplesales.rpd in one window, paint.rpd on the other, both running from one server

Problems you might encounter

When doing this amount of configuration work it never does any harm to throw in cheeky service restart to see if it resolves an error. It’s probably good practice to try and work through an error first, if only for gathering understanding.

500 Internal Server Error

Servlet error: An exception occurred. The current application deployment descriptors do not allow for including it in this response. Please consult the application log for details.
This is a generic message meaning that the Presentation Services plugin (“analytics”) has thrown an error. To find details either get the log file from disc ($J2EE home/application-deployments//home_default_group_1/application.log) or from OC4J: homeOracle Enterprise Manager (oc4jadmin) - Log Files_1251205732988
From the log file you can get the real error message of what’s going on

Port 9710 is in use on the local system

Check that you’re starting sawserver directly, and not using sawserver.sh.
If you use sawserver.sh then your -c argument will be ignored because sawserver.sh calls the sawserver binary without any arguments.

Doublecheck your customised instanceconfig.xml file, because sawserver won’t necessarily flag an error if it’s invalid, it will just revert to default values including port (9710).

Your new analytics instance shows the same repository as the default one

You analytics is probably connecting to the incorrect Presentation Services, or the Presentation Services it is connecting to is not running with the correct instanceconfig.xml file

  • What port is Presentation Services plugin (analytics) looking for Presentation Services (sawserver) on? see $J2EE home/applications/[your analytics]/analytics/WEB-INF/web.xml and check the param-value for oracle.bi.presentation.sawserver.Port
  • Shut down all Presentation Server (sawserver) instances that aren’t configured to serve the port in question. Use netstat to verify that the port is state LISTEN
  • Try logging in again – if you get the login screen then you’re connecting to Presentation Services correctly, so the problem must be with the configuration there
  • Check the instanceconfig file that the Presentation Services is started with, have you updated DSN, CatalogPath and Listener Port as described above?

java.io.EOFException at com.siebel.analytics.web.sawconnect.sawprotocol.SAWProtocol.readInt

09/08/25 14:04:50.46 analytics: Servlet error
at com.siebel.analytics.web.sawconnect.sawprotocol.SAWProtocol.readInt(SAWProtocol.java:167)
at com.siebel.analytics.web.sawconnect.sawprotocol.SAWProtocolInputStreamImpl.readChunkHeader(SAWProtocolInputStreamImpl.java:232)

This means that the Presentation Services plugin (analytics) cannot communicate with Presentation Services (sawserver).

  • What port is analytics configured to use? see $J2EE home/applications/[your analytics]/analytics/WEB-INF/web.xml and check the param-value for oracle.bi.presentation.sawserver.Port
  • Is Presentation Services (sawserver) started?
  • Is Presentation Services (sawserver) listening on the same port as is configured in analytics’ web.xml? Check the instanceconfig file that sawserver was started with, and use netstat -a to check if it’s state LISTEN or not
  • If all of these look correct, try bouncing your application server (OC4J, OAS, etc)

[nQSError: 10058] A general error has occurred. [nQSError: 12008] Unable to connect to port 9703 on machine localhost.

Whoops, you forgot to start your BI server…

Charts aren’t working, I just get a yellow triangle symbol

Is the Javahost service running?

Starting both Presentation Services neatly


run-saw.sh is the script used in Unix to control Presentation Services. You can examine it in $OracleBI/setup/run-saw.sh and create your own hack based on your requirements (eg if you always want both started, or to control them individually).

Be aware that run-saw.sh checks for an running instance of “sawserver” so you’ll need to cater for that.

One method would be to create a new startup script like this:

# Hacky script to run two versions of Presentation Services
# https://rnm1978.wordpress.com/
# ---------------------------------------------------
# start your default Presentation Services
echo 'Starting default Presentation Services...'
echo ' '
run-saw.sh start
# The above should be "start64" if you're in 64 bit mode

# Now start the additional Presentation Services
echo '----'
echo ' '
echo 'Starting additional Presentation Services...'
echo ' '
. ./common.sh
. ./sa-init.sh
sawserver -c /data/web/config/instanceconfigRNM.xml  >> ${logfile} 2>&1 &
# The above should be "sawserver64" if you're in 64 bit mode
echo 'See '${logfile}' for log'

Stopping Presentation Services is easier, as run-saw.sh is ruthless in its approach and kills all instances of sawserver. If you don’t want this and want to target a specific instance you’ll need to use ps -ef|grep sawserver and kill the required process.


To add your new Presentation Services as a service in its own right using Microsoft’s sc, follow these steps.
This involves editing the registry! Do so at your own risk!

  1. From the commandline enter:
    sc create sawsvc2 binpath= SEARCHFORMEPLEASE displayname= "Oracle BI Presentation Server 2"

    (note the spaces after the equals character)

  2. Run regedt32 and search for SEARCHFORMEPLEASE
  3. Hopefully you’ll find HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sawsvc2
  4. Edit the ImagePath Value to “C:\OracleBI\web\bin\sawserver.exe” /service /c c:\OracleBIData\web\config\instanceconfigRNM.xml (replacing paths where appropriate)reg
  5. Go to Services and you should see Oracle BI Presentation Server 2 which when started should bring up your new Presentation Services.services

(I couldn’t get sc to accept the full command hence the SEARCHFORME hack!)

If you don’t want to muck around with services something like this simple script should suffice. It uses PsExec (from the excellent PsTools suite of utilities) to start multiple sawserver instances in the background.

REM runMultiplePS.bat
REM Hacky script to run two versions of Presentation Services
REM https://rnm1978.wordpress.com/
REM Uses psExec, download it from http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx
REM and put it somewhere in your PATH like c:\windows\system32
REM ---------------------------------------------------
REM Default instance. Comment this line out if you're running it from Services instead.
REM (you could include -c c:\OracleBIData\web\config\instanceconfig.xml  if you wanted, same difference)
psexec -d C:\OracleBI\web\bin\sawserver.exe
REM Additional instance:
psexec -d C:\OracleBI\web\bin\sawserver.exe -c c:\OracleBIData\web\config\instanceconfigRNM.xml
REM ---------------------------------------------------
REM paths will be something like C:\OracleBI\web\bin64\sawserver64.exe for 64-bit


Hopefully this article demonstrates clearly and in enough detail how to set up multiple Presentation Services, without overwhelming the reader. It is actually easy to do, and is great practice for understanding the architecture behind the OBIEE stack. Things to consider after this are the other shared resources (like javahost and logconfig.xml) which may want isolating depending on the use.

Remember that multiple Presentation Services instances on a machine is UNSUPPORTED BY ORACLE!

As well as working on multiple RPDs & Web Cats, this method could be used for one RPD but multiple web cats, maybe at different development levels, or as a sandbox for certain users. In that case the instanceconfig for each Presentation Services would specify the same ODBC DSN.

References / sources

Multiple RPDs on one server – Part 1 – the BI Server

Filed under: obiee, sawserver, unix — rmoff @ 16:12


In this article I plan to get samplesales and paint repositories hosted on a single server, using one BI Server instance and two Presentation Services instances. This is on both Unix (OEL 4) and Windows, and both OC4J (OBIEE’s “basic installation” option) and OAS (“Advanced Installation”).

Both samplesales and paint are shipped with of OBIEE, you’ll find them in $OracleBI/OracleBI/server/Sample. This article assumes you’ve got the RPD of each into $OracleBI/OracleBI/server/Repository and unpacked the web cats for each into $OracleBIdata/web/catalog.
It also assumes that you know your way around the architecture of BI and are familiar with NQSConfig.ini and instanceconfig.xml – if neither of those files mean anything to you then you will find some background reading useful.

Verify paint and samplesales RPDs

Check that both paint and samplesales both work independently before we start trying to get them to work alongside each other.


Set NQSConfig.ini to

Star    =       paint.rpd ;

and instanceconfig.xml to


(assuming $OracleBIData is /data/web)

Restart BI Server and Presentation Services. Login and check you get something like this:

Oracle BI Interactive Dashboards_1251110032149

paint - default dashboard view


Set NQSConfig.ini to

Star    =       samplesales.rpd ;

and instanceconfig.xml to


(assuming $OracleBIData is /data/web)

Restart BI Server and Presentation Services. Login and check you get something like this:

Oracle BI Interactive Dashboards_1251110222626

samplesales (navigate to dashboard 00 Overview and then report 1.1 - Multi Dim Top Ns)

If you don’t get these working then you need to before continuing. See here for information on setting up samplesales

Configuring both RPDs alongside each other

Edit the NQSConfig.ini file to :

samplesales =       samplesales.rpd , DEFAULT;
paint    =       paint.rpd ;

See page 201 of the Installation and Configuratino guide for the syntax, which is basically:
<logical name> = <filename>.rpd;
The default logical name is Star, but it doesn’t have to be this. If just one repository is loaded in BI Server then it will be connected to for all incoming connections, assuming you have left the Repository= statement as default in the odbc.ini configuration file.

It’s important to understand here how Presentation Services communicates with BI Server. The BI Server uses the ODBC protocol to communicate with all clients, and that includes Presentation Services. Don’t confuse this ODBC with the the protocol that BI Server uses to communicate with the database, which may or may not be ODBC (or OCI, etc). The configuration for Presentation Services communicating with BI Server is in instanceconfig.xml which defines the ODBC DSN to use in the WebConfig > ServerInstance > DSN tag.

ODBC config – Unix

The DSN is defined in $OracleBI/setup/odbc.ini. To test that BI Server is running both RPDs, add two new entries to your odbc.ini file, copying the existing AnalyticsWeb, and specifying the Repository in each:




ODBC config – Windows

The DSN is defined in the GUI ODBC Data Source Administrator (odbcad32.exe) under System DSNs, Driver type Oracle BI Server. As above create two new DSNs, one for Paint and one for SampleSales, and put the repository name in the “Change the default repository to” box. If you’ve updated your NQSConfig.ini as above and restarted BI Server then you should be able to tick “Connect to Oracle BI Server to obtasin defaultsettings […]” and click Next and get a successful connection.

Common errors

nQSError: 43004 repository name: is invalid : Review your NQSConfig.ini logical repository name (on the left of the config line, default is Star)
Path not found … Error Codes: U9KP7Q94: Check your CatalogPath is correct in instanceconfig.xml.

Testing the BI server with two RPDs

Update your instanceconfig.xml and change AnalyticsWeb for AnalyticsWebSampleSales, and make sure the CatalogPath is that of the samplesales webcat. Restart Presentation Services, and log in to Dashboards and verify that the samplesales repo is in use.

Do the same for Paint (update instanceconfig.xml to use AnalyticsWebPaint, and CatalogPath set to paint web repo).

Next steps

You’ve now got a single BI server hosting two repositories. See Part 2 – Presentation Services for setting up multiple Presentation Services to work with these repositories.

References / sources

August 24, 2009

Tech Support Cheat Sheet [xkcd.com]

Filed under: silly — rmoff @ 20:32

xkcd.com is one of my favourite comics on the web. It strikes just the right balance of geeky witty humour without being too smart-ass.

I liked this recent one a lot 🙂

A couple of other favourites:

OBIEE error/message code reference

Filed under: obiee, oracle, support — rmoff @ 06:44

For some reason Oracle haven’t put out a 10.x version of the error & message codes reference guide for OBIEE, but the previous version for Siebel Analytics is still useful:

August 21, 2009

Querying SQL Server from OBIEE running on Unix

Filed under: obiee, sqlserver, unix, windows — rmoff @ 15:00

A question that pops up on the OBIEE OTN forum quite often is how to use non-Oracle databases like MS SQL Server when the OBIEE server is running on a non-Windows OS such as Linux.

The answer in a nutshell is that since version OBIEE has been bundled with ODBC drivers for unix/linux from a company called DataDirect. See the release notes here for more information and installation instructions (as well as a list of support databases).

The instructions are pretty simple but here’s a step-by-step guide, in this instance for data on SQL Server. The steps vary a bit for other database so check the release notes.

  • On Windows define a System DSN for your SQL Server database. Set the default database to the database you are working with
  • Build and test your RPD, setting your connection pool to ODBC 3.5 and data source name to the DSN you defined in step (1).
  • On your Linux (or unix, but from here on I’ll just write Linux!) box, locate the fully-qualified path to the ODBC driver file, SEmsss23.so. It should be in $OracleBI/odbc/lib (or lib64)
  • Backup $OracleBI/setup/odbc.ini
  • Copy the entry from the release notes into odbc.ini.

Description=DataDirect 5.1 SQL Server Wire Protocol

Points to note:

  • The header of the entry should correspond to your DSN you used on Windows:
  • The Address should be the IP (I’ve not tested with hostname) of the SQL Server, then a comma, then the port (default1433). It is a comma, not a colon!
  • Remember to set Database to the database that you’re using
  • Full documentation is on the DataDirect website
  • For SQL Server, backup $OracleBI/server/Config/DBFeatures.INI and then edit it to change



    (if your Database in the Physical Database data source definition is not SQL Server 7.0/2000 then you’ll need to edit the relevant SQL_SERVER section)

  • Copy across your RPD to your linux server and start BI Server up.
  • Use the Issue SQL Directly function of Answers to trial the connection (or through nqcmd, or Oracle ODBC client). If you get an error double check your odbc.ini configuration. Also, make your you have “Use Oracle BI Presentation Services Cache” UNTICKED, as it will cache the response to your query so even if everything’s set up correctly after fixing an error you’ll still get an apparent failure!odbc02
  • If everything works you should see your data returned:


OBIEE and Load Runner – part 2

Filed under: loadrunner, obiee, performance, sawserver — rmoff @ 12:24

See a HOWTO for OBIEE and LoadRunner here: https://rnm1978.wordpress.com/2009/10/01/obiee-and-loadrunner-howto/

This is following on from my first post about OBIEE and LoadRunner, in which I failed dismally to get a simple session replaying.

In a nutshell where I’d got to was using the “Web (Click and Script)” function which worked fine for logging in but when running a report resulted in an error on the rendered page. Digging around showed the error was from the javascript of the OBIEE front end.

AJAX (Asynchronous Javascript And XML) is a combination of technologies but in essence lets a web page load once whilst refreshing its contents with calls back to the web server. In the context of OBIEE this means a dashboard page can load with placeholders for reports and as the data comes back (from the datasource via the BI Server and then parsed through sawserver) each dashboard report can update immediately, without the whole webpage reloading. I’m sure this is where the problem lies with LoadRunner, and it’s going to be important to get it right otherwise the numbers we get out won’t be reliable.

I checked Metalink 3 for any entries and Doc 496417.1 says that LoadRunner’s been used with OBIEE successfully before..

VUGen (LoadRunner Virtual User Generator) offers several protocols. I’d been working with “Web (Click and Script)” but after a fair bit of Googling tried “AJAX (Click and Script)” which didn’t work any better, and then “Web (HTTP/HTML)”.

In the Options dialog prior to Recording there are some Siebel correlations defined including one called Siebel_Analytic_ViewState. Correlation is how LoadRunner deals with a data in a session that is passed back to the server in a subsequent step. For example, at login a user might get a sessionID of some sort which the web server requires in any subsequent calls back. LoadRunner can automatically detect some of these, and you have to define the rest.
The correlations I picked up were:

  • _scid
  • ViewState

The replay still wasn’t working properly, the replay screenshots showed this error:

Using Fiddler2 again to analyse the traffic showed this pattern of requests/responses:

saw.dll?Dashboard This is the main dashboard with placeholders for content
saw.dll?DocPart&_scid=3QNnUBQ3IJo&StateID=943636977 this is a dashboard flash component
saw.dll?DocPart&_scid=3QNnUBQ3IJo&StateID=943636978 this is a dashboard flash component
saw.dll?DocPart&_scid=3QNnUBQ3IJo&StateID=943636979 this is a dashboard flash component
saw.dll?DocPart&_scid=3QNnUBQ3IJo&StateID=943636980 this is a dashboard flash component

The StateID in the URL is embedded in the dashboard template, and is unique so can’t be hardcoded in the VUser script. The script as recorded is hardcoding these numbers and thus requesting flash charts from a dashboard query long-gone, hence the very true “invalid state identifier”

LoadRunner has a feature called ContentCheck (accessed from the Run-time Settings dialog) which can be configured to halt the test if pre-defined text is found, so I added “invalid state identifier” and “! Error : Response from server contained an error” into it and clicked the Set as Default so they’d come up for each script from now
[edit] this doesn’t fire for “! Error : Response from server contained an error”, maybe because it’s inserted through ajax rather than the HTML response? [/edit]

After tinkering around a bit more I recorded another VUser, using “Web (Click and Script)” but on the Recording Options screen set it to URL mode instead of GUI. This captured all of the content requests (css, js, gif, etc), and gave a better replay:

The Help text explains:

  • “..GUI-based script option instructs VuGen to record HTML actions as context sensitive GUI functions such as web_text_link…”
  • “..URL-based script mode option instructs VuGen to record all browser requests and resources from the server that were sent due to the user’s actions. It automatically records every HTTP resource as URL steps (web_url statements). For normal browser recordings, it is not recommended to use the URL-based mode since is more prone to correlation related issues…”

(my emphasis)

Looking at the script it’s still got saw.dll?DocPart calls with a hardcoded StateID. This means that flash-content won’t be being returned. To an extent this doesn’t matter so long as it’s still being generated (i.e. imposing the desired load on the server), but it’s not a full simulation of user activity because there’s less network traffic as a result.

So using the URL-based mode generates better results (i.e. no server error) but looks pretty much hardcoded to the specific scenario recorded. It’s all very well getting a single dashboard working, but I want to simulate hundreds of users using tens of dashboards. In an ideal world I’d define a login action with parametrised username/password, then a dashboard navigation / refresh action with a parametrised list of dashboard titles, and then a logout action.

With the caveat here that I have no training in LoadRunner, it appears to my untrained eye that the only way I’m going to get repeatable, reusable scripts is using the GUI recording, that is, using the web_text_link function to simulate a user clicking, rather than the web_submit_data function which simulates the POST behaviour of ajax but is specific to the dashboard in question and needs some hardcore LR coding to correlate IDs embedded in the HTML with server requests to populate them.

Going back to the Click and Script (GUI Mode) and Fiddler2 I did a line-by-line comparison of the Fiddler-captured HTTP traffic between the recording session and replay. The login action was the same. The clicking onto the dashboard was as follows:
This shows that the initial dashboard request works, and that the first “ReloadDashboard” ajax call correctly retrieves some of the data, but (a) this isn’t ‘rendered’ correctly, and (b) no further data is retrieved (there should be a second ReloadDashboard saw call, plus four flash charts).
(Fiddler’s copy -> full summary is useful for this, as is the breakpoint feature so you can pause after each response and see how it’s rendered to determine what the content was.)

So, web_text_link is great for navigating but is the case that LR’s replay engine doesn’t honour the ajax sufficiently, and/or I’m misunderstanding the principle of the tool?
Using “URL mode” captures the ajax behaviour, eg:

		"Name=InFrameset", "Value=false", ENDITEM,
		"Name=Page", "Value=Overview", ENDITEM,
		"Name=_scid", "Value={CSRule_1_UID2}", ENDITEM,
		"Name=Embed", "Value=true", ENDITEM,
		"Name=PortalPath", "Value=/shared/Financials/_portal/General Ledger", ENDITEM,
		"Name=Caller", "Value=Dashboard", ENDITEM,
		"Name=ViewState", "Value=tvr45qs2u7d1glbfaopqlvvinu", ENDITEM,
		"Name=reloadTargets", "Value=d:dashboard~p:d127730sp2eqcj54~r:ojn7k4k6te44d9ag", ENDITEM,
		"Name=ajaxType", "Value=iframe", ENDITEM,

but as you can see the POSTed data is full of IDs that I assume must correlate with the dashboard HTML.
Given enough time and enough monkeys I’m sure it would be possible to write a LR script that did this – but that would be with the net result of a single dashboard being replayable.

We can get a semblance of load testing on the database server by using web_text_link, but since the data coming back isn’t rendered properly it’s not possible to simulate a real user’s session, only one-off hits of dashboards.

August 20, 2009

Logging specific types of sawserver activity

Filed under: config, log, sawserver — rmoff @ 13:13

As well as tinkering with the sawserver (Presentation Services) logging level and format, we can specific which bits of the log we’re interested in. This is useful for two reasons:

  1. We can enable detailed logging for a specific area, without impacting performance as much as detailed logging throughout would cause
  2. By only logging in detail the area of interest we can more easily read the log output and not have to wade through pages of irrelevant information

Chapter 9 (“Using the Oracle BI Presentation Services Logging Facility”) of the Presentation Services Administration Guide details the log configuration.

To capture, for example, only inbound and outbound HTTP logs, you would amend your logconfig.xml to include this in the <Filters> section, where path is the restriction you want to apply.

<FilterRecord writerClassGroup="File" path="saw.httpserver.request" information="51" warning="100" error="100" security="41" />
<FilterRecord writerClassGroup="File" path="saw.httpserver.response" information="51" warning="100" error="100" security="41" />

If you want to write the information to a separate file, define a new Writer:

<Writer implementation="FileLogWriter" name="Global File Logger" writerClassId="7" dir="/tmp" filePrefix="sawodbc"/>

(use an unused writerClassId)
and WriterClassGroup:

<WriterClassGroup name="FileODBC">7</WriterClassGroup>

and use the newly defined WriterClassGroup in the Filter:

 <FilterRecord writerClassGroup="FileODBC" path = "saw.odbc" information="51" warning="100" error="100" security="41"/>

All of the odbc logging will now be written to a file in /tmp called sawodbc0.log.

To get a list of all possible path values, run sawserver with the -logsources commandline option

$ . ./common.sh
$ . ./sa-init.sh
$ sawserver -logsources
[...etc etc...]

Do you mean (pt II)

Filed under: metalink, silly, support — rmoff @ 08:52

A follow up to my previous post about Metalink’s “Do you mean” feature, this one made me laugh:

I shall miss this kind of thing when Metalink3 merges into My Oracle Support….

Meep meep!


August 19, 2009

OBIEE and Load Runner – part 1

Filed under: loadrunner, obiee, performance — rmoff @ 17:57

See a HOWTO for OBIEE and LoadRunner here: https://rnm1978.wordpress.com/2009/10/01/obiee-and-loadrunner-howto/


LoadRunner is a tool from HP (bought from Mercury) that can be used to simulate user activity. It supports a whole host of protocols but for OBIEE I’m obviously using the Web one.

There are two flavours, “Web (Click and Script)” and “Web (HTTP/HTML)”. The latter simply shoves HTTP requests at the server, whereas “Click and Script” simulates mouse and keyboard entry and thus is more appropriate for this user-based application. [edit]I’m not sure if this is actually the case[/edit]

You can write the script from scratch if you’ve more time than sense, or you can “record” a session where LoadRunner scrapes all activity from a session and then generates a script based on it. From this you can then refine your script. A script is called a VUser (Virtual User).

It’s a good idea to have mapped out what you are trying to test and how, rather than just randomly clicking through the application. Doing this has two disadvantages:

  1. Your script will be a pig to debug & customise
  2. Your script will be little use other than replicating multiple instances of randomly clicking.

Much better to do something simple like this:

  1. Login (record it under the “vuser_init” action)
  2. Navigate to a dashboard
  3. Logout (record it under the “vuser_end” action)

Once you’ve got your simple script you can then get funky. Parametrise the username and password, and then the dashboard that you select. Suddenly what looked like a simple script can be set to go and open all your dashboards!

Validating VUser script

Now you have a simple script that you should be able to replay. Using the Verify Replay option you can test what you’ve recorded. On replay I got “No Errors Detected” :replay01

but the screenshots thumbnails showed an difference :


Going to View -> Test Results and examining the full-size screenshots showed the error
! Error : Response from server contained an error


Doc ID 735158.1 on Metalink details this problem, but doesn’t have a solution. The error message is apparently not from OBI but the webserver. I don’t know enough about the web technology to trace this through to source. In the HTML there is always a placeholder for a message :

<DIV style="display:none" id="DashboardErrorDiv"></DIV>

I did a detailed examination of the sawserver log (using detailed logging level) but couldn’t find any errors. I checked the analytics web app log too, and the oc4j and apache logs. All turned up nothing. Using Fiddler2 I set up a trace of the network traffic from LoadRunner to OBIEE (define Fiddler2 as a proxy in LoadRunner) – and the blasted thing worked! No error! So then I removed the proxy setting and again it worked, no problem. How frustrating.

Taking a step back, I restarted sawserver, ran the Replay and got the error again. Changed to go via Fiddler2, no error. Bounced sawserver again, ran the Replay through Fiddler2 first this time – and got the error. Phew. So it looks like it’s maybe cache-based, and at least it’s repeatable.

Analysing the Fiddler2 output revealed:

  • DashboardErrorDiv is populated in res/b_mozilla/dashboards/portalscript.js saw.dashboard.showError, which is an error handler
  • The error itself is thrown in res/b_mozilla/common/ajax.js (header indicates that it is for Server Calls – used to retrieve XML from server)

FireBug was also useful for backing up the analysis in capturing known-good sessions.

I’m not convinced the Metalink article is entirely truthful, since it is still OBI throwing the error, just clientside javascript. The problem is that OBIEE is heavily relient on ajax, and running it on the simulated browser of LoadRunner is not working. I’m hoping the solution is somewhere in tweaking the LoadRunner replay config. I’ve tried using “AJAX (Click and Script)” but get the same results.

sawserver log – short format

Filed under: config, hack, log, sawserver — rmoff @ 14:02

I posted a while ago about the sawserver (Presentation Services) log configuration file.
Today I’m doing some work digging around why sawserver’s throwing an error and so increased the log detail. This parameter is really helpful to use:


Consider in these two screenshots, the first is with the default log format and shows about six entries. The second is short log format and is about ten times as much data.


default log format


short log format

Horses for courses, but on a “fishing expedition” through a log I’d say the short format is definitely easier to work with.

To implement it update $OracleBIData/web/config/logconfig.xml and change the Writer definition:

		<Writer implementation="CoutWriter" name="Global Output  Logger" writerClassId="2"/>
		<Writer fmtName="short" implementation="CoutWriter" name="Global Output  Logger" writerClassId="2"/>

and restart Presentation Services. On a tangent, a lazy way to do this on unix whilst leaving time for ports to free up before restarting is:

run-saw.sh stop;sleep 60;run-saw.sh start64
Older Posts »

Blog at WordPress.com.