commit
d7925f5b12
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
config.yml
|
||||
cs_credentials.json
|
||||
pids
|
||||
|
@ -2,11 +2,13 @@ language: ruby
|
||||
rvm:
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
services: riak
|
||||
before_install:
|
||||
- sh .travis/install_riakcs.sh
|
||||
before_script:
|
||||
- cp config.yml.example config.yml
|
||||
script: rake test
|
||||
notifications:
|
||||
email: false
|
||||
webhooks:
|
||||
urls:
|
||||
- http://hook-juggler.heroku.com/hooks/travis
|
||||
|
32
.travis/install_riakcs.sh
Normal file
32
.travis/install_riakcs.sh
Normal file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl http://apt.basho.com/gpg/basho.apt.key | sudo apt-key add -
|
||||
sudo bash -c "echo deb http://apt.basho.com $(lsb_release -sc) main > /etc/apt/sources.list.d/basho.list"
|
||||
sudo apt-get update
|
||||
|
||||
sudo apt-get install -o Dpkg::Options::="--force-confnew" -q -y riak=1.4.2-1
|
||||
sudo apt-get install -q -y riak-cs=1.4.1-1
|
||||
sudo apt-get install -q -y stanchion=1.4.1-1
|
||||
|
||||
sudo bash -c "echo '127.0.0.1 cs.example.com' >> /etc/hosts"
|
||||
|
||||
sudo cp .travis/riak.app.config /etc/riak/app.config
|
||||
sudo cp .travis/riak.vm.args /etc/riak/vm.args
|
||||
sudo cp .travis/riakcs.app.config /etc/riak-cs/app.config
|
||||
sudo cp .travis/riakcs.vm.args /etc/riak-cs/vm.args
|
||||
sudo cp .travis/stanchion.app.config /etc/stanchion/app.config
|
||||
sudo cp .travis/stanchion.vm.args /etc/stanchion/vm.args
|
||||
|
||||
sudo service riak start
|
||||
sudo service riak-cs start
|
||||
sudo service stanchion start
|
||||
|
||||
sleep 4
|
||||
|
||||
curl -H 'Content-Type: application/json' -X POST http://localhost:8080/riak-cs/user --data '{"email":"admin@5apps.com", "name":"admin"}' -o cs_admin_credentials.json
|
||||
cat cs_admin_credentials.json
|
||||
|
||||
curl -H 'Content-Type: application/json' -X POST http://localhost:8080/riak-cs/user --data '{"email":"liquorcabinet@5apps.com", "name":"liquor cabinet"}' -o cs_credentials.json
|
||||
cat cs_credentials.json
|
||||
|
||||
echo "\nFinished"
|
135
.travis/riak.app.config
Normal file
135
.travis/riak.app.config
Normal file
@ -0,0 +1,135 @@
|
||||
[
|
||||
{kernel, [
|
||||
{inet_dist_listen_max, 7999},
|
||||
{inet_dist_listen_min, 6000}
|
||||
]},
|
||||
{lager, [
|
||||
{crash_log, "/var/log/riak/crash.log"},
|
||||
{crash_log_count, 5},
|
||||
{crash_log_date, "$D0"},
|
||||
{crash_log_msg_size, 65536},
|
||||
{crash_log_size, 10485760},
|
||||
{error_logger_hwm, 100},
|
||||
{error_logger_redirect, true},
|
||||
{handlers, [
|
||||
{lager_file_backend, [
|
||||
{"/var/log/riak/error.log", error, 10485760, "$D0", 5},
|
||||
{"/var/log/riak/console.log", info, 10485760, "$D0", 5}
|
||||
]}
|
||||
]}
|
||||
]},
|
||||
{merge_index, [
|
||||
{buffer_rollover_size, 1048576},
|
||||
{data_root, "/var/lib/riak/merge_index"},
|
||||
{max_compact_segments, 20}
|
||||
]},
|
||||
{riak_api, [
|
||||
{pb, [
|
||||
{"127.0.0.1", 8087}
|
||||
]},
|
||||
{pb_backlog, 128}
|
||||
]},
|
||||
{riak_control, [
|
||||
{admin, true},
|
||||
{auth, userlist},
|
||||
{enabled, false},
|
||||
{userlist, [
|
||||
{"user", "pass"}
|
||||
]}
|
||||
]},
|
||||
{riak_core, [
|
||||
{cluster_mgr, {"127.0.0.1", 9085}},
|
||||
{default_bucket_props, [
|
||||
{allow_mult, true}
|
||||
]},
|
||||
{dtrace_support, false},
|
||||
{handoff_port, 8099},
|
||||
{http, [
|
||||
{"127.0.0.1", 8098}
|
||||
]},
|
||||
{platform_bin_dir, "/usr/sbin"},
|
||||
{platform_data_dir, "/var/lib/riak"},
|
||||
{platform_etc_dir, "/etc/riak"},
|
||||
{platform_lib_dir, "/usr/lib/riak"},
|
||||
{platform_log_dir, "/var/log/riak"},
|
||||
{ring_creation_size, 64},
|
||||
{ring_state_dir, "/var/lib/riak/ring"}
|
||||
]},
|
||||
{riak_jmx, [
|
||||
{enabled, false}
|
||||
]},
|
||||
{riak_kv, [
|
||||
{add_paths, [
|
||||
"/usr/lib/riak-cs/lib/riak_cs-1.4.1/ebin"
|
||||
]},
|
||||
{anti_entropy, {on, [
|
||||
]}},
|
||||
{anti_entropy_build_limit, {1, 3600000}},
|
||||
{anti_entropy_concurrency, 2},
|
||||
{anti_entropy_data_dir, "/var/lib/riak/anti_entropy"},
|
||||
{anti_entropy_expire, 604800000},
|
||||
{anti_entropy_leveldb_opts, [
|
||||
{write_buffer_size, 4194304},
|
||||
{max_open_files, 20}
|
||||
]},
|
||||
{anti_entropy_tick, 15000},
|
||||
{fsm_limit, 50000},
|
||||
{hook_js_vm_count, 2},
|
||||
{http_url_encoding, on},
|
||||
{js_max_vm_mem, 8},
|
||||
{js_thread_stack, 16},
|
||||
{listkeys_backpressure, true},
|
||||
{map_js_vm_count, 8},
|
||||
{mapred_2i_pipe, true},
|
||||
{mapred_name, "mapred"},
|
||||
{multi_backend, [
|
||||
{be_default, riak_kv_eleveldb_backend, [
|
||||
{cache_size, 4194304},
|
||||
{data_root, "/var/lib/riak/leveldb"},
|
||||
{max_open_files, 50}
|
||||
]},
|
||||
{be_blocks, riak_kv_bitcask_backend, [
|
||||
{data_root, "/var/lib/riak/bitcask"}
|
||||
]}
|
||||
]},
|
||||
{multi_backend_default, be_default},
|
||||
{multi_backend_prefix_list, [
|
||||
{<<"0b:">>, be_blocks}
|
||||
]},
|
||||
{object_format, v1},
|
||||
{reduce_js_vm_count, 6},
|
||||
{storage_backend, riak_cs_kv_multi_backend},
|
||||
{vnode_vclocks, true}
|
||||
]},
|
||||
{riak_repl, [
|
||||
{data_root, "/var/lib/riak/riak_repl"}
|
||||
]},
|
||||
{riak_search, [
|
||||
{enabled, false}
|
||||
]},
|
||||
{riak_sysmon, [
|
||||
{busy_dist_port, true},
|
||||
{busy_port, true},
|
||||
{gc_ms_limit, 0},
|
||||
{heap_word_limit, 40111000},
|
||||
{port_limit, 2},
|
||||
{process_limit, 30}
|
||||
]},
|
||||
{sasl, [
|
||||
{sasl_error_logger, false}
|
||||
]},
|
||||
{snmp, [
|
||||
{agent, [
|
||||
{config, [
|
||||
{dir, "/etc/riak/snmp/agent/conf"},
|
||||
{force_load, true}
|
||||
]},
|
||||
{db_dir, "/var/lib/riak/snmp/agent/db"},
|
||||
{net_if, [
|
||||
{options, [
|
||||
{bind_to, true}
|
||||
]}
|
||||
]}
|
||||
]}
|
||||
]}
|
||||
].
|
10
.travis/riak.vm.args
Normal file
10
.travis/riak.vm.args
Normal file
@ -0,0 +1,10 @@
|
||||
+A 64
|
||||
+K true
|
||||
+W w
|
||||
-env ERL_CRASH_DUMP /var/log/riak/erl_crash.dump
|
||||
-env ERL_FULLSWEEP_AFTER 0
|
||||
-env ERL_MAX_ETS_TABLES 256000
|
||||
-env ERL_MAX_PORTS 64000
|
||||
-name riak@127.0.0.1
|
||||
-setcookie riak
|
||||
-smp enable
|
65
.travis/riakcs.app.config
Normal file
65
.travis/riakcs.app.config
Normal file
@ -0,0 +1,65 @@
|
||||
[
|
||||
{lager, [
|
||||
{crash_log, "/var/log/riak-cs/crash.log"},
|
||||
{crash_log_count, 5},
|
||||
{crash_log_date, "$D0"},
|
||||
{crash_log_msg_size, 65536},
|
||||
{crash_log_size, 10485760},
|
||||
{error_logger_redirect, true},
|
||||
{handlers, [
|
||||
{lager_file_backend, [
|
||||
{"/var/log/riak-cs/error.log", error, 10485760, "$D0", 5},
|
||||
{"/var/log/riak-cs/console.log", info, 10485760, "$D0", 5}
|
||||
]}
|
||||
]}
|
||||
]},
|
||||
{riak_cs, [
|
||||
{access_archive_period, 3600},
|
||||
{access_archiver_max_backlog, 2},
|
||||
{access_log_flush_factor, 1},
|
||||
{access_log_flush_size, 1000000},
|
||||
{admin_key, "secret"},
|
||||
{admin_secret, "secret"},
|
||||
{anonymous_user_creation, true},
|
||||
{auth_module, riak_cs_s3_auth},
|
||||
{connection_pools, [
|
||||
{bucket_list_pool, {5, 0}},
|
||||
{request_pool, {128, 0}}
|
||||
]},
|
||||
{cs_ip, "127.0.0.1"},
|
||||
{cs_port, 8080},
|
||||
{cs_root_host, "cs.example.com"},
|
||||
{cs_version, 10300},
|
||||
{dtrace_support, false},
|
||||
{fold_objects_for_list_keys, false},
|
||||
{gc_interval, 900},
|
||||
{gc_retry_interval, 21600},
|
||||
{leeway_seconds, 86400},
|
||||
{n_val_1_get_requests, true},
|
||||
{rewrite_module, riak_cs_s3_rewrite},
|
||||
{riak_ip, "127.0.0.1"},
|
||||
{riak_pb_port, 8087},
|
||||
{stanchion_ip, "127.0.0.1"},
|
||||
{stanchion_port, 8085},
|
||||
{stanchion_ssl, false},
|
||||
{storage_archive_period, 86400},
|
||||
{storage_schedule, [
|
||||
]},
|
||||
{trust_x_forwarded_for, false},
|
||||
{usage_request_limit, 744}
|
||||
]},
|
||||
{sasl, [
|
||||
{sasl_error_logger, false},
|
||||
{utc_log, true}
|
||||
]},
|
||||
{webmachine, [
|
||||
{log_handlers, [
|
||||
{riak_cs_access_log_handler, [
|
||||
]},
|
||||
{webmachine_log_handler, [
|
||||
"/var/log/riak-cs"
|
||||
]}
|
||||
]},
|
||||
{server_name, "Riak CS"}
|
||||
]}
|
||||
].
|
8
.travis/riakcs.vm.args
Normal file
8
.travis/riakcs.vm.args
Normal file
@ -0,0 +1,8 @@
|
||||
+A 64
|
||||
+K true
|
||||
+W w
|
||||
-env ERL_CRASH_DUMP /var/log/riak-cs/erl_crash.dump
|
||||
-env ERL_FULLSWEEP_AFTER 0
|
||||
-env ERL_MAX_PORTS 4096
|
||||
-name riak-cs@127.0.0.1
|
||||
-setcookie riak-cs
|
29
.travis/stanchion.app.config
Normal file
29
.travis/stanchion.app.config
Normal file
@ -0,0 +1,29 @@
|
||||
[
|
||||
{lager, [
|
||||
{crash_log, "/var/log/stanchion/crash.log"},
|
||||
{crash_log_count, 5},
|
||||
{crash_log_date, "$D0"},
|
||||
{crash_log_msg_size, 65536},
|
||||
{crash_log_size, 10485760},
|
||||
{error_logger_redirect, true},
|
||||
{handlers, [
|
||||
{lager_file_backend, [
|
||||
{"/var/log/stanchion/error.log", error, 10485760, "$D0", 5},
|
||||
{"/var/log/stanchion/console.log", info, 10485760, "$D0", 5}
|
||||
]}
|
||||
]}
|
||||
]},
|
||||
{sasl, [
|
||||
{sasl_error_logger, false},
|
||||
{utc_log, true}
|
||||
]},
|
||||
{stanchion, [
|
||||
{admin_key, "secret"},
|
||||
{admin_secret, "secret"},
|
||||
{auth_bypass, false},
|
||||
{riak_ip, "127.0.0.1"},
|
||||
{riak_pb_port, 8087},
|
||||
{stanchion_ip, "127.0.0.1"},
|
||||
{stanchion_port, 8085}
|
||||
]}
|
||||
].
|
8
.travis/stanchion.vm.args
Normal file
8
.travis/stanchion.vm.args
Normal file
@ -0,0 +1,8 @@
|
||||
+A 64
|
||||
+K true
|
||||
+W w
|
||||
-env ERL_CRASH_DUMP /var/log/stanchion/erl_crash.dump
|
||||
-env ERL_FULLSWEEP_AFTER 0
|
||||
-env ERL_MAX_PORTS 4096
|
||||
-name stanchion@127.0.0.1
|
||||
-setcookie stanchion
|
1
Gemfile
1
Gemfile
@ -4,6 +4,7 @@ gem "sinatra"
|
||||
gem "sinatra-contrib"
|
||||
gem "activesupport"
|
||||
gem "riak-client"
|
||||
gem "fog"
|
||||
|
||||
group :test do
|
||||
gem 'rake'
|
||||
|
27
Gemfile.lock
27
Gemfile.lock
@ -6,16 +6,34 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
backports (3.3.0)
|
||||
beefcake (0.3.7)
|
||||
builder (3.1.3)
|
||||
builder (3.2.2)
|
||||
eventmachine (1.0.3)
|
||||
excon (0.16.10)
|
||||
fog (1.7.0)
|
||||
builder
|
||||
excon (~> 0.14)
|
||||
formatador (~> 0.2.0)
|
||||
mime-types
|
||||
multi_json (~> 1.0)
|
||||
net-scp (~> 1.0.4)
|
||||
net-ssh (>= 2.1.3)
|
||||
nokogiri (~> 1.5.0)
|
||||
ruby-hmac
|
||||
formatador (0.2.4)
|
||||
i18n (0.6.1)
|
||||
innertube (1.0.2)
|
||||
kgio (2.7.4)
|
||||
m (1.2.1)
|
||||
method_source (>= 0.6.7)
|
||||
rake (>= 0.9.2.2, < 1.0.0)
|
||||
method_source (0.8)
|
||||
mime-types (1.23)
|
||||
minitest (2.10.0)
|
||||
multi_json (1.3.6)
|
||||
multi_json (1.8.0)
|
||||
net-scp (1.0.4)
|
||||
net-ssh (>= 1.99.1)
|
||||
net-ssh (2.6.7)
|
||||
nokogiri (1.5.10)
|
||||
purdytest (1.0.0)
|
||||
minitest (~> 2.2)
|
||||
rack (1.5.2)
|
||||
@ -25,11 +43,13 @@ GEM
|
||||
rack (>= 1.0)
|
||||
raindrops (0.10.0)
|
||||
rake (0.9.2.2)
|
||||
riak-client (1.0.5)
|
||||
riak-client (1.4.1)
|
||||
beefcake (~> 0.3.7)
|
||||
builder (>= 2.1.2)
|
||||
i18n (>= 0.4.0)
|
||||
innertube (~> 1.0.2)
|
||||
multi_json (~> 1.0)
|
||||
ruby-hmac (0.4.0)
|
||||
sinatra (1.4.3)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.4)
|
||||
@ -52,6 +72,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
activesupport
|
||||
fog
|
||||
m
|
||||
purdytest
|
||||
rake
|
||||
|
@ -3,20 +3,26 @@ development: &defaults
|
||||
riak: &riak_defaults
|
||||
host: localhost
|
||||
http_port: 8098
|
||||
riak_cs:
|
||||
credentials_file: "cs_credentials.json"
|
||||
endpoint: "http://cs.example.com:8080"
|
||||
buckets:
|
||||
data: rs_data
|
||||
directories: rs_directories
|
||||
binaries: rs_binaries
|
||||
cs_binaries: rs.binaries
|
||||
authorizations: rs_authorizations
|
||||
opslog: rs_opslog
|
||||
|
||||
test:
|
||||
<<: *defaults
|
||||
riak:
|
||||
<<: *riak_defaults
|
||||
buckets:
|
||||
data: rs_data_test
|
||||
directories: rs_directories_test
|
||||
binaries: rs_binaries_test
|
||||
cs_binaries: rs.binaries.test
|
||||
authorizations: rs_authorizations_test
|
||||
opslog: rs_opslog_test
|
||||
|
||||
|
9
lib/rack/common_logger.rb
Normal file
9
lib/rack/common_logger.rb
Normal file
@ -0,0 +1,9 @@
|
||||
# Disable Rack logger completely
|
||||
module Rack
|
||||
class CommonLogger
|
||||
def call(env)
|
||||
# do nothing
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
@ -5,37 +5,22 @@ require "active_support/core_ext/time/conversions"
|
||||
require "active_support/core_ext/numeric/time"
|
||||
|
||||
module RemoteStorage
|
||||
module Riak
|
||||
class Riak
|
||||
|
||||
::Riak.url_decoding = true
|
||||
|
||||
def client
|
||||
@client ||= ::Riak::Client.new(:host => settings.riak['host'],
|
||||
:http_port => settings.riak['http_port'])
|
||||
end
|
||||
attr_accessor :settings, :server, :cs_credentials
|
||||
|
||||
def data_bucket
|
||||
@data_bucket ||= client.bucket(settings.riak['buckets']['data'])
|
||||
end
|
||||
def initialize(settings, server)
|
||||
self.settings = settings
|
||||
self.server = server
|
||||
|
||||
def directory_bucket
|
||||
@directory_bucket ||= client.bucket(settings.riak['buckets']['directories'])
|
||||
end
|
||||
|
||||
def auth_bucket
|
||||
@auth_bucket ||= client.bucket(settings.riak['buckets']['authorizations'])
|
||||
end
|
||||
|
||||
def binary_bucket
|
||||
@binary_bucket ||= client.bucket(settings.riak['buckets']['binaries'])
|
||||
end
|
||||
|
||||
def opslog_bucket
|
||||
@opslog_bucket ||= client.bucket(settings.riak['buckets']['opslog'])
|
||||
credentials = File.read(settings['riak_cs']['credentials_file'])
|
||||
self.cs_credentials = JSON.parse(credentials)
|
||||
end
|
||||
|
||||
def authorize_request(user, directory, token, listing=false)
|
||||
request_method = env["REQUEST_METHOD"]
|
||||
request_method = server.env["REQUEST_METHOD"]
|
||||
|
||||
if directory.split("/").first == "public"
|
||||
return true if request_method == "GET" && !listing
|
||||
@ -44,22 +29,29 @@ module RemoteStorage
|
||||
authorizations = auth_bucket.get("#{user}:#{token}").data
|
||||
permission = directory_permission(authorizations, directory)
|
||||
|
||||
halt 403 unless permission
|
||||
server.halt 403 unless permission
|
||||
if ["PUT", "DELETE"].include? request_method
|
||||
halt 403 unless permission == "rw"
|
||||
server.halt 403 unless permission == "rw"
|
||||
end
|
||||
rescue ::Riak::HTTPFailedRequest
|
||||
halt 403
|
||||
server.halt 403
|
||||
end
|
||||
|
||||
def get_data(user, directory, key)
|
||||
object = data_bucket.get("#{user}:#{directory}:#{key}")
|
||||
|
||||
headers["Content-Type"] = object.content_type
|
||||
headers["Last-Modified"] = last_modified_date_for(object)
|
||||
server.headers["Content-Type"] = object.content_type
|
||||
server.headers["Last-Modified"] = last_modified_date_for(object)
|
||||
|
||||
if binary_link = object.links.select {|l| l.tag == "binary"}.first
|
||||
object = client[binary_link.bucket].get(binary_link.key)
|
||||
if binary_key = object.meta["binary_key"]
|
||||
object = cs_binary_bucket.files.get(binary_key[0])
|
||||
|
||||
case object.content_type[/^[^;\s]+/]
|
||||
when "application/json"
|
||||
return object.body.to_json
|
||||
else
|
||||
return object.body
|
||||
end
|
||||
end
|
||||
|
||||
case object.content_type[/^[^;\s]+/]
|
||||
@ -69,21 +61,21 @@ module RemoteStorage
|
||||
return serializer_for(object.content_type) ? object.data : object.raw_data
|
||||
end
|
||||
rescue ::Riak::HTTPFailedRequest
|
||||
halt 404
|
||||
server.halt 404
|
||||
end
|
||||
|
||||
def get_directory_listing(user, directory)
|
||||
directory_object = directory_bucket.get("#{user}:#{directory}")
|
||||
timestamp = directory_object.data.to_i
|
||||
timestamp /= 1000 if timestamp.to_s.length == 13
|
||||
headers["Content-Type"] = "application/json"
|
||||
headers["Last-Modified"] = Time.at(timestamp).to_s(:rfc822)
|
||||
server.headers["Content-Type"] = "application/json"
|
||||
server.headers["Last-Modified"] = Time.at(timestamp).to_s(:rfc822)
|
||||
|
||||
listing = directory_listing(user, directory)
|
||||
|
||||
return listing.to_json
|
||||
rescue ::Riak::HTTPFailedRequest
|
||||
headers["Content-Type"] = "application/json"
|
||||
server.headers["Content-Type"] = "application/json"
|
||||
return "{}"
|
||||
end
|
||||
|
||||
@ -97,31 +89,32 @@ module RemoteStorage
|
||||
object.meta["timestamp"] = timestamp
|
||||
|
||||
if binary_data?(object.content_type, data)
|
||||
save_binary_data(object, data) or halt 422
|
||||
save_binary_data(object, data) or server.halt 422
|
||||
new_object_size = data.size
|
||||
else
|
||||
set_object_data(object, data) or halt 422
|
||||
set_object_data(object, data) or server.halt 422
|
||||
new_object_size = object.raw_data.size
|
||||
end
|
||||
|
||||
object.store
|
||||
response = object.store
|
||||
|
||||
log_count = object_exists ? 0 : 1
|
||||
log_operation(user, directory, log_count, new_object_size, existing_object_size)
|
||||
|
||||
update_all_directory_objects(user, directory, timestamp)
|
||||
|
||||
halt 200
|
||||
server.halt 200
|
||||
rescue ::Riak::HTTPFailedRequest
|
||||
halt 422
|
||||
server.halt 422
|
||||
end
|
||||
|
||||
def delete_data(user, directory, key)
|
||||
object = data_bucket.get("#{user}:#{directory}:#{key}")
|
||||
existing_object_size = object_size(object)
|
||||
|
||||
if binary_link = object.links.select {|l| l.tag == "binary"}.first
|
||||
client[binary_link.bucket].delete(binary_link.key)
|
||||
if binary_key = object.meta["binary_key"]
|
||||
object = cs_binary_bucket.files.get(binary_key[0])
|
||||
object.destroy
|
||||
end
|
||||
|
||||
riak_response = data_bucket.delete("#{user}:#{directory}:#{key}")
|
||||
@ -133,12 +126,11 @@ module RemoteStorage
|
||||
timestamp = (Time.now.to_f * 1000).to_i
|
||||
delete_or_update_directory_objects(user, directory, timestamp)
|
||||
|
||||
halt riak_response[:code]
|
||||
server.halt riak_response[:code]
|
||||
rescue ::Riak::HTTPFailedRequest
|
||||
halt 404
|
||||
server.halt 404
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def extract_category(directory)
|
||||
@ -174,9 +166,9 @@ module RemoteStorage
|
||||
end
|
||||
|
||||
def object_size(object)
|
||||
if binary_link = object.links.select {|l| l.tag == "binary"}.first
|
||||
response = head(settings.riak['buckets']['binaries'], escape(binary_link.key))
|
||||
response[:headers]["content-length"].first.to_i
|
||||
if binary_key = object.meta["binary_key"]
|
||||
response = cs_client.head_object cs_binary_bucket.key, binary_key[0]
|
||||
response.headers["Content-Length"].to_i
|
||||
else
|
||||
object.raw_data.nil? ? 0 : object.raw_data.size
|
||||
end
|
||||
@ -186,17 +178,9 @@ module RemoteStorage
|
||||
::Riak.escaper.escape(string).gsub("+", "%20").gsub('/', "%2F")
|
||||
end
|
||||
|
||||
# Perform a HEAD request via the backend method
|
||||
def head(bucket, key)
|
||||
client.http do |h|
|
||||
url = riak_uri(bucket, key)
|
||||
h.head [200], url
|
||||
end
|
||||
end
|
||||
|
||||
# A URI object that can be used with HTTP backend methods
|
||||
def riak_uri(bucket, key)
|
||||
rc = settings.riak.symbolize_keys
|
||||
rc = settings.symbolize_keys
|
||||
URI.parse "http://#{rc[:host]}:#{rc[:http_port]}/riak/#{bucket}/#{key}"
|
||||
end
|
||||
|
||||
@ -373,14 +357,13 @@ module RemoteStorage
|
||||
end
|
||||
|
||||
def save_binary_data(object, data)
|
||||
binary_object = binary_bucket.new(object.key)
|
||||
binary_object.content_type = object.content_type
|
||||
binary_object.raw_data = data
|
||||
binary_object.indexes = object.indexes
|
||||
binary_object.store
|
||||
cs_binary_object = cs_binary_bucket.files.create(
|
||||
:key => object.key,
|
||||
:body => data,
|
||||
:content_type => object.content_type
|
||||
)
|
||||
|
||||
link = ::Riak::Link.new(binary_bucket.name, binary_object.key, "binary")
|
||||
object.links << link
|
||||
object.meta["binary_key"] = cs_binary_object.key
|
||||
object.raw_data = ""
|
||||
end
|
||||
|
||||
@ -406,5 +389,64 @@ module RemoteStorage
|
||||
|
||||
parent_directories << ""
|
||||
end
|
||||
|
||||
def client
|
||||
@client ||= ::Riak::Client.new(:host => settings['host'],
|
||||
:http_port => settings['http_port'])
|
||||
end
|
||||
|
||||
def data_bucket
|
||||
@data_bucket ||= begin
|
||||
bucket = client.bucket(settings['buckets']['data'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def directory_bucket
|
||||
@directory_bucket ||= begin
|
||||
bucket = client.bucket(settings['buckets']['directories'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def auth_bucket
|
||||
@auth_bucket ||= begin
|
||||
bucket = client.bucket(settings['buckets']['authorizations'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def binary_bucket
|
||||
@binary_bucket ||= begin
|
||||
bucket = client.bucket(settings['buckets']['binaries'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def opslog_bucket
|
||||
@opslog_bucket ||= begin
|
||||
bucket = client.bucket(settings['buckets']['opslog'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def cs_client
|
||||
@cs_client ||= Fog::Storage.new({
|
||||
:provider => 'AWS',
|
||||
:aws_access_key_id => cs_credentials['key_id'],
|
||||
:aws_secret_access_key => cs_credentials['key_secret'],
|
||||
:endpoint => settings['riak_cs']['endpoint']
|
||||
})
|
||||
end
|
||||
|
||||
def cs_binary_bucket
|
||||
@cs_binary_bucket ||= cs_client.directories.create(:key => settings['buckets']['cs_binaries'])
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -6,16 +6,6 @@ require 'sinatra/config_file'
|
||||
require "sinatra/reloader"
|
||||
require "remote_storage/riak"
|
||||
|
||||
# Disable Rack logger completely
|
||||
module Rack
|
||||
class CommonLogger
|
||||
def call(env)
|
||||
# do nothing
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class LiquorCabinet < Sinatra::Base
|
||||
|
||||
#
|
||||
@ -36,11 +26,8 @@ class LiquorCabinet < Sinatra::Base
|
||||
enable :logging
|
||||
end
|
||||
|
||||
if settings.riak
|
||||
include RemoteStorage::Riak
|
||||
# elsif settings.redis
|
||||
# include RemoteStorage::Redis
|
||||
# end
|
||||
configure :production, :staging do
|
||||
require "rack/common_logger"
|
||||
end
|
||||
|
||||
#
|
||||
@ -64,23 +51,19 @@ class LiquorCabinet < Sinatra::Base
|
||||
|
||||
token = env["HTTP_AUTHORIZATION"] ? env["HTTP_AUTHORIZATION"].split(" ")[1] : ""
|
||||
|
||||
authorize_request(@user, @directory, token, @key.blank?) unless request.options?
|
||||
storage.authorize_request(@user, @directory, token, @key.blank?) unless request.options?
|
||||
end
|
||||
|
||||
options path do
|
||||
halt 200
|
||||
end
|
||||
end
|
||||
|
||||
["/:user/*/:key", "/:user/:key"].each do |path|
|
||||
get path do
|
||||
get_data(@user, @directory, @key)
|
||||
storage.get_data(@user, @directory, @key)
|
||||
end
|
||||
end
|
||||
|
||||
["/:user/*/", "/:user/"].each do |path|
|
||||
get path do
|
||||
get_directory_listing(@user, @directory)
|
||||
end
|
||||
end
|
||||
|
||||
["/:user/*/:key", "/:user/:key"].each do |path|
|
||||
put path do
|
||||
data = request.body.read
|
||||
|
||||
@ -90,19 +73,29 @@ class LiquorCabinet < Sinatra::Base
|
||||
content_type = env['CONTENT_TYPE']
|
||||
end
|
||||
|
||||
put_data(@user, @directory, @key, data, content_type)
|
||||
storage.put_data(@user, @directory, @key, data, content_type)
|
||||
end
|
||||
end
|
||||
|
||||
["/:user/*/:key", "/:user/:key"].each do |path|
|
||||
delete path do
|
||||
delete_data(@user, @directory, @key)
|
||||
storage.delete_data(@user, @directory, @key)
|
||||
end
|
||||
end
|
||||
|
||||
["/:user/*/:key", "/:user/:key", "/:user/*/", "/:user/"].each do |path|
|
||||
options path do
|
||||
halt 200
|
||||
["/:user/*/", "/:user/"].each do |path|
|
||||
get path do
|
||||
storage.get_directory_listing(@user, @directory)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def storage
|
||||
@storage ||= begin
|
||||
if settings.riak
|
||||
RemoteStorage::Riak.new(settings.riak, self)
|
||||
# elsif settings.redis
|
||||
# include RemoteStorage::Redis
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -282,13 +282,13 @@ describe "App with Riak backend" do
|
||||
last_response.body.must_equal @image
|
||||
end
|
||||
|
||||
it "indexes the binary set" do
|
||||
indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes
|
||||
indexes["user_id_bin"].must_be_kind_of Set
|
||||
indexes["user_id_bin"].must_include "jimmy"
|
||||
# it "indexes the binary set" do
|
||||
# indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes
|
||||
# indexes["user_id_bin"].must_be_kind_of Set
|
||||
# indexes["user_id_bin"].must_include "jimmy"
|
||||
|
||||
indexes["directory_bin"].must_include "documents"
|
||||
end
|
||||
# indexes["directory_bin"].must_include "documents"
|
||||
# end
|
||||
|
||||
it "logs the operation" do
|
||||
objects = []
|
||||
@ -323,13 +323,13 @@ describe "App with Riak backend" do
|
||||
last_response.body.must_equal @image
|
||||
end
|
||||
|
||||
it "indexes the binary set" do
|
||||
indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes
|
||||
indexes["user_id_bin"].must_be_kind_of Set
|
||||
indexes["user_id_bin"].must_include "jimmy"
|
||||
# it "indexes the binary set" do
|
||||
# indexes = binary_bucket.get("jimmy:documents:jaypeg").indexes
|
||||
# indexes["user_id_bin"].must_be_kind_of Set
|
||||
# indexes["user_id_bin"].must_include "jimmy"
|
||||
|
||||
indexes["directory_bin"].must_include "documents"
|
||||
end
|
||||
# indexes["directory_bin"].must_include "documents"
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
@ -427,9 +427,9 @@ describe "App with Riak backend" do
|
||||
|
||||
it "removes the binary object" do
|
||||
last_response.status.must_equal 204
|
||||
lambda {
|
||||
binary_bucket.get("jimmy:documents:jaypeg")
|
||||
}.must_raise Riak::HTTPFailedRequest
|
||||
|
||||
binary = cs_binary_bucket.files.get("jimmy:documents:jaypeg")
|
||||
binary.must_be_nil
|
||||
end
|
||||
|
||||
it "logs the operation" do
|
||||
|
@ -38,28 +38,64 @@ if app.settings.riak
|
||||
end
|
||||
|
||||
def data_bucket
|
||||
@data_bucket ||= client.bucket(app.settings.riak['buckets']['data'])
|
||||
end
|
||||
|
||||
def auth_bucket
|
||||
@auth_bucket ||= client.bucket(app.settings.riak['buckets']['authorizations'])
|
||||
@data_bucket ||= begin
|
||||
bucket = client.bucket(app.settings.riak['buckets']['data'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def directory_bucket
|
||||
@directory_bucket ||= client.bucket(app.settings.riak['buckets']['directories'])
|
||||
@directory_bucket ||= begin
|
||||
bucket = client.bucket(app.settings.riak['buckets']['directories'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def binary_bucket
|
||||
@binary_bucket ||= client.bucket(app.settings.riak['buckets']['binaries'])
|
||||
def auth_bucket
|
||||
@auth_bucket ||= begin
|
||||
bucket = client.bucket(app.settings.riak['buckets']['authorizations'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def opslog_bucket
|
||||
@opslog_bucket ||= client.bucket(app.settings.riak['buckets']['opslog'])
|
||||
@opslog_bucket ||= begin
|
||||
bucket = client.bucket(app.settings.riak['buckets']['opslog'])
|
||||
bucket.allow_mult = false
|
||||
bucket
|
||||
end
|
||||
end
|
||||
|
||||
def cs_credentials
|
||||
@cs_credentials ||= begin
|
||||
credentials = File.read(app.settings.riak['riak_cs']['credentials_file'])
|
||||
JSON.parse(credentials)
|
||||
end
|
||||
end
|
||||
|
||||
def cs_client
|
||||
@cs_client ||= Fog::Storage.new({
|
||||
:provider => 'AWS',
|
||||
:aws_access_key_id => cs_credentials['key_id'],
|
||||
:aws_secret_access_key => cs_credentials['key_secret'],
|
||||
:endpoint => app.settings.riak['riak_cs']['endpoint']
|
||||
})
|
||||
end
|
||||
|
||||
def cs_binary_bucket
|
||||
@cs_binary_bucket ||= cs_client.directories.create(:key => app.settings.riak['buckets']['cs_binaries'])
|
||||
end
|
||||
|
||||
def purge_all_buckets
|
||||
[data_bucket, directory_bucket, auth_bucket, binary_bucket, opslog_bucket].each do |bucket|
|
||||
[data_bucket, directory_bucket, auth_bucket, opslog_bucket].each do |bucket|
|
||||
bucket.keys.each {|key| bucket.delete key}
|
||||
end
|
||||
|
||||
cs_binary_bucket.files.each do |file|
|
||||
file.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user