1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Refactoring: #each_part in MockObject.

@bytes => @bytes_used in MockObject as well, for consistency with
MockContainer.
This commit is contained in:
Ash Wilson 2013-12-20 11:46:25 -05:00
parent 4e309df4e2
commit 6642ae013d
7 changed files with 84 additions and 87 deletions

View file

@ -55,7 +55,7 @@ module Fog
return not_found(object) unless o
# What happens if o isn't a static large object?
raise Fog::Storage::Rackspace::BadRequest.new unless o.static_manifest
raise Fog::Storage::Rackspace::BadRequest.new unless o.static_manifest?
segments = Fog::JSON.decode(o.body)
paths = segments.map { |s| s['path'] }

View file

@ -54,7 +54,7 @@ module Fog
results << {
"hash" => mock_file.hash,
"last_modified" => mock_file.last_modified.strftime('%Y-%m-%dT%H:%M:%S.%L'),
"bytes" => mock_file.bytes,
"bytes" => mock_file.bytes_used,
"name" => key,
"content_type" => mock_file.content_type
}

View file

@ -36,38 +36,9 @@ module Fog
body, size = "", 0
# Recognize an X-Object-Manifest header.
prefix = o.large_object_prefix
if prefix
# Concatenate the contents and sizes of each matching object.
# Note that cname and oprefix are already escaped.
cname, oprefix = prefix.split('/', 2)
target_container = data[cname]
if target_container
target_container.objects.each do |name, obj|
next unless name.start_with? oprefix
body << obj.body
size += obj.bytes
end
end
elsif o.static_manifest
segments = Fog::JSON.decode(o.body)
segments.each do |segment|
cname, oname = segment['path'].split('/', 2)
target_container = mock_container cname
next unless target_container
target_object = target_container.mock_object oname
next unless target_object
body << target_object.body
size += target_object.bytes
end
else
body = o.body
size = o.bytes
o.each_part do |part|
body << part.body
size += part.bytes_used
end
if block_given?
@ -75,9 +46,9 @@ module Fog
block.call(body, 0, size)
end
# TODO set headers
response = Excon::Response.new
response.body = body
response.headers = o.to_headers
response
end
end

View file

@ -30,41 +30,16 @@ module Fog
headers = o.to_headers
prefix = o.large_object_prefix
if prefix
# Concatenate the contents and sizes of each matching object.
# Note that cname and oprefix are already escaped.
cname, oprefix = prefix.split('/', 2)
target_container = data[cname]
if target_container
ohash = target_container.objects
matching = ohash.keys.select { |k| k.start_with? oprefix }
hashes = matching.sort.map { |k| ohash[k].hash }
headers['Etag'] = "\"#{Digest::MD5.hexdigest(hashes.join)}\""
end
elsif o.static_manifest
hashes, length = [], 0
segments = Fog::JSON.decode(o.body)
segments.each do |segment|
cname, oname = segment['path'].split('/', 2)
target_container = mock_container cname
next unless target_container
target_object = target_container.mock_object oname
next unless target_object
hashes << target_object.hash
length += target_object.bytes
end
headers['Etag'] = "\"#{Digest::MD5.hexdigest(hashes.join)}\""
headers['Content-Length'] = length.to_s
headers['X-Static-Large-Object'] = "True"
hashes, length = [], 0
o.each_part do |part|
hashes << part.hash
length += part.bytes_used
end
headers['Etag'] = "\"#{Digest::MD5.hexdigest(hashes.join)}\""
headers['Content-Length'] = length.to_s
headers['X-Static-Large-Object'] = "True" if o.static_manifest?
response = Excon::Response.new
response.status = 200
response.headers = headers

View file

@ -25,20 +25,14 @@ module Fog
class Mock
def put_container(name, options={})
escaped = Fog::Rackspace.escape(name)
container = MockContainer.new
existed = ! mock_container(name).nil?
container = add_container(name)
options.keys.each do |k|
container.meta[k] = options[k].to_s if k =~ /^X-Container-Meta/
end
data[escaped] = container
response = Excon::Response.new
if data.has_key?(escaped)
response.status = 202 # Accepted
else
response.status = 201 # Created
end
response.status = existed ? 202 : 201
response
end
end

View file

@ -77,7 +77,7 @@ module Fog
errors << [segment[:path], 'Etag Mismatch']
end
unless target_object.bytes == segment[:size_bytes]
unless target_object.bytes_used == segment[:size_bytes]
errors << [segment[:path], 'Size Mismatch']
end
end

View file

@ -121,9 +121,10 @@ module Fog
include Common
class MockContainer
attr_reader :objects, :meta
attr_reader :objects, :meta, :service
def initialize
def initialize service
@service = service
@objects, @meta = {}, {}
end
@ -132,7 +133,7 @@ module Fog
end
def bytes_used
@objects.values.map { |o| o.bytes }.inject(0) { |a, b| a + b }
@objects.values.map { |o| o.bytes_used }.inject(0) { |a, b| a + b }
end
def to_headers
@ -151,7 +152,7 @@ module Fog
end
def add_object name, data
@objects[Fog::Rackspace.escape(name)] = MockObject.new(data)
@objects[Fog::Rackspace.escape(name)] = MockObject.new(data, service)
end
def remove_object name
@ -160,14 +161,15 @@ module Fog
end
class MockObject
attr_reader :hash, :bytes, :content_type, :last_modified
attr_reader :body, :meta
attr_reader :hash, :bytes_used, :content_type, :last_modified
attr_reader :body, :meta, :service
attr_accessor :static_manifest
def initialize data
def initialize data, service
data = Fog::Storage.parse_data(data)
@service = service
@bytes = data[:headers]['Content-Length']
@bytes_used = data[:headers]['Content-Length']
@content_type = data[:headers]['Content-Type']
if data[:body].respond_to? :read
@body = data[:body].read
@ -180,6 +182,57 @@ module Fog
@static_manifest = false
end
def static_manifest?
@static_manifest
end
def dynamic_manifest?
! large_object_prefix.nil?
end
def each_part
case
when dynamic_manifest?
# Concatenate the contents and sizes of each matching object.
# Note that cname and oprefix are already escaped.
cname, oprefix = large_object_prefix.split('/', 2)
target_container = service.data[cname]
if target_container
keys = target_container.objects.keys.
select { |name| name.start_with? oprefix }.
sort
keys.each do |name|
yield target_container.objects[name]
end
else
Fog::Logger.warning "Invalid container in dynamic object manifest: #{cname}"
yield self
end
when static_manifest?
Fog::JSON.decode(body).each do |segment|
cname, oname = segment['path'].split('/', 2)
cont = service.mock_container cname
unless cont
Fog::Logger.warning "Invalid container in static object manifest: #{cname}"
next
end
obj = cont.mock_object oname
unless obj
Fog::Logger.warning "Invalid object in static object manifest: #{oname}"
next
end
yield obj
end
else
yield self
end
end
def large_object_prefix
@meta['X-Object-Manifest']
end
@ -187,7 +240,7 @@ module Fog
def to_headers
{
'Content-Type' => @content_type,
'Content-Length' => @bytes,
'Content-Length' => @bytes_used,
'Last-Modified' => @last_modified.strftime('%a, %b %d %Y %H:%M:%S %Z'),
'ETag' => @hash
}.merge(@meta)
@ -239,6 +292,10 @@ module Fog
mock_container(cname) or raise Fog::Storage::Rackspace::NotFound.new
end
def add_container cname
data[Fog::Rackspace.escape(cname)] = MockContainer.new(self)
end
def remove_container cname
data.delete Fog::Rackspace.escape(cname)
end