Tutorial 2 - Passing parameters to Pipelines
Description
This tutorial will show you how to extract and manipulate request parameters from a HTTP request.
We will be creating the following XPE pipeline:
Our first pipeline just echoed back a HTTP GET request submitted from a browser as an XML document in a HTTP Response. This tutorial will now extract a username and password passed as request parameters and compare them against some hardcoded values returning an indication of whether the username/password is valid or invalid. (A later tutorial (SQL) will compare the passed parameters agains those in a database)
Before proceeding enter the HTTP request from the previous tutorial to make sure XPE is listening and working correctly by navigating to the following URL:
http://localhost:8188/xpe/tutorial/tut1/echo?username=fred&password=flintstone
You should see something similar to:
<h:requestor host="127.0.0.1" />
<h:heads>
<h:head name="host" value="localhost:8188" />
<h:head name="user-agent" value="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1" />
<h:head name="accept" value="text/xml,application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" />
<h:head name="accept-language" value="en-us,en;q=0.5" />
<h:head name="accept-encoding" value="gzip,deflate" />
<h:head name="accept-charset" value="ISO-8859-1,utf-8;q=0.7,*;q=0.7" />
<h:head name="keep-alive" value="300" />
<h:head name="connection" value="keep-alive" />
<h:head name="cookie" value="xpeSessionId=48f47fbee12a08c1" />
</h:heads>
<h:cookies>
<h:cookie name="xpeSessionId" value="48f47fbee12a08c1" maxAge="-1" secure="false" version="0" />
</h:cookies>
<h:params>
<h:param name="password" value="flintstone" />
<h:param name="username" value="fred" />
</h:params>
</h:httpRequest>
Notice how the username and password parameters are represented in the XML stream under the params elements. Lets see how we can access these parameters from an XPE pipeline.
Step 1 - Register (Define) a new XPE Service
Recall that registering a service is accomplished by adding a line similar to:
in the file xar/META-INF/xpipedef.xml. We will now register a new service called authenticate. Edit the xpipedef.xml file so that it looks like:
<xpipeDef xmlns="http://www.xml.org/xml/pipe" >
<register uri="tut1/echo" >
<xpipe>
<xnode type="http://www.xml.org/pipe/xpe/source/http" />
<xsink type="http://www.xml.org/pipe/xpe/sink/http" >
<property name="method" value="xml" />
</xsink>
</xpipe>
</register>
<register uri="tut2/authenticate" >
<xpipe>
<xnode type="http://www.xml.org/pipe/xpe/source/http" />
<xsink type="http://www.xml.org/pipe/xpe/sink/http" >
<property name="method" value="xml" />
</xsink>
</xpipe>
</register>
</xpipeDef>
This will define our new service. At present it will just echo our request like our initial service. But we will change that soon
Step 2 - Mapping a URl to a Service
Next we need to define a url mapping that will allow outside users to access this service. Recall that this is accomplised by adding the mapping to the file xar/META-INF/urlPattern.xml:
<urlPattern xmlns="http://www.xml.org/xml/pipe" >
<method name="GET" >
<map pattern="/tutorial/tut1/echo" xpipe="http://www.xml.org/pipe/xpe/tutorial/tut1/echo" />
<map pattern="/tutorial/tut2/authenticate" xpipe="http://www.xml.org/pipe/xpe/tutorial/tut2/authenticate" />
</method>
</urlPattern>
Now if you build and deploy the application you should be able to use the url:
http://localhost:8188/xpe/tutorial/tut2/authenticate?username=fred&password=flintstone
At this stage it still just acts as an echo pipeline like tutorial 1. But not for long...
Step 3 - Defining the XML Pipe processing
This is where we will begin changing the pipe definition to begin doing some business processing. What we wish to do is:
- extract the username and password parameters;
- compare them against some predefined values;
- return an indication of whether the two sets match.
We will do this by adding an XSLT transformation to the pipe. Edit the pipe definition in the xpipedef.xml so that it looks like:
<xpipeDef xmlns="http://www.xml.org/xml/pipe" >
<register uri="xslt/authenticate" >
<xslt href="ROOT/tutorial/xslt/authenticate.xsl" />
</register>
<register uri="tut1/echo" >
<xpipe>
<xnode type="http://www.xml.org/pipe/xpe/source/http" />
<xsink type="http://www.xml.org/pipe/xpe/sink/http" >
<property name="method" value="xml" />
</xsink>
</xpipe>
</register>
<register uri="tut2/authenticate" >
<xpipe>
<xnode type="http://www.xml.org/pipe/xpe/source/http" />
<xnode type="xslt/authenticate" />
<xsink type="http://www.xml.org/pipe/xpe/sink/http" >
<property name="method" value="xml" />
</xsink>
</xpipe>
</register>
</xpipeDef>
What we have done here is:
- Defined (Registered) a new node type uri - xslt/authenticate that references a file: ROOT/xslt/authenticate.xsl. This file is an XSL Transformation that will act on the XML SAX event stream emminating from the http source xnode.
- Changed the tut2/authenticate pipe to add a xnode filter referencing this transformation element after the source xnode and before the http sink.
Step 4 - Defining the transformation
We now need to write the XSL transformation that extracts the username/password parameters, compares them against our hardcoded ones, and produces our final result.
If you are familiar with XSLT and pipelines, you may wish to try your hand at this transformation. If so just create the file in the directory ROOT/tutorial/xslt and call it authenticate.xsl. In this way it will match the uri that we specified in the xpipedef.xml file.
If you are new to either XSL and/or XML pipes, you can copy the file from the worked solutions directory.
Lets take a quick look at the contents of the xslt transformation and see what is happening.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:http="http://www.xml.org/pipe/HTTP" >
<xsl:output method="xml" />
<xsl:template match="http:httpRequest" >
<xsl:choose>
<xsl:when test="//http:params/http:param[@name='password'] and //http:params/http:param[@name='username']" >
<xsl:variable name="username" >
<xsl:value-of select="//http:params/http:param[@name='username']/@value" />
</xsl:variable>
<xsl:variable name="password" >
<xsl:value-of select="//http:params/http:param[@name='password']/@value" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$password='flintstone' and $username='fred'" >
<result status="success" xmlns="" />
</xsl:when>
<xsl:otherwise>
<result status="error" xmlns="" >
<error>
Username not found or password is invalid.
</error>
</result>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<result status="error" xmlns="" >
<error>
username and password are required parameters.
</error>
</result>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Lets quickly analyse this stylesheet
First of all note that the stylesheet version is set to 2.0 to indicate that xsl 2.0 elements/functions are being used by the stylesheet. When using XPE you should always use version 2.0 as it is significantly more powerfull than version 1.0
The next point of interest is the match element that matches the http:httpRequest element of our XML stream. Within this match we look to see if a username and password parameter has been specified. If not an error condition is output. If a username and password has been provided, then a check is made to see if the username matches fred and the password matches flintstone. If they do then a successfull result is output otherwise an error condition is output.
Step 5 - Testing our pipeline
Now build and deploy the application. XPE should respond with a successfull deployment page. If no errors are reported, then the application has been successfully deployed.
You can test that the application has been deployed by trying to navigate to the url that identifies your new XPE service:
The XPE result should be similar to:
Now try issueing a GET using a wrong password or without specifying a password at all.
You should see the two different error conditions output:
<error>
Username not found or password is invalid.
</error>
</result>
<error>
username and password are required parameters.
</error>
</result>
Summary
This tutorial has illustrated how simple it is to extract request parameters from a HTTP GET request. The next tutorial will show how XPE interfaces to SQL database, extracting data and automaticaly generating XML from the SQL resultset that can be used within an XPE pipeline.
Any Problems?
If you have problems getting this tutorial to work look at the completed solution in the tutorials/solutions/tutorial2 directory It should have all files required to buld and run the tutorial.