blobby-s3 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb92e09ebb4fb6aa87581485a6fb49e926f97746
4
+ data.tar.gz: 426467d4d7cde0580260e569132c728fff71eea0
5
+ SHA512:
6
+ metadata.gz: 0c2519c24da67688afb17718f8c9b1b49a4d3bd8be9d50592fab3e79e0f1e9a1e46561bbd3ba9d1c413a60a279b43abe843a8a18a5360453281ba86ae64cfc91
7
+ data.tar.gz: abaf0b989d2a9ffa8e143fe3b6ac3a9c2898a8a74a5104d50d0bd602f670bddde6fcc7fa9254a33b4028b8f586dd2dc3b7becc5e8bb9daa9d1f973d1ad2a46a3
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .rbenv-*
6
+ .ruby-version
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,47 @@
1
+ Eval:
2
+ Exclude:
3
+ - "Rakefile"
4
+
5
+ Metrics/AbcSize:
6
+ Enabled: false
7
+
8
+ Metrics/LineLength:
9
+ Max: 120
10
+
11
+ Metrics/MethodLength:
12
+ Max: 30
13
+
14
+ Style/ClassAndModuleChildren:
15
+ EnforcedStyle: nested
16
+ Exclude:
17
+ - "spec/**/*"
18
+
19
+ Style/Documentation:
20
+ Exclude:
21
+ - "spec/**/*"
22
+
23
+ Style/EmptyLinesAroundBlockBody:
24
+ Enabled: false
25
+
26
+ Style/EmptyLinesAroundClassBody:
27
+ EnforcedStyle: empty_lines
28
+
29
+ Style/EmptyLinesAroundModuleBody:
30
+ Enabled: false
31
+
32
+ Style/Encoding:
33
+ EnforcedStyle: when_needed
34
+ Enabled: true
35
+
36
+ Style/FileName:
37
+ Exclude:
38
+ - "bin/*"
39
+
40
+ Style/HashSyntax:
41
+ EnforcedStyle: hash_rockets
42
+
43
+ Style/StringLiterals:
44
+ EnforcedStyle: double_quotes
45
+
46
+ Style/WordArray:
47
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Runtime dependencies in *.gemspec
4
+ gemspec
5
+
6
+ gem "blobby", :path => "../blobby"
7
+ gem "rake"
8
+ gem "rspec", "~> 3.1"
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # Blobby::S3Store
2
+
3
+ This gem provides an S3-based implementation of the "store" interface defined by the ["blobby"](https://github.com/realestate-com-au/blobby) gem. It's been packaged separately, to avoid adding dependencies to the core gem.
4
+
5
+ The simplest use-case is writing to a single bucket:
6
+
7
+ s3_store = Blobby::S3Store.new("mybucket")
8
+ s3_store["key"].write("something big")
9
+
10
+ Credentials can be provided, if required:
11
+
12
+ credentials = { :access_key_id => "KEY, :secret_access_key => "SECRET" }
13
+ s3_store = Blobby::S3Store.new("mybucket", credentials)
14
+
15
+ If none are specified, we'll look for them in [the normal places](https://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs).
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler"
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ require "rspec/core/rake_task"
8
+
9
+ task "default" => "spec"
data/blobby-s3.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+
5
+ gem.authors = ["Mike Williams"]
6
+ gem.email = ["mdub@dogbiscuit.org"]
7
+ gem.summary = "Store BLOBs in S3"
8
+ gem.homepage = "https://github.com/realestate-com.au/blobby-s3"
9
+
10
+ gem.name = "blobby-s3"
11
+ gem.version = "1.0.0"
12
+
13
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_runtime_dependency("aws-sdk-resources", "~> 2.1")
19
+ gem.add_runtime_dependency("blobby")
20
+
21
+ end
@@ -0,0 +1,113 @@
1
+ require "aws-sdk-resources"
2
+ require "blobby/key_constraint"
3
+
4
+ module Blobby
5
+
6
+ # A BLOB store backed by an S3 bucket.
7
+ #
8
+ class S3Store
9
+
10
+ # Create a new instance.
11
+ #
12
+ # bucket_name - name of the bucket to store things in
13
+ # s3_options - options passed to AWS::S3.new
14
+ #
15
+ def initialize(bucket_name, s3_options = {})
16
+ @bucket_name = bucket_name.to_str
17
+ @s3_options = s3_options.dup
18
+ @s3_options[:endpoint] = s3_endpoint_for_bucket
19
+ end
20
+
21
+ attr_reader :bucket_name
22
+ attr_reader :s3_options
23
+
24
+ def available?
25
+ bucket.objects.first
26
+ true
27
+ rescue ::Aws::Errors::ServiceError
28
+ false
29
+ end
30
+
31
+ def [](key)
32
+ KeyConstraint.must_allow!(key)
33
+ StoredObject.new(bucket.object(key))
34
+ end
35
+
36
+ class StoredObject
37
+
38
+ def initialize(s3_object)
39
+ @s3_object = s3_object
40
+ end
41
+
42
+ def exists?
43
+ s3_object.exists?
44
+ end
45
+
46
+ def read
47
+ body = s3_object.get.body
48
+ if block_given?
49
+ body.each_line do |line|
50
+ yield force_binary(line)
51
+ end
52
+ nil
53
+ else
54
+ force_binary(body.read)
55
+ end
56
+ rescue Aws::S3::Errors::NoSuchKey
57
+ nil
58
+ end
59
+
60
+ def write(payload)
61
+ s3_object.put(:body => force_binary(payload))
62
+ nil
63
+ end
64
+
65
+ def delete
66
+ return false unless s3_object.exists?
67
+ s3_object.delete
68
+ true
69
+ end
70
+
71
+ private
72
+
73
+ attr_reader :s3_object
74
+
75
+ def force_binary(s)
76
+ return s unless s.respond_to?(:encoding)
77
+ return s if s.encoding.name == "ASCII-8BIT"
78
+ s.dup.force_encoding("ASCII-8BIT")
79
+ end
80
+
81
+ end
82
+
83
+ private
84
+
85
+ def s3_client
86
+ ::Aws::S3::Client.new(s3_options)
87
+ end
88
+
89
+ def s3_endpoint_for_bucket
90
+ location = s3_client.get_bucket_location(:bucket => bucket_name).location_constraint
91
+ case location
92
+ when ""
93
+ "https://s3.amazonaws.com"
94
+ when "EU"
95
+ "https://s3-eu-west-1.amazonaws.com"
96
+ else
97
+ "https://s3-#{location}.amazonaws.com"
98
+ end
99
+ rescue ::Aws::Errors::ServiceError
100
+ "https://s3.amazonaws.com"
101
+ end
102
+
103
+ def s3_resource
104
+ ::Aws::S3::Resource.new(s3_options)
105
+ end
106
+
107
+ def bucket
108
+ s3_resource.bucket(bucket_name)
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,96 @@
1
+ require "aws-sdk-resources"
2
+ require "blobby/s3_store"
3
+
4
+ # Load the abstract "Store" tests from "blobby".
5
+ # This depends on the gem being packaged with "spec" dir intact.
6
+ $LOAD_PATH << Gem.loaded_specs["blobby"].full_gem_path + "/spec"
7
+
8
+ require "blobby/store_behaviour"
9
+
10
+ describe Blobby::S3Store, :integration => true do
11
+
12
+ before(:all) do
13
+ unless ENV.key?("AWS_ACCESS_KEY_ID")
14
+ fail "No AWS credentials provided"
15
+ end
16
+ end
17
+
18
+ context "with a writable bucket" do
19
+
20
+ EXISTING_BUCKET_NAME = "fake-aws-sdk-s3-test"
21
+
22
+ let(:s3_resource) { Aws::S3::Resource.new(:region => "us-east-1")}
23
+ let(:bucket) { s3_resource.bucket(EXISTING_BUCKET_NAME) }
24
+
25
+ before do
26
+ bucket.clear!
27
+ end
28
+
29
+ subject do
30
+ described_class.new(EXISTING_BUCKET_NAME)
31
+ end
32
+
33
+ it_behaves_like Blobby::Store
34
+
35
+ describe "#write" do
36
+
37
+ let(:key) { "data/file" }
38
+ let(:content) { "CONTENT" }
39
+
40
+ before do
41
+ subject[key].write(content)
42
+ end
43
+
44
+ it "stores stuff in S3" do
45
+ expect(bucket.object(key).get.body.read).to eq(content)
46
+ end
47
+
48
+ end
49
+
50
+ describe "#delete" do
51
+
52
+ let(:key) { "my_key" }
53
+
54
+ before do
55
+ subject[key].write("content")
56
+ subject[key].delete
57
+ end
58
+
59
+ it "removes stuff from S3" do
60
+ expect(bucket.object(key)).to_not exist
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ context "when we can't talk to S3" do
68
+
69
+ let(:bogus_credentials) do
70
+ {
71
+ :access_key_id => "bogus",
72
+ :secret_access_key => "bogus"
73
+ }
74
+ end
75
+
76
+ subject do
77
+ described_class.new(EXISTING_BUCKET_NAME, bogus_credentials)
78
+ end
79
+
80
+ it { is_expected.not_to be_available }
81
+
82
+ end
83
+
84
+ context "when the bucket does not exist" do
85
+
86
+ BOGUS_BUCKET_NAME = "bogusmcbogusness"
87
+
88
+ subject do
89
+ described_class.new(BOGUS_BUCKET_NAME)
90
+ end
91
+
92
+ it { is_expected.not_to be_available }
93
+
94
+ end
95
+
96
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blobby-s3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-resources
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: blobby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - mdub@dogbiscuit.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".rubocop.yml"
51
+ - Gemfile
52
+ - README.md
53
+ - Rakefile
54
+ - blobby-s3.gemspec
55
+ - lib/blobby/s3_store.rb
56
+ - spec/blobby/s3_store_spec.rb
57
+ homepage: https://github.com/realestate-com.au/blobby-s3
58
+ licenses: []
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.4.8
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Store BLOBs in S3
80
+ test_files:
81
+ - spec/blobby/s3_store_spec.rb