TIBCO Spotfire Community

Welcome to TIBCO Spotfire Community Sign in | Join | Help

Making Web Requests in Spotfire Extensions

This article targets: TIBCO Spotfire 2.0 and forward

 

Introduction

If you have ever written a piece of .NET code that deals with network communication, I bet that you recognize the following snippet. You may even have written something similar yourself. Although the code works fine in your regular .NET applications, this article will highlight the dangers of it when run in the context of TIBCO Spotfire extensions.

HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://stn.spotfire.com");
HttpWebResponse response = (HttpWebResponse) request.GetResponseStream();

 

Explaining the WebRequest Class

First, let me explain what the lines of code in the snippet above really do. The method WebRequest.Create(…) is a factory method for subclasses to WebRequest. Which class you obtain an instance of when you call the method, depends on the URI you pass to it. For instance, A URI that starts with http:// will result in an object of type HttpWebRequest whereas ftp:// will give you an instance of class FtpWebRequest. What Microsoft doesn’t normally tell you, is that this framework is extendible. This allows anyone to plug in code to handle new protocols beside HTTP and FTP or, better yet, plug out existing code and replace it with new (e.g. to provide a new implementations for HTTP web requests).

 

The Spotfire HTTP Client

As of version 2.0, TIBCO Spotfire bundles its own HTTP client for server communications. The new client is based on the same code as Internet Explorer, which means that:

  • its prerequisites are built into the operating system,
  • it is built on top of a component that is well tested,
  • it is easy to configure (e.g. proxy server settings, HTTPS certificates, cookie handling, etc.),
  • and last, but definitely not least, it is very fault tolerant (e.g. for slow or shaky network connections).

All in all the HTTP client has much better quality than the one built into the .NET framework.

The Spotfire HTTP client is injected into the .NET framework using the approach explained in the previous section. This means that using it is completely transparent. Whenever a call is made to WebRequest.Create(…) with a HTTP or HTTPS URL, as opposed to creating an instance of the standard HttpWebRequest .NET class, the Spotfire web request implementation is created. Of course, a consequence of this is that all code that expects the Create method to return an instance of HttpWebRequest (by casting to it) will fail with a ClassCastException. This is a big problem since all of Microsoft’s code examples revolving around HTTP communication advocate the cast.

 

How to Post Data

So, assume we are writing a Spotfire extension that needs to make calls to an external web service to retrieve or post some data. How would you go about and do this the right way?
Here is a code snippet that illustrates a Tool doing an HTTP POST to a web server.

public class CommunicationsTool : CustomTool<AnalysisApplication>
{
    public CommunicationsTool() : base("Search Yahoo")
    {
        // Empty
    }

    protected override void ExecuteCore(AnalysisApplication context)
    {
        string query = "p=spotfire";

        WebRequest request = WebRequest.Create("http://search.yahoo.com/search");
        request.Method = "POST";
        using (Stream s = request.GetRequestStream())
        {
            byte[] data = Encoding.UTF8.GetBytes(query);
            s.Write(data, 0, data.Length);
        }
        // NOTE: We don’t have to set the ContentLength property on the
        // request. That is automatically calculated by the client. In fact,
        // attempting to set it will throw an exception.

        WebResponse response = request.GetResponse();
        using (StreamReader r = new StreamReader(response.GetResponseStream()))
        {
            Trace.WriteLine(r.ReadToEnd());
        }
        
    }
}


Using WebClient

Here a simple rewrite of the ExecuteCore method that uses the .NET WebClient to download a file. As the WebClient is written on top of the WebRequest class, it too will use the Spotfire HTTP client.

protected override void ExecuteCore(AnalysisApplication context)
{
    WebClient c = new WebClient();
    c.DownloadFile("http://stn.spotfire.com/stn/Images/first.png", "c:\\first.png");
}

 

Limitations

In its current implementation, the Spotfire HTTP client has one minor limitation that is good to be aware of, namely that it does not support asynchronous operations. That is, you are not allowed to use any of the Begin… and End… methods (e.g. BeginGetResponse) that the WebRequest base class defines. In practice this is not that big of a deal, since you always can use the .NET ThreadPool or a Thread to spin off the communication in a parallel thread and hence avoid hanging the main thread of your application while you wait for the response to get back.

 

Conclusions

To conclude, always remember that whenever you attempt to communicate over HTTP within TIBCO Spotfire, you will be doing it using a much more stable HTTP client than what is provided out-of-the-box in .NET.
Also, I hope I have given you a good example of why hard casting of types always is a bad idea.

Comments
 

Sai Boyedapu said:

By using the above technique (extension invoking a webserive) can the data obtained be used with-in Spotfire Client and WebPlayer to fuel a visualization?

January 27, 2009 9:27 AM
 

Ehsan Yazdani said:

Reading data from a web service is not really related to how to visualize data in Spotfire Professional or the Web Player. There is an example in the Spotfire SDK that shows how to read data from an HTTP data source. The principles in that article can be applied to a Web Service as well. And there are articles on the Spotfire Technology Network that explain how to create visualizations for both Spotfire Pro and the Web Player.

January 27, 2009 10:45 AM
 

Sai Boyedapu said:

Normally for creating reports in Spotfire Professional one has to Load Data (from a DB, file, Information Link etc), Add Data (Calculated Colums etc) and then design the Visualization Layout including the configuration of visualization (bar chart, pie chart etc).

If a Spofire extension is created to read from a HTTP data source, I am interested in understanding if the usage of this extension, will be treated as the Load Data activity within the Spotfire Client as described above?

I am not looking at creating any custom visualizations.

Thanks for your reply.

January 27, 2009 8:53 PM
 

Daniel Vulcan said:

Yes, all custom data sources are equal members to the other data sources that is shipped with the product and visible in menus and dialogs etc. In fact our own data sources is implemented using the same extension point.

January 29, 2009 8:49 AM

About Ehsan Yazdani

Ehsan Yazdani is a developer with the TIBCO Spotfire and the TIBCO Spotfire Analytics Server Framework teams. His fields of expertise are network communication, web services, and framework extensibility.