Prefix_delete for cellar
This commit is contained in:
parent
e2c583480d
commit
07134684d4
2 changed files with 111 additions and 9 deletions
|
@ -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
|
||||
|
|
|
@ -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>"bf1d737a4d46a19f3bced6905cc8b902"</ETag>
|
||||
<Size>142863</Size>
|
||||
<StorageClass>STANDARD</StorageClass>
|
||||
</Contents>
|
||||
<Contents>
|
||||
<Key>sample2.jpg</Key>
|
||||
<LastModified>2011-02-26T01:56:20.000Z</LastModified>
|
||||
<ETag>"bf1d737a4d46a19f3bced6905cc8b902"</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
|
||||
|
|
Loading…
Reference in a new issue