dynamodb_framework 1.7.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e8d0250d290cb006f3cbfecaffcd35a3c61819c7
4
- data.tar.gz: 98398a2a0aae655ef04ba9ccd01155bd320c5cf1
2
+ SHA256:
3
+ metadata.gz: 684b8ee781de8cd470c33dcc3faf97381381b96ca1f206f844f8aa415b713ea9
4
+ data.tar.gz: f8a3f678f62b0c2630c7168520821026d6665443bebc7de929be42881756859f
5
5
  SHA512:
6
- metadata.gz: d46aac43125f003b06522522790d87dcf201728af48f80e64effe39812bb53a83895aefd331b341b6e4437788f2de9642d74c126b257d8991e2feeaae2d67e69
7
- data.tar.gz: 71428f806932374f1c52a81f04f9cddc6aaafcdce0c11e0c6899825bd12644b663a319b5dbe93a212a164fc9238ef35596306d53df93e0c97ae3d30f3593524d
6
+ metadata.gz: b11aff7b20d0c65a307952f6661e19c1640bcbdebd22c09afa17aa6548288add75d1732c3fd90b11f7a4fa8be08b81655781a81c18a7cbb20ad363b9842ef811
7
+ data.tar.gz: e7bf59c3dc18ef7fe1e8ecaa50c738ac5fe1ce12ebf494b1760441d43e53e34b8b79efd371cd6faee61e589eaef5382e40dd61986daba02544390e0db1bc9392
@@ -46,7 +46,7 @@ module DynamoDbFramework
46
46
  self.instance_variable_set(:@range_key, { field: field, type: type })
47
47
  end
48
48
 
49
- def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25, submit: true)
49
+ def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25, submit: true, billing_mode: 'PROVISIONED')
50
50
  unless self.instance_variable_defined?(:@table)
51
51
  raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.')
52
52
  end
@@ -84,10 +84,10 @@ module DynamoDbFramework
84
84
 
85
85
  range_key_field = range_key[:field] unless range_key == nil
86
86
 
87
- index =table_manager.create_global_index(full_index_name, partition_key[:field], range_key_field, read_capacity, write_capacity)
87
+ index =table_manager.create_global_index(full_index_name, partition_key[:field], range_key_field, read_capacity, write_capacity, billing_mode)
88
88
 
89
89
  if submit
90
- table_manager.add_index(table_name, builder.attributes, index)
90
+ table_manager.add_index(table_name, builder.attributes, index, billing_mode)
91
91
  end
92
92
 
93
93
  index
@@ -66,7 +66,7 @@ module DynamoDbFramework
66
66
 
67
67
  end
68
68
 
69
- def add_index(table_name, attributes, global_index)
69
+ def add_index(table_name, attributes, global_index, billing_mode = 'PROVISIONED')
70
70
 
71
71
  attribute_definitions = []
72
72
 
@@ -79,7 +79,8 @@ module DynamoDbFramework
79
79
  :attribute_definitions => attribute_definitions,
80
80
  :global_secondary_index_updates => [
81
81
  :create => global_index
82
- ]
82
+ ],
83
+ :billing_mode => billing_mode
83
84
  }
84
85
 
85
86
  dynamodb.client.update_table(table)
@@ -115,6 +116,33 @@ module DynamoDbFramework
115
116
  DynamoDbFramework.logger.info "[#{self.class}] -Table: [#{table_name}] updated."
116
117
  end
117
118
 
119
+ def update_ttl_attribute(table_name, enabled, attribute_name)
120
+ table = {
121
+ :table_name => table_name,
122
+ :time_to_live_specification => {
123
+ :enabled => enabled,
124
+ :attribute_name => attribute_name
125
+ }
126
+ }
127
+
128
+ DynamoDbFramework.logger.info "[#{self.class}] -Updating TTL Attribute: #{attribute_name}."
129
+ dynamodb.client.update_time_to_live(table)
130
+
131
+ # wait for table to be updated
132
+ DynamoDbFramework.logger.info "[#{self.class}] -Waiting for table: [#{table_name}] to be updated."
133
+ wait_until_ttl_changed(table_name)
134
+
135
+ DynamoDbFramework.logger.info "[#{self.class}] -Table: [#{table_name}] updated."
136
+ end
137
+
138
+ def get_ttl_status(table_name)
139
+ table = {
140
+ :table_name => table_name
141
+ }
142
+
143
+ dynamodb.client.describe_time_to_live(table)['time_to_live_description']
144
+ end
145
+
118
146
  def drop_index(table_name, index_name)
119
147
  unless has_index?(table_name, index_name)
120
148
  return
@@ -235,7 +263,25 @@ module DynamoDbFramework
235
263
 
236
264
  end
237
265
 
238
- def create(table_name, attributes, partition_key, range_key = nil, read_capacity = 20, write_capacity = 10, global_indexes = nil)
266
+ def wait_until_ttl_changed(table_name)
267
+
268
+ end_time = wait_timeout
269
+ while Time.now < end_time do
270
+
271
+ status = get_ttl_status(table_name)['time_to_live_status']
272
+
273
+ if status == 'ENABLED' || status == 'DISABLED'
274
+ return
275
+ end
276
+
277
+ sleep(5)
278
+ end
279
+
280
+ raise "Timeout occurred while waiting for table: #{table_name}, to update TTL status."
281
+
282
+ end
283
+
284
+ def create(table_name, attributes, partition_key, range_key = nil, read_capacity = 20, write_capacity = 10, global_indexes = nil, billing_mode = 'PROVISIONED')
239
285
 
240
286
  if exists?(table_name)
241
287
  return
@@ -257,11 +303,17 @@ module DynamoDbFramework
257
303
  :table_name => table_name,
258
304
  :attribute_definitions => attribute_definitions,
259
305
  :key_schema => key_schema,
306
+ :billing_mode => billing_mode
307
+ }
308
+
309
+ unless billing_mode == 'PAY_PER_REQUEST'
310
+ table = table.merge(
260
311
  :provisioned_throughput => {
261
- :read_capacity_units => read_capacity,
262
- :write_capacity_units => write_capacity
312
+ :read_capacity_units => read_capacity,
313
+ :write_capacity_units => write_capacity
263
314
  }
264
- }
315
+ )
316
+ end
265
317
 
266
318
  if global_indexes != nil
267
319
  table[:global_secondary_indexes] = global_indexes
@@ -316,11 +368,17 @@ module DynamoDbFramework
316
368
  :table_name => table_name,
317
369
  :attribute_definitions => attribute_definitions,
318
370
  :key_schema => key_schema,
371
+ :billing_mode => options[:billing_mode] || 'PROVISIONED'
372
+ }
373
+
374
+ unless options[:billing_mode] == 'PAY_PER_REQUEST'
375
+ table = table.merge(
319
376
  :provisioned_throughput => {
320
- :read_capacity_units => options[:read_capacity],
321
- :write_capacity_units => options[:write_capacity]
377
+ :read_capacity_units => options[:read_capacity],
378
+ :write_capacity_units => options[:write_capacity]
322
379
  }
323
- }
380
+ )
381
+ end
324
382
 
325
383
  if options[:global_indexes] != nil
326
384
  table[:global_secondary_indexes] = options[:global_indexes]
@@ -338,7 +396,7 @@ module DynamoDbFramework
338
396
  DynamoDbFramework.logger.info "[#{self.class}] - Table: [#{table_name}] created."
339
397
  end
340
398
 
341
- def create_global_index(name, partition_key, range_key = nil, read_capacity = 20, write_capacity = 10)
399
+ def create_global_index(name, partition_key, range_key = nil, read_capacity = 20, write_capacity = 10, billing_mode = 'PROVISIONED')
342
400
 
343
401
  key_schema = []
344
402
 
@@ -352,13 +410,18 @@ module DynamoDbFramework
352
410
  :key_schema => key_schema,
353
411
  :projection => {
354
412
  :projection_type => :ALL
355
- },
356
- :provisioned_throughput => {
357
- :read_capacity_units => read_capacity,
358
- :write_capacity_units => write_capacity,
359
413
  }
360
414
  }
361
415
 
416
+ if billing_mode == 'PROVISIONED'
417
+ index = index.merge(
418
+ :provisioned_throughput => {
419
+ :read_capacity_units => read_capacity,
420
+ :write_capacity_units => write_capacity,
421
+ }
422
+ )
423
+ end
424
+
362
425
  return index
363
426
  end
364
427
 
@@ -1,3 +1,3 @@
1
1
  module DynamoDbFramework
2
- VERSION = '1.7.0'
2
+ VERSION = '2.0.1'
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'aws-sdk-dynamodb'
1
2
  require 'hash_kit'
2
3
  require 'json'
3
4
  require_relative 'dynamodb_framework/version'
@@ -117,6 +117,56 @@ RSpec.describe DynamoDbFramework::TableManager do
117
117
 
118
118
  end
119
119
 
120
+ it 'can update the TTL attribute' do
121
+
122
+ exists = subject.exists?('update_ttl_test')
123
+
124
+ if exists
125
+ subject.drop('update_ttl_test')
126
+ end
127
+
128
+ builder = DynamoDbFramework::AttributesBuilder.new
129
+ builder.add(:ttl_date, :N)
130
+
131
+ subject.create('update_ttl_test', builder.attributes, :ttl_date)
132
+
133
+ subject.update_ttl_attribute('update_ttl_test', true, 'ttl_date')
134
+
135
+ expect(subject.get_ttl_status('update_ttl_test')['time_to_live_status']).to eq('ENABLED')
136
+
137
+ subject.drop('update_ttl_test')
138
+
139
+ end
140
+
141
+ it 'can disable the TTL attribute' do
142
+
143
+ exists = subject.exists?('update_ttl_test')
144
+
145
+ if exists
146
+ subject.drop('update_ttl_test')
147
+ end
148
+
149
+ builder = DynamoDbFramework::AttributesBuilder.new
150
+ builder.add(:ttl_date, :N)
151
+
152
+ subject.create('update_ttl_test', builder.attributes, :ttl_date)
153
+
154
+ subject.update_ttl_attribute('update_ttl_test', true, 'ttl_date')
155
+
156
+ subject.update_ttl_attribute('update_ttl_test', false, 'ttl_date')
157
+
158
+ expect(subject.get_ttl_status('update_ttl_test')['time_to_live_status']).to eq('DISABLED')
159
+
160
+ subject.drop('update_ttl_test')
161
+
162
+ end
163
+
164
+ it 'handles timeouts when dynamodb fails to respond' do
165
+ allow(subject).to receive('wait_timeout').and_return(Time.now)
166
+
167
+ expect{subject.wait_until_ttl_changed('update_ttl_test')}.to raise_error("Timeout occurred while waiting for table: update_ttl_test, to update TTL status.")
168
+ end
169
+
120
170
  it 'can drop an existing global secondary index' do
121
171
 
122
172
  exists = subject.exists?('drop_index_test')
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter '/spec/'
4
+ end
5
+
1
6
  require "rubygems"
2
7
  require "bundler"
3
- require 'aws-sdk-core'
4
8
  require 'dynamodb_framework'
5
9
  require_relative '../spec/test_migration_script1'
6
10
  require_relative '../spec/test_migration_script2'
@@ -9,12 +13,7 @@ require_relative '../spec/example_table'
9
13
  require_relative '../spec/example_index'
10
14
  require 'pry'
11
15
 
12
- require 'simplecov'
13
- SimpleCov.start do
14
- add_filter '/spec/'
15
- end
16
-
17
- DYNAMODB_STORE_ENDPOINT = 'http://dynamodb:8000'
16
+ DYNAMODB_STORE_ENDPOINT = ENV.fetch('DYNAMODB_ENDPOINT', 'http://localhost:8000')
18
17
 
19
18
  Aws.config[:credentials] = Aws::Credentials.new('test_key', 'test_secret')
20
19
  Aws.config[:region] = 'eu-west-1'
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamodb_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - vaughanbrittonsage
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-09 00:00:00.000000000 Z
11
+ date: 2021-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -95,23 +95,37 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: aws-sdk-core
98
+ name: aws-sdk-dynamodb
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '2.10'
103
+ version: '1'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '2.10'
110
+ version: '1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "<"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.18.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "<"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.18.0
111
125
  description: A lightweight framework to provide managers for working with aws dynamodb
112
126
  (incuding local version).
113
127
  email:
114
- - vaughanbritton@gmail.com
128
+ - vaughan.britton@sage.com
115
129
  executables: []
116
130
  extensions: []
117
131
  extra_rdoc_files: []
@@ -132,16 +146,16 @@ files:
132
146
  - lib/dynamodb_framework/dynamodb_table_manager.rb
133
147
  - lib/dynamodb_framework/hash_helper.rb
134
148
  - lib/dynamodb_framework/version.rb
135
- - spec/dynamodb_index_spec.rb
136
- - spec/dynamodb_migration_manager_spec.rb
137
- - spec/dynamodb_namespace_migration_manager_spec.rb
138
- - spec/dynamodb_query_spec.rb
139
- - spec/dynamodb_repository_spec.rb
140
- - spec/dynamodb_table_manager_spec.rb
141
- - spec/dynamodb_table_spec.rb
149
+ - spec/dynamodb_framework/dynamodb_index_spec.rb
150
+ - spec/dynamodb_framework/dynamodb_migration_manager_spec.rb
151
+ - spec/dynamodb_framework/dynamodb_namespace_migration_manager_spec.rb
152
+ - spec/dynamodb_framework/dynamodb_query_spec.rb
153
+ - spec/dynamodb_framework/dynamodb_repository_spec.rb
154
+ - spec/dynamodb_framework/dynamodb_table_manager_spec.rb
155
+ - spec/dynamodb_framework/dynamodb_table_spec.rb
156
+ - spec/dynamodb_framework/hash_helper_spec.rb
142
157
  - spec/example_index.rb
143
158
  - spec/example_table.rb
144
- - spec/hash_helper_spec.rb
145
159
  - spec/spec_helper.rb
146
160
  - spec/test_item.rb
147
161
  - spec/test_migration_script1.rb
@@ -165,8 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
167
181
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.5.1
182
+ rubygems_version: 3.1.2
170
183
  signing_key:
171
184
  specification_version: 4
172
185
  summary: A lightweight framework to provide managers for working with aws dynamodb