Skip to content

Commit 7f2457b

Browse files
Reconstruct fog-aliyun by using oss (#147)
* reconstruct the directories * reconstruct the directory * reconstruct the files * reconstruct parts of file * reconstruct parts two of file * reconstruct case test * reconstruct cover case test * reconstruct perform test Co-authored-by: zjd <1418408614@qq.com>
1 parent 87e6969 commit 7f2457b

31 files changed

+1094
-1172
lines changed

lib/fog/aliyun/models/storage/directories.rb

Lines changed: 30 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,81 +10,47 @@ class Directories < Fog::Collection
1010
model Fog::Aliyun::Storage::Directory
1111

1212
def all
13-
containers = service.get_containers
14-
return nil if containers.nil?
13+
buckets = service.get_service[0]
14+
return nil if buckets.size < 1
1515
data = []
1616
i = 0
17-
containers.each do |entry|
18-
key = entry['Prefix'][0]
19-
key[-1] = ''
20-
data[i] = { key: key }
17+
buckets.each do |b|
18+
data[i] = { key: b.name }
2119
i += 1
2220
end
23-
2421
load(data)
2522
end
2623

27-
# get method used to get a specified directory.
28-
# If the directory is not exist, this method will create a new with 'key'
29-
# In order to support multi-buckets scenario which making bucket as a solo directory, it have been expanded.
30-
# If key is a directory(including /), return an existed or a new one;
31-
# If key does not contain /, if bucket, return '', else return an existed or a new one directory;
24+
3225
def get(key, options = {})
33-
if key.is_a? Array
34-
key = key[0]
26+
data = service.get_bucket(key, options)
27+
28+
directory = new(:key => key, :is_persisted => true)
29+
30+
options = data[1]
31+
options[:max_keys] = options[:limit]
32+
directory.files.merge_attributes(options)
33+
34+
objects = []
35+
i = 0
36+
data[0].each do |o|
37+
objects[i] = {
38+
'Key' => o.key,
39+
'Type' => o.type,
40+
'Size' => o.size,
41+
'ETag' => o.etag,
42+
'LastModified' => o.last_modified
43+
}
44+
i += 1
3545
end
36-
if !key.nil? && key != '' && key != '.'
37-
key = key.chomp('/')
38-
if key.include? '/'
39-
dir = key + '/'
40-
begin
41-
ret = service.head_object(dir, options)
42-
new(key: key) if ret.data.code.to_i == 200
43-
rescue Exception => error
44-
case error.http_code.to_i
45-
when 404
46-
nil
47-
else
48-
raise(error)
49-
end
50-
end
51-
else
52-
remap_attributes(options, {
53-
:delimiter => 'delimiter',
54-
:marker => 'marker',
55-
:max_keys => 'max-keys',
56-
:prefix => 'prefix'
57-
})
58-
data = service.get_bucket(key, options)
59-
directory = new(:key => data['Name'], :is_persisted => true)
60-
options = {}
61-
for k, v in data
62-
if ['CommonPrefixes', 'Delimiter', 'IsTruncated', 'Marker', 'MaxKeys', 'Prefix'].include?(k)
63-
# Sometimes, the v will be a Array, like "Name"=>["blobstore-droplet1"], "Prefix"=>[{}], "Marker"=>[{}], "MaxKeys"=>["100"], "Delimiter"=>[{}], "IsTruncated"=>["false"]
64-
# and there needs to parse them
65-
if !v.nil? && (v.is_a? Array) && (v.size > 0)
66-
if v[0].is_a? Hash
67-
v = nil
68-
else
69-
v = v[0]
70-
end
71-
end
72-
options[k] = v
73-
end
74-
end
75-
directory.files.merge_attributes(options)
76-
if data.key?('Contents') && !data['Contents'].nil?
77-
directory.files.load(data['Contents'])
78-
else
79-
directory.files.load([])
80-
end
81-
directory
82-
end
46+
directory.files.load(objects)
47+
directory
48+
rescue AliyunOssSdk::ServerError => error
49+
if error.error_code == "NoSuchBucket"
50+
nil
8351
else
84-
new(key: '')
52+
raise(error)
8553
end
86-
rescue Fog::Aliyun::Storage::NotFound
87-
nil
8854
end
8955
end
9056
end

lib/fog/aliyun/models/storage/directory.rb

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,62 @@ module Fog
77
module Aliyun
88
class Storage
99
class Directory < Fog::Model
10+
VALID_ACLS = ['private', 'public-read', 'public-read-write']
11+
12+
attr_reader :acl
1013
identity :key, :aliases => ['Key', 'Name', 'name']
1114

15+
attribute :creation_date, :aliases => 'CreationDate', :type => 'time'
16+
17+
def acl=(new_acl)
18+
unless VALID_ACLS.include?(new_acl)
19+
raise ArgumentError.new("acl must be one of [#{VALID_ACLS.join(', ')}]")
20+
else
21+
@acl = new_acl
22+
end
23+
end
24+
1225
def destroy
1326
requires :key
14-
prefix = key + '/'
15-
ret = service.list_objects(prefix: prefix)['Contents']
16-
17-
if ret.nil?
27+
service.delete_bucket(key)
28+
true
29+
rescue AliyunOssSdk::ServerError => error
30+
if error.error_code == "NoSuchBucket"
1831
false
19-
elsif ret.size == 1
20-
service.delete_container(key)
21-
true
2232
else
23-
raise Fog::Aliyun::Storage::Error, ' Forbidden: Direction not empty!'
33+
raise(error)
34+
end
35+
end
36+
37+
def destroy!(options = {})
38+
requires :key
39+
options = {
40+
timeout: Fog.timeout,
41+
interval: Fog.interval,
42+
}.merge(options)
43+
44+
begin
45+
clear!
46+
Fog.wait_for(options[:timeout], options[:interval]) { objects_keys.size == 0 }
47+
service.delete_bucket(key)
48+
true
49+
rescue AliyunOssSdk::ServerError
2450
false
2551
end
2652
end
2753

54+
def location
55+
region = @aliyun_region_id
56+
region ||= Storage::DEFAULT_REGION
57+
@location = (bucket_location || 'oss-' + region)
58+
end
59+
60+
# NOTE: you can't change the region once the bucket is created
61+
def location=(new_location)
62+
new_location = 'oss-' + new_location unless new_location.start_with?('oss-')
63+
@location = new_location
64+
end
65+
2866
def files
2967
@files ||= begin
3068
Fog::Aliyun::Storage::Files.new(
@@ -34,25 +72,66 @@ def files
3472
end
3573
end
3674

75+
# TODO
76+
def public=(new_public)
77+
nil
78+
end
79+
80+
# TODO
3781
def public_url
3882
nil
3983
end
4084

4185
def save
4286
requires :key
4387

44-
# Checking whether the key is a bucket and meet the multi-bucket scenario.
45-
# If the key is a existing bucket, return it directly.
46-
key = key.chomp('/')
47-
if !key.nil? && key != '' && key != '.' && !(key.include? '/')
48-
data = service.get_bucket(key)
49-
if data.class == Hash && data.key?('Code') && !data['Code'].nil? && !data['Code'].empty?
50-
service.put_container(key)
51-
end
52-
end
88+
options = {}
89+
90+
options['x-oss-acl'] = acl if acl
91+
92+
# https://help.aliyun.com/document_detail/31959.html
93+
# if !persisted?
94+
# # There is a sdk bug that location can not be set
95+
# options[:location] = location
96+
# end
97+
98+
service.put_bucket(key, options)
99+
attributes[:is_persisted] = true
53100

54101
true
55102
end
103+
104+
def persisted?
105+
# is_persisted is true in case of directories.get or after #save
106+
# creation_date is set in case of directories.all
107+
attributes[:is_persisted] || !!attributes[:creation_date]
108+
end
109+
110+
private
111+
112+
def bucket_location
113+
requires :key
114+
return nil unless persisted?
115+
service.get_bucket_location(key)
116+
end
117+
118+
def objects_keys
119+
requires :key
120+
bucket_query = service.get_bucket(key)
121+
122+
object_keys = []
123+
i = 0
124+
bucket_query[0].each do |o|
125+
object_keys[i] = o.key
126+
i += 1
127+
end
128+
object_keys
129+
end
130+
131+
def clear!
132+
requires :key
133+
service.delete_multiple_objects(key, objects_keys) if objects_keys.size > 0
134+
end
56135
end
57136
end
58137
end

0 commit comments

Comments
 (0)