WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

The mapper overlay mediates and relays requests from a host space to a wrapped space. As with all overlays the wrapped space is accessible only through the mapper overlay. The mapper overlay is opaque - the only endpoints surfaced in the host space are those explicitly defined in its configuration. This overlay functions as a mapper because configured logical endpoints are mapped to logical endpoints in the wrapped space. The processing steps are illustrated in this diagram:

2009-06-20 12:22ZCanvas 1Layer 1Host SpaceWrappedSpaceMapperOverlay231a41

  • 1. A request is received by the mapper overlay
    • 1a. The configuration determines how the request is mapped to a constructed sub-request destined for the wrapped space.
  • 2. The constructed request is issued into the wrapped space.
  • 3. The response arrives at the mapper overlay.
  • 4. The mapper overlay relays response (3) as its response to the initial request (1).

A mapper overlay is declared with the mapper element which must have a config child element and must have a space child element. The config element contains the logical endpoint mappings between the host and the wrapped spaces. The space element contains the definition of the wrapped space.

<mapper>
  <config />
  <space />
</mapper>

The wrapped space must be defined within the space element. The configuration may be defined within the config element or it may be a reference to a configuration resource (which may be a static or dynamically generated resource).

<config>res:/resources/mapperconfig.xml</config>

The configuration resource must have a root element named config and may include import elements and endpoint declarations.

<config>
  <endpoint />
  <endpoint />
  <endpoint /> ...
  <import>res:/resources/additionalConfiguration.xml</import>
</config>

Endpoint

In the config element one or more child endpoint elements each declare a logical endpoint which is surfaced in the host space and which defines the mapping to a standard declarative request issued into the wrapped space. An endpoint element must have a request and usually must have a grammar:

<endpoint>
  <grammar />
  <request />
</endpoint>

An endpoint may have any of the following child elements:

ElementDescription
idLogical endpoint identifier for the surfaced endpoint
nameHuman readable name displayed for this endpoint in system tools.
descriptionHuman readable description displayed for this endpoint in system tools.
docResource identifier for Wiki text documentation for this endpoint which is displayed in system tools.
iconResource identifier used as the icon for this endpoint in system tools.
headerSets a response header on the returned response
verbsA comma separated list of verbs that are resolved to this logical endpoint
privateVisibility constraint.
protectedVisibility constraint.

verb

Note: The verb element of the standard declarative request used in the mapper is ignored. Instead, the verb of the resolved request is used for the request issued into the wrapped space.

tolerant missing arguments

When mapping grammars with optional arguments you can place arguments onto the constructed request and these will gracefully fail if those arguments are not specified on the incoming request.

Mapping

The mapper overlay provides the context for one or more logical endpoint to declarative request mappings. This simple relationship is surprisingly powerful. The following examples illustrate a sample of the capabilities.

RESTful Path Parsing

A mapping between a RESTful path and an active service request can be created in a logical endpoint declaration. In the following example, an endpoint grammar parses and names the final part of the RESTful identifier and then uses this as the value for the argument named id in the sub-request. Note that the reference arg:customer-id in the request refers to the parsed part named "customer-id" in the grammar.

<mapper>
  <config>
    <endpoint>
      <grammar>res:/customer/
        <group name="customer-id">
          <regex type="alphanum" />
        </group>
      </grammar>
      <request>
        <identifier>active:customer</identifier>
        <argument name="id">arg:customer-id</argument>
      </request>
    </endpoint>
  </config>
  <space> ... </space>
</mapper>

RESTful Path to RESTful Path Translation

One aspect of the mapping is between identifiers. The set of identifiers defined by the endpoint grammar map to the set of identifiers that can be used in the declarative request. Aiding this mapping is the arg: scheme mapping. As described elsewhere, a grammar parses a request identifier into constituent (named) parts and these named parts can then be referenced in the standard declarative request using the arg: scheme. For example, this logical endpoint definition reorders the parts of a RESTful identifier and uses the new form for the issued request:

<endpoint>
  <grammar>res:/customer/id/
    <group name="customer-id">
      <regex type="alphanum" />
    </group>/order/
    <group name="order-id">
      <regex type="alphanum" />
    </group>
  </grammar>
  <request>
    <identifier>res:/order/[[arg:order-id]]/customer/[[arg:customer-id]]</identifier>
  </request>
</endpoint>

Interface / Implementation Separation

A benefit of NetKernel's dynamic environment is that real service implementations can be substituted for the stub implementations in a 24*7 operational system with no downtime.

It is frequently beneficial to separate the interface of a resource from its implementation. During system development one team can develop software that uses a resource or service while another team develops the implementation if a temporary stub can be provided. This can be achieved with the mapper overlay as illustrated in the following example.

The first mapper overlay shows an interface defined for a list of books, res:/booklist/, and the initial static representation provided by an XML file:

<mapper>
  <config>
    <endpoint>
      <grammar>
        <group>res:/booklist/</group>
      </grammar>
      <request>
        <identifier>res:/resources/statics/booklist.xml</identifier>
      </request>
    </endpoint>
  </config>
  <space>
    <fileset>
      <regex>res:/resources/statics/.*</regex>
    </fileset>
  </space>
</mapper>

The second mapper overlay shows the same interface mapped to a dynamic implementation. This second mapper definition can be used once the team developing the implementation has tested and released their service.

<mapper>
  <config>
    <endpoint>
      <grammar>
        <group>res:/booklist/</group>
      </grammar>
      <request>
        <identifier>active:groovy</identifier>
        <argument name="operator">res:/org/netkernel/doc/bookList.gy</argument>
      </request>
    </endpoint>
  </config>
  <space>
    <fileset>
      <regex>res:/org/netkernel/doc/.*</regex>
    </fileset>
    <import>
      <uri>urn:org:netkernel:lang:groovy</uri>
    </import>
  </space>
</mapper>

Filter

Because the mapper overlay is opaque, each endpoint in the wrapped space that is to be surfaced in the host space must have an endpoint declared in the configuration. If all that is required is a pass-through and not a mapping of the inner endpoint then configured endpoint need only refer to logical endpoint identifier of the inner endpoint.

In this example a mapper is used to surface two of four internal logical endpoints (essentially filtering the endpoint):

<mapper>
  <config>
    <endpoint>
      <request>
        <identifier>meta:one</identifier>
      </request>
    </endpoint>
    <endpoint>
      <request>
        <identifier>meta:two</identifier>
      </request>
    </endpoint>
  </config>
  <space>
    <accessor>
      <id>meta:one</id> ...
    </accessor>
    <accessor>
      <id>meta:two</id> ...
    </accessor>
    <accessor>
      <id>meta:three</id> ...
    </accessor>
    <accessor>
      <id>meta:four</id> ...
    </accessor>
  </space>
</mapper>

Other Mappings

These example show only a sample of the capabilities of the mapper overlay. To illustrate even more richness, examine the following endpoint:

<endpoint>
  <grammar>res:/configuration/
    <group name="resource">
      <regex type="nmtoken" />
    </group>
  </grammar>
  <request>
    <identifier>active:configuration</identifier>
    <argument name="resource">arg:resource</argument>
    <argument name="host">active:hostname</argument>
  </request>
</endpoint>

This mapping is used by a large company to allow a single set of NetKernel modules provide configurations unique to their production, test, staging and development platforms.

Notice that the request includes a reference to a service active:hostname, which presumably returns the host name of the current computer. This information is then used by the active:configuration service to provide different configuration resources for a standard resource request depending on the machine running the application.

All of the information and all of the services within the request context are available for the mapping. This implies that architectural designs that in pure physical system would require extensive code can be created declaratively with NetKernel's ROC platform.

Optional Elements

id

The id element specifies the logical endpoint identifier for the logical endpoint declared in the mapper configuration. If the inner logical endpoint has a logical endpoint identifier, the id declaration overrides the value of the inner logical endpoint.

name, doc, icon, description

The name, description, icon and doc elements can be placed within an endpoint declaration to override any defaults which may be generated or inherited from the delegated endpoint. The endpoint declaration supports the standard endpoint metadata standard endpoint metadata declarations

A header element sets a response header name-value pair. The header must have a name attribute which specifies the header key and must have either a text value or a nested literal tag that is used to specify the header value. An endpoint may have any number of header elements. For example, to set the MIME type of a response use the following header element:

<header name="mime">text/html</header>
or
<header name="mime">
  <literal type="string">text/html</literal>
</header>

Setting a response to not cache:

<header name="no-cache">
  <literal type="boolean">true</literal>
</header>

verbs

The verb element can contain a comma separate list of verbs that constrain the verbs that are resolved to the endpoint. For example:

<verbs>SOURCE,SINK</verbs>

constrains request resolution to those request using either SOURCE or SINK and no others. The supported verbs are SOURCE, SINK, NEW, DELETE and EXISTS.

public / private / protected

Logical endpoint declared in the mapper overlay are always visible in the wrapped space. In addition, their visibility beyond the wrapped space may be controlled.

By default, logical endpoints are public; they can be referenced within the wrapped space, the host space and spaces that import the host space.

If the protected element is added to an endpoint declaration then that endpoint will be visible in the wrapped space, and the host space but not in spaces that import the host space.

If the private element is added to an endpoint declaration then that endpoint will be visible in the wrapped space only. It will not be visible in the host space nor in spaces that import the host space.

Configuration Import

The mapper overlay configuration may be import in whole or in parts. To import in whole, the config element contains a reference for a resource containing the configuration information:

<config>res:/resources/mapperConfig.xml</config>

In addition a configuration resource may contain import elements which refer to a portion of the configuration information:

<config>
  <endpoint />
  <import>res:/resources/moreConfig.xml</import>
</config>

There is no limit to the depth to which imports may be made.