The first 'release' of the storage service will support the following major features:
- Check-in/check-out - the ability to add files to the storage repository (upload) and get them
back (download).
- Versioning - the ability to track changes in items and to 'roll back' to a previous item.
- Repository Browsing - the ability to get a representative view of the items in the repository,
to the extent allowed by security restrictions.
Major features not supported in the initial release, but planned for upcoming releases:
- Security - the ability to restrict a user's ability to store and retrieve items to and from
certain directories
- Taxonomies - the ability to structure the information in the repository in a hierarchical
manner
- Search - the ability to search the repository.
The storage service uses the following terminology:
- Repository - the database which contains all of the directories and items managed by the
storage service.
- Item - any file or document managed by the storage service.
- Directory - an abstract term for a collection of Items.
- Ticket- a token providing temporary access to a requested item/directory
The API supports a few useful conventions:
- Authorization failures will cause the service to return HTTP code 401
- Item Not Found failures will cause the service to return HTTP code 404
- Internal Errors will cause the service to return HTTP code 500
- As a general guideline, the service will attempt to return appropriate HTTP codes wherever possible.
The Storage Service API
Resource: Items
- POST /items => Post an item to the repository. The POST should only be used when
writing a file for the first time - PUT should be used for updates. POSTs to existing files will result
in a 400 error.
The following request attributes are supported. Note, if cropping, all crop_ attributes must be set.
- width: If content is an image, resize to this width
- height: If content is an image, resize to this height
- crop_left: If content is an image, crop to this point from the left (can be a % or pixel amount).
- crop_top: If content is an image, crop to this point from the top (can be a % or pixel amount).
- crop_width: If content is an image, crop to this point wide (can be a % or pixel amount).
- crop_height: If content is an image, crop to this point height (can be a % or pixel amount).
Expected return status:
- Authorization Failure: 401 (TBD)
- Item Already Exists: 400
- Internal Error: 500
- Success:
<?xml version="1.0" encoding="UTF-8"?>
<RESULT>
<FILENAME>aaa.txt</FILENAME>
<PATH>aaa.txt</PATH>
<TYPE>text/plain</TYPE>
<ID>df970957-9a8c-4d5a-a7e8-92c4ea5f6e98</ID>
<CREATED_BY>4806f1d0-5da3-11dd-bbf6-001d09a5d9db</CREATED_BY>
</RESULT>
The value in the ID element may be used to construct a GET that will retrieve the file.
- POST /items?sync => Post an item to the repository synchronously. This is slower, but
it's transactional. This means that if the repository fails - for any reason - to store the file you posted,
you'll know about it and can take appropriate action. There are ways of dealing with this is an
asynchronous manner, but they are more complex and require state to be maintained in the client that
would otherwise be unnecessary.
The following request attributes are supported. Note, if cropping, all crop_ attributes must be set.
- width: If content is an image, resize to this width
- height: If content is an image, resize to this height
- crop_left: If content is an image, crop to this point from the left (can be a % or pixel amount).
- crop_top: If content is an image, crop to this point from the top (can be a % or pixel amount).
- crop_width: If content is an image, crop to this point wide (can be a % or pixel amount).
- crop_height: If content is an image, crop to this point height (can be a % or pixel amount).
Expected return status:
- Authorization Failure: 401 (TBD)
- Item Already Exists: 400
- Internal Error: 500
- Success:
<?xml version="1.0" encoding="UTF-8"?>
<RESULT>
<FILENAME>aaa.txt</FILENAME>
<PATH>aaa.txt</PATH>
<TYPE>text/plain</TYPE>
<ID>df970957-9a8c-4d5a-a7e8-92c4ea5f6e98</ID>
<ALTID/>
<CREATED_BY>4806f1d0-5da3-11dd-bbf6-001d09a5d9db</CREATED_BY>
<HISTORY>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.0">Wed Nov 07 14:59:12 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.1">Wed Nov 07 15:12:42 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.2">Wed Nov 07 15:33:31 CST 2007</VERSION>
</HISTORY>
</RESULT>
Because the file is posted asynchronously (continues to upload after the call completes), the TEMPID returned is just a placeholder,
and cannot be used to retrieve the file once the upload is complete. Use the encoded-dirname form of the
GET or HEAD request, which will always work.
- POST /items/<base64-encoded dirname> => Post an item to the specified directory
with the repository. The example below shows the results from the ninth upload of a given file. This form of the
POST also supports the ?sync flag.
The following request attributes are supported. Note, if cropping, all crop_ attributes must be set.
- width: If content is an image, resize to this width
- height: If content is an image, resize to this height
- crop_left: If content is an image, crop to this point from the left (can be a % or pixel amount).
- crop_top: If content is an image, crop to this point from the top (can be a % or pixel amount).
- crop_width: If content is an image, crop to this point wide (can be a % or pixel amount).
- crop_height: If content is an image, crop to this point height (can be a % or pixel amount).
Expected return status:
- Authorization Failure: 401 (TBD)
- Item Already Exists: 400
- Internal Error: 500
- Success:
<?xml version="1.0" encoding="UTF-8"?>
<RESULT>
<FILENAME>aaa.txt</FILENAME>
<PATH>aaa.txt</PATH>
<TYPE>text/plain</TYPE>
<ID>df970957-9a8c-4d5a-a7e8-92c4ea5f6e98</ID>
<ALTID>3be4ed3f-572c-46d3-b826-b895f81a48de</ALTID>
<CREATED_BY>4806f1d0-5da3-11dd-bbf6-001d09a5d9db</CREATED_BY>
<HISTORY>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.0">Wed Nov 07 14:59:12 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.1">Wed Nov 07 14:59:27 CST 2007</VERSION>
<VERSION name="1.2">Wed Nov 07 14:59:39 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.3">Wed Nov 07 14:59:48 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.4">Wed Nov 07 14:59:55 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.5">Wed Nov 07 15:00:03 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.6">Wed Nov 07 15:00:10 CST 2007</VERSION>
<VERSION name="1.7">Wed Nov 07 15:00:18 CST 2007</VERSION>
</HISTORY>
</RESULT>
- POST /items/<base64-encoded dirname>/<item_name> => Post an item to the
specified directory within the repository and rename it <item_name>
(as opposed to the default filename which is the filename associated with the uploaded document.)
The example below shows the results from the ninth upload of a given file. This form of the POST also supports
the ?sync flag.
The following request attributes are supported. Note, if cropping, all crop_ attributes must be set.
- width: If content is an image, resize to this width
- height: If content is an image, resize to this height
- crop_left: If content is an image, crop to this point from the left (can be a % or pixel amount).
- crop_top: If content is an image, crop to this point from the top (can be a % or pixel amount).
- crop_width: If content is an image, crop to this point wide (can be a % or pixel amount).
- crop_height: If content is an image, crop to this point height (can be a % or pixel amount).
Expected return status:
- Authorization Failure: 401 (TBD)
- Item Already Exists: 400
- Internal Error: 500
- Success:
<?xml version="1.0" encoding="UTF-8"?>
<RESULT>
<FILENAME>aaa.txt</FILENAME>
<PATH>aaa.txt</PATH>
<TYPE>text/plain</TYPE>
<ID>df970957-9a8c-4d5a-a7e8-92c4ea5f6e98</ID>
<ALTID>3be4ed3f-572c-46d3-b826-b895f81a48de</ALTID>
<CREATED_BY>4806f1d0-5da3-11dd-bbf6-001d09a5d9db</CREATED_BY>
<HISTORY>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.0">Wed Nov 07 14:59:12 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.1">Wed Nov 07 14:59:27 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.2">Wed Nov 07 14:59:39 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.3">Wed Nov 07 14:59:48 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.4">Wed Nov 07 14:59:55 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.5">Wed Nov 07 15:00:03 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.6">Wed Nov 07 15:00:10 CST 2007</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.7">Wed Nov 07 15:00:18 CST 2007</VERSION>
</HISTORY>
</RESULT>
- DELETE /items/<item_id>
- POST /items/<item_id>?_method=delete => both forms 'soft delete' the item,
removing it from directory listings, but leaving it in the repository. It's unclear at this point in time how
permalinks to deleted files will be handled.
- Success: 200
- Failed authorization: 401 (TBD)
- Nonexistent Item ID: 404
- Internal error: 500
- GET /items/<item_id> => returns the requested file
- <item id> - the unique ID of the item (i.e. 4b90f328-e46f-4da3-b464-f915603afcf5), returned as part of the response to a call to POST items
- Authorization Failure: 401
- Nonexistent Item ID: 404
- Internal Error: 500
- HEAD /items/<item_id> => returns the metadata for the requested file in custom headers, including an XML partial of the version history
- <item id> - the unique ID of the item (i.e. 4b90f328-e46f-4da3-b464-f915603afcf5), returned as part of the response to a call to POST items
- Authorization Failure: 401
- Nonexistent Item ID: 404
- Internal Error: 500
- Success:
HTTP/1.1 200 OK
Date: Wed, 17 Mar 2004 18:00:49 GMT
Server: Apache/2.0.48 (Unix) mod_ssl/2.0.48 OpenSSL/0.9.6l PHP/4.3.4
Last-Modified: Wed, 25 Feb 2004 22:37:23 GMT
CONTENT-TYPE : text/plain; charset=iso-8859-1
Content-Length : 45346
PERM-ITEM-ID : 4b90f328-e46f-4da3-b464-f915603afcf5
TEMP-ITEM-ID : 690236ea-e7c0-45c8-918d-1741b35eb83e
ITEM-NAME : testHeadItem.txt
ITEM-PATH : /abc/def/testHeadItem.txt
ITEM-VERSION : 1.0
ITEM-HISTORY :
<?xml version="1.0" encoding="UTF-8"?>
<HISTORY>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.0">Tue Mar 25 13:58:16 CDT 2008</VERSION>
<VERSION created_by="4806f1d0-5da3-11dd-bbf6-001d09a5d9db" name="1.1">Tue Mar 25 13:58:17 CDT 2008</VERSION>
</HISTORY>
- GET /items/<item_id>/<version> = returns the requested version of
the requested file
- <item name> - the unique ID of the item (i.e. 4b90f328-e46f-4da3-b464-f915603afcf5), returned as part of the response to a call to POST items
- <version> - the desired version (i.e. '1.7'), or 'HEAD' for latest
- Authorization Failure: 401
- Nonexistent Item ID: 404
- Nonexistent version: 404
- Internal Error: 500
- HEAD /items/<item id>/<version> => returns the metadata for the requested file in custom
headers.
- <item name> - the unique ID of the item (i.e. 4b90f328-e46f-4da3-b464-f915603afcf5), returned as part of the response to a call to POST items
- <version> - the desired version (i.e. '1.7'), or 'HEAD' for latest
- Authorization Failure: 401
- Nonexistent Item ID: 404
- Nonexistent version: 404
- Internal Error: 500
- Success:
HTTP/1.1 200 OK
Date: Wed, 17 Mar 2004 18:00:49 GMT
Server: Apache/2.0.48 (Unix) mod_ssl/2.0.48 OpenSSL/0.9.6l PHP/4.3.4
Last-Modified: Wed, 25 Feb 2004 22:37:23 GMT
CONTENT-TYPE : text/plain; charset=iso-8859-1
Content-Length : 765341
PERM-ITEM-ID : 4b90f328-e46f-4da3-b464-f915603afcf5
ITEM-NAME : testHeadItem.doc
ITEM-PATH : /abc/def/testHeadItem.txt
ITEM-VERSION : 1.7
- GET /items/<item name>/<version>/<encoded relative path> = returns the requested version of
the requested file from the requested directory
- <item name> - the file name (i.e. apsummary.xls)
- <version> - the desired version (i.e. '1.7'), or 'HEAD' for latest
- <encoded path - Base64-encoded relative path to the file (i.e. 'users/john/2004', which encodes to 'dXNlcnMvam9obi8yMDA0').
- Authorization Failure: 401
- Nonexistent Item ID: 404
- Nonexistent version: 404
- Internal Error: 500
- HEAD /items/<item name>/<version>/<encoded relative path> => returns the metadata for the requested file in custom
headers.
- <item name> - the file name (i.e. apsummary.xls)
- <version> - the desired version (i.e. '1.7'), or 'HEAD' for latest
- <encoded path - Base64-encoded relative path to the file (i.e. 'users/john/2004', which encodes to 'dXNlcnMvam9obi8yMDA0').
- Authorization Failure: 401
- Nonexistent Item: 404
- Nonexistent version: 404
- Internal Error: 500
- Success:
HTTP/1.1 200 OK
Date: Wed, 17 Mar 2004 18:00:49 GMT
Server: Apache/2.0.48 (Unix) mod_ssl/2.0.48 OpenSSL/0.9.6l PHP/4.3.4
Last-Modified: Wed, 25 Feb 2004 22:37:23 GMT
CONTENT-TYPE : text/plain; charset=iso-8859-1
Content-Length : 765341
PERM-ITEM-ID : 4b90f328-e46f-4da3-b464-f915603afcf5
TEMP-ITEM-ID : 73c4196a2-3476-ae55-c600-dd5286d2e111
ITEM-NAME : testHeadItem.doc
ITEM-PATH : /abc/def/testHeadItem.txt
ITEM-VERSION : 1.7
Resource: Directories
- GET /directories/<encoded dirname>
- Directory Not Found: 404
- Internal Error: 500
- Success: 200
- Returns in body:
<?xml version="1.0" encoding="UTF-8"?>
<RESPONSE>
<dirname jcr:created="2008-04-27T13:17:27.640-05:00"
jcr:primaryType="nt:folder"
xmlns:BSG="http://storage.bsgplatform.com/bsg/1.0"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:fn_old="http://www.w3.org/2004/10/xpath-functions"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:mix="http://www.jcp.org/jcr/mix/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:rep="internal"
xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<file1 jcr:created="2008-04-27T13:17:27.718-05:00" jcr:primaryType="nt:file">
<jcr:content BSG:bsgguid="c29fad88-675a-42b0-ab80-0af36c6c3211"
jcr:baseVersion="de2d2dc3-16de-44d5-9f42-965da80b80bd"
jcr:data="JjonTEwyRlg7Ri5fRltZRDRcOiE2Vy5cMCteMzJeUCJJXEAkRzNFVTAxVT09JDdKJSk="
jcr:isCheckedOut="false"
jcr:lastModified="2008-04-27T13:17:27.625-05:00"
jcr:mimeType="text/plain" jcr:primaryType="nt:resource"
jcr:uuid="c29fad88-675a-42b0-ab80-0af36c6c3211" jcr:versionHistory="cbc018c5-40fd-48d5-b8f6-0dfc8740645b"/>
</file1>
<file2 jcr:created="2008-04-27T13:17:48.953-05:00" jcr:primaryType="nt:file">
<jcr:content BSG:bsgguid="5bc2fecf-4376-4783-8d60-b7615e49ef60"
jcr:baseVersion="5c86b3c7-b279-4ddd-a63d-61cfc825b5b3"
jcr:data="Wk01WjJWLEJXXjtUKTIjPlNMLF45PFVJIDRaTF4pPjNII0kyJSosJDtUN19VWlxPKkk="
jcr:isCheckedOut="false"
jcr:lastModified="2008-04-27T13:17:48.953-05:00"
jcr:mimeType="text/plain" jcr:primaryType="nt:resource"
jcr:uuid="5bc2fecf-4376-4783-8d60-b7615e49ef60" jcr:versionHistory="99c559d9-07ed-4d44-8167-a99169c49939"/>
</file2>
</dirname>
</RESPONSE>
- DELETE /directories/<encoded dirname>
- Success: 200
- Failed authorization: 401 (TBD)
- Directory Not Found: 404
- Internal Error: 500
Resource: Tickets
- GET /tickets/<provision name>?request_url=<encoded request uri> => returns a ticket to provide temporary access to the request item defined in the uri.
- <provision name> - The provision name of the resource to access. (i.e. service_storageauth_items for items)
- <encoded request uri> - Base64 encoded uri of the item/directory resource for the ticket to provide access too
- No BSGRA_GUID provided in request header: 400
- Authorization Failure: 401
- Internal Error: 500
- Success: 200
- Returns in body:
<?xml version="1.0" encoding="UTF-8"?>
<ticket-url>http://storageauth.ngenplatform.com/items/df970957-9a8c-4d5a-a7e8-92c4ea5f6e98?ticket=ab992b23kdf3k33jk3k3j</ticket-url>
The value in the ticket-url element may be used to temporarily GET the specified item without providing a BSGRA_GUID header
Storage Service APIs yet to be published, in roughly this order:
- search API
- GET /items?parm1=val1&parm2=val2&parm3=val3&parm4=val4
- account management/usage API
- create new 'accounts' - track service accounts to S3 accounts for billing purposes
- get usage stats - space, bandwidth, cost
- taxonomy API
- Generate and maintain a folder-like hierarchy, and allow the repository, search, account management
and security APIs to access it
- security API
- Generate and maintain ACLs
- docType API
- Generate and maintain custom document types (i.e. sets of properties that are supported and
searchable)