Introduction
HTTP is a stateless protocol, there is no innate mechanism to preserve context from one request to the next.
Web-applications are considerably simpler to develop with a stateful session holding
transient information that must persist during the lifetime of the application interaction.
Netscape developed Cookies as a mechanism to provide low-level stateful web-interaction . Cookies can be used
directly for client-side session data. J2EE Servlets abstract the Cookie mechanism entirely and provide
a Session object in which transient session objects can be stored. The servlet automatically sets a cookie on the browser
which holds a key which ensures session affinity for subsequent requests.
The NetKernel ext_session module provides a session management framework. Like the Servlet it abstracts the Cookie mechanism, but in
addition it may be used independently of HTTP and web-applications to provide general session resource management.
Sessions
NetKernel uses URIs to reference all resources. ext_session provides a managed session URI address space. Sessions and session
resources are simply URI addressable resources which can be used in processes just like any other resource.
A session has a URI of the form session:AB134534652AF56321545. The "session:" scheme indicates that this
URI will be handled by the session data accessor. The session data accessor holds all sessions and is responsible for creating
and managing sessions. The identifier part of session URI is a GUID which the session data accessor guarantees is unique.
Creating a session
A new session can be created by making a new resource request to the session data accessor. This can be achieved in DPML
by using the new accessor to issue a new request to the session: data accessor (equally it could be made directly with
a URRequest in a custom accessor) ...
<instr>
<type>new</type>
<operand>session:</operand>
<target>var:session</target>
</instr>
Here the operand is a session URI with no GUID part. The session data accessor creates a new session and returns the URI of the
session, which in this case is stored in the variable var:session.
Storing a session resource
It would not be practical to create a new session URI for every resource we might want to persist. To get round this the session URI is
actually the root of a session compound URI address space. We can store many resources in the same session but each one must be identified by
a individual key. A session resource belongs to a session and is identified by a compound URI of the form.
session:AB134534652AF56321545+key@myresource
The key@myresource is a compound URI argument identifying a session resource in the the session:AB134534652AF56321545
session.
Session resource URI's can be built by hand in a custom accessor. Alternatively the utility accessor buildSessionResourceURI
can construct a session resource compound URI from a session URI and a key identifier. Here's an example...
<instr>
<type>buildSessionResourceURI</type>
<operand>var:session</operand>
<operator>
<key>myresource</key>
</operator>
<target>var:mySessionResourceURI</target>
</instr>
This would store in the variable var:mySessionResourceURI the URI session:AB134534652AF56321545+key@myresource we saw above.
Using a session resource
Although the construction of a session and session resource URI may initially seem a little elaborate. The power of this approach is
clear when we come to using a session resource. In fact since a session resource URI is a reference to a URI resource just like any other
we can request and target the URI just like any other. A session resource URI has no special requirements for use. Here's an example which
stores a stupid XML fragment into the session Resource mySessionResourceURI we created a second ago...
<instr>
<type>copy</type>
<operand>
<hello>session data</hello>
</operand>
<target>curi:var:mySessionResourceURI</target>
</instr>
We can equally as easily retrieve a session resource...
<instr>
<type>copy</type>
<operand>curi:var:mySessionResourceURI</operand>
<target>this:response</target>
</instr>
Note we use the curi: prefix in a DPML process since the result of the buildSessionResourceURI is a canonical URI document. In a custom
accessor we would use the URI directly.
Deleting a session
Session resources use system resources and it is a good thing to delete them when they're no longer required. By default a session
resource will automatically expire if it is not used for 5 minutes. It can also be deleted at any time.
<instr>
<type>delete</type>
<operand>curi:var:mySessionResourceURI</operand>
</instr>
Here a single session resource is deleted. We could equally delete the whole session.
Summary
We have seen that a session provided by ext_session consists of URI addressable resources. A session resource URI can be used just like any
other to store and retrieve resources of any type. The session mechanism is transport independent and may be used to create email or
web-service session as easily as a web-site session. Below we'll discuss automatic session affinity with the HTTP transport.
Session Affinity
Above we have seen how ext_session provides URI based sessions. It is useful to automatically connect a request for a resource
in a URI address space with a session. ext_session provides the Session Mapper accessor that performs automatic session
creation and cookie based session affinity for zoned regions of a module's URI address space.
Below is a diagram of a module URI address space and the session URI address space managed by the session data accessor. A
session zone is a transparent layer over the the module address space.
All requests for resources which are in the session zone will
be automatically reconnected to their session. If the session does not exist a new session will be created for that request.
Module Configuration
Note: NetKernel v1.x.x users. In order to reduce the proliferation of internal URI schemes, the URI of the sessionmapper accessor
has been changed from sessionmapper: to active:sessionmapper, the URI to be mapped to a session must be escaped and passed
on the uri argument.
To update modules to the new sessionmapper URI change the old style rewrite rule...
<rule>
<match>(.*)</match>
<to>sessionmapper:$1</to>
</rule>
to the new rewrite rule shown below. No other changes have been made to the sessionmapper.
A module that wants to use automatic session mapping can pass all requests to the session mapper with a simple URI rewrite rule in the
internal module.xml definition.
<rule>
<match>(.*)</match>
<to>active:sessionmapper+uri@$e1</to>
</rule>
The session mapper will now receive all requests and attempt to match the request URI against known session zones (note in the rule, $e1 is important and
indicates that the URI to be mapped to a session is escaped). The session mapper zones are
configured in the ffcpl:/SessionPolicy.xml document in the root of the session mapped module. The session policy document defines
one or more session mapped zones. Below is a single zone which creates a session zone for all requests in the .*/mypath/.*
URI address space.
<SessionPolicy>
<zone>
<match>.*/mypath/.*</match>
<token>cookie</token>
<path>/mypath/</path>
<type>
<simple />
</type>
</zone>
<meta>
<id>SomeIdentifier</id>
<max-sessions>10</max-sessions>
<max-duration>60000</max-duration>
<min-duration>30000</min-duration>
</meta>
</SessionPolicy>
-
match is a regex on the internal URI of the request. Note: the match will be on the URI request including any rewrites
the request may have gone through before reaching the Session Mapper.
- token is the type of the external session token to use. Currently only cookie is supported.
- path is the path that will be set on the cookie. This should match the external public address space of the web
request that will be handled by this module. Usually it is sufficient to make this path the same as the match path.
- type contains settings for the session type to create. Currently only simple is supported.
If the request matches a session zone it will be reconnected. If it does not match then the resource will be requested as normal - in
this way the session mapper is transparent to requests that are not in a session zone.
Meta
In version 1.1 of the session mapper we've introduced a new meta section to apply general properties to all sessions. These configure the
duration of sessions and also to specift a maximum limit to the number of sessions - this prevents unbounded numbers of sessions from
consuming all system resources.
-
id a unique identifier for this session policy [default "DefaultPolicy"]
- max-sessions the maximum number of sessions to permit. [default 50]
- max-duration the maximum age that a session may have. [default 300,000]
- min-duration the minimum age before a session is at risk of being culled by new sessions.[default 30,000
Example
Using the example zone policy given above. Suppose that a request is received by our session mapped module for
active:dpml+operand@ffcpl:/mypath/myprocess.idoc, that is a request to execute the idoc /mypath/myprocess.idoc.
The rewrite rule <match>(.*)</match> ensures that every request is passed to the session mapper.
The session mapper tries to match the request URI against it's defined session zone policy. Since the request contains /mypath/
then it will be matched. The session mapper uses a cookie passed with the request to reconnect to the session URI. If no cookie is found
a new session is created. Finally the session mapper reissues the original request with the session URI attached.
active:dpml+operand@ffcpl:/mypath/myprocess.idoc+session@session1234567890123456
Once the session mapper's re-request is completed the session mapper automatically and transparently attaches a session cookie to the
response as it is passed back to the requestor.
Any subsequent external request will include the cookie on the request. The session mapper strips the external cookie session token, reconnects to
the session and exchanges the cookie for the internal session URI. If the session has expired a brand new session will be created.
Using the mapped session in an idoc
A session mapped request to execute an idoc receives the session URI as the session argument of the dpml request. An idoc can
use the session by refering to it with the URI
this:param:session
This is just a DPML reference to the session URI. The reference can be used just like the var:session URI examples shown in the first section.