Accessors may be written in any scripting language
supported by NetKernel. This guide explores how to write an active accessor in a scripting language
and package it in a module.
To create an accessor you will:
Write the accessor in your choice of scripting language.
Expose the script as an accessor.
Write the Accessor
An active accessor typically goes through these four steps:
Determine type of request,
Retrieve parameters,
Process request, and
Prepare and return result.
For our example we will re-implement in beanshell script the 'case' accessor we developed in
the Java active accessor development guide.
Type of Request
Active accessors must support SOURCE, and may support SINK,
DELETE, EXISTS, and NEW request types.
The accessor code can discover the request type by calling
context.getThisRequest().getRequestType() and must throw a
com.ten60.netkernel.util.NetKernelException if it receives a request type that it does
not handle.
import com.ten60.netkernel.urii.*;
import com.ten60.netkernel.urii.aspect.*;
import org.ten60.netkernel.layer1.nkf.*;
import org.ten60.netkernel.layer1.nkf.impl.*;
import org.ten60.netkernel.layer1.representation.*;
void main()
{ requestType = context.getThisRequest().getRequestType();
if ( INKFRequestReadOnly.RQT_SOURCE == requestType )
{ // process SOURCE request type (see below)...
}
else
{ throw new NetKernelException("Unsupported request type");
}
}
Retrieve Parameters
The scripted accessor retrieves parameters from the invoking request by
using the context object.
// process SOURCE request type...
// get argument "operand" as an IAspectString
sa=context.sourceAspect("this:param:operand", IAspectString.class);
Process Request
The code to implement the processing is almost the same as in the Java example - although
notice that we are taking advantage of Beanshell's loose typing by not declaring variable types.
Also note that, compared with the previous Java implementation, we have had to change name of the configuration argument
on the active URI interface of the service. The code now looks for configuration passed as the
'mode' argument on the request - we shall see below that this is to avoid contention for the named argument
'operator' which must be used for the script itself. This small contention for the 'operator' argument in the active URI address
is the only limitation of implementing accessors using a scripted language runtime.
// determine operating mode (e.g. to-upper or to-lower)
toUpper=true;
if (context.hasArgument("mode"))
{ // get argument "mode" as an IAspectNVP - name value pair.
nvpa=context.sourceAspect("this:param:mode", IAspectNVP.class);
type=nvpa.getValue("case").toUpperCase(); //get 'case' and make case-insensitive!
if(type.equals("UPPER")) toUpper=true;
else if(type.equals("LOWER")) toUpper=false;
else throw new Exception("Unsupported case in operator NVP - 'case' must be 'upper' or 'lower'");
}
// perform processing
String processed=null;
if(toUpper)
{ processed=sa.getString().toUpperCase();
}
else
{ processed=sa.getString().toLowerCase();
}
Return Result
A script returns a response through the context object
// build result
// create string aspect
aspect = new StringAspect(processed);
// create response
response=context.createResponseFrom(aspect);
response.setMimeType("text/plain");
// set response
context.setResponse(response);
Expose the Accessor
Once written, export the accessor's URI interface from the module and
then rewrite requests on that interface to an invocation of the script by its language runtime.
We can expose this as a service active:caseService as follows: in your module export section add an entry...
In your module's mapping section add a rewrite rule which maps request for active:upperService to the beanshell runtime with the
upperAccessor.bsh script. Notice that the rewrite rule must use 'operator' for the script argument to the beanshell runtime - for this
reason we had to implement the scripted accessor to obtain its configuration from an argument called 'mode'.
That's it. Your module now provides an accessor active:upperService - it is irrelevant to the user that this service is implemented by
the execution of a beanshell script.
[Note: to ensure the script gets executed by the active:beanshell runtime your module must import the ext-script module etc.]