Funky Town: Custom UI Extension

This post is part of the Funky Town series of articles, where we take ridiculous User Centric Design (UCD) requirements and put them into practice.

[Background]

I was commissioned to design a custom Integration framework for a client. As part of this framework, the client needed to have a test harness that allows:

1. The developer to generate a pre-populated SOAP request for any predefined Siebel Web Service, with run time data and authentication headers.

2. Allow the developer to send the request and see the SOAP response in real time in the UI

3. They should also be able to modify the SOAP request on the fly and re-submit the message

4. and all of the above for XML over MQ as well

The design needed to load a run time data into the request, but the test data itself was transient and did'nt need to be saved. The size of the payloads are always unknown, especially when dealing with binary encoded data, the response would be massive, so I needed a way of storing unlimited data on the UI.

The closest thing that resembled what i wanted is the Script Editor Applet (Business Service Script Editor Applet2) under Business Service - Administration. Its just an applet with a massive text area, however the field that it maps to has a physical limit.

The idea was to design a custom IE window that could load the request message based on some predefined integration settings, allow the user to modify the request through a text area field, submit it to the transport, read the response and display it on the custom UI window.

This article will focus on how to build a custom window and handle the two way communication between the custom client and Siebel server. Details around integration points in Siebel will be glossed over.

[Design]

This is what the finished product looks like.



1. The chain of events starts when the user clicks on a button called "Launch Harness" which invokes "TestIntegrationCall" to launch our custom window.

a) On WebApplet_PreInvokeMethod of "TestIntegrationCall", we call a process that Generates Request message

In code it would look like this

switch(MethodName){
case "TestIntegrationCall":
//Generate a sample request XML and store it in a Profile Attribute that can be access by the browser
TheApplication().SetProfileAttr("REQUEST_MSG",[Your Request Msg]);
break;
}


b) On Applet_InvokeMethod TestIntegrationCall, we create an IE Window with the following code

//Browser Declarations
var results;

//Applet_InvokeMethod

switch(name){
case "TestIntegrationCall":
results=window.open('','Test Harness','height=600,width=900,scrollbar=yes,resizeable=yes');
var sendButton = "<input type='button' value='Send Request' onclick='opener.sendServerRequest(this)' /><br />";
var requestXML = "<textarea id='request' name='request' rows='30' cols='50'>"+ theApplication().GetProfileAttr("REQUEST_MSG")+"</textarea>";
var responseXML = "<textarea id='response' name='response' rows='30' cols='50'>"+ theApplication().GetProfileAttr("RESPONSE_MSG")+"</textarea>";

var html = "<title>Test Harness</title>"+
"<body style='background-color:#bbbbbb'>"+info+"<table><tr><td>"+requestButton+requestXML+"</td>"+
"<td>"+responseButton+responseXML+"</td></tr></table><br />"+sendButton+"</body>";
results.document.write(html);
results.focus();
results.document.close();
theApplication().SetProfileAttr("REQUEST_MSG","");
theApplication().SetProfileAttr("RESPONSE_MSG","");
break;
}


2. Using the "requestXML" variable in the step above, the Request message is injected into the 1st text area as part of the IE window creation process.

3. Applet_PreInvokeMethod SendRequest
Do nothing.

4. Applet_InvokeMethod SendRequest
Invoke a browser function that will invoke a server method that will initiate the integration call

This is initiated, from the "Send Request" button on our new created UI, which was created in Step 1b.

var sendButton = "<input type='button' value='Send Request' onclick='opener.sendServerRequest(this)' /><br />";

When the user clicks on "Send Request", it will use the "opener" method to lookup the parent window, which is the Form Applet and call the
sendServerRequest
browser function which is defined on the Form Applet as so.

function sendServerRequest(win)
{
var requestXMLStr = win.document.getElementById("request").value;
theApplication().SetProfileAttr("REQUEST_MSG",requestXMLStr);
applet.InvokeMethod("SendRequest");
theApplication().SetProfileAttr("REQUEST_MSG","");
}

Notice that we pass in "this", which is the handle to our custom IE window, this lets us read the values from our custom window.
The first line grabs the XML request from our text area, and calls a server side event.

case "SendRequest":
//Get Request String from our custom IE window
//Convert to correct format and calls the interface

5. The above code will make the interface call and return the results back to our Form Applet, which will convert the Output to a string and store it in a ProfileAttribute which will be accessed by browser script to inject back into our custom IE window as shown in the next step.

6. Get the handle for the IE window, and inject the results into the 2nd text area

case "SendRequest":
var responseXMLStr = theApplication().GetProfileAttr("RESPONSE_MSG");
results.document.getElementById("response").value = responseXMLStr;
theApplication().SetProfileAttr("RESPONSE_MSG", "");
break;


Here are the sequence of events again

Open test harness

1. Browser PreInvoke TestIntegrationCall - Do nothing
2. Server PreInvoke TestIntegrationCall - Generate Request message and convert to string
3. Browser Invoke TestIntegrationCall - Construct IE window and Request message
4. Server Invoke TestIntegrationCall - Do nothing

Send request

1. Browser PreInvoke SendRequest - Do nothing
2. Server PreInvoke SendRequest - Call interface
3. Browser Invoke SendRequest - Injects the response into our Custom IE window
4. Server Invoke SendRequest - Do nothing

[Conclusion]

We have just designed a complex, yet highly unique and functional test harness to assist developers in their day to day jobs, however the concept of a custom UI window can be extended to any part of the application that requires features that are not available out of the box.

Lets look at our criteria again

1. Will it perform well?
N/A. It is a fit for purpose utility

2. Is it maintainable?
Yes, if the code is made production ready

3. Can it be upgraded?
Yes, as it does not use any undocumented methods

and

4. Is it sexy?
It is a no contest, it is like beauty and the beast.


0 comments:

Post a Comment

Comments are open to all, please make it constructive.