Class: OpenStack::Swift::StorageObject
- Defined in:
- lib/openstack/swift/storage_object.rb
Instance Attribute Summary collapse
-
#container ⇒ Object
readonly
Returns the value of attribute container.
-
#metadata ⇒ Object
readonly
returns just the user defined custom metadata obj.metadata => ”herpa“=>”derp“.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
-
.create(container, objectname, headers = {}, data = nil) ⇒ Object
create a new Object in a given Container optional headers: { :metadata=>key1=>value1, … :content_type=>content type of created object :etag=>MD5 checksum of object data to be compared to that on server side :cache_control=>cache control header :manifest=>set manifest header for segmented large object }.
Instance Method Summary collapse
-
#bytes ⇒ Object
Size of the object (in bytes) obj.bytes => “493009”.
-
#cache_control ⇒ Object
Cache-Control header of the object obj.cache_control => “application/json”.
-
#content_type ⇒ Object
Content type of the object data obj.content_type => “application/json”.
-
#copy(object_name, container_name, headers = {}) ⇒ Object
Copy this object to a new location (optionally in a new container).
-
#data(size = -1,, offset = 0, headers = {}) ⇒ Object
(also: #read)
Retrieves the data from an object and stores the data in memory.
-
#data_stream(size = -1,, offset = 0, &block) ⇒ Object
Retrieves the data from an object and returns a stream that must be passed to a block.
-
#etag ⇒ Object
ETag of the object data obj.etag => “494e444f92a8082dabac80a74cdf2c3b”.
-
#initialize(container, objectname, force_exists = false) ⇒ StorageObject
constructor
Builds a new OpenStack::Swift::StorageObject in the specified container.
-
#last_modified ⇒ Object
Date of the object’s last modification obj.last_modified => “Thu, 26 Apr 2012 09:22:51 GMT”.
-
#manifest ⇒ Object
Returns the object’s manifest.
-
#move(object_name, container_name, headers = {}) ⇒ Object
Takes the same options as the copy method, only it does a copy followed by a delete on the original object.
-
#object_metadata ⇒ Object
Retrieves Metadata for the object object = container.object(“conversion_helper.rb”) => #<OpenStack::Swift::StorageObject:0xb7692488 .…
-
#set_manifest(manifest) ⇒ Object
Sets the manifest for an object.
-
#set_metadata(metadatahash) ⇒ Object
(also: #metadata=)
Sets the metadata for an object.
-
#to_s ⇒ Object
:nodoc:.
-
#write(data, headers = {}) ⇒ Object
Takes supplied data and writes it to the object, saving it.
Constructor Details
#initialize(container, objectname, force_exists = false) ⇒ StorageObject
Builds a new OpenStack::Swift::StorageObject in the specified container. If force_exist is set, the object must exist or a OpenStack::Exception::ItemNotFound will be raised. If not, an “empty” StorageObject will be returned, ready for data via the write method
The container parameter must be an OpenStack::Swift::Container object.
This constructor is typically not called directly. You can get a reference to an existing Object via OpenStack::Swift::Container::object method or create a new Object via OpenStack::Swift::Container::create_object method
25 26 27 28 29 30 31 32 33 |
# File 'lib/openstack/swift/storage_object.rb', line 25 def initialize(container, objectname, force_exists = false) @container = container @containername = container.name @name = objectname if force_exists raise OpenStack::Exception::ItemNotFound.new("No Object \"#{@name}\" found in Container \"#{@containername}\"", "404", "") unless container.object_exists?(objectname) end end |
Instance Attribute Details
#container ⇒ Object (readonly)
Returns the value of attribute container.
10 11 12 |
# File 'lib/openstack/swift/storage_object.rb', line 10 def container @container end |
#metadata ⇒ Object (readonly)
returns just the user defined custom metadata obj.metadata
> ”herpa“=>”derp“
89 90 91 |
# File 'lib/openstack/swift/storage_object.rb', line 89 def @metadata end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
9 10 11 |
# File 'lib/openstack/swift/storage_object.rb', line 9 def name @name end |
Class Method Details
.create(container, objectname, headers = {}, data = nil) ⇒ Object
create a new Object in a given Container optional headers:
:metadata=>{key=>value, key1=>value1, ...
:content_type=>content type of created object
:etag=>MD5 checksum of object data to be compared to that on server side
:cache_control=>cache control header
:manifest=>set manifest header for segmented large object
}
The container parameter must be an OpenStack::Swift::Container object. Typically you’d create an Object by first getting a Container: cont = os.container(“foo_container”) cont.create_object(“my_new_object”, {}, “object data”)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/openstack/swift/storage_object.rb', line 49 def self.create(container, objectname, headers={}, data=nil) provided_headers = (headers[:metadata] || {}).inject({}){|res, (k,v)| ((k.to_s.match /^X-Object-Meta-/i) ? res[k.to_s]=v : res["X-Object-Meta-#{k.to_s}"]=v) ;res} provided_headers["content-type"] = headers[:content_type] unless headers[:content_type].nil? provided_headers["ETag"] = headers[:etag] unless headers[:etag].nil? provided_headers["Cache-Control"] = headers[:cache_control] unless headers[:cache_control].nil? provided_headers["X-Object-Manifest"] = headers[:manifest] unless headers[:manifest].nil? if data.nil? #just create an empty object path = "/#{container.name}/#{objectname}" provided_headers["content-length"] = "0" container.swift.connection.req("PUT", URI.encode(path), {:headers=>provided_headers}) else self.new(container, objectname).write(data, provided_headers) end self.new(container, objectname) end |
Instance Method Details
#bytes ⇒ Object
Size of the object (in bytes) obj.bytes
> “493009”
96 97 98 |
# File 'lib/openstack/swift/storage_object.rb', line 96 def bytes self.[:bytes] end |
#cache_control ⇒ Object
Cache-Control header of the object obj.cache_control
> “application/json”
124 125 126 |
# File 'lib/openstack/swift/storage_object.rb', line 124 def cache_control self.[:cache_control] end |
#content_type ⇒ Object
Content type of the object data obj.content_type
> “application/json”
117 118 119 |
# File 'lib/openstack/swift/storage_object.rb', line 117 def content_type self.[:content_type] end |
#copy(object_name, container_name, headers = {}) ⇒ Object
Copy this object to a new location (optionally in a new container)
You must supply a name for the new object as well as a container name.
new_object = object.copy("new_obj", "my_container")
You may also supply a hash of headers to set Content-Type, or custom key=>value metadata: optional headers:
:metadata=>{key=>value, key1=>value1, ...
:content_type=>content type of created object
}
copied = object.copy('newfile.tmp', "my_container", :metadata=>{:herp=>"derp", "X-Object-Meta-foo"=>"bar } )
=> => #<OpenStack::Swift::StorageObject:0xb728974c .....
Returns the new OpenStack::Swift::StorageObject for the copied item.
285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/openstack/swift/storage_object.rb', line 285 def copy(object_name, container_name, headers = {}) provided_headers = (headers[:metadata] || {}).inject({}){|res, (k,v)| ((k.to_s.match /^X-Object-Meta-/i) ? res[k.to_s]=v : res["X-Object-Meta-#{k.to_s}"]=v) ;res} provided_headers["content-type"] = headers[:content_type] unless headers[:content_type].nil? provided_headers["X-Copy-From"] = "/#{@containername}/#{@name}" provided_headers["content-length"] = "0" path = "/#{container_name}/#{object_name}" begin response = @container.swift.connection.req("PUT", URI.encode(path), {:headers=>provided_headers}) rescue OpenStack::Exception::ItemNotFound => not_found msg = "Can't copy \"#{@name}\": No Object \"#{@name}\" found in Container \"#{@containername}\". #{not_found.}" raise OpenStack::Exception::ItemNotFound.new(msg, not_found.response_code, not_found.response_body) end OpenStack::Swift::StorageObject.new(@container.swift.container(container_name), object_name) end |
#data(size = -1,, offset = 0, headers = {}) ⇒ Object Also known as: read
Retrieves the data from an object and stores the data in memory. The data is returned as a string. Throws a OpenStack::Exception::ItemNotFound if the object doesn’t exist.
If the optional size and range arguments are provided, the call will return the number of bytes provided by size, starting from the offset provided in offset.
object.data
=> "This is the text stored in the file"
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/openstack/swift/storage_object.rb', line 136 def data(size = -1, offset = 0, headers = {}) headers = {'content-type'=>'application/json'} if size.to_i > 0 range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1) headers['Range'] = range end path = "/#{@containername}/#{@name}" begin response = @container.swift.connection.req("GET", URI.encode(path), {:headers=>headers}) response.body rescue OpenStack::Exception::ItemNotFound => not_found msg = "No Object \"#{@name}\" found in Container \"#{@containername}\". #{not_found.}" raise OpenStack::Exception::ItemNotFound.new(msg, not_found.response_code, not_found.response_body) end end |
#data_stream(size = -1,, offset = 0, &block) ⇒ Object
Retrieves the data from an object and returns a stream that must be passed to a block. Throws a OpenStack::Exception::ItemNotFound if the object doesn’t exist.
If the optional size and range arguments are provided, the call will return the number of bytes provided by size, starting from the offset provided in offset.
The method returns the HTTP response object
data = ""
object.data_stream do |chunk| data += chunk end
=> #<Net::HTTPOK 200 OK readbody=true>
data
=> "This is the text stored in the file"
166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/openstack/swift/storage_object.rb', line 166 def data_stream(size = -1, offset = 0, &block) headers = {'content-type'=>'application/json'} if size.to_i > 0 range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1) headers['Range'] = range end server = @container.swift.connection.service_host path = @container.swift.connection.service_path + URI.encode("/#{@containername}/#{@name}") port = @container.swift.connection.service_port scheme = @container.swift.connection.service_scheme response = @container.swift.connection.csreq("GET", server, path, port, scheme, headers, nil, 0, &block) raise OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/) response end |
#etag ⇒ Object
ETag of the object data obj.etag
> “494e444f92a8082dabac80a74cdf2c3b”
110 111 112 |
# File 'lib/openstack/swift/storage_object.rb', line 110 def etag self.[:etag] end |
#last_modified ⇒ Object
Date of the object’s last modification obj.last_modified
> “Thu, 26 Apr 2012 09:22:51 GMT”
103 104 105 |
# File 'lib/openstack/swift/storage_object.rb', line 103 def last_modified self.[:last_modified] end |
#manifest ⇒ Object
Returns the object’s manifest.
object.manifest
=> "container/prefix"
212 213 214 |
# File 'lib/openstack/swift/storage_object.rb', line 212 def manifest self.[:manifest] end |
#move(object_name, container_name, headers = {}) ⇒ Object
Takes the same options as the copy method, only it does a copy followed by a delete on the original object.
Returns the new OpenStack::Swift::StorageObject for the moved item. You should not attempt to use the old object after doing a move. optional headers:
:metadata=>{key=>value, key1=>value1, ...
:content_type=>content type of created object
}
309 310 311 312 313 |
# File 'lib/openstack/swift/storage_object.rb', line 309 def move(object_name, container_name, headers={}) new_object = self.copy(object_name, container_name, headers) @container.delete_object(@name) new_object end |
#object_metadata ⇒ Object
Retrieves Metadata for the object
object = container.object("conversion_helper.rb")
=> #<OpenStack::Swift::StorageObject:0xb7692488 ....
object.object_metadata
=> {:manifest=>nil, :bytes=>"1918", :content_type=>"application/octet-stream", :metadata=>{"foo"=>"bar, "herpa"=>"derp"}, :etag=>"1e5b089a1d92052bcf759d86465143f8", :last_modified=>"Tue, 17 Apr 2012 08:46:35 GMT", :cache_control=>nil}
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/openstack/swift/storage_object.rb', line 71 def path = "/#{@containername}/#{@name}" response = @container.swift.connection.req("HEAD", URI.encode(path)) resphash = response.to_hash = { :bytes=>resphash["content-length"][0], :content_type=>resphash["content-type"][0], :last_modified=>resphash["last-modified"][0], :etag=>resphash["etag"][0], :cache_control=> (resphash.has_key?("cache-control") ? resphash["cache-control"][0] : nil), :manifest=> (resphash.has_key?("x-object-manifest") ? resphash["x-object-manifest"][0] : nil), :metadata=>{}} resphash.inject({}){|res, (k,v)| [:metadata].merge!({ k.gsub("x-object-meta-", "") => v.first }) if k.match(/^x-object-meta-/)} end |
#set_manifest(manifest) ⇒ Object
Sets the manifest for an object. By passing a string as an argument, you can set the manifest for an object. However, setting manifest will overwrite any existing manifest for the object.
Throws OpenStack::Exception::ItemNotFound if the object doesn’t exist. Returns true if the call is successful.
222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/openstack/swift/storage_object.rb', line 222 def set_manifest(manifest) headers = {'X-Object-Manifest' => manifest} path = "/#{@containername}/#{@name}" begin response = @container.swift.connection.req("POST", URI.encode(path), {:headers=>headers}) rescue OpenStack::Exception::ItemNotFound => not_found msg = "Can't set manifest: No Object \"#{@name}\" found in Container \"#{@containername}\". #{not_found.}" raise OpenStack::Exception::ItemNotFound.new(msg, not_found.response_code, not_found.response_body) end true end |
#set_metadata(metadatahash) ⇒ Object Also known as: metadata=
Sets the metadata for an object. By passing a hash as an argument, you can set the metadata for an object. However, setting metadata will overwrite any existing metadata for the object. Returns true if the call was successful. Throws OpenStack::Exception::ItemNotFound if the object doesn’t exist.
The OpenStack mandated ‘X-Object-Meta’ prefix is optional:
obj.set_metadata(“X-Object-Meta-herpa”=>“derp”, “author”=>“me”)
> true
obj.metadata
> “author”=>“me”, “herpa”=>“derp”
193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/openstack/swift/storage_object.rb', line 193 def () headers = .inject({}){|res, (k,v)| ((k.to_s.match /^X-Object-Meta-/i) ? res[k.to_s]=v : res["X-Object-Meta-#{k.to_s}"]=v ) ;res} headers['content-type'] = 'application/json' path = "/#{@containername}/#{@name}" begin response = @container.swift.connection.req("POST", URI.encode(path), {:headers=>headers}) rescue OpenStack::Exception::ItemNotFound => not_found msg = "Can't set metadata: No Object \"#{@name}\" found in Container \"#{@containername}\". #{not_found.}" raise OpenStack::Exception::ItemNotFound.new(msg, not_found.response_code, not_found.response_body) end true end |
#to_s ⇒ Object
:nodoc:
315 316 317 |
# File 'lib/openstack/swift/storage_object.rb', line 315 def to_s # :nodoc: @name end |
#write(data, headers = {}) ⇒ Object
Takes supplied data and writes it to the object, saving it. You can supply an optional hash of headers, including Content-Type and ETag, that will be applied to the object.
If you would rather stream the data in chunks, instead of reading it all into memory at once, you can pass an IO object for the data, such as: object.write(open(‘/path/to/file.mp3’))
You can compute your own MD5 sum and send it in the “ETag” header. If you provide yours, it will be compared to the MD5 sum on the server side.
Returns true on success, raises exceptions if stuff breaks.
object = container.create_object("newfile.txt")
object.write("This is new data")
=> true
object.data
=> "This is new data"
255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/openstack/swift/storage_object.rb', line 255 def write(data, headers = {}) server = @container.swift.connection.service_host path = @container.swift.connection.service_path + URI.encode("/#{@containername}/#{@name}") port = @container.swift.connection.service_port scheme = @container.swift.connection.service_scheme body = (data.is_a?(String))? StringIO.new(data) : data body.binmode if (body.respond_to?(:binmode)) response = @container.swift.connection.put_object(server, path, port, scheme, headers, body, 0) raise OpenStack::Exception.raise_exception(response) unless response.code.match(/^20.$/) true end |