Class: Fog::Storage::HP::Mock

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/fog/hp/requests/storage/get_object.rb,
lib/fog/hp/storage.rb,
lib/fog/hp/requests/storage/put_object.rb,
lib/fog/hp/requests/storage/head_object.rb,
lib/fog/hp/requests/storage/post_object.rb,
lib/fog/hp/requests/storage/delete_object.rb,
lib/fog/hp/requests/storage/get_container.rb,
lib/fog/hp/requests/storage/put_container.rb,
lib/fog/hp/requests/storage/get_containers.rb,
lib/fog/hp/requests/storage/head_container.rb,
lib/fog/hp/requests/storage/post_container.rb,
lib/fog/hp/requests/storage/head_containers.rb,
lib/fog/hp/requests/storage/delete_container.rb,
lib/fog/hp/requests/storage/get_shared_object.rb,
lib/fog/hp/requests/storage/put_shared_object.rb,
lib/fog/hp/requests/storage/head_shared_object.rb,
lib/fog/hp/requests/storage/get_object_temp_url.rb,
lib/fog/hp/requests/storage/delete_shared_object.rb,
lib/fog/hp/requests/storage/get_shared_container.rb,
lib/fog/hp/requests/storage/head_shared_container.rb

Overview

:nodoc:all

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#cdn, #create_temp_url, #generate_object_temp_url, #get_object_http_url, #get_object_https_url, #header_to_perm_acl, #perm_acl_to_header, #perm_to_acl, #public_url, #url

Constructor Details

#initialize(options = {}) ⇒ Mock

Returns a new instance of Mock.



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/fog/hp/storage.rb', line 287

def initialize(options={})
  # deprecate hp_account_id
  if options[:hp_account_id]
    Fog::Logger.deprecation(":hp_account_id is deprecated, please use :hp_access_key instead.")
    @hp_access_key = options.delete(:hp_account_id)
  end
  @hp_access_key = options[:hp_access_key]
  unless @hp_access_key
    raise ArgumentError.new("Missing required arguments: hp_access_key. :hp_account_id is deprecated, please use :hp_access_key instead.")
  end
  @hp_secret_key = options[:hp_secret_key]
  @hp_tenant_id = options[:hp_tenant_id]
  @os_account_meta_temp_url_key = options[:os_account_meta_temp_url_key]

  @hp_storage_uri = options[:hp_auth_uri]

  uri = URI.parse(@hp_storage_uri)
  @host   = uri.host
  @path   = uri.path
  @persistent = options[:persistent] || false
  @port   = uri.port
  @scheme = uri.scheme
end

Class Method Details

.acls(type) ⇒ Object



267
268
269
# File 'lib/fog/hp/storage.rb', line 267

def self.acls(type)
  type
end

.dataObject



271
272
273
274
275
276
277
278
279
280
281
# File 'lib/fog/hp/storage.rb', line 271

def self.data
  @data ||= Hash.new do |hash, key|
    hash[key] = {
      :acls => {
        :container => {},
        :object => {}
      },
      :containers => {}
    }
    end
end

.resetObject



283
284
285
# File 'lib/fog/hp/storage.rb', line 283

def self.reset
  @data = nil
end

Instance Method Details

#dataObject



311
312
313
# File 'lib/fog/hp/storage.rb', line 311

def data
  self.class.data[@hp_access_key]
end

#delete_container(container_name) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/fog/hp/requests/storage/delete_container.rb', line 21

def delete_container(container_name)
  response = Excon::Response.new
  if self.data[:containers][container_name].nil?
    response.status = 404
    raise Fog::Storage::HP::NotFound
  elsif self.data[:containers][container_name] && !self.data[:containers][container_name][:objects].empty?
    response.status = 409
    raise(Excon::Errors.status_error({:expects => 204}, response))
  else
    self.data[:containers].delete(container_name)
    response.status = 204
  end
  response
end

#delete_object(container_name, object_name, options = {}) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/fog/hp/requests/storage/delete_object.rb', line 22

def delete_object(container_name, object_name, options = {})
  response = Excon::Response.new
  if container = self.data[:containers][container_name]
    if (object = container[:objects][object_name])
      response.status = 204
      container[:objects].delete(object_name)
    else
      raise Fog::Storage::HP::NotFound
    end
  else
    raise Fog::Storage::HP::NotFound
  end
  response
end

#delete_shared_object(shared_object_url) ⇒ Object



25
26
27
28
29
# File 'lib/fog/hp/requests/storage/delete_shared_object.rb', line 25

def delete_shared_object(shared_object_url)
  response = Excon::Response.new
  response.status = 204
  response
end

#get_container(container_name, options = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/fog/hp/requests/storage/get_container.rb', line 43

def get_container(container_name, options = {})
  unless container_name
    raise ArgumentError.new('container_name is required')
  end
  if options['delimiter']
    Fog::Mock.not_implemented
  end
  response = Excon::Response.new
  obj_count = 0
  obj_total_bytes = 0
  if container = self.data[:containers][container_name]
    contents = container[:objects].values.sort {|x,y| x['Key'] <=> y['Key']}.reject do |object|
        (options['prefix'] && object['Key'][0...options['prefix'].length] != options['prefix']) ||
        (options['marker'] && object['Key'] <= options['marker'])
      end.map do |object|
        obj_count = obj_count + 1
        obj_total_bytes = obj_total_bytes + object['Content-Length'].to_i
        data = {
          'name'          => object['Key'],
          'hash'          => object['ETag'],
          'bytes'         => object['Content-Length'].to_i,
          'content_type'  => object['Content-Type'],
          'last_modified' => Time.parse(object['Date'])
        }
      data
    end

    response.status = 200
    response.body = contents
    response.headers = {
      'X-Container-Object-Count' => obj_count,
      'X-Container-Bytes-Used'   => obj_total_bytes,
      'Accept-Ranges'            => 'bytes',
      'Content-Type'             => container['Content-Type'],
      'Content-Length'           => container['Content-Length']
    }
    response
  else
    raise Fog::Storage::HP::NotFound
  end
end

#get_containers(options = {}) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fog/hp/requests/storage/get_containers.rb', line 32

def get_containers(options = {})
  response = Excon::Response.new
  acc_cont_count = 0
  acc_obj_count = 0
  acc_obj_bytes = 0
  containers = self.data[:containers].map do |key, container|
    acc_cont_count = acc_cont_count + 1
    obj_count = 0
    container[:objects].values.map do |object|
      acc_obj_count = acc_obj_count + 1
      acc_obj_bytes = acc_obj_bytes + object['Content-Length'].to_i
      obj_count = obj_count + 1
      container['Object-Count'] = obj_count
    end
    data = {
      'name'  => key,
      'count' => container['Object-Count'].to_i,
      'bytes' => container['Content-Length'].to_i
    }
    data
  end
  response.body = containers
  response.headers = {
    'X-Account-Object-Count'    => acc_obj_count,
    'X-Account-Bytes-Used'      => acc_obj_bytes,
    'X-Account-Container-Count' => acc_cont_count,
    'Accept-Ranges'             => 'bytes'
  }
  response.status = 200
  response
end

#get_object(container_name, object_name, options = {}, &block) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/fog/hp/requests/storage/get_object.rb', line 33

def get_object(container_name, object_name, options = {}, &block)
  unless container_name
    raise ArgumentError.new('container_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end
  response = Excon::Response.new
  if (container = self.data[:containers][container_name])
    if (object = container[:objects][object_name])
      if options['If-Match'] && options['If-Match'] != object['ETag']
        response.status = 412
      elsif options['If-Modified-Since'] && options['If-Modified-Since'] >= Time.parse(object['Last-Modified'])
        response.status = 304
      elsif options['If-None-Match'] && options['If-None-Match'] == object['ETag']
        response.status = 304
      elsif options['If-Unmodified-Since'] && options['If-Unmodified-Since'] < Time.parse(object['Last-Modified'])
        response.status = 412
      else
        response.status = 200
        for key, value in object
          case key
          when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-Length', 'Content-MD5', 'Content-Type', 'ETag', 'Expires', 'Last-Modified', /^X-Object-Meta-/
            response.headers[key] = value
          end
        end
        unless block_given?
          response.body = object[:body]
        else
          data = StringIO.new(object[:body])
          remaining = data.length
          while remaining > 0
            chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
            block.call(chunk)
            remaining -= Excon::CHUNK_SIZE
          end
        end
      end
    else
      raise Fog::Storage::HP::NotFound
    end
  else
    raise Fog::Storage::HP::NotFound
  end
  response
end

#get_object_temp_url(container, object, expires, method) ⇒ Object



18
19
20
21
22
# File 'lib/fog/hp/requests/storage/get_object_temp_url.rb', line 18

def get_object_temp_url(container, object, expires, method)
  @hp_storage_uri = "https://swift-cluster.example.com:443/v1/account"

  generate_object_temp_url(container, object, expires, method)
end

#get_shared_container(shared_container_url, options = {}) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fog/hp/requests/storage/get_shared_container.rb', line 45

def get_shared_container(shared_container_url, options = {})
  response = Excon::Response.new
  data = {
    'name'          => Fog::Mock.random_letters(10),
    'hash'          => Fog::HP::Mock.etag,
    'bytes'         => 11,
    'content_type'  => "text/plain",
    'last_modified' => Time.now
  }
  response.status = 200
  response.body = [data]
  response.headers = {
    'X-Container-Object-Count' => 1,
    'X-Container-Bytes-Used'   => 11,
    'Accept-Ranges'            => 'bytes',
    'Content-Type'             => "application/json",
    'Content-Length'           => 11,
    'X-Trans-Id'               => "tx#{Fog::Mock.random_hex(32)}"
  }
  response
end

#get_shared_object(shared_object_url, &block) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fog/hp/requests/storage/get_shared_object.rb', line 34

def get_shared_object(shared_object_url, &block)
  response = Excon::Response.new
  response.status = 200
  response.headers = {
    'Last-Modified'            => Date.today.rfc822,
    'Etag'                     => Fog::HP::Mock.etag,
    'Accept-Ranges'            => 'bytes',
    'Content-Type'             => "text/plain",
    'Content-Length'           => 11,
    'X-Trans-Id'               => "tx#{Fog::Mock.random_hex(32)}"
  }
  unless block_given?
    response.body = "This is a sample text.\n"
  else
    data = StringIO.new("This is a sample text.\n")
    remaining = data.length
    while remaining > 0
      chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
      block.call(chunk)
      remaining -= Excon::CHUNK_SIZE
    end
  end
  response
end

#head_container(container_name) ⇒ Object



27
28
29
30
31
32
# File 'lib/fog/hp/requests/storage/head_container.rb', line 27

def head_container(container_name)
  response = get_container(container_name)
  response.body = nil
  response.status = 204
  response
end

#head_containersObject



24
25
26
27
28
# File 'lib/fog/hp/requests/storage/head_containers.rb', line 24

def head_containers
  response = get_containers
  response.body = nil
  response
end

#head_object(container_name, object_name, options = {}) ⇒ Object



22
23
24
25
26
27
# File 'lib/fog/hp/requests/storage/head_object.rb', line 22

def head_object(container_name, object_name, options = {})
  response = get_object(container_name, object_name, options)
  response.body = nil
  response.status = 200
  response
end

#head_shared_container(shared_container_url) ⇒ Object



31
32
33
34
35
36
# File 'lib/fog/hp/requests/storage/head_shared_container.rb', line 31

def head_shared_container(shared_container_url)
  response = get_shared_container(shared_container_url)
  response.body = nil
  response.status = 204
  response
end

#head_shared_object(shared_object_url) ⇒ Object



25
26
27
28
29
30
# File 'lib/fog/hp/requests/storage/head_shared_object.rb', line 25

def head_shared_object(shared_object_url)
  response = get_shared_object(shared_object_url)
  response.body = nil
  response.status = 200
  response
end

#post_container(container_name, headers = {}) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/fog/hp/requests/storage/post_container.rb', line 22

def post_container(container_name, headers = {})
  if self.data[:containers][container_name].nil?
    raise Fog::Storage::HP::NotFound
  end
  response = Excon::Response.new
  response.status = 204
  response
end

#post_object(container_name, object_name, headers = {}) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/fog/hp/requests/storage/post_object.rb', line 23

def post_object(container_name, object_name, headers = {})
  response = Excon::Response.new
  if container = self.data[:containers][container_name]
    response.status = 202
    object = container[:objects][object_name]

    for key, value in headers
      case key
      when 'Content-Disposition', 'Content-Encoding', 'X-Delete-At', 'X-Delete-After', /^X-Object-Meta-/
        object[key] = value unless value.nil?
      end
    end

    container[:objects][object_name] = object
    response.headers = {
      'Content-Length'  => object['Content-Length'],
      'Content-Type'    => object['Content-Type'],
      'ETag'            => object['ETag'],
      'Date'            => object['Date']
    }
  else
    raise Fog::Storage::HP::NotFound
  end
  response
end

#put_container(container_name, options = {}) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/fog/hp/requests/storage/put_container.rb', line 22

def put_container(container_name, options = {})
  read_h  = options['X-Container-Read']  || ''
  write_h = options['X-Container-Write'] || ''
  unless options
    read_acl, write_acl = self.class.header_to_perm_acl(read_h, write_h)
    self.data[:acls][:container][container_name] = {:read_acl => read_acl, :write_acl => write_acl}
  end

  response = Excon::Response.new
  container = {
    :objects  => {}
  }
  if self.data[:containers][container_name]
    response.status = 202
  else
    response.status = 201
    self.data[:containers][container_name] = container
  end
  response
end

#put_object(container_name, object_name, data, options = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/fog/hp/requests/storage/put_object.rb', line 39

def put_object(container_name, object_name, data, options = {})
  response = Excon::Response.new
  ### Take care of case of copy operation
  source = options['X-Copy-From']
  if (source && data.nil?)
    # split source container and object
    _, source_container_name, source_object_name = source.split('/')
    # dup object into target object
    source_container = self.data[:containers][source_container_name]
    container = self.data[:containers][container_name]
    if (source_container && container)
      response.status = 201
      source_object = source_container[:objects][source_object_name]
      target_object = source_object.dup
      target_object.merge!({
        'Key'    => object_name,
        'Date'   => Fog::Time.now.to_date_header
      })
      container[:objects][object_name] = target_object
    else
      raise Fog::Storage::HP::NotFound
    end
  else
    data = Fog::Storage.parse_data(data)
    unless data[:body].is_a?(String)
      data[:body] = data[:body].read
    end
    if (container = self.data[:containers][container_name])
      response.status = 201
      object = {
        :body             => data[:body],
        'Content-Type'    => options['Content-Type'] || data[:headers]['Content-Type'],
        'ETag'            => Fog::HP::Mock.etag,
        'Key'             => object_name,
        'Date'            => Fog::Time.now.to_date_header,
        'Content-Length'  => options['Content-Length'] || data[:headers]['Content-Length'],
      }

      for key, value in options
        case key
        when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-MD5', 'Expires', /^X-Object-Meta-/
          object[key] = value
        end
      end

      container[:objects][object_name] = object
      response.headers = {
        'Content-Length'  => object['Content-Length'],
        'Content-Type'    => object['Content-Type'],
        'ETag'            => object['ETag'],
        'Date'            => object['Date']
      }
    else
      raise Fog::Storage::HP::NotFound
    end
  end
  response
end

#put_shared_object(shared_container_url, object_name, data, options = {}, &block) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fog/hp/requests/storage/put_shared_object.rb', line 45

def put_shared_object(shared_container_url, object_name, data, options = {}, &block)
  response = Excon::Response.new
  data = Fog::Storage.parse_data(data)
  unless data[:body].is_a?(String)
    data[:body] = data[:body].read
  end
  response.status = 201
  object = {
    :body             => data[:body],
    'Content-Type'    => options['Content-Type'] || data[:headers]['Content-Type'],
    'ETag'            => Fog::HP::Mock.etag,
    'Key'             => object_name,
    'Date'            => Fog::Time.now.to_date_header,
    'Content-Length'  => options['Content-Length'] || data[:headers]['Content-Length'],
  }

  for key, value in options
    case key
    when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-MD5', 'Expires', /^X-Object-Meta-/
      object[key] = value
    end
  end

  response.headers = {
    'Content-Length'  => object['Content-Length'],
    'Content-Type'    => object['Content-Type'],
    'ETag'            => object['ETag'],
    'Date'            => object['Date']
  }

  response
end

#reset_dataObject



315
316
317
# File 'lib/fog/hp/storage.rb', line 315

def reset_data
  self.class.data.delete(@hp_access_key)
end