My First Module
Creating a Hello World Service and Module from first principles
Index > Books > Declarative Development Guide > Trailmaps > My First Module

Rate this page:
Really useful
Satisfactory
Not helpful
Confusing
Incorrect
Unsure
Extra comments:


In this tutorial we'll create a simple "hello world" service and deploy it in a simple module. At each step we'll describe what we are doing and why. Where necessary links are given to further reading.

We'll create a service which produces an XML fragment which is bound to a URL path on a HTTP port. The XML fragment is:

<hello>world</hello>

The XML document will be generated by a DPML (Declarative Processing Markup Language) script.

1) Create a directory structure for a module

All functionality deployed on NetKernel is packaged into modules. Modules exist on the filesystem of the host as either .jar archive file or expanded into a directory structure. For development purposes you will always be working with a directory.

Lets create the module directory; there are no limitations on its name or location but for this example lets call it HelloWorld and place it in the modules directory of your installation. That is [install]/modules/HelloWorld/ where [install] is the location you installed NetKernel.

2) Create a module definition

The module definition is a file called module.xml which exists in the root directory of every module. The purpose of the module definition is to define meta data about the module, its publicly exposed interface, the handling chain for requests on the module, and finally and specialised components that are hosted by the module. The module definition conforms to the module definition schema.

Here is a minimal module definition for our module:

<module>
  <identity>
    <uri>urn:hello-world</uri>
    <version>0.1.0</version>
  </identity>
  <info>
    <name>Hello World</name>
    <description>my first module</description>
    <type>application</type>
  </info>
  <export>
    <uri>
      <match>ffcpl:/hello/world</match>
    </uri>
    <class />
  </export>
  <rewrite>
    <rule>
      <match>ffcpl:/hello/world</match>
      <to>active:dpml+operand@ffcpl:/world.idoc</to>
    </rule>
  </rewrite>
  <mapping>
    <this>
      <match>ffcpl:/.*</match>
    </this>
    <import>
      <uri>urn:org:ten60:netkernel:ext:dpml</uri>
    </import>
  </mapping>
</module>

Lets look at what the module definition is specifying skipping over the identity and info sections (more information.) The export section declares that this module will accept any request with a URI of ffcpl:/hello/world. These specifications for URIs may be wildcarded with standard regular expressions. The ffcpl: URI scheme is an internal NetKernel scheme which is used to map on to the interfaces and internal resources of modules.

The rewrite section declares that a URI of ffcpl:/hello/world will be rewritten to active:dpml+operand@ffcpl:/world.idoc. This rewritten URI is matched by the DPML service which is being imported into the internal address space of this module by the import statement in the mapping section. Above that, the this statement declares that all URIs starting with ffcpl:/ are matched against static resources in this module.

It is worth spending a moment to look at the unusual URI which is matched by the DPML service. The active: scheme is another internal NetKernel scheme. By convention it is used to map to services which perform processing. The way to parse it is to split it by the + character. The first part, active:dpml, is what is matched by the DPML service. The second and subsequent parts, operand@ffcpl:/world.idoc, are name-value argument pairs separated by the @ character which are passed to the service. The value is always another nested URI. In this case the operand is the script that the DPML service should execute. More detail about active URIs here.

So in summary this module definition declares a module which will accept a request with URI ffcpl:/hello/world and execute a DPML script to create a response.

3) Create a DPML script

In the previous section we declared a rewrite rule in the module definition which would execute a DPML script with a URI of ffcpl:/world.idoc. We also declared that all requests with URI's starting ffcpl:/ would be resolved to resources in this module. Therefore if we create a file in the root directory of this module with a name world.idoc it will be this that is used. This script has one instruction that copies a literal XML document to the response:

<idoc>  <instr>
    <type>copy</type>
    <operand>
      <hello>world</hello>
    </operand>
    <target>this:response</target>
  </instr>
</idoc>

For more information on the DPML language see here.

4) Register module

When NetKernel starts or restarts it commisions all modules that are registered in [install]/etc/deployedModules.xml. To register our new module we need to add the following fragment to root element of deployedModuled.xml:

<module>modules/HelloWorld/</module>
This defines the path to a module to commision. More information on deployedModules.xml is available here.

5) Associate module with HTTP server

If we restarted NetKernel now we would have our module deployed; however this module would be orphaned- no other module is importing it so it is unused. The next step is to import our new module into the "frontend fulcrum". The frontend fulcrum is the name given to a module that ships with NetKernel Standard Edition which starts a HTTP server on port 8080 and is in expanded module form for easy editing. You can find the frontend fulcrum module configuration at [install]/modules/mod-fulcrum-frontend/module.xml. Edit this to add the following fragment into the mapping section as the next to last element- (the super element should remain at the end):

<import>  <uri>urn:hello-world</uri>
</import>

The term "fulcrum" is the name of module pattern which pivots a transport, which receives external requests (in this case HTTP), with modules that handle those requests (in this case our hello world module. The fulcrum pattern along with other module patterns are documented here.

6) Run service

Now we have everything setup we need to restart NetKernel. Go to the Cold Restart Tool on the control panel, confirm the restart and then wait a few seconds.

Now enter http://localhost:8080/hello/world into your HTTP browser address bar. You should receive the hello world message:

<hello>world</hello>

If you were to enter a different URI, say http://localhost:8080/hello/mars this URI would not be matched by any modules in the fulcrum and you would receive a URI Resolution Failure exception. The default configuration of the HTTP transport maps this into a HTML error page. It is worth noting that you can get more detail on the error by clicking on the Exception Trace link, this shows a full request trace hopefully detailing exactly where and why the error occured. More details on configuring the HTTP transport are available here.

Wrap up

Thats it! - you have now created your first module and service. Not only do you have a starting point to work from but you have learned a lot of the basic concepts. You know how to create and deploy modules. You know how to link a module to a transport and how a service gets invoked. This is, of course, more details behind all of these concepts...

Here are some links to continue your exploration:

  • Using the Tools - a quick run through some of the tools on the System Services Fulcrum showing how they relate to the module and service we have just created.
  • Text2Image Service - a more complex example that explores parameter passing, calling sub-services and exception handling.
  • Scripted Services - a set of trailmaps creating services using procedural scripting languages.

© 2003-2005, 1060 Research Limited. 1060 registered trademark, NetKernel trademark of 1060 Research Limited.