How to Develop a Connector That Connects Tableau and OBIEE

Cody Schneider7 min read

Bridging the gap between Tableau’s powerful visualization capabilities and OBIEE’s robust data models can feel like a complex puzzle. While OBIEE provides a secure and governed semantic layer, its native dashboards often lack the interactivity and intuitive design users love in Tableau. This article will guide you through the process of developing a custom Web Data Connector (WDC) to connect Tableau directly to your OBIEE data, unlocking the best of both worlds.

Understanding the Challenge: Why is a Custom Connector Needed?

Connecting third-party BI tools to OBIEE isn't straightforward. OBIEE's strength lies in its repository file (RPD), which contains the business model and mapping layer. This layer translates complex database schemas into understandable business terms, manages joins, and enforces security rules. A simple SQL connection to the underlying database bypasses this entire governance structure, defeating the purpose of having OBIEE in the first place.

To leverage Tableau's visualization features while respecting OBIEE's business logic, you need a method that can query the semantic layer itself. This is where a custom Web Data Connector comes in. A WDC allows Tableau to connect to data sources that are accessible over HTTP, essentially letting you build a bridge to almost any web-based API, including those offered by OBIEE.

Prerequisites: What You’ll Need to Get Started

Before you begin building, make sure you have the following tools and a basic understanding of a few key technologies. You don’t need to be an expert, but familiarity will help immensely.

  • Tableau Desktop: The platform where you will use and test your connector.
  • OBIEE Instance Access: You'll need credentials and permissions to access OBIEE and execute a report or a logical query via its web services.
  • Web Development Basics: A foundational knowledge of HTML, JavaScript, and JSON/XML is essential. The WDC is built using these technologies.
  • Tableau WDC SDK: A collection of files, templates, and a simulator to help you build and test your connector. You can download it directly from Tableau's official GitHub page.
  • A Web Server: You need a place to host your connector's HTML and JavaScript files. For development, you can run a simple local server using Node.js with the http-server package or a similar tool.

Step-by-Step Guide: Building Your OBIEE Web Data Connector

Our goal is to create a simple web page (the connector) that prompts a user for their OBIEE report details, fetches the data via OBIEE's web services, and passes it to Tableau in a structured format.

Step 1: Set Up Your Development Environment

First, download and unzip the Tableau WDC SDK. Inside, you'll find a boilerplate template directory with an HTML file and a JavaScript file. This is the perfect starting point.

The SDK also includes a simulator (wdc-simulator/index.html). This tool is invaluable for testing your connector's logic and schema without having to constantly open Tableau Desktop. To get started, navigate to your downloaded SDK folder in your terminal and run a simple local web server. If you have Node.js installed, you can do this with:

npx http-server

This command will make the SDK files, including the simulator and your new connector, available at an address like http://localhost:8080.

Step 2: Design the Connector's User Interface (connector.html)

The User Interface (UI) is what the user sees when they add a Web Data Connector in Tableau. For OBIEE, users will need to provide their credentials, the server URL, and the logical SQL query they want to run.

Open the connector.html file and create a simple form to collect this information. This HTML file will also need to include references to the Tableau WDC library JavaScript file and your own connector script.

<!DOCTYPE html>
<html>
<head>
    <title>OBIEE Connector</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://connectors.tableau.com/libs/wdc/2.3.latest/wdc-2.3.latest.js"></script>
    <!-- Your custom JS file -->
    <script src="connector.js"></script>
</head>
<body>
    <h1>Connect to OBIEE</h1>
    <form>
        <label for="obiee-url">OBIEE Analytics URL:</label><br>
        <input type="text" id="obiee-url" value="http://your-obiee-server/analytics-ws/saw.dll"><br>
        
        <label for="username">Username:</label><br>
        <input type="text" id="username"><br>
        
        <label for="password">Password:</label><br>
        <input type="password" id="password"><br>
        
        <label for="logical-sql">Logical SQL Query:</label><br>
        <textarea id="logical-sql" rows="5" cols="50">SET VARIABLE QUERY_SRC_CD='Report', SELECT "Time"."Fiscal Year" saw_0, "Products"."Brand" saw_1, "Base Facts"."Revenue" saw_2 FROM "Sample Sales Lite" ORDER BY saw_0, saw_1</textarea><br>
    </form>
    <button id="getDataBtn">Get OBIEE Data</button>
</body>
</html>

Step 3: Write the Connector Logic (connector.js)

This is where the magic happens. The JavaScript file will connect to OBIEE, fetch the data, define the data structure for Tableau, and then pass the actual data rows.

Phase 1: Initialize the Connector

(function() {
    // Create the connector object
    var myConnector = tableau.makeConnector(),

    // Define the schema
    myConnector.getSchema = function(schemaCallback) {
        // ... We will fill this in later ...
    },

    // Download the data
    myConnector.getData = function(table, doneCallback) {
        // ... And this too ...
    },

    tableau.registerConnector(myConnector),

    // Event listener for the button
    $(document).ready(function() {
        $("#getDataBtn").click(function() {
            var connData = {
                url: $("#obiee-url").val().trim(),
                username: $("#username").val().trim(),
                password: $("#password").val().trim(),
                sql: $("#logical-sql").val().trim()
            },
            tableau.connectionData = JSON.stringify(connData),
            tableau.connectionName = "OBIEE Report Data",
            tableau.submit(),
        }),
    }),
})(),

Phase 2: Fetch Data from OBIEE using a SOAP Request

myConnector.getData = function(table, doneCallback) {
    let connData = JSON.parse(tableau.connectionData),
    let tableData = [],

    // Construct the SOAP message for the Logical SQL Query
    const soapMessage = `
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v12="urn://oracle.bi.webservices/v12">
       <soapenv:Header/>
       <soapenv:Body>
          <v12:executeSQLQuery>
             <v12:sql>${connData.sql}</v12:sql>
             <v12:outputFormat>SAWRowsetData</v12:outputFormat>
             <v12:executionOptions/>
             <v12:sessionID>???</v12:sessionID> <!-- You need to log in first and get a session ID! -->
          </v12:executeSQLQuery>
       </soapenv:Body>
    </soapenv:Envelope>`,

    // Note: In real implementation, you need to authenticate first to get sessionID

    fetch(connData.url, {
        method: 'POST',
        headers: {
            'Content-Type': 'text/xml,charset=UTF-8',
            'SOAPAction': 'executeSQLQuery'
        },
        body: soapMessage
    })
    .then(response => response.text())
    .then(str => {
        let parsedData = {
            columnHeaders: ["Fiscal Year", "Brand", "Revenue"],
            rows: [
                { "Fiscal Year": "2022", "Brand": "MyBrand", "Revenue": 150000 },
                { "Fiscal Year": "2023", "Brand": "MyBrand", "Revenue": 250000 }
            ]
        },

        if (parsedData.rows.length > 0) {
            for (var i=0, i < parsedData.rows.length, i++) {
                tableData.push({
                    "Fiscal Year": parsedData.rows[i]["Fiscal Year"],
                    "Brand": parsedData.rows[i]["Brand"],
                    "Revenue": parsedData.rows[i]["Revenue"]
                }),
            }
        }
        table.appendRows(tableData),
        doneCallback(),
    })
    .catch(error => {
        console.error("Error fetching data from OBIEE:", error),
        tableau.abortWithError("Failed to fetch data from OBIEE."),
    }),
},

Phase 3 and 4: Define the Schema and Append Data

myConnector.getSchema = function(schemaCallback) {
    const cols = [
        { id: "Fiscal_Year", alias: "Fiscal Year", dataType: tableau.dataTypeEnum.string },
        { id: "Brand", alias: "Brand", dataType: tableau.dataTypeEnum.string },
        { id: "Revenue", alias: "Revenue", dataType: tableau.dataTypeEnum.float }
    ],

    const tableSchema = {
        id: "OBIEEReport",
        alias: "OBIEE Report",
        columns: cols
    },

    schemaCallback([tableSchema]),
},

Testing and Deployment

Use the WDC simulator to test your connector. Enter all the details in its UI, click the button, and you should:

  • Click "Fetch schema": You should see a table schema defined by your connector.
  • Click "Fetch Data": Your mock data should appear in the simulator.

Once it works in the simulator, open Tableau Desktop and choose "Web Data Connector." Paste your local host address (e.g., http://localhost:8080/connector/connector.html). If all goes well, your UI should appear, and you can pull your OBIEE data into Tableau!

Best Practices and Considerations

The above example is a starting point, but for a robust connector, consider the following:

  • Performance Optimization: Large result sets can be slow to fetch. Always filter data in your logical SQL (where possible) and only select the columns you need.
  • Error Handling: Implement clear messages for users when their input data is incorrect or when the OBIEE server responds with an error.
  • Security: Passing credentials as plain text is not ideal for production use. Consider implementing more secure authentication methods or use a backend proxy that handles authentication securely.
  • Scalability: Both OBIEE and Tableau servers have API rate limits. Ensure your connector is not making too many unnecessary calls, especially if extracts or refreshes are scheduled.

Final Thoughts

Building a custom Tableau Web Data Connector is an excellent way to unlock the full potential of your OBIEE data with Tableau’s interactive visualizations. While the process requires some web development skills, the end result is well worth the effort, giving you the best of both worlds.

While building custom connectors can be rewarding, understand that not everyone wants to handle the complexities of APIs and maintenance. For those who prefer pre-built solutions, consider using Graphed to simplify the entire process by letting you connect your marketing and sales data sources, from Google Analytics to HubSpot to Salesforce, and build live dashboards in plain English instead of writing code. We automate the manual reporting workflows so you can focus on actually using our tool to make smarter decisions, faster.

Related Articles

How to Connect Facebook to Google Data Studio: The Complete Guide for 2026

Connecting Facebook Ads to Google Data Studio (now called Looker Studio) has become essential for digital marketers who want to create comprehensive, visually appealing reports that go beyond the basic analytics provided by Facebook's native Ads Manager. If you're struggling with fragmented reporting across multiple platforms or spending too much time manually exporting data, this guide will show you exactly how to streamline your Facebook advertising analytics.

Appsflyer vs Mixpanel​: Complete 2026 Comparison Guide

The difference between AppsFlyer and Mixpanel isn't just about features—it's about understanding two fundamentally different approaches to data that can make or break your growth strategy. One tracks how users find you, the other reveals what they do once they arrive. Most companies need insights from both worlds, but knowing where to start can save you months of implementation headaches and thousands in wasted budget.