class Atmos::Object

Object

This class represents an object in an Atmos store.

Object Data

When an object is instantiated, it's data is not loaded due to memory considerations. You can access an object's data as a ruby String or as a progressive download via a block.

all at once

obj.data

progressive download

obj.data_as_stream do |chunk|
   datafile.write(chunk)
end

partial data

obj.data_as_stream(0...59) do |chunk|
   readin.concat(chunk)
end

System Metadata

Each object has some information about it stored by the system. This information is read only, and available as a hash on the object:

obj.system_metadata => Hash

obj.system_metadata.each do |key,value|
  puts "#{key}=#{value}"
end

See Atmos::Metadata for more detailed information.

User Metadata

There are two kinds of user metadata, listable and non-listable. Each of these is available as a hash on the object class. These can both be modified.

obj.listable_metadata => Hash

obj.listable_metadata.each do |key,value|
  puts "#{key}=#{value}"
end

obj.metadata => Hash

obj.metadata.each do |key,value|
  puts "#{key}=#{value}"
end

See Atmos::Metadata for more detailed information.

Access Control Lists (ACLs)

There are two hashes for access control available as properties on the object: user_acl and group_acl.

The keys are the Atmos usernames and the values are one of :none, :read, :write, :full.

puts obj.user_acl.inspect => {user => :full}
puts obj.group_acl.inspect => {other => :none}

See Atmos::ACL for more detailed information.

Public Class Methods

new(store, action, options = {}) click to toggle source

This constructor is only meant for internal use. Get or create an object with an Atmos::Store object:

obj = store.create
obj = store.get(:id => obj_id)
obj = store.get(:namespace => obj_id)
# File lib/atmos/object.rb, line 95
def initialize(store, action, options = {})
   Atmos::LOG.debug("obj.new options: #{options.inspect}")   
   validate_options(options)

   @deleted    = false
   @aoid       = aoid
   @store      = store
   @request    = Atmos::Request.new(:store => @store)
   @user       = @store.user

   if (action == :create)
      
         if (options[:id])
            raise Atmos::Exceptions::ArgumentException, "You can't specify an id on object creation."
         end
      
         Atmos::LOG.debug("Object.new: creating new object")
         response = @request.do(:create_object, options)
         @aoid = response.id
      
   elsif (action == :get)
      
         Atmos::LOG.debug("Retrieving object: id: #{options[:id]}; namespace: #{options[:namespace]}")
         response = @request.do(:get_object_info, options)
         @aoid = Atmos::Parser::response_get_string(response.http_response, '//xmlns:objectId')            
         Atmos::LOG.debug("Retrieved object id for namespace: #{@aoid}")
   end

end

Public Instance Methods

data(range = nil) click to toggle source

Returns all the object data in a single string. Be judicious about use of this method, since it can load the entire blob into memory.

Optional:

  • :range - range of bytes to retrieve (e.g. 0…10000)

# File lib/atmos/object.rb, line 215
def data(range = nil)
   do_delete_check
   response = @request.do(:read_object, :id => @aoid, 'Range' => range)
   response.http_response.body
end
data_as_stream(range = nil, &block) click to toggle source

Allows progressive download of the object's data. Takes a block:

obj.data_as_stream do |chunk|
   datafile.write(chunk)
end

Optional:

  • :range - range of bytes to retrieve (e.g. 0…10000)

# File lib/atmos/object.rb, line 232
def data_as_stream(range = nil, &block)
   do_delete_check
   @request.do(:read_object, :id => @aoid, 'Range' => range) do |response|
      response.read_body do |chunk| 
         block.call(chunk)
      end
   end
end
delete() click to toggle source

Deletes the object from Atmos and invalidates the object.

obj = store.create
obj.delete
# File lib/atmos/object.rb, line 201
def delete
   do_delete_check
   response = @request.do(:delete_object, :id => @aoid)
   @deleted = true
end
exists?() click to toggle source

Checks to see if the represented object exists on Atmos by requesting it's system metadata.

Returns boolean true or false.

# File lib/atmos/object.rb, line 253
def exists?
   rv = true
   begin
      @request.do(:list_system_metadata, :id => @aoid)
   rescue Atmos::Exceptions::NoSuchObjectException
      rv = false
   end
   rv
end
group_acl() click to toggle source

Lazy evaluation of hash-like object containing group access control properties of the object.

# File lib/atmos/object.rb, line 142
def group_acl
   if (@group_acl.nil?)
      @group_acl = Atmos::ACL.new(self, Atmos::ACL::GROUP)
   end
   
   @group_acl
end
listable_metadata() click to toggle source

Lazy evaluation of hash-like object containing listable metadata properties of the object.

# File lib/atmos/object.rb, line 166
def listable_metadata
   if (@listable_metadata.nil?)
      @listable_metadata = Atmos::Metadata.new(self, Atmos::Metadata::LISTABLE)
   end
   
   @listable_metadata
end
metadata() click to toggle source

Lazy evaluation of hash-like object containing non-listable properties of the object.

# File lib/atmos/object.rb, line 154
def metadata
   if (@metadata.nil?)
      @metadata = Atmos::Metadata.new(self, Atmos::Metadata::NON_LISTABLE)
   end
   
   @metadata
end
system_metadata() click to toggle source

Lazy evaluation of Hash-like object containing read-only system metadata associated with the object.

# File lib/atmos/object.rb, line 178
def system_metadata
   if (@system_metadata.nil?)
      @system_metadata = Atmos::Metadata.new(self, Atmos::Metadata::SYSTEM)
   end
   
   @system_metadata
end
truncate() click to toggle source

Truncates the object to size 0 without changing any of the Metadata or ACLs.

# File lib/atmos/object.rb, line 190
def truncate
   do_delete_check
   response = @request.do(:trunc_object, :id => @aoid, :data => nil, :length => 0)
end
update(data, range=nil) click to toggle source
# File lib/atmos/object.rb, line 242
def update(data, range=nil)    
   response = @request.do(:update_object, :id => @aoid, :data => data, 'Range' => range)
end
user_acl() click to toggle source

Lazy evaluation of hash-like object containing user access control properties of the object.

# File lib/atmos/object.rb, line 128
def user_acl
   #Atmos::LOG.warn("user_acl: #{@user_acl.inspect}")   
   if (@user_acl.nil?)
      @user_acl = Atmos::ACL.new(self, Atmos::ACL::USER)
      #Atmos::LOG.warn("user_acl: #{@user_acl.inspect}")   
   end
   
   @user_acl
end

Private Instance Methods

do_delete_check() click to toggle source
# File lib/atmos/object.rb, line 282
def do_delete_check
   raise Atmos::Exceptions::InvalidStateException if (@deleted)
end
validate_options(options) click to toggle source
# File lib/atmos/object.rb, line 286
def validate_options(options)
   invalid_values = []

   valid_options = [:checksum, :user_acl, :group_acl, :metadata, :listable_metadata, :mimetype, :length, :data, :namespace, :id].freeze
   invalid_options = options.keys - valid_options
   raise Atmos::Exceptions::ArgumentException, "Unrecognized options: #{invalid_options.inspect}" if (!invalid_options.empty?)
   
   options.each do |k,v|
      case k
      when :checksum
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Boolean))
      when :user_acl
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Hash))
      when :group_acl
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Hash))
      when  :metadata
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Hash))
      when  :listable_metadata
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Hash))
      when  :mimetype
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(String))
      when  :namespace
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(String))
      when  :length 
         invalid_values.push(k) if (options[k].nil? || !options[k].kind_of?(Integer))
      when  :data
         invalid_values.push(k) if (options[k].nil? || (!options[k].kind_of?(String) && !options[k].class.ancestors.include?(IO)))
      end
   end

   raise Atmos::Exceptions::ArgumentException, "Options of invalid type: #{invalid_values.inspect}" if (!invalid_values.empty?)
end