Currently, I’m a happy camper since two blog posts were recently written on absolutely fundamental subjects which for me fall into the category: “Know and understand these concepts or just please don’t touch any OBIEE RPD, thanks.”

First post is from Andy Rocha over at RittmanMead and concerns LTSs and outer join pruning:

Second one is from Jeff McQuigg on dimensionsal hierarchies and – by extension – the “dreaded” content level tab:

Both of these posts touch on subjects which are the subject of questions about 10 times a week on forums.oracle.com and comunities.oracle.com …each!
LTS modelling (one vs several), non-conformed dimensionalities in business models (leading to nQSError: 14025 and his buddies) and all the other beautiful and powerful options that the RPD gives you are still amongst the least understood subjects.

These are basics which must be understood. Comprehension is mandatory! Not just slavish adherence to “best practice guides” or “replicating what the guy before you did”.


I often get to hear the following question concerning OBIEE agents:

“Why can’t we send out personalized content (filtered data / row-level security) to non-OBIEE users by simply using their email address residing in the data?”

Killer answer: Security!

Think about it: If you use “Get Recipients from the Analysis used in the Agent Condition”, it will actually perform a complete login with authentication + authorization through the security realm and only the fetch the data.

Now imagine that you bypass this “because it’s so convenient to just have the email in the data”. And now imagine me doing this:

update MYTABLE set EMAIL = ‘uber.h4xx0r@somenastyplace.thief’;

I think this should be answer enough as to why you do NOT want to be able to do this.
At all.


When upgrading existing customized installations of OBIEE to, one thing that you may run into is a subtle change in the usage of the vanilla style and skin of the application.

FusionFX has become the default, but isn’t immediately or better directly suited as a basis for your own custom style and skin.
The reason for that is, that FusionFX itself is only a subset of a full style+skin package and the vanilla application continues to use a lot of blafp.

Oh yes, /web/app/res also has become /web/appv2/res for some reason or another within Oracle_BI1, so here’s what you find in there:

A cursory glance at the folder contents of FusionFX and blafp side-by-side shows quite some differences already:

Whipping out out trusty Firebug and what an out-of-the-box applications actually renders, we see blafp used for the application header:

while we see FusionFX being the source for the dashboards themselves:

As most GUI customizations replace first and foremost the logos in the application header and then moving on to the look & feel of the dashboards and analyses, this logically means that adapting the default FusionFX will only get you halfway to your destination.

What you need to do, in order to have a full and complete basis for your own custom skin, which contains all files and artifacts while retaining the slick FusionFX look (it does look a lot leaner and nicer now), is to merge the two into one package. doing this couldn’t be any simpler than this:
1.) clone s_blafp and sk_blafp
2.) copy all the content of s_FusionFX and sk_FusionFX into the respective blafp folders, replacing all existing files

Since FusionFX is a modified subset of blafp, you’ll retain all base blafp files and gain the modified and “newer” FusionFX files which supersede blafp.

All you need to do now, is rename the resulting folders…

…push them to the /analyticsRes/ directory (or whatever directory holds the deployment of your custom style and skin), reference it in the instanceconfig.xml and, voila, you’ve got a complete and fully customizable style and skin package.


Just a quick note on some security-related things to watch out or during/after an in-place upgrade to OBIEE These were experienced on a to upgrade on 64bit Linux:

1.) Application Policies:

All custom-created application policies were dropped during the upgrade, leaving only the vanilla ones. Affected file: system-jazn-data.xml.

2.) Application Roles (this one is a bit queerer):

Affected file: system-jazn-data.xml.

Unmodified vanilla roles come through the upgrade unharmed and retain all their vanilla members (users, groups and app roles alike).
Custom roles equally come through the upgrade unharmed and retain all their vanilla as well as custom members of all kinds.

The problem is with vanilla application roles which have received new/additional members when compared to a plain install:
The role itself still exists, but it loses all vanilla members and only retains custom members.

Example application role “BIAdministrator”:

Pre-upgrade members: vanilla group “BIAdministrators” (WLS-native LDAP group); group “CustomAdministrators” (custom LDAP derived group); user “cberg” (custom LDAP derived user) and several others.

Post-upgrade members: group “CustomAdministrators” (custom LDAP derived group); user “cberg” (custom LDAP derived user) – the WLS-native LDAP group has been dropped.

This wasn’t immediately visible due to the new way the members of an application role are displayed (call me old-fashioned, but I prefered the old style – the new doesn’t allocate enough screen real-estate) doesn’t really show it at quick glance and I was wondering why I got weird “Logon Failed” errors when wanting to check the RPD online while all the logs proudly proclaimed “No no, you’re definitely authenticated nicely”. WLS and EM logons oviously work since the app role concept doens’t kick in.

Hope this helps other people from wasting time.

@Borkur seems to have another nice one related to security hanging around. I’ll make sure to ask him to post his one into the comments.



OBIEE (aka BP6) is out and until MOS hosts a proper tracking note, here is the list of all patches making up this patch set with direct links.

Patch 15844023    Patch (1 of 7) Oracle Business Intelligence Installer
Patch 15844066    Patch (2 of 7) Oracle Real Time Decisions
Patch 14800665    Patch (3 of 7) Oracle Business Intelligence Publisher
Patch 15843961    Patch (4 of 7) Oracle Business Intelligence ADF Components
Patch 15844096    Patch (5 of 7) Enterprise Performance Management Components Installed from BI Installer
Patch 14791926    Patch (6 of 7) Oracle Business Intelligence
Patch 15839347    Patch (7 of 7) Oracle Business Intelligence Platform Client Installers and MapViewer

As always: don’t forget JDEV patch 13952743



While I was off, Oracle released OBIEE which is another bugfixing patch set which doesn’t bring in new functionality but irons out quite a few quirks.

Here you can find the main MOS article detailling the patches making up this patch set as all bugs fixed in it.

By the way…make sure you don’t forget JDEV patch 13952743.



Patch is here and can be downloaded from MOS.

Once more it’s a 7-pack patch and here are the patch numbers and direct links:

Patch 14285344: Patch (3 of 7) Oracle Business Intelligence Publisher
Patch 14415773: Patch (5 of 7) Enterprise Performance Management Components Installed from BI Installer
Patch 14405222: Patch (6 of 7) Oracle Business Intelligence
Patch 14409674: Patch (7 of 7) Oracle Business Intelligence Platform Client Installers and MapViewer

Documentation’s here: https://updates.oracle.com/Orion/Services/download?type=readme&aru=15499675



With the
release of the BP1 SampleApp V207, I’ve taken a moment to dissect
the usage of the D3.js calendar contained within since it is one of the
examples frequently pointed out to showcase new visualisation capabilities.
Let’s dive a bit deeper into this to understand the way the D3 calendar works and what is necessary to embed this
in any other OBIEE installation.
As-Is in
the Answers Criteria block, the analysis is quite straight-forward. “Color Low”
and “Color High” being simply presentation variables grabbing the values passed
from the “Red / Green Color Limit” prompts on the dashboard page.
The actual
functionality of the D3 calendar is contained and controlled by the two narrative
views of the analysis which I will be calling the “Context Narrative” and “Content
Narrative” respectively for the purpose of this post:


Key here are
the four JavaScript variables which will be used by the code within the content
narrative below. These are filled by the values collected from the 1st
line of the analysis data set (Rows to display = 1). Generally, when analysing
the D3.js examples, it is hugely helpful to add a simple table view to the
analysis in order to see what the data stream actually brings along from the OBI
server since most examples use mixtures of column references and variables.

IMPORTANT: year_range2 must always be the end year +1!
You don’t
have to provide these values through dashboard prompts and simply read the from
the data set, but having a means to restrict the data displayed is always comfortable.



<script type=”text/javascript” src=”/analyticsRes/d3/d3.v2.js”></script>
    <link type=”text/css” rel=”stylesheet” href=”/analyticsRes/d3/lib/colorbrewer/colorbrewer.css”/>
    <link type=”text/css” rel=”stylesheet” href=”/analyticsRes/d3/examples/calendar/calendar.css”/>

    <div id=”my_chart”></div>
    <script type=”text/javascript”>
var margin = {top: 19, right: 20, bottom: 20, left: 19},
    width = @{Width}{720}- margin.right – margin.left, // width
    height = @{Height}{136} – margin.top – margin.bottom, // height
    cellSize = @{CellSize}{12}; // cell size

var day = d3.time.format(“%w”),
    week = d3.time.format(“%U”),
    percent = d3.format(“.1%”),
    format = d3.time.format(“%Y-%m-%d”);

var color = d3.scale.quantize()

var svg = d3.select(“#my_chart”).selectAll(“svg”)
    .data(d3.range(year_range1, year_range2))
    .attr(“width”, width + margin.right + margin.left)
    .attr(“height”, height + margin.top + margin.bottom)
    .attr(“class”, “RdYlGn”)
    .attr(“transform”, “translate(” + (margin.left + (width – cellSize * 53) / 2) + “,” + (margin.top + (height – cellSize * 7) / 2) + “)”);
    .attr(“transform”, “translate(-6,” + cellSize * 3.5 + “)rotate(-90)”)
    .attr(“text-anchor”, “middle”)
var rect = svg.selectAll(“rect.day”)
    .data(function(d) { return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
    .attr(“class”, “day”)
    .attr(“width”, cellSize)
    .attr(“height”, cellSize)
    .attr(“x”, function(d) { return week(d) * cellSize; })
    .attr(“y”, function(d) { return day(d) * cellSize; })
    .text(function(d) { return d; });
    .data(function(d) { return d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
    .attr(“class”, “month”)
    .attr(“d”, monthPath);

    var csv =[];


What happens
here that I can influence?
controls the size of the rendered calendar. Parameters are passed from the dashboard
prompt via presentation variables. If you don’t want users to be able to choose
this, simply put static values.
Date format
is controlled here. VERY IMPORTANT: you must match the date format in this part
of the script to the date format provided within the data set:
means “format
= d3.time.format(“%Y-%m-%d”);”
If your
date picture is for example DD.MM.YYYY (e.g. 14.08.2012), then you need to
adjust the script to:
format = d3.time.format(“%d.%m.%Y “);

the colour limits (.domain) as retrieved by the dashboard prompts.

the display of the year number in front of the rectangles representing the
Leave the
rest as-is.
retrieves the values for date and measure from the data set (per row!). Leave
this as-is.
  var data = d3.nest()
    .key(function(d) { return d.Date; })
    .rollup(function(d) { return d[0].Metric/100; })

  rect.filter(function(d) { return d in data; })
      .attr(“class”, function(d) { return “day q” + color(data[d]) + “-9”; })
      .text(function(d) { return d + “: ” + percent(data[d]); });

function monthPath(t0) {
  var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
      d0 = +day(t0), w0 = +week(t0),
      d1 = +day(t1), w1 = +week(t1);
  return “M” + (w0 + 1) * cellSize + “,” + d0 * cellSize
      + “H” + w0 * cellSize + “V” + 7 * cellSize
      + “H” + w1 * cellSize + “V” + (d1 + 1) * cellSize
      + “H” + (w1 + 1) * cellSize + “V” + 0
      + “H” + (w0 + 1) * cellSize + “Z”;

What happens
here that I can influence?
For the SampleApp
example, this transforms the values retrieved from the data set into an index representation
for transformation into a percentile representation in the tooltip display.
If you want absolute
values, simply change
“.rollup(function(d) {
return d[0].Metric/100; })”
“.rollup(function(d) {
return d[0].Metric; })”

This colours the date
rectangles and the actual tooltip with date information and the added percentile
representation of the measure. Here, if you want absolute values, simply change
“.text(function(d) {
return d + “: ” + percent(data[d]); });”
“.text(function(d) {
return d + “: ” + data[d] });”
Leave the rest as-is.
So what do you need
all-in-all to transplant this into any OBIEE implementation?

1.) The
D3 libraries contained in the d3 and d3-cloud folders. Quickest way – if you
have the SampleApp lying around – is to just grab them from the analyticsRes
folder of the VirtualBox and slap them into your own analyticsRes