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:httpRequest  requestURL="http://localhost:8188/xpe/tutorial/tut1/echo"  h:timestamp="1141626523125"  pipeContext="/tutorial/tut1/echo"  path="/tutorial/tut1/echo"  pathParent="/tutorial/tut1/"  node="echo"  contextPath="/xpe"  uri="/xpe/tutorial/tut1/echo"  sessionId="48f47fbee12a08c1"  method="GET"  xmlns:h="http://www.xml.org/pipe/HTTP" >
   <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:

<register  uri="tut1/echo"  xmlns="http://www.xml.org/xml/pipe" />

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:

<?xml version="1.0">
<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:

<?xml version="1.0">
<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:

  1. extract the username and password parameters;
  2. compare them against some predefined values;
  3. 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:

<?xml version="1.0">
<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:

  1. 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.
  2. 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.

<?xml version="1.0">
<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:

<result  status="success" />

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:

<result  status="error" >
   <error>
      Username not found or password is invalid.
   </error>
</result>
<result  status="error" >
   <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.