Post: Web Portal Integration with IBM Cognos Mashup Service

As a custom solutions shop that deals with IBM Cognos on a daily basis, one of the problems that comes up frequently is the integration of a specific report into an existing corporate web portal without involving Cognos Connection. Most commonly this is a dashboard which takes up a small portion of screen real estate in order to show something relevant to the rest of the page content or possibly something that has great importance and always needs to be in the user’s face. Typically this type of work fell to the Cognos SDK URL invocation. The Mashup Service gives us yet another approach to solve this sort of requirement.

There are a number of advantages to using the Cognos Mashup Service for such a task.

  • It is relatively simple (compared to the URL invocation) and offers a complete end to end flow for these types of tasks
  • It offers greater control of the user experience. For example often a cognos web session will time out resulting in the user being challenged for their cognos credentials inside the dashboard frame. This looks pretty tacky. Coding around in order to control flow is tricky. Ultimately using the Cognos Mashup Service allows a developer greater control of the outcome without having to worry about Cognos Connection bleeding into your dashboard

In order to make this sample more relevant, we will do a little role playing. We are developers for the venerable Great Outdoors sporting goods company. If you are reading this it is not likely to be a big stretch. Our CEO has requested that we construct an application for him so that he can monitor his key reports in the same page as his stock ticker and email. I picture the CEO of the Great Outdoors sporting goods company as a demanding J.Jonah Jameson type. Great Outdoors uses Google to host their corporate mail. After speaking with the CEO we also find out that he uses the iGoogle portal to consolidate personal data inside gadgets.

His page looks something like this:

Click Image to Enlarge

We leave breathing a sigh of relief. A great deal of the infrastructure has been provided by Google Gadgets. We have an ample section right in the middle of his page in which we can place our reporting gadget. This gives us a basic and somewhat realistic problem that can be solved through the Cognos Mashup Service.

Here is a diagram of what we have come up with for our solution’s basic architecture.

Click Image to Enlarge

To summarize the diagram above, we have the simplest of Google Gadgets to serve as a container for our dashboard report. The Gadget references a descriptor and page page which are hosted on our corporate web server. The web page contains all the logic that is required to interact with the Cognos Mashup Service in order to get the report output desired.

Playing the “at home” version of the game

The example application described below can be implemented by the reader with the appropriate version of Cognos and access to a development web server. There are a number items that will need to be localized from the generic example into the reader’s specific environment. If there is a call for the reader to make some change in their local environment it will be denoted in a “Bringing it Home” section. These sections look like this:

Bringing it Home:
This is some information that will help localize the example to your environment if you wish to follow along

Let us start from the bottom up as we build our solution.

The Mashup Web Page

This is the bulk of our implementation, it performs the following tasks:

  1. Authenticates our user to the Cognos BI Server
  2. Invokes the relevant report and acquires the output
  3. Describes the detailed page layout

Mashup services reside as an extension of the cognos gateway. For example if my gateway is athttp://www.greatoutdoors.com/cognos/cgi-bin/cognos.cgi, then mashup services are found by adding the /rds resource to the gateway. The various functions of the mashup service are found by adding additional resources to the URL. For example the authentication service for login would be at the following URL:

http://www.greatoutdoors.com/cognos/cgi-bin/cognos.cgi/rds/auth/logon.

On a related note regarding using the mashup services – It is important to be consistent with the base URL and port for your AJAX mashup applications. This means that you should remove references to hard IP address and localhost. If you don’t then you’ll likely get silent failures where your application does not raise any errors but data just refuses to render. This is partly due to same site origin restrictions to prevent cross site scripting. Although there are some other reasons as well. It is best to just be consistent with your access to the service across all layers of your application and then you won’t have to worry about scratching your head when report data just refuses to render.

Authentication through Mashup Services

The code below implements a function for authenticating the user with Cognos. It builds an xml string containing the necessary namepace, userid, and password. Then kicks off an AJAX request pointed at the appropriate logon resource. If successful it sets a cookie in the browser and returns the response. The onFailure handler for this request contains a useful bit of mashup code which will tease out the error code via regular expressions. If you want just the error code independent of the whole string it is at index err[2].

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
function logon(aNamespace, aUserid, aPassword){ //build the xml credentials element var xmlData = "<credentials>" + "<credentialElements><name>CAMNamespace</name><label>Namespace:</label>" + "<value><actualValue>" + aNamespace + "</actualValue></value>" + "</credentialElements><credentialElements><name>CAMUsername</name><label>User ID:</label>" + "<value><actualValue>" + aUserid + "</actualValue></value>" + "</credentialElements><credentialElements><name>CAMPassword</name><label>Password:</label>" + "<value><actualValue>" + aPassword + "</actualValue></value>" + "</credentialElements></credentials>"; //authentication resource var rdsLogonUrl = cognosUrl + '/rds/auth/logon'; var request = new Ajax.Request(rdsLogonUrl,{ asynchronous : false, method : 'get', parameters :{ xmlData : xmlData }, onSuccess : function(aTransport) { return aTransport.responseText; }, onFailure : function(aTransport) { var regex = /(RDS-ERR-)(d*)/; var err = aTransport.responseText.match(regex); if (err != null) { alert(aTransport.responseText); } }); }

Running the report and getting the output

Now that our identity with Cognos has been established it is time to rustle up some some report data. This follows the same idiom as the logon method as far as building the URL and sending it to the Cognos gateway through an AJAX request.

The resource used to run a report by virtue of specifying its path is:

<gateway_url>/rdl/reportData/path/<report_path> ; where the appropriate gateway_url is substituted in as well as the logical path for the report that one would like to execute in place of <report_path>. Now, it is important to note that this is not the xpath based search path expression. Rather when it comes to Mashup services, path based report locations are identified in a directory fashion. For example, the report that the CEO is interested in seeing on his dashboard is located at /Public Folders/GO Sales and Retailers/Report Studio Report Samples/Global Sales.

The parameters section of this request is worth a look. The “fmt” property has been set to ‘HTML’ signifying that we want this output returned in HTML. By default the Mashup service returns LDX (an xml representation of the data). In this case HTML is closest to the report studio version of the report and that is what our CEO is used to seeing. So we’ll go with that.

The ‘selection’ property of the request allows us to cherry pick a portion of a report and ignore the rest. In this case there is a bar chart containing all of the information that the CEO requires on his dashboard. The value for this selection property can be found by examining the report in Report Studio and finding the Miscellaneous Properties::name property of the relevant object.

The ‘async’ property indicates whether or not the request to the mashup services should block until complete or return a reference to the request which can be polled periodically to see how it is doing. For the sake of simplicity this example will block until complete.

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
function getReportData(aReportPath){ var restPath = cognosUrl + '/rds/reportData/path' + aReportPath; var response; var request = new Ajax.Request(restPath,{ asynchronous : false, method : 'get', parameters :{ async : 'OFF', fmt : 'HTML' , selection : 'Combination Chart1' }, onSuccess : function(aTransport){ response = aTransport; }, onFailure : function(aTransport){ var regex = /(RDS-ERR-)(d*)/; var err = aTransport.responseText.match(regex); if (err != null){ alert(aTransport.responseText); }}}); return response; }

The return value from this request is the same HTML which would render if one were to type the full REST path on in a browser address bar. In this case the full URL would look like this:

http://www.greatoutdoors.com/cognos/cgi-bin/cognos.cgi/rds/reportData/path/Public%20Folders/GO%20Sales%20and%20Retailers/Report%20Studio%20Report%20Samples/Global%20Sales?async=OFF&fmt=HTML&selection=Combination%20Chart1

Adding the HTML Plating

The code below is the web page in its entirety. It adds the html body including an onLoad event listener to call the JavaScript function which performs our business logic yielding a chart which would look like this:

Click Image to Enlarge

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!--We are relying on prototype.js to make our lives easier. Get it from http://www.prototypejs.org/download--> <script type="text/javascript" src="js/prototype/prototype.js"></script> <style type="text/css"> #Combination__Chart1 { height: 250px; width: 400px; } </style> <script type="text/javascript"> //cognos base URL information var wsUrl = 'www.greatoutdoors.com'; var cognosUrl = 'http://' + wsUrl + '/cognos/cgi-bin/cognos.cgi'; //hard coded credentials var namespace = 'go'; var username = 'goceo'; var password = 'supersecret'; //dashboard report location var reportPath = '/Public Folders/GO Sales and Retailers/Report Studio Report Samples/Global Sales'; function logon(aNamespace, aUserid, aPassword) { //logon to cognos var xmlData = "<credentials>" + "<credentialElements><name>CAMNamespace</name><label>Namespace:</label>" + "<value><actualValue>" + aNamespace + "</actualValue></value>" + "</credentialElements><credentialElements><name>CAMUsername</name><label>User ID:</label>" + "<value><actualValue>" + aUserid + "</actualValue></value>" + "</credentialElements><credentialElements><name>CAMPassword</name><label>Password:</label>" + "<value><actualValue>" + aPassword + "</actualValue></value>" + "</credentialElements></credentials>"; var rdsLogonUrl = cognosUrl + '/rds/auth/logon'; //ajax provided by prototype.js var request = new Ajax.Request(rdsLogonUrl, { asynchronous : false, method : 'get', parameters :{ xmlData : xmlData }, onSuccess : function(aTransport) { return aTransport.responseText; }, onFailure : function(aTransport) { var regex = /(RDS-ERR-)(d*)/; var err = aTransport.responseText.match(regex); if (err != null) { alert(aTransport.responseText); } } }); } function runReport(){ logon(namespace, username, password); var response = getReportData(reportPath); var e = document.getElementById('report_body'); e.innerHTML = response.responseText; } function getReportData(aReportPath){ var restPath = cognosUrl + '/rds/reportData/path' + aReportPath; var response; var request = new Ajax.Request(restPath, { asynchronous : false, method : 'get', parameters :{ async : 'OFF', fmt : 'HTML' , selection : 'Combination Chart1' }, onSuccess : function(aTransport) { response = aTransport; }, onFailure : function(aTransport) { var regex = /(RDS-ERR-)(d*)/; var err = aTransport.responseText.match(regex); if (err != null) { alert(aTransport.responseText); } } }); return response; } </script> <title></title> </head> <body onload="runReport()"> <div id="report_body">Loading...</div> </body> </html>
Bringing it home:
You’ll need to change the following variables to values that are appropriate to your test environment

  • wsUrl – base host name for your web server
  • cognosUrl – the path to the cognos gateway
  • namespace – security namespace containing your user
  • username – the userid for your test user
  • password – the password for for your test user
  • reportPath – the logical directory path of your favorite report
  • selection – if you would like to return the entire report then you can remove this variable

The Gadget Descriptor

This is a simple xml file that will be hosted on a web server which provides information about how the gadget will behave in the iGoogle portal. It also provides a reference to the actual web page which provides the mashup content. This file is deployed in the same directory as the mashup html/javascript web page. In this case our gadget descriptor will be located at:

http://www.greatoutdoors.com/dashboards/google-gadget-mashup.xml

Bringing it home:
If you are implementing this example you’ll need to change the href value to point to your own web page and save this content in an xml file next to your Mashup web page. If the report is out of bounds in your google gadget, then you can change the height attribute.
1 2 3 4 5
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="Revenue Report" height="300" /> <Content type="url" href="http://www.greatoutdoors.com/dashboards/revenue.html"></Content> </Module>

The iGoogle portal

Now it is time to test your integrated solution in your own iGoogle portal. In the interest of keeping this article tightly focused on Cognos Mashup I will be as brief as possible on this topic.

  1. Point your browser to http://www.google.com
  2. Click on the iGoogle link in the upper right hand corner
  3. Click on the “Add Stuff >>”in the upper right quadrant of the page
  4. Click the “Add Feed or Gadget” link in the right most column.
  5. Enter the URL to your gadget descriptor and click Add. The URL of the gadget is a reference to the xml descriptor on your web server. For example;http://www.greatoutdoors.com/dashboards/google-gadget-mashup.xml You’ll likely get a warning that this was produced by someone other than Google. It is OK to ignore this since you are the producer.
  6. When you return to your iGoogle page you will now see your mashup gadget along with the existing gadgets.

Here is the finished product.

Click Image to Enlarge

Conclusion

A mere day later you walk into the CEO’s office and add your new dashboard gadget to his iGoogle portal. He responds, “What took you so long!”, then proceeds to give you the go ahead to continue to go forward and start enhancing this product. On the way out the door you catch the CEO’s reflection in the office door as he blinks and shakes his head in astonishment. He lets slip a barely audible whispered “Wow”.

You can now see that even the simplest use for consuming Cognos BI services can produce impressive results. Come back next time when we use the Cognos Mashup Service to produce pizza and beer out of thin air. Ok…that is simply not true, but I bet we’ll do something cool with it.

{{cta(‘7df2324d-a053-46bf-b4a3-adf18ca4e0db’)}}

 

Scroll to Top
As the BI space evolves, organizations must take into account the bottom line of amassing analytics assets.
The more assets you have, the greater the cost to your business. There are the hard costs of keeping redundant assets, i.e., cloud or server capacity. Accumulating multiple versions of the same visualization not only takes up space, but BI vendors are moving to capacity pricing. Companies now pay more if you have more dashboards, apps, and reports. Earlier, we spoke about dependencies. Keeping redundant assets increases the number of dependencies and therefore the complexity. This comes with a price tag.
The implications of asset failures differ, and the business’s repercussions can be minimal or drastic.
Different industries have distinct regulatory requirements to meet. The impact may be minimal if a report for an end-of-year close has a mislabeled column that the sales or marketing department uses, On the other hand, if a healthcare or financial report does not meet the needs of a HIPPA or SOX compliance report, the company and its C-level suite may face severe penalties and reputational damage. Another example is a report that is shared externally. During an update of the report specs, the low-level security was incorrectly applied, which caused people to have access to personal information.
The complexity of assets influences their likelihood of encountering issues.
The last thing a business wants is for a report or app to fail at a crucial moment. If you know the report is complex and has a lot of dependencies, then the probability of failure caused by IT changes is high. That means a change request should be taken into account. Dependency graphs become important. If it is a straightforward sales report that tells notes by salesperson by account, any changes made do not have the same impact on the report, even if it fails. BI operations should treat these reports differently during change.
Not all reports and dashboards fail the same; some reports may lag, definitions might change, or data accuracy and relevance could wane. Understanding these variations aids in better risk anticipation.

Marketing uses several reports for its campaigns – standard analytic assets often delivered through marketing tools. Finance has very complex reports converted from Excel to BI tools while incorporating different consolidation rules. The marketing reports have a different failure mode than the financial reports. They, therefore, need to be managed differently.

It’s time for the company’s monthly business review. The marketing department proceeds to report on leads acquired per salesperson. Unfortunately, half the team has left the organization, and the data fails to load accurately. While this is an inconvenience for the marketing group, it isn’t detrimental to the business. However, a failure in financial reporting for a human resource consulting firm with 1000s contractors that contains critical and complex calculations about sickness, fees, hours, etc, has major implications and needs to be managed differently.

Acknowledging that assets transition through distinct phases allows for effective management decisions at each stage. As new visualizations are released, the information leads to broad use and adoption.
Think back to the start of the pandemic. COVID dashboards were quickly put together and released to the business, showing pertinent information: how the virus spreads, demographics affected the business and risks, etc. At the time, it was relevant and served its purpose. As we moved past the pandemic, COVID-specific information became obsolete, and reporting is integrated into regular HR reporting.
Reports and dashboards are crafted to deliver valuable insights for stakeholders. Over time, though, the worth of assets changes.
When a company opens its first store in a certain area, there are many elements it needs to understand – other stores in the area, traffic patterns, pricing of products, what products to sell, etc. Once the store is operational for some time, specifics are not as important, and it can adopt the standard reporting. The tailor-made analytic assets become irrelevant and no longer add value to the store manager.