NetKernel/News/3/35/August_31st_2012
search:

NetKernel News Volume 3 Issue 35

August 31st 2012

What's new this week?

Catch up on last week's news here

Repository Updates

The following updates are available in the NKEE and NKSE repositories...

  • http-client 2.11.1
    • Added properties to configure max connections and max connections per host to the default ConnectionManager pool
  • layer1 1.39.1
    • SimpleDynamicImport now supports an optional priority weighting of the discovered imports (for details, after update see here).
  • nkse-control-panel 1.25.1
    • Update to styling for doc map
  • nkse-doc-content 1.43.1
    • Doc enhancements
  • nkse-doc-patterns 1.5.1
    • Doc enhancements
  • nkse-docs 1.19.1
    • New Documentation Map - a mindmap showing historical use of docs (see below)
  • nkse-search 1.17.1
    • Added log event after index completes
  • nkse-visualizer 1.21.1
    • Fix to potential NPE when saving traces.
  • pds-core 1.8.1
    • Fix to internal golden thread model for the InMemory implementation - now correctly cuts thread on DELETE.

*NEW* Documentation Visualization

We have released to the repositories an update to the nkse-docs application. This now provides a stateful "mindmap" charting the historical coverage and use of the documentation...

Every time any of the core documentation is used, it is logged and can be viewed in the map viewer which is linked at the top of every page.

Please note that at present, to keep things manageable, the tool only displays the core system documentation. This means that documentation for libraries should be explored using either:

or

Resource Oriented Analysis and Design - Part 2

Second in a series of articles taking a well understood domain problem and casting it as an ROC solution. Read Part 1 Here.

Recap

In part 1 we started to consider a Resource Oriented model of the TicTacToe problem. Here's a quick recap...

  • We identified that a cell on the board could be considered as the primary atomic resource.
  • We then discovered that the higher level resources could be considered as sets of cells - which we called "composite resources".
  • Finally, with a low-level resource model shaping up, we set our mind on the higher level resources that would be necessary to implement the TicTacToe game. Again we found that these were also composite resources - we also started to see that the representation state of these resources could simply consist of sets of identifiers to other composite resources. We called the resources associated with the TicTacToe game, "meta resources" and saw that from an ROC perspective they are metadata.

Up to now we've used high-level function-like notation as the resource identifiers - as a sort of "casual short-hand" while we got our heads around the resource model. Today we're going to examine how, over a thirty minute period, I went about turning the conceptual model into URI addressable resources...

TicTacToe in ROC: Defining the resources

My first step was to create a new module which, using our URN-style reverse domain name convention for naming, I called urn:org:netkernel:demo:tictactoe. I could have created a module with the new module wizard - but its as easy to create a completely empty module with the bare minimum content by cutting and pasting another module.xml from any old module I had to hand. I blew away its rootspace with an empty one and changed its metadata to get this...

<module version="2.0">
  <meta>
    <identity>
      <uri>urn:org:netkernel:demo:tictactoe</uri>
      <version>1.1.1</version>
    </identity>
    <info>
      <name>Demo / Tic Tac Toe</name>
      <description>Tic Tac Toe in ROC</description>
    </info>
  </meta>
  <system>
    <dynamic />
  </system>
  <rootspace />
</module>

In the physical-sense my starting point is a completely empty space as it defines no endpoints. Alternatively, with an ROC perspective and remembering that in ROC we think of resources as abstract, we could look at it entirely the opposite way - this space contains potentially all possible abstract resources. Our job, just like that of a sculptor, is to "make the right moves" so that the possible set of resources is constrained to ensure only those we care about in our resource model can be reified.

Excuse the philosophical mind-games but this is relevant. What I'm trying to highlight is that if you are a "coder" - you will think of the job of solving the problem as one of "adding physical code" until we get the information we want. Whereas if you can switch to thinking in terms of resources - you can imagine that the information you want is already in there and your job is to release it by "trimming away" what we don't want to leave us what we do. If you can learn to switch between both perspectives you open yourself up to many powerful opportunities...

With my new module constructed I registered it with NetKernel by adding a reference to it in a file called [ install ]/etc/modules.d/tictactoe.xml. I really love the new modules.d/ capability and use it for grouping all my applications into different collections that I can load and unload. For example changing the file extension .xml -> .xml.hide will unload a set.

My next step was to immediately copy my new module (cut and paste the directory) to create a complementary test module. I renamed the copy and give it the name urn:test:org:netkernel:demo:tictactoe - the same name as the demo but with a "test" prefix. After changing the identity and descriptive metadata in its module.xml I also registered this with NK by cutting and pasting the line in tictactoe.xml for the first module and adding the "test" prefix. I then checked with the space explorer that my two modules (and two empty address spaces) were there and NK was happily managing them for me. For the record, here's my tictactoe.xml file...

<modules>
  <module runlevel="7">../urn.org.netkernel.demo.tictactoe/</module>
  <module runlevel="7">../urn.test.org.netkernel.demo.tictactoe/</module>
</modules>

Total elapsed time: Somewhere less than one minute.

Setting up the XUnit Test Context

You can skip this section if you wish - its detail which you may already know about, or if you use the New Module Wizard has been automated for you. But if you want to know exactly what I did, then this is the literal story...

I now set-aside the first module and put all my focus on the test module. I created a directory structure with paths /etc/system/ and /test/. I copied and pasted a Tests.xml file from an existing test module into the /etc/system/ directory. I edited Tests.xml file to look like this...

<tests>
  <test>
    <id>urn:test:org:netkernel:demo:tictactoe</id>
    <name>TicTacToe Tests</name>
    <desc>Tests for the TicTacToe Demo</desc>
    <uri>res:/test/testlist.xml</uri>
  </test>
</tests>

This is the metadata description for a set of XUnit tests. Now I needed to make sure that my rootspace exposed this resource so that the test framework would find this test set, so I added a <fileset> pointing to Tests.xml, to the empty <rootspace>...

<rootspace>
  <fileset>
    <regex>res:/etc/system/Tests.xml</regex>
  </fileset>
</rootspace>

You can see that the test set in Tests.xml has a link to the <uri> of the actual test declaration resource that will be used when this set of tests is actually run. Usually I start off calling my test list the same name every time res:/test/testlist.xml and I know that I've got to add this, so I created a testlist.xml file to the test/ directory which looked like this...

<testlist />

And then made sure this would be resolvable by exposing the files under the test/ directory to the ROC domain with another <fileset> in the rootspace...

<rootspace>
  <fileset>
    <regex>res:/etc/system/Tests.xml</regex>
  </fileset>
  <fileset>
    <regex>res:/test/.*</regex>
  </fileset>
</rootspace>

Now I took a look at XUnit to make sure my test set was being automatically discovered and aggregated into the test framework

http://localhost:1060/test/

which shows this test set...

Finally, I have one thing left to do. I need to import my real module so that its resources can be requested by my tests. Which leaves me with this as my contextual test space...

<rootspace>
  <fileset>
    <regex>res:/etc/system/Tests.xml</regex>
  </fileset>
  <fileset>
    <regex>res:/test/.*</regex>
  </fileset>
  <import>
    <uri>urn:org:netkernel:demo:tictactoe</uri>
  </import>
</rootspace>

I have tried to show the precise steps I took. Including how I went to the tools to verify each of my changes. If you like, the New Module Wizard will do all these steps for you in one go - for your convenience it puts the test space into the new module too. However, our convention is to keep tests separate so we always have a separate test module for each of our production modules.

Total elapsed time: Somewhere less than two minutes.

The Art of Thinking of Good Names

The real work starts here. I now had to think of how I would turn the casual identities I'd described in part 1 into useful, long-lived and stable names in my ROC solution.

The first thing I did was procrastinate. I deferred the work and simply created a test with literally the same casual name I'd used already. I added a test requesting cell(0,0)...

<test name="cell(0,0)">
  <request>
    <identifier>cell(0,0)</identifier>
  </request>
  <assert>
    <exception />
  </assert>
</test>

This test asserts <exception> since, as we know, the tictactoe <rootspace> is still empty and so this request will not be resolvable. I tabbed over to the XUnit view, ran the tests and received a satisfying 1 test run 0 failures report.

I like to always keep things "green" and so asserting that I know this will fail allows me to know that I am on top of things - there are no unknowns - I expected this. If you prefer to have your tests fail you could assert <notNull> which would then lead to a failing "red" test.

While what I'd proposed so far was a perfectly legitimate identifier and would serve as a name for a cell resource, I was uneasy and knew that it was only a temporary step. But I still procrastinated...

Next I considered the cells{...} composite resource from our model. Again I avoided the work of thinking of a good name and instead just created a second test like this...

<test name="cells{cell(0,0),cell(0,1),cell(0,2)}">
  <request>
    <identifier>cells{cell(0,0),cell(0,1),cell(0,2)}</identifier>
  </request>
  <assert>
    <exception />
  </assert>
</test>

My initial unease was manifest. This was not a nice looking thing at all. All those commas and mixtures of brackets!

As I had already intuited, I decided that what was needed, since we were going to have composite resources that would themselves be linked data to cell resources, was a really compact identifier for the cell resources.

I played around with res:/cell/x/y and cell:/x/y but these were still too verbose, so I settled on c:x:y - which I think is probably the most compact name you could have while preserving the implicit structure.

Through a bit of search-replace my tests became...

<testlist>
  <test name="c:0:0">
    <request>
      <identifier>c:0:0</identifier>
    </request>
    <assert>
      <exception />
    </assert>
  </test>
  <test name="cells{c:0:0,c:0:1}">
    <request>
      <identifier>cells{c:0:0,c:0:1}</identifier>
    </request>
    <assert>
      <exception />
    </assert>
  </test>
</testlist>

Progress, and perfectly legitimate identifiers. NetKernel doesn't care what you call anything. All identifiers are just opaque tokens to the kernel...

...this is true. But even though its convenient for shorthand, just as when mapping REST paths to internal service implementations, I like to know that there is a normalized and standard form of active: identifier for implementing services. So I added two more tests like this...

<testlist> ...existing initial c:0:0 and cells{} tests...
  <test name="active:cell+x@0+y@0">
    <request>
      <identifier>active:cell</identifier>
      <argument name="x">0</argument>
      <argument name="y">0</argument>
    </request>
    <assert>
      <exception />
    </assert>
  </test>
  <test name="active:cells+operand@c:0:0,c:0:1">
    <request>
      <identifier>active:cells</identifier>
      <argument name="operand">c:0:0,c:0:1</argument>
    </request>
    <assert>
      <exception />
    </assert>
  </test>
</testlist>

By doing this I had determined that I would have the primary implementations as active:cell and active:cells (plural) each with appropriate and normalized arguments. I didn't waste time trying to think what the argument for a collection of cells ought to be called and went with the convention of just using "operand".

You'll note that I am expecting the argument to be an identifier reference consisting of a list of cell identities. This is because in our part-1 analysis we'd recognised that certain sets of cells would be aliased to shorthand names (row, column, diagonal). By using a reference identifier as the argument it leaves me free to create these aliases with no code. I can "get away with this" since the possible range of identities is pretty small in this problem - in a larger resource space I would probably have gone with the operand as a resource transreptable to HDS containing a list of cell identities. We might see later that we may also, for completeness, require a service with an explicit pass-by-value argument (let's see).

At this point I had a set of tests and the requests they declared defined the resources my tictactoe space needed to reify. Time to switch over to the demo module...

Total elapsed time: Somewhere around ten minutes.

Implementing the Resources

Before I switched my attention back to the main tictactoe space, I quickly changed all my asserts in my tests to <notNull> - since now my attention had changed from defining identifiers to actually having my test requests resolve to tangible resources. So now I would know when I had my space configured with correctly resolvable resources.

With this change, my tests were now all red.

In the tictactoe space, my first step was to add a mapper like this...

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

I then stubbed out the first normalized active:cell service which consisted of an active grammar definition and a dummy request...

<mapper>
  <config>
    <endpoint>
      <grammar>
        <active>
          <identifier>active:cell</identifier>
          <argument name="x" />
          <argument name="y" />
        </active>
      </grammar>
      <request>
        <identifier>res:/dummy</identifier>
      </request>
    </endpoint>
  </config>
  <space />
</mapper>

By way of scaffolding I simply mapped active:cell to a dummy resource request with identity res:/dummy. For my tests to succeed I therefore had to actually provide that dummy resource inside the target <space> of the mapper. I used a convenient recent feature of the standard module and used an inline <literal> resource declaration like this..

<mapper>
  <config> ... </config>
  <space>
    <literal uri="res:/dummy" type="string">ReplaceMe!</literal>
  </space>
</mapper>

I ran my tests. The second test - to active:cell - went green. We had a channel and it was returning a resource representation. No matter that it is a string with "ReplaceMe!" - we'd trimmed down the potential of the space and it was starting to gives us a representation for a cell.

Now it was simple to implement c:x:y all I needed to do was add this mapping...

<endpoint>
  <grammar>
    <simple>c:{x}:{y}</simple>
  </grammar>
  <request>
    <identifier>active:cell</identifier>
    <argument name="x">arg:x</argument>
    <argument name="y">arg:y</argument>
  </request>
</endpoint>

I cheated. I just made c:x:y an alias for a long-hand request to active:cell. If reading these mappings isn't second nature yet, then here's a visualizer trace of what's going on...

...notice that c:0:0 gets mapped to active:cell+x@0+y@0 and this gets mapped to the dummy resource. Notice also that my requests are all cacheable - this will start to come into play later.

At this point my first and second tests now passed.

Next I added a mapping for active:cells. It went green. Finally I added another alias from cells{...} to active:cells. My last test went green.

My mapper config looked like this...

<config>
  <!--Cell Endpoints-->
  <endpoint>
    <grammar>
      <simple>c:{x}:{y}</simple>
    </grammar>
    <request>
      <identifier>active:cell</identifier>
      <argument name="x">arg:x</argument>
      <argument name="y">arg:y</argument>
    </request>
  </endpoint>
  <endpoint>
    <grammar>
      <active>
        <identifier>active:cell</identifier>
        <argument name="x" />
        <argument name="y" />
      </active>
    </grammar>
    <request>
      <identifier>res:/dummy</identifier>
    </request>
  </endpoint>
  <!--Cells{} Endpoints-->
  <endpoint>
    <grammar>
      <simple>cells\{{operand}\}</simple>
    </grammar>
    <request>
      <identifier>active:cells</identifier>
      <argument name="operand">arg:operand</argument>
    </request>
  </endpoint>
  <endpoint>
    <grammar>
      <active>
        <identifier>active:cells</identifier>
        <argument name="operand" />
      </active>
    </grammar>
    <request>
      <identifier>res:/dummy</identifier>
    </request>
  </endpoint>
</config>

Which, I think you'll agree starts to make the module.xml look much more complicated than it really is. So to clean up I moved these mapper configurations for the atomic resources to a separate file called atomMapperConfig.xml located in a directory org/netkernel/demo/tictactoe/atom/. I then pointed the mapper to this as a resource with an <import> and made sure this would resolve to my file by adding a <fileset> into the mapped <space>.

I ended up with my <rootspace> looking like this...

<rootspace>
  <mapper>
    <config>
      <import>res:/org/netkernel/demo/tictactoe/atom/atomMapperConfig.xml</import>
    </config>
    <space>
      <literal type="string" uri="res:/dummy">ReplaceMe!</literal>
      <fileset>
        <regex>res:/org/netkernel/demo/tictactoe/.*</regex>
      </fileset>
    </space>
  </mapper>
</rootspace>

I checked my tests. All still green. I hadn't broken anything.

Checkpoint

You can download a snapshot of both my modules at this point here...

Composite Resources

Using the same process, next I moved on to defining the resources row(y), column(x) and the two diagonals. Having just thought about the shorthand for c:x:y I didn't need to pause to think in order to adopt a similar shorthand notation for a row row:y and declared a test...

<test name="row:0">
  <request>
    <identifier>row:0</identifier>
  </request>
  <assert>
    <stringEquals>ReplaceMe!</stringEquals>
  </assert>
</test>

The test fails. So switching to the tictactoe <rootspace> I added a new endpoint to the mapper <config> with a grammar that would resolve row:x like this...

<config>
  <import>res:/org/netkernel/demo/tictactoe/atom/atomMapperConfig.xml</import>
  <endpoint>
    <grammar>
      <simple>row:{y}</simple>
    </grammar>
    <request>
      <identifier>cells{c:0:[[arg:y]],c:1:[[arg:y]],c:2:[[arg:y]]}</identifier>
    </request>
  </endpoint>
</config>

Notice I don't have to implement anything as we know from last time that row:x is actually just an alias to a set of cells. So all I had to do was declare the request for that set of cells using the shorthand cells{...} notation we'd already provided in the atom mappings. Notice that the mapper <config> allows you to mix resource imports with local <endpoint> mappings.

The tests all pass again.

Using cut and paste and renaming the things that needed renaming I added a test and a mapping for column:x and then both of the named sets of cells for diagonal:0 (top-left to bottom right) and for diagonal:1 (bottom-left to top-right).

My tests for atoms and composites are all passing. My space is starting to contain the resolvable resources we're interested in. (Don't worry about the representation's all being "ReplaceMe!" at this point the representation state is irrelevant).

Finally I tidy up my new composite resource mappings by moving them to a file called compositeMapperConfig.xml in directory next to the atom stuff. I changed the mapper to import this and ended up with a tidy module again...

<rootspace>
  <mapper>
    <config>
      <import>res:/org/netkernel/demo/tictactoe/atom/atomMapperConfig.xml</import>
      <import>res:/org/netkernel/demo/tictactoe/composite/compositeMapperConfig.xml</import>
    </config>
    <space>
      <literal type="string" uri="res:/dummy">ReplaceMe!</literal>
      <fileset>
        <regex>res:/org/netkernel/demo/tictactoe/.*</regex>
      </fileset>
    </space>
  </mapper>
</rootspace>

My tests were green. I hadn't screwed the space up. At this point, I put down my tools and went off to reward myself with a cup of coffee. In thirty minutes I'd broken the back of the problem, in another 5 minutes I'd be done, with a full persistent cache-coherent implementation of the atom resource model and I wouldn't have to write a line of code ... which is where we'll start again next time...

Checkpoint

You can download a snapshot of the modules at this point here...

Alternate Perspective

Tom Geudens has risen to the challenge and has implemented an initial version of the core resource model...

http://practical-netkernel.blogspot.be/2012/08/minimalistic-oxo.html

This is really helpful since next time I'll be able to compare and contrast with the approach I'm heading towards.

Incidentally, in Belgium they call tictactoe: "oxo" - same resource, different identifier.

[Read part 3]

NetKernel West 2013

Several people have recently asked if we're planning a conference. To which the answer is: "planning" would be too strong a word - but heck, yeah, why not...

So here's the "plan"...

Date: lets say spring 2013 to give everyone some lead time.

Location: USA. Those who've been to any of the previous three conferences will know we have exacting requirements. It has to be somewhere young, cool and hip (college towns have been good to us so far), within reasonable travel from a decent airport, *not* be a corporate hotel and (purely coincidentally) have a thriving local brew-scene. Any ideas?

Format: Shall we stick with the one or two day pre-conference bootcamp followed by two-day main conference?

Content: Now you could come along and listen to me go on and on about the esoteric nature of reality and the relation between resource spaces and chrono-synclastic infundibulae*... But its time to get real. To share experiences. To establish common practice. To get a shared perspective of how ROC fits in the IT landscape....

What we as a community all need are your presentations describing your experience, your practices, your patterns, your stories...

So get thinking and send me a short proposal. All selected speakers will be rewarded with some shameless give-away (can we do your own weight in beer?)...

Sounds like a plan... see you in 2013...

*Courtesy of Kurt Vonnegut and pointed out by B. Sletten Esq.


Have a great weekend.

Comments

Please feel free to comment on the NetKernel Forum

Follow on Twitter:

@pjr1060 for day-to-day NK/ROC updates
@netkernel for announcements
@tab1060 for the hard-core stuff

To subscribe for news and alerts

Join the NetKernel Portal to get news, announcements and extra features.

NetKernel will ROC your world

Download now
NetKernel, ROC, Resource Oriented Computing are registered trademarks of 1060 Research


WiNK
© 2008-2011, 1060 Research Limited