|
|
Porting WBI Plugins from 4.1 to 4.3
The WBI APIs have been updated as we have moved from WBI Development Kit for Java
version 4.1 to version 4.3. (Version 4.2 was an internal-only release). We
try to minimize changes to the API so that our users can avoid changing their
plugins, but some improvements are necessary for (1) uniformity, simplicity,
and ease of use, (2) infrastructure testing, and (3) abstraction of pluggable
classes into interfaces.
This document explains the changes to the WBI API from version 4.1 to 4.3 and
illustrates the necessary changes in the Demo
Plugin to port it to the WBI Development Kit for Java 4.3.
| WBI API Change Summary from 4.1 to 4.3 |
| Class | Change |
| FetchUrl |
- A RequestEvent object must be passed as the
first parameter of all fetch(...) calls. For MEGs, simply use the RequestEvent
that was passed in with the handleRequest(...) method.
- The fetch(...) method returns a ServiceResult object
that can be used to access the resulting RequestInfo
(which can be cast to a DocumentInfo for HTTP requests)
and the MegInputStream that contains the resulting data.
|
| HttpResponse |
- Some methods have been renamed for better naming consistency. The original
methods are all there, but have been deprecated.
|
| Packaging |
- The WBI classes have been moved into different packages with a simpler
and more logical structure. A major improvement of the current packaging
scheme is that a number of system-level classes and methods have been
reduced to package scope so that we can avoid having too many public classes
and methods that simply confuse things.
- The import packages that most WBI programmers will need to use are:
- com.ibm.wbi.*;
- com.ibm.wbi.protocol.http.*;
- com.ibm.wbi.protocol.http.beans.*;
- com.ibm.wbi.util.*;
- com.ibm.pvccommon.util.* (for Databases)
|
| RequestEvent |
- the
getRead() and getWrite() methods have been
deprecated, preferring getMegInputStream() and
getMegOutputStream(). This change removes
the confusion over character vs. byte I/O.
|
| Plugin |
- initialize(String) has been replaced with initialize(). The String was always
empty. The original method still works, but was deprecated.
|
| MEG Conditions |
- The rule syntax has been improved to have a more Java/C-like appearance.
The basic form is
field = value rather than the less-intuitive
field value. Arbitrary levels of parentheses can be used.
For more information, see the documentation for Meg.setCondition(java.lang.String).
- Case sensitivity has changed. Use '=' for a case-sensitive comparison, e.g.
to separate
path=/foo from path=/Foo. Use '~'
to ignore case, e.g. path~/foo will match /foo or
/Foo or /FoO. Also beware that certain browser input
is converted to lower-case before processing. For example, the server name part
of the URL is converted to lower case so a browser request for http://MyServer/
will be seen internally as http://myserver. A condition of
host=MyServer will fail but host=myserver or
host~MyServer will match.
|
| Database |
- moved from com.ibm.wbi.util package to com.ibm.pvccommon.util package
- MissingRequiredResourceException must be caught when accessing Databases. This
exception is not thrown under basic WBI configurations, but may result when using
external databases to store WBI configuration information.
- Database.createSection(...) has a new required second
parameter. Use "" (an emptyString).
|
Example -- Porting the Demo Plugin
As an example of porting a simple plugin, here are the changes that were made
to the Demo Plugin.
Imports
The WBI packages have been rearranged to group classes more consistently and to
reduce the total number of packages.
Version 4.1
import com.ibm.wbi.io.MegInputStream;
import com.ibm.wbi.io.MegOutputStream;
import com.ibm.wbi.plugin.*;
import com.ibm.wbi.http.HttpHeader;
import com.ibm.wbi.http.FetchUrl;
import com.ibm.wbi.http.request.DocumentInfo;
import com.ibm.wbi.http.plugin.*;
import com.ibm.wbi.http.beans.AddPreambleEditor;
import com.ibm.wbi.http.beans.PageMovedGenerator;
import com.ibm.wbi.http.beans.StaticHtmlGenerator;
import com.ibm.wbi.http.beans.HtmlTemplateGenerator;
|
Version 4.3
import com.ibm.wbi.*;
import com.ibm.wbi.protocol.http.*;
import com.ibm.wbi.protocol.http.beans.*;
|
Plugin initialize(...)
The Plugin.initialize() no longer takes a parameter. Information
needed by plugin initialization can be found with the Plugin.getSystemContext()
method.
Version 4.1
public class demo extends HttpPlugin {
...
public void initialize(String initData) {
...
}
...
}
|
Version 4.3
public class demo extends HttpPlugin {
...
public void initialize() {
...
}
...
}
|
MEG Conditions
The conditions that determine when MEGs are involved in a transaction have been
made to look more like normal Java/C syntax. There are also a few values
such as %null% that have special meaning. There are both '='
(case sensitive) and '~' (non-case sensitive) operators.
Version 4.1
public void initialize() {
// A generator to say "Hello",
// either as a server at the path: "/" or
// as a proxy at the URL: "//_demo/"
StaticHtmlGenerator shg = new StaticHtmlGenerator();
shg.setName( "helloWorld" );
shg.setCondition( "(host null | host _demo) &
path /" );
shg.setPriority( 10 );
shg.setStaticHtml( html );
addMeg( shg );
// now one for "/whoami"
Generator whog = new WhoAmITheOldWay();
whog.setName( "whoAmI" );
whog.setCondition( "(host null | host _demo) &
path /whoami" );
whog.setPriority( 10 );
addMeg( whog );
...
}
|
Version 4.3
public void initialize() {
// A generator to say "Hello",
//either as a server at the path: "/" or
// as a proxy at the URL: "//_demo/"
StaticHtmlGenerator shg = new StaticHtmlGenerator();
shg.setName( "helloWorld" );
shg.setCondition( "(host=%null% | host~_demo) &
path=/" );
shg.setPriority( 10 );
shg.setStaticHtml( html );
addMeg( shg );
// now one for "/whoami"
Generator whog = new WhoAmITheOldWay();
whog.setName( "whoAmI" );
whog.setCondition( "(host=%null% | host~_demo) &
path=/whoami" );
whog.setPriority( 10 );
addMeg( whog );
...
}
|
Accessing the MegInput/OutputStreams in a MEG
The getRead() and getWrite() methods have been
deprecated, preferring getMegInputStream() and
getMegOutputStream(). This change removes
the confusion over character vs. byte I/O.
Version 4.1
public void handleRequest( RequestEvent e )
throws RequestRejectedException, IOException {
...
// get the input stream
MegInputStream is = e.getRead();
...
// the stream we write to
MegOutputStream os = e.getWrite();
...
}
|
Version 4.3
public void handleRequest( RequestEvent e )
throws RequestRejectedException, IOException {
...
// get the input stream
MegInputStream is = e.getMegInputStream();
...
// the stream we write to
MegOutputStream os = e.getMegOutputStream();
...
}
|
Using FetchUrl
FetchUrl is a utility class for accessing web resources either
directly or through WBI's MEG chain. It has been changed in two ways:
- A
RequestEvent is needed to launch the fetch operation. Normally the MEG
that needs to fetch a web resource just uses the same RequestEvent object
that was passed to the MEG's handleRequest(...) method.
- The
fetch(...) method now returns a ServiceResult
object that allows the caller to access the resulting RequestInfo
and MegInputStream, which contain that result of the fetch operation.
Version 4.1
public void handleRequest( RequestEvent e )
throws RequestRejectedException, IOException {
String getme = "http://www.yahoo.com/";
MegInputStream mis;
if (++count % 2 == 0) {
mis = FetchUrl.fetch( getme );
} else {
mis = FetchUrl.fetchThroughProxy( e, getme );
}
// retrieve the response header from the
// fetched content and make
// it our own response header
// note: mis.getRequestInfo() is deprecated
DocumentInfo di = (DocumentInfo) e.getRequestInfo();
DocumentInfo mdi = (DocumentInfo) mis.getRequestInfo();
di.setResponseHeader( mdi.getResponseHeader() );
// copy the fetched content to our output stream
e.getWrite().write( mis );
// all done!
e.getWrite().close();
}
|
Version 4.3
public void handleRequest( RequestEvent e )
throws RequestRejectedException, IOException {
String getme = "http://www.yahoo.com/";
ServiceResult sr = null;
if (++count % 2 == 0) {
sr = FetchUrl.fetch( e, getme );
} else {
sr = FetchUrl.fetchThroughProxy( e, getme );
}
// retrieve the response header from the
// fetched content and make
// it our own response header
// note: mis.getRequestInfo() is deprecated
DocumentInfo di = (DocumentInfo) e.getRequestInfo();
DocumentInfo sdi = (DocumentInfo) sr.getRequestInfo();
di.setResponseHeader( sdi.getResponseHeader() );
// copy the fetched content to our output stream
e.getMegOutputStream().write( sr.getMegInputStream() );
// all done!
e.getMegOutputStream().close();
}
|
|