Permalink
Browse files

Support object storage classes.

- PUT-OBJECT (and derivatives), COPY-OBJECT updated to take an
  additional storage-class keyword parameter defaulting to "STANDARD"

- New function SET-STORAGE-CLASS changes an existing object's storage
  class with COPY-OBJECT

- New key-object attribute function STORAGE-CLASS returns the storage
  class of an object

- Docs updated where needed
  • Loading branch information...
1 parent 92af45e commit 17ea3c958746417358ed4b3d5995a2b2c999fa77 @xach committed Jan 19, 2012
Showing with 113 additions and 15 deletions.
  1. +4 −2 bucket-listing.lisp
  2. +71 −2 doc/index.html
  3. +30 −8 interface.lisp
  4. +4 −1 objects.lisp
  5. +4 −2 package.lisp
View
@@ -141,7 +141,8 @@
(defun key-binding-key (binding)
(alist-bind (key
last-modified etag size
- owner-id owner-display-name)
+ owner-id owner-display-name
+ storage-class)
binding
(make-instance 'key
:name key
@@ -151,7 +152,8 @@
:owner (when owner-id
(make-instance 'person
:id owner-id
- :display-name owner-display-name)))))
+ :display-name owner-display-name))
+ :storage-class storage-class)))
(defmethod specialized-initialize ((response bucket-listing) source)
(let* ((bindings (xml-bind *list-bucket-binder* source))
View
@@ -438,7 +438,8 @@ <h2>Contents</h2>
<a href='#size'><tt>SIZE</tt></a>,
<a href='#etag'><tt>ETAG</tt></a>,
<a href='#last-modified'><tt>LAST-MODIFIED</tt></a>,
- and <a href='#owner'><tt>OWNER</tt></a>.
+ <a href='#owner'><tt>OWNER</tt>, and
+ <a href='#storage-class'><tt>STORAGE-CLASS</tt></a></a>.
<p>This function is built
on <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> and may
@@ -875,6 +876,23 @@ <h2>Contents</h2>
</div>
+<div class='item'>
+ <div class='type'><a name='storage-class'>[Function]</a></div>
+ <div class='signature'>
+ <code class='name'>storage-class</code>
+ <span class='args'>
+ <var>key-object</var>
+ </span>
+ <span class='result'>=> <var>storage-class</var></span>
+ </div>
+
+ <blockquote class='description'>
+ <p>Returns the storage class of <var>key-object</var>.
+ </blockquote>
+</div>
+
+
+
<a name='object-ops'><h3>Operations on Objects</h3></a>
@@ -1057,6 +1075,7 @@ <h2>Contents</h2>
<var>content-disposition</var>
<var>content-type</var>
<var>expires</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1113,7 +1132,14 @@ <h2>Contents</h2>
GET or HEAD requests. If <i>content-type</i> is not set, it
defaults to "binary/octet-stream". The others default to
NIL. If <i>expires</i> is provided, it should be a universal time.
- </blockquote>
+
+ <p>If provided, <var>storage-class</var> should refer to one of
+ the standard storage classes available for S3; currently the
+ accepted values are the strings "STANDARD" and
+ "REDUCED_REDUNDANCY". Using other values may trigger an API error
+ from S3. For more information about reduced redundancy storage,
+ see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/Introduction.html#RRS">Reduced
+ Redundancy Storage</a> in the Developer Guide.
</div>
<div class='item'>
@@ -1131,6 +1157,7 @@ <h2>Contents</h2>
<var>content-encoding</var>
<var>content-type</var>
<var>expires</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1166,6 +1193,7 @@ <h2>Contents</h2>
<var>content-encoding</var>
<var>content-type</var>
<var>expires</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1198,6 +1226,7 @@ <h2>Contents</h2>
<var>public</var> <var>metadata</var>
<var>content-disposition</var> <var>content-encoding</var> <var>content-type</var>
<var>expires</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1238,6 +1267,7 @@ <h2>Contents</h2>
<var>public</var> <var>metadata</var>
<var>content-disposition</var> <var>content-encoding</var> <var>content-type</var>
<var>expires</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1285,6 +1315,7 @@ <h2>Contents</h2>
<var>when-modified-since</var>
<var>unless-modified-since</var> <br>
<var>metadata</var> <var>public</var> <var>precondition-errors</var>
+ <var>storage-class</var>
<var>credentials</var>
</span>
<span class='result'>=> |</span>
@@ -1315,6 +1346,14 @@ <h2>Contents</h2>
with <a href='#put-object'><tt>PUT-OBJECT</tt></a>. Passing NIL
means that the new object has no metadata. Otherwise, the metadata
is copied from the original object.
+
+ <p>If <var>storage-class</var> is provided, it should refer to one
+ of the standard storage classes available for S3; currently the
+ accepted values are the strings "STANDARD" and
+ "REDUCED_REDUNDANCY". Using other values may trigger an API error
+ from S3. For more information about reduced redundancy storage,
+ see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/Introduction.html#RRS">Reduced
+ Redundancy Storage</a> in the Developer Guide.
</blockquote>
</div>
@@ -1410,6 +1449,36 @@ <h2>Contents</h2>
</blockquote>
</div>
+<div class='item'>
+ <div class='type'><a name='set-storage-class'>[Function]</a></div>
+ <div class='signature'>
+ <code class='name'>set-storage-class</code>
+ <span class='args'>
+ <var>bucket</var>
+ <var>key</var>
+ <var>storage-class</var>
+ <code class='llkw'>&amp;key</code>
+ <var>credentials</var>
+ </span>
+ <span class='result'>=> |</span>
+ </div>
+
+ <blockquote class='description'>
+ <p>Sets the storage class of the object identified
+ by <var>bucket</var> and <var>key</var>
+ to <var>storage-class</var>. This is a convenience function that
+ uses <a href='#copy-object'><tt>COPY-OBJECT</tt></a> to make
+ storage class changes.
+
+ <p>The storage class of an object can be determined by querying
+ the bucket with <a href='#all-keys'><tt>ALL-KEYS</tt></a>
+ or <a href='#query-bucket'><tt>QUERY-BUCKET</tt></a> and
+ using <a href='#storage-class'><tt>STORAGE-CLASS</tt></a> on one
+ of the resulting key objects.
+ </blockquote>
+</div>
+
+
<a name='access-control'><h3>Access Control</h3></a>
View
@@ -322,6 +322,7 @@ constraint."
content-disposition
expires
content-type
+ (storage-class "STANDARD")
((:credentials *credentials*) *credentials*))
(let ((content
(etypecase object
@@ -332,12 +333,16 @@ constraint."
((or vector pathname) object)))
(content-length t)
(policy-header (access-policy-header access-policy public)))
+ (setf storage-class (or storage-class "STANDARD"))
(submit-request (make-instance 'request
:method :put
:bucket bucket
:key key
:metadata metadata
- :amz-headers policy-header
+ :amz-headers
+ (append policy-header
+ (list (cons "storage-class"
+ storage-class)))
:extra-http-headers
(parameters-alist
:cache-control cache-control
@@ -360,6 +365,7 @@ constraint."
content-disposition
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (or start end)
(setf vector (subseq vector (or start 0) end)))
@@ -371,7 +377,8 @@ constraint."
:content-encoding content-encoding
:content-disposition content-disposition
:content-type content-type
- :expires expires))
+ :expires expires
+ :storage-class storage-class))
(defun put-string (string bucket key &key
start end
@@ -384,6 +391,7 @@ constraint."
content-disposition
(content-type "text/plain")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (or start end)
(setf string (subseq string (or start 0) end)))
@@ -396,7 +404,8 @@ constraint."
:content-encoding content-encoding
:content-type content-type
:cache-control cache-control
- :string-external-format external-format))
+ :string-external-format external-format
+ :storage-class storage-class))
(defun put-file (file bucket key &key
@@ -409,6 +418,7 @@ constraint."
content-encoding
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(when (eq key t)
(setf key (file-namestring file)))
@@ -424,7 +434,8 @@ constraint."
:content-disposition content-disposition
:content-encoding content-encoding
:content-type content-type
- :expires expires)))
+ :expires expires
+ :storage-class storage-class)))
(defun put-stream (stream bucket key &key
(start 0) end
@@ -436,6 +447,7 @@ constraint."
content-encoding
(content-type "binary/octet-stream")
expires
+ storage-class
((:credentials *credentials*) *credentials*))
(let ((content (stream-subset-vector stream start end)))
(put-object content bucket key
@@ -446,7 +458,8 @@ constraint."
:content-disposition content-disposition
:content-encoding content-encoding
:content-type content-type
- :expires expires)))
+ :expires expires
+ :storage-class storage-class)))
;;; Delete & copy objects
@@ -526,6 +539,7 @@ constraint."
access-policy
public
precondition-errors
+ (storage-class "STANDARD")
((:credentials *credentials*) *credentials*))
"Copy the object identified by FROM-BUCKET/FROM-KEY to
TO-BUCKET/TO-KEY.
@@ -551,8 +565,6 @@ users. Otherwise, a default ACL is present on the new object.
(error "FROM-BUCKET is required"))
(unless from-key
(error "FROM-KEY is required"))
- (unless (or to-bucket to-key)
- (error "Can't copy an object to itself."))
(setf to-bucket (or to-bucket from-bucket))
(setf to-key (or to-key from-key))
(handler-bind ((precondition-failed
@@ -564,6 +576,7 @@ users. Otherwise, a default ACL is present on the new object.
(parameters-alist :copy-source (format nil "~A/~A"
(url-encode (name from-bucket))
(url-encode (name from-key)))
+ :storage-class storage-class
:metadata-directive
(if metadata-supplied-p "REPLACE" "COPY")
:copy-source-if-match when-etag-matches
@@ -601,6 +614,16 @@ users. Otherwise, a default ACL is present on the new object.
collect (cons meta value))))))
+;;; Convenience bit for storage class
+
+(defun set-storage-class (bucket key storage-class &key
+ ((:credentials *credentials*) *credentials*))
+ "Set the storage class of the object identified by BUCKET and KEY to
+STORAGE-CLASS."
+ (copy-object :from-bucket bucket :from-key key
+ :storage-class storage-class))
+
+
;;; ACL twiddling
(defparameter *public-read-grant*
@@ -655,7 +678,6 @@ users. Otherwise, a default ACL is present on the new object.
(put-acl owner grants :bucket bucket :key key)))
-
;;; Logging
(defparameter *log-delivery-grants*
View
@@ -71,7 +71,10 @@
:accessor size)
(owner
:initarg :owner
- :accessor owner)))
+ :accessor owner)
+ (storage-class
+ :initarg :storage-class
+ :accessor storage-class)))
(defmethod print-object ((key key) stream)
(print-unreadable-object (key stream :type t)
View
@@ -57,7 +57,8 @@
#:last-modified
#:etag
#:size
- #:owner)
+ #:owner
+ #:storage-class)
;; Objects
(:export #:get-object
#:get-vector
@@ -72,7 +73,8 @@
#:delete-object
#:delete-objects
#:delete-all-objects
- #:object-metadata)
+ #:object-metadata
+ #:set-storage-class)
;; Access Control
(:export #:get-acl
#:put-acl

0 comments on commit 17ea3c9

Please sign in to comment.