|
NetKernel News Volume 2 Issue 28
May 13th 2011
What's new this week?
- Repository Updates
- Unattended Apposite REST Interface
- Documentation Watermarking Tip
- 1060 Forum Migration
- RequestForResponse
Catch up on last week's news here
Repository Updates
The following updates are available in the NKEE repository...
- nkee-apposite 1.23.1
- Added unattended apposite REST interfaces
- nkee-installer 1.7.1
- Unattended install from jar
- nkee-license-manager 1.6.1
- Improved reporting of license expiry
Unattended Apposite REST Interface
The update to nkee-apposite provides a new set of Unattended REST Services with which Apposite may be controlled by an unattended external configuration management tool such as, for example, Chef.
This version was slipstreamed into the NKEE download so you can set up an NKEE from the jar using the unattended install and then immediately instruct it to pull down all the latest packages and a software image from your repositories.
Here's a couple of examples of the interfaces taken from the documentation...
REST Interface
GET /tools/apposite/unattended/v1/update
Purpose
Instructs Apposite to automatically download and update all currently installed packages to the latest versions available from the repositories.
Response
This tool will report that the update process has commenced but returns before the update can begin. This is due to the nature of the transient reconfiguration of the NetKernel system which potentially is completely decommissioned and restarted.
To verify the update we recommend allowing a suitable amount of time for the system to reconfigure and then check the status of the completed update with the History and/or Installed services.
REST Interface
GET /tools/apposite/unattended/v1/history
Purpose
Display the complete history of changes applied to this system.
Response
This tool is a reverse time ordered list of changesets with the following XML form...
<EVENTS>
<EVENTTIME>2011-05-10 09:32:08</EVENTTIME>
<EVENT>
<NAME>wink</NAME>
<VERSION>1.16.1</VERSION>
<ACTION>remove</ACTION>
</EVENT>
</EVENTS>
<EVENTS>
<EVENTTIME>2011-05-10 09:29:23</EVENTTIME>
<EVENT>
<NAME>wink</NAME>
<VERSION>1.16.1</VERSION>
<ACTION>install</ACTION>
</EVENT>
</EVENTS>
<EVENTS>
<EVENTTIME>2011-05-09 18:26:13</EVENTTIME>
<EVENT>
<NAME>demo1</NAME>
<VERSION>1.2.1</VERSION>
<ACTION>install</ACTION>
</EVENT>
</EVENTS>
</HISTORY>
Each set of changes is grouped by an <EVENTS> tag and contains one <EVENT> item for each changed package.
Future Directions
We've deliberately given the API a versioned interface. Due to the nature of apposite working with a real repository and changing the installed platform its non-trivial to implement and test. Therefore if you write tools to call this version we will commit to maintain this interface. However if, with your feedback, we introduce new features or enhancements we have the headroom to introduce a new version whilst preserving the legacy (that's one of the essential properties of ROC after all).
Documentation Watermarking Tip
When you have a dynamic modular system it follows that people need to find out what something does when they install it. It has long been one of the cornerstone philosophies of NetKernel that modules contain their own documentation.
And, like everything else, documentation is just another resource, and the documentation system is just an ROC application for building the composite documentation resources. And the search tools are another layer of ROC applications over the documentation resources.
Its simple to get started documenting your own module, the easiest way is to let the new module wizard create you a module and take a look and experiment with the stubbed out documentation resources it creates. (It should be self-evident, but there's also a reference guide here).
Watermark Macros
The documentation runtime is extensible and enables plug-in macros. But did you know that one of the built-in macro engines allows you to place status watermarks in your documentation. (This entry has been marked as draft).
Here's the detail of how you would use the watermarking macro's...
{draft} Your documentation wiki source {/draft}
{candidate} Your documentation wiki source {/candidate}
{review} Your documentation wiki source {/review}
{editor} Your documentation wiki source {/editor}
Generally we put them at the top and bottom of any page and since the documentation rendering is recursive all the existing content (including any other macros) will be recursively composed.
When we were putting together the NK4 distribution we had quite a significant documentation management challenge and made extensive use these watermarks to ensure our documentation workflow went through a good QA process. We progressively used these draft/candidate/review/editor stages to demark the progress of the documentation (and by implication the status of the module).
Getting into the habit of watermarking your module's docs can be a very effective way of conveying your module's development status to your colleagues.
1060 Forum Migration
With some excellent assistance from Chris Cormack we took the plunge and have migrated the NetKernel Forums to the new, NetKernel4-based, nk4um application. Old links will carry on working, but the new application interface is located here...
All the existing content is still there, and all old links are redirected. Existing user accounts and passwords were also migrated - but there's just one notable change - you must now use your registered email address as the logon name (not the forum username, as before).
The other significant refinement (aside from the swishy modern look-and-feel) is that the text entry is now mediawiki syntax - which is faster to edit and more well known than the ancient BB-code syntax of the old forum. All the typical documentation macros are there and have shortcuts in the editor form.
Chris and I went through a radical performance tuning cycle last night and found several dramatic performance optimisations. There are still some more to come - mostly DB query optimisations and the introduction of ajax pagination of the topic listing.
Please let Chris and/or me know if you hit any teething troubles. But hopefully we're now set for the next 7 years.
Forum History Trivia
I wrote the old forum in 5 days on NK-2 back in 2004 - I know you won't believe me but its never had a bug fix and has moved across multiple generations of NK. However, it was showing its age (especially the look and feel) and furthermore it was our last production NetKernel-3 application. So, with a lump in our throats, this morning we switched off our last NK3 instance.
Farewell NK3 - you served us well...
Repository / Source
Chris plans to release a public repository for nk4um. In the mean time you can get the builds and/or participate in development here. I'll undoubtedly post a news item with more details when they are available.
To report any problems - nk4um has its own forum here!
RequestForResponse
Recently I was asked about a pattern in which a static file server script was being called from a mapped interface to create a pseudo-static web server pattern.
Barring a little logic to decide which bucket to get its content from, the server script was sourcing with a sub-request into its resource space.
So the question arose, how does this server script know how to set the metadata on its response? Does it need to look at the dotted-extension of all the resources and work out the mimetype?
Well the answer is no, and it was a less-than-one-line change... changing the issuing of the inner request from context.issueRequest() to context.issueRequestForResponse(). Let me explain...
Give me the Response
If you look at the INKFRequestContext you'll notice that there are bunch of methods that end with ForResponse. For example this is the general interface to issue a request...
INKFResponseReadOnly issueRequestForResponse(INKFRequest aRequest)
With the convenience SOURCE variant...
INKFResponseReadOnly sourceForResponse(java.lang.String aIdentifier)
So what do these do?
Ordinarily we try to make NKF feel as much as possible like you are writing code to do classical method invocation. So when you construct a request for a resource you'd probably issue that request with context.issueRequest() and immediately receive back the representation state as an object (or transrepted to the requested object if you specify the representation class).
When you need to use the state of the resource you requested, then this feels pretty seamless - you get back the state and start working with it.
But sometimes, you're writing an endpoint which does not directly care about the state of the resources - its just there to route requests. In these circumstances the last thing you want to do is "touch that state" - your aim is to be invisible.
That's where the ForResponse interfaces come in. When you use these methods you are saying, give me the true underlying response. Requests and Responses are what make the ROC world tick. The Kernel is just like these endpoints, it doesn't give a damn about the state - its just routing requests-to spaces and responses-from endpoints.
A response is an Object-container which holds the representation state, but it also includes response metadata (like mimetype), but also response headers and also a direct interface to isExpired(). A response is the rich and full story from the ROC-domain.
When you're working in a pseudo-classical way - you're actually calling convenience methods which unpack the representation from the response for you - so that it feels like your request to the endpoint was something similar to a method invocation. But actually your request resulted in a full and rich response.
So if you're in the situation of not caring about the state, and you don't want to affect the metadata, you can just requestForResponse. You can then just relay this response, to make it your response too, that's what the variant of createResponseFrom() is for...
createResponseFrom(INKFResponseReadOnly )
So, in the use-case I opened with, we just changed to requestForResponse and relayed that. It so happens that the <fileset> endpoint automatically determines the mimetype of files based on an extension lookup map. So it followed that the router endpoint suddenly started serving the correct mimetype for the web requests it was handling - because it was relaying the full response from the fileset - including the correct metadata.
Expiry Trigger Patterns
Notice I said that the response has an isExpired() method. The response you receive is your response. The kernel doesn't mind if you hang on to it. It follows that, if you like, you can sneek a peak at the isExpired() method whenever it suits you. Some interesting patterns ensue where you can rapidly react to the expiration of a resource.
Obviously you need to take a little care with these patterns - since the implication is that you have a stateful endpoint and so you need to manage your own state and make sure you're not going to introduce unbounded memory leaks etc. But you're not going to break the abstraction by holding references to responses if its useful to do so.
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.