Prefix_delete for cellar

This commit is contained in:
Frederic Merizen 2018-02-14 18:58:22 +01:00
parent e2c583480d
commit 07134684d4
2 changed files with 111 additions and 9 deletions

View file

@ -12,12 +12,11 @@ module ActiveStorage
end
def download(key)
# TODO: error handling
if block_given?
instrument :streaming_download, key: key do
http_start do |http|
request = Net::HTTP::Get.new(URI::join(@endpoint, "/#{key}"))
sign(request, key)
http.request(request) do |response|
http.request(get_request(key)) do |response|
response.read_body do |chunk|
yield(chunk.force_encoding(Encoding::BINARY))
end
@ -27,9 +26,7 @@ module ActiveStorage
else
instrument :download, key: key do
http_start do |http|
request = Net::HTTP::Get.new(URI::join(@endpoint, "/#{key}"))
sign(request, key)
response = http.request(request)
response = http.request(get_request(key))
if response.is_a?(Net::HTTPSuccess)
response.body.force_encoding(Encoding::BINARY)
end
@ -39,11 +36,23 @@ module ActiveStorage
end
def delete(key)
# TODO: error handling
instrument :delete, key: key do
http_start do |http|
request = Net::HTTP::Delete.new(URI::join(@endpoint, "/#{key}"))
sign(request, key)
http.request(request)
perform_delete(http, key)
end
end
end
def delete_prefixed(prefix)
# TODO: error handling
# TODO: handle pagination if more than 1000 keys
instrument :delete_prefixed, prefix: prefix do
http_start do |http|
list_prefixed(http, prefix).each do |key|
# TODO: use bulk delete instead
perform_delete(http, key)
end
end
end
end
@ -112,5 +121,47 @@ module ActiveStorage
"#{canonicalized_amz_headers}#{canonicalized_resource}"
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), @secret_access_key, string_to_sign)).strip
end
def list_prefixed(http, prefix)
request = Net::HTTP::Get.new(URI::join(@endpoint, "/?list-type=2&prefix=#{prefix}"))
sign(request, "")
response = http.request(request)
if response.is_a?(Net::HTTPSuccess)
parse_bucket_listing(response.body)
end
end
def parse_bucket_listing(bucket_listing_xml)
doc = Nokogiri::XML(bucket_listing_xml)
doc
.xpath('//xmlns:Contents/xmlns:Key')
.map{ |k| k.text }
end
def get_request(key)
request = Net::HTTP::Get.new(URI::join(@endpoint, "/#{key}"))
sign(request, key)
request
end
def bulk_deletion_request_body(keys)
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.Delete do
xml.Quiet("true")
keys.each do |k|
xml.Object do
xml.Key(k)
end
end
end
end
builder.to_xml
end
def perform_delete(http, key)
request = Net::HTTP::Delete.new(URI::join(@endpoint, "/#{key}"))
sign(request, key)
http.request(request)
end
end
end

View file

@ -112,4 +112,55 @@ describe 'CellarService' do
)
end
end
describe 'parse_bucket_listing' do
let(:response) do
'<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>example-bucket</Name>
<Prefix></Prefix>
<KeyCount>2</KeyCount>
<MaxKeys>1000</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>sample1.jpg</Key>
<LastModified>2011-02-26T01:56:20.000Z</LastModified>
<ETag>&quot;bf1d737a4d46a19f3bced6905cc8b902&quot;</ETag>
<Size>142863</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>sample2.jpg</Key>
<LastModified>2011-02-26T01:56:20.000Z</LastModified>
<ETag>&quot;bf1d737a4d46a19f3bced6905cc8b902&quot;</ETag>
<Size>142863</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>'
end
subject { cellar_service.send(:parse_bucket_listing, response) }
it { is_expected.to eq(["sample1.jpg", "sample2.jpg"]) }
end
describe 'bulk_deletion_request_body' do
let(:expected_response) do
'<?xml version="1.0" encoding="UTF-8"?>
<Delete>
<Quiet>true</Quiet>
<Object>
<Key>chapi</Key>
</Object>
<Object>
<Key>chapo</Key>
</Object>
</Delete>
'
end
subject { cellar_service.send(:bulk_deletion_request_body, ['chapi', 'chapo']) }
it { is_expected.to eq(expected_response) }
end
end