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/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/head_containers.rb,
lib/fog/hp/requests/storage/delete_container.rb

Overview

:nodoc:all

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#acl_to_header, #cdn, #header_to_acl, #url

Constructor Details

#initialize(options = {}) ⇒ Mock

Returns a new instance of Mock.



109
110
111
112
113
# File 'lib/fog/hp/storage.rb', line 109

def initialize(options={})
  require 'mime/types'
  @hp_secret_key = options[:hp_secret_key]
  @hp_account_id = options[:hp_account_id]
end

Class Method Details

.acls(type) ⇒ Object



89
90
91
# File 'lib/fog/hp/storage.rb', line 89

def self.acls(type)
  type
end

.dataObject



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/fog/hp/storage.rb', line 93

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

.resetObject



105
106
107
# File 'lib/fog/hp/storage.rb', line 105

def self.reset
  @data = nil
end

Instance Method Details

#dataObject



115
116
117
# File 'lib/fog/hp/storage.rb', line 115

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

#delete_container(container_name) ⇒ Object



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

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



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

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

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



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
# File 'lib/fog/hp/requests/storage/get_container.rb', line 46

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



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
# File 'lib/fog/hp/requests/storage/get_containers.rb', line 35

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



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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/fog/hp/requests/storage/get_object.rb', line 32

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

#head_container(container_name) ⇒ Object



30
31
32
33
34
# File 'lib/fog/hp/requests/storage/head_container.rb', line 30

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

#head_containersObject



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

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

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



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

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

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



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

def put_container(container_name, options = {})
  acl = options['X-Container-Read'] || 'private'
  if !['private', 'public-read'].include?(acl)
    #raise Excon::Errors::BadRequest.new('invalid X-Container-Read')
  else
    self.data[:acls][:container][container_name] = self.class.acls(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



31
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
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
# File 'lib/fog/hp/requests/storage/put_object.rb', line 31

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

#reset_dataObject



119
120
121
# File 'lib/fog/hp/storage.rb', line 119

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