Showing posts with label SOAP. Show all posts
Showing posts with label SOAP. Show all posts

Sunday, August 3, 2008

ZK Version 3.0.7 released

The ZK front-end app to KnowledgeTree was developed using version 3.0.6. The newer version 3.0.7 was released on August 1 and I had the chance to install ZK from scratch and run the ZK front-end app successfully.

Here are the steps:

  • download zk-bin-3.0.7.zip from sourceforge.net
  • copy the MyApp directory (from the demo package) under the webapps directory of Apache Tomcat. Rename it to accordingly (I used zk307 in this example).
  • Create the WEB-INF/lib sub-directory. Place here all the jars found under the dist/lib directory of the zk-bin-3.0.7 package. Copy the jars under the ext and zkforge directories also but omit the directories - place all jars under WEB-INF/lib
  • Add the ktws.jar and the jars required by Apache Axis (see previous blog entry)

Fire up Tomcat and point your browser to http://localhost:8080/zk307/ktlogin.zul

There are over 9 new features and 22 bug fixes under this new release. Read more about the new ZK release here.

Saturday, August 2, 2008

ZK + SOAP + KnowledgeTree

Here's a working ZK app that performs a SOAP login to KnowledgeTree's web services.



I've uploaded the source code to a KnowledgeTree repository and can be downloaded using the KT-Gadget.

You need to download the following files:
  • ZK front-end app (ktlogin.zul)
  • ZK include script (ktlogin.zk)
You can download the Ajax spinner here or create your own.

My testbed:
  • Apache Tomcat Version 5.5.26
  • ZK 3.0.6
  • Windows XP Prof Service Pack 2
  • Mozilla Firefox 3.0

Sunday, July 20, 2008

Using KnowledgeTree SOAP Services from Java apps

I'm making a front-end to KnowledgeTree using the ZK Ajax framework so I eventually dipped my fingers into KT's web service integration from a Java app. My previous SOAP projects involved a Tcl client and a Google gadget using the javascript/php combo.

KnowledgeTree's wiki article on Web Service integration using Java has been most helpful. Since I'm doing my development work on Windows, I've adapted the procedures slightly. And since ZK uses the Beanshell interpreter to execute the Java code, I also modified the tester client application accordingly.

What's needed:

The proxy classes were generated using the WSDL2Java utility provided by the Apache Axis. I'm providing the packaged ktws.jar available for download here. To generate the proxy classes yourself, you would need the Java Compiler and not just the JRE. Here's the batch file to generate the jar package.

set CP=axis-1_4/lib/axis.jar;axis-1_4/lib/commons-discovery-0.2.jar
set CP=%CP%;axis-1_4/lib/commons-logging-1.0.4.jar;axis-1_4/lib/jaxrpc.jar
set CP=%CP%;axis-1_4/lib/log4j-1.2.8.jar;axis-1_4/lib/saaj.jar
set CP=%CP%;axis-1_4/lib/wsdl4j-1.5.1.jar
java -cp %CP% org.apache.axis.wsdl.WSDL2Java -c T1 -p com.pipoltek.ktws http://docs.pipoltek.com/ktwebservice/webservice.php?wsdl
"%JAVA_HOME%\bin\javac" -d . -classpath %CP% com/pipoltek/ktws/*.java
"%JAVA_HOME%\bin\jar" cvf ktws.jar .\com\pipoltek\ktws\*.class

Here's the Beanshell script to execute a login via SOAP.

/*
filename: ktsoaptest.bsh
to run, type from the command-line:
java -cp bsh-2.0b4.jar bsh.Interpreter ktsoaptest.bsh
*/

// add axis classes
addClassPath ("./axis-1_4/lib/axis.jar");
addClassPath ("./axis-1_4/lib/axis-ant.jar");
addClassPath ("./axis-1_4/lib/jaxrpc.jar");
addClassPath ("./axis-1_4/lib/commons-logging-1.0.4.jar");
addClassPath ("./axis-1_4/lib/commons-discovery-0.2.jar");
addClassPath ("./axis-1_4/lib/log4j-1.2.8.jar");
addClassPath ("./axis-1_4/lib/wsdl4j-1.5.1.jar");
addClassPath ("./axis-1_4/lib/saaj.jar");

// knowledgetree proxy classes
addClassPath ("./ktws.jar");

// others
addClassPath ("./lib/activation.jar");
addClassPath ("./lib/mail.jar");

import com.pipoltek.ktws.KnowledgeTreeBindingStub;
import com.pipoltek.ktws.Kt_response;
import com.pipoltek.ktws.Kt_folder_contents;
import com.pipoltek.ktws.Kt_workflow_transitions_response;
import org.apache.axis.client.Service;
import java.net.URL;
import com.pipoltek.ktws.Kt_folder_item;

URL url = new URL("http://kt352c.pipoltek.com/ktwebservice/webservice.php");

KnowledgeTreeBindingStub stub = new KnowledgeTreeBindingStub(url, new Service());

System.out.println("Logging into KnowledgeTree");
Kt_response response = stub.login("rexjun","cabanilla","127.0.0.1");

int status_code=response.getStatus_code();
String session;
if (status_code == 0) {
session = response.getMessage();
System.out.println("Session: " + session);
} else {
System.out.println("Status Code: " + status_code);
System.out.println("Session: " + response.getMessage());
return;
}

I'll be using this piece of code to invoke SOAP services from my ZK app. More on this later..

Friday, June 20, 2008

KnowledgeTree document download via Google Gadget

This is an installment feature for the KT-Gadget, a widget for KnowledgeTree, an open-source document management system.

As mentioned in the previous post, I employed an application proxy to act as a bridge between a Google Gadget and KnowledgeTree's SOAP services. Originally, the application proxy responses were formatted in XML. Moving forward, I decided to adopt the JSON format instead of XML owing to simpler methods in handling JSON feeds from both PHP and (of course) Javascript worlds.

The application proxy's SOAP client is based on PHP and converting an associative array of response items to JSON format is implemented simply by using PHP's json_encode function. At the gadget side, the requests for remote data are invoked using Google's _IG_FetchContent function. Using Javascript's eval() function, the returned JSON text response is converted to an object whose members can be easily accessed using dot or subscript operators.

Here are the details.. To download a document, KT-Gadget sends a request to the helper application by invoking the url:

http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=download_document&sid=rsop4e364ptf4slkp2a2vtvb96&did=4

The JSON response by the application proxy is of the form:
{"response":{"status_code":0,"message":"http:\/\/docs.pipoltek.com\/ktwebservice\/download.php?code=d2db2c0868ab0c9cd053fe2e43ab9926d1bcf94c&d=4&u=6a0j9qqpqc11de6nju6o0ej5o7"}}

The relevant block of KT-Gadget code is reproduced hereunder:

var url = "http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=" + sessionID__MODULE_ID__ + "&fid=6";
_IG_FetchContent(url, function (jsonFeed) {
var jsonData = eval('(' + jsonFeed + ')');
if (jsonData.response.status_code != 0) {
alert ('Error in retrieving document!');
} else{
dd_link = jsonData.response.message;
_gel("ktg-lnk").innerHTML = '<a href="' + dd_link + '">@';
}
})

Once the application proxy has responded, the JSON text response (jsonFeed) is converted to an object (jsonData) using the eval() function. The response contains the download URL the value of which can be referenced as jsonData.response.message.

Where did the Session-ID (sid) and Document-ID (did) used as URL parameters come from? The Session-ID is assigned during login and the Document-ID, together with the rest of the document details, is returned by a call to get_folder_contents.

Here's the login invocation:
http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=login&uid=rexjun&pwd=cabanilla

The invocation to get_folder_contents:
http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=0j8jkhjn55t7r3b0rshbcchpn1&fid=6

If you get a "Session is invalid" error, it's because the link is using an ID of an expired session. Change the URL parameter (sid) to a fresh Session-ID returned by the login call to get better results.

You may try out KT-Gadget by adding it to your iGoogle page or view the gadget source code here.

Thursday, June 12, 2008

Accessing Soap Services from Google Gadgets

The earlier gadget projects I developed have utilized third-party web services from a variety of sources:

  • Google Maps for geographic data
  • Google Docs spreadsheet as XML datasource
  • IP-Geolocation (IP address->Country) service from HostIP.Info
  • User profile and gaming statistics as XML feeds from Xfire.
Given the constraints of a space-restricted, remotely-hosted, javascript-only application, gadgets primarily rely on web services to provide richer data content without the attendant complexity. However, javascript is beset by cross-domain restrictions that even impact xmlHttpRequest, the very underpinnings of Ajax. Since Google gadgets are javascript apps, the same-origin security policy prevents it from making requests outside the domain it is running on.

Although Google addressed this problem by providing the _IG_FetchXMLContent function, it lacks support for https, SOAP and POST. It looks like the newer gadget.io.makeRequest function is intended to address these deficiencies. However, the availability of the gadget.io.* functions in Google's production servers is yet forthcoming.

I decided not to hold my breath..

KT-Gadget is a widget front-end to KnowledgeTree - an open-source document management system. To access KnowledgeTree's SOAP services, I had to deploy another application to receive the requests from Google's _IG_FetchXMLContent calls, make the corresponding SOAP requests, and generate the appropriate XML output. Two basic functions are implemented: login and get_folder_contents. The functions are based on PHP, the same language that was used to develop KnowlegeTree.

After pushing the login button, the gadget will indicate the progress of the subsequent operations:
  • Logging in
  • Fetching Documents
  • Sorting Documents
In its current state, the gadget is useful as a watcher of some sort of inbox for workflow-enabled documents like incoming faxes needing disposition or requisitions requiring approval. Sit around and watch your work pile up...

I plan to implement two more functions: download_document and perform_document_workflow_transition. We don't want work to pile up, do we? Other nice-to-have features: watch all accessible folders and sub-folders; show number of documents per folder; folder and document colors based on certain thresholds like document count, age, metadata contents (priority, etc); automatic refresh.

But don't hold your breath...