This document discusses the basic design principles of the XIRUSS system.
The SnapCM model is completely generic and the XIRUSS-T repository therefore can be exposed for access in any number of ways. It imposes no constraints or requirements on how you make it visible to clients and humans.
The XIRUSS-T system as delivered includes a simple HTTP server that provides read/write access to the repository using normal HTTP PUT, GET, and POST operations. This is only one of an infinite number of possible ways to expose a XIRUSS-T repository.
This URL scheme is implemented by the org.xiruss.http.jetty.XirussResource class.
The URL schema I've used for this HTTP server attempts to reflect the principles in Hans Reiser's paper on file system naming schemes, available here: http://www.namesys.com/whitepaper.html. If I understand the principle, the basic idea is that everything, including operations that are queries, should be expressed using the same simple naming syntax. That is, everything is a name all names have same syntax. In any case, my URL syntax started as at least an experiement with these principles. In particular, it means that rather than having URL that are really function calls or primarily collections of query parameters, it means that all the repository components can be addressed by normal-looking URLs where the name components are all nouns.
The exception to this is URLs that modify the state of the repository--these do include verb components (createBranch, createVersion), etc. because I couldn't see a way around it. In any case, this is all experimental and there's no particular magic or authority to this particular URL scheme. Nothing about SnapCM itself or the XIRUSS-T SnapCM constrains how you expose the repository in any way, so if you wanted to provide a completely different URL scheme for your repository, you are free to do so.
Note, however, that for a given repository instance, the URL scheme must be consistent as address rewriting on import needs to be able to use URLs that will be reliably resolvable against that repository instance.
The rules for XIRUSS-T GET URLs are as follows:
/branches/br_00000002/snap_00000002/res_00000002 /branches/br_00000002/snap_00000002/res_00000002?resolutionpolicy=onSnapshot /branches/br_00000002/snap_00000002/ver_00000001
PUT requests are used to create new versions of resources. From the documentation in the code:
Note that all other objects are created by POST requests because they don't contain data directly nor do they have a notion of being versioned. By contrast, versions can contain data (and most version types exist in order to contain data) and therefore the semantic of "posting to a resource" is the best match for creating a new version of a resource. This also reflects the distinction made in the HTTP spec between POST being handled by one object that then changes the data state of the server, possibly by creating new objects, while PUT is applied directly to a resource in order to change that resource's state (i.e., to set its content).
Thus, while "posting to a resource" results in a new version object, conceptually the (SnapCM) resource is the union of its versions so, semantically, creating a new version of a resource is identical to creating a new version of a file where the new file has the same URL as the old file.
These URLs are constructed by the org.xiruss.http.client.XirussHttpClientHelper class.
The URL pattern is:
The parameters are:
If a user ID is not specified then a new user is created automatically.
Any other URL parameters will be set as properties on the version.
This operation creates the Version object and, if the version object is one that takes data (i.e., an instance of StorageObject), the client can write that data to the newly-created version (see the doPut() method in the XirussHttpClientHelper class).
Note that the snapshot involved must be a mutable snapshot ("sandbox"). It is not possible to create a new version on a snapshot that has been "fixed".
All repository modification except version creation is via POST requests.
As for PUT, all repository mutation operations take a userid parameter whose value is the object ID of a user.
Each repository mutation operation is identified by a keyword that is the last path component in the URL. Preceding the operation keyword are path components that address the context for operation (i.e., branch, snapshot, resource, etc.) as for GET URLs.
NOTE: The creation of these URLs and their posting is supported by the org.xiruss.http.client.XirussHttpClientHelper class. You can use this class from importer or interactive client code to handle the communication to the XIRUSS-T server.
The POST operation keywords and their parameters are:
Commits a mutable snapshot to the repository, making it the latest snapshot on the containing branch.
Creates a new branch in the repository.
Creates a new dependency link between a version and a resource
/branches/br000001/snap000002/ver0000006/createDependency? resolutionpolicy=com.example.xiruss.policies.MyResoluitionPolicyClass& someparam=somevalue& name=doc_01.xml& userid=user001
Any other parameters are taken as constructor parameters for the dependency instance.
Creates a new resource in the repository.
Creates a new mutable snapshot in the repository within a specified branch.
Creates a new user in the repository.
Any other parameters are set as properties of the user object.
Sets a property on the repository object addressed by the URL.
Here is a short Jython session that uses the XirussHttpClientHelper to create some things in the repository:
C:\users\eliot\eclipse\workspace\xiruss-t\build>jython Jython 2.1 on java1.5.0_07 (JIT: null) Type "copyright", "credits" or "license" for more information. >>> from org.xiruss.http.client import XirussHttpClientHelper >>> helper = XirussHttpClientHelper("localhost", 9090) >>> cn = helper.createNewUser("drmacro") >>> cn.getResponseMessage() 'user_11' >>> cn = helper.createNewBranch("test") >>> cn.getResponseMessage() 'br_00000004' >>> cn = helper.createNewSnapshot('br_00000003', "snap_00000007", "user_11") >>> cn.getResponseMessage() 'snap_00000007' >>> cn = helper.commitSnapshot('br_00000003', "snap_00000007", "user_11", "") >>> cn.getResponseMessage() 'Snapshot committed to branch br_00000003' >>>