Class: LambdaWrap::DynamoDbManager

Inherits:
Object
  • Object
show all
Defined in:
lib/lambda_wrap/dynamo_db_manager.rb

Overview

The DynamoDBManager simplifies setting up and destroying a DynamoDB database.

Note: In case an environment specific DynamoDB tablename such as <baseTableName>-production should be used, then it has to be injected directly to the methods since not all environments necessarily need separated databases.

Instance Method Summary collapse

Constructor Details

#initializeDynamoDbManager

The constructor does some basic setup

  • Validating basic AWS configuration

  • Creating the underlying client to interact with the AWS SDK.



13
14
15
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 13

def initialize
  @client = Aws::DynamoDB::Client.new
end

Instance Method Details

#delete_database(table_name) ⇒ Object

Deletes a DynamoDB table. It does not wait until the table has been deleted.

Arguments

table_name

The dynamoDB table name to delete.



133
134
135
136
137
138
139
140
141
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 133

def delete_database(table_name)
  table_details = get_table_details(table_name)
  if table_details.nil?
    puts 'Table did not exist. Nothing to delete.'
  else
    wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'
    @client.delete_table(table_name: table_name)
  end
end

#publish_database(table_name, attribute_definitions, key_schema, read_capacity, write_capacity, local_secondary_indexes = nil, global_secondary_indexes = nil) ⇒ Object

Publishes the database and awaits until it is fully available. If the table already exists, it only adjusts the read and write capacities upwards (it doesn’t downgrade them to avoid a production environment being impacted with a default setting of an automated script).

Arguments

table_name

The table name of the dynamoDB to be created.

attribute_definitions

The dynamoDB attribute definitions to be used when the table is created.

key_schema

The dynamoDB key definitions to be used when the table is created.

read_capacity

The read capacity to configure for the dynamoDB table.

write_capacity

The write capacity to configure for the dynamoDB table.

local_secondary_indexes

The local secondary indexes to be created.

global_secondary_indexes

The global secondary indexes to be created.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 83

def publish_database(
    table_name, attribute_definitions, key_schema, read_capacity, write_capacity, local_secondary_indexes = nil,
    global_secondary_indexes = nil
)
  has_updates = false

  table_details = get_table_details(table_name)

  if !table_details.nil?
    wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'

    if  read_capacity > table_details.provisioned_throughput.read_capacity_units ||
        write_capacity > table_details.provisioned_throughput.write_capacity_units
      set_table_capacity(read_capacity, write_capacity)
      has_updates = true
    else
      puts "Table #{table_name} already exists and the desired read capacity of #{read_capacity} and " \
      "write capacity of #{write_capacity} has at least been configured. Downgrading capacity units is not " \
      'supported. No changes were applied.'
    end
  else
    puts "Creating table #{table_name}."
    ad = attribute_definitions || [{ attribute_name: 'Id', attribute_type: 'S' }]
    ks = key_schema || [{ attribute_name: 'Id', key_type: 'HASH' }]

    params = {
      table_name: table_name, key_schema: ks, attribute_definitions: ad,
      provisioned_throughput: {
        read_capacity_units: read_capacity, write_capacity_units: write_capacity
      }
    }

    params[:local_secondary_indexes] = local_secondary_indexes unless local_secondary_indexes.nil?
    params[:global_secondary_indexes] = global_secondary_indexes unless global_secondary_indexes.nil?

    @client.create_table(params)
    has_updates = true
  end

  if has_updates
    wait_until_table_available(table_name)
    puts "DynamoDB table #{table_name} is now fully available."
  end
end

#set_table_capacity(table_name, read_capacity, write_capacity) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 17

def set_table_capacity(table_name, read_capacity, write_capacity)
  puts "Updating new read/write capacity for table #{table_name}.
   Read #{table_details.provisioned_throughput.read_capacity_units} ==> #{read_capacity}.
   Write #{table_details.provisioned_throughput.write_capacity_units} ==> #{write_capacity}."
  @client.update_table(
    table_name: table_name,
    provisioned_throughput: { read_capacity_units: read_capacity, write_capacity_units: write_capacity }
  )
end

#update_table_capacity(table_name, read_capacity, write_capacity) ⇒ Object

Updates the provisioned throughput read and write capacity of the requested table. If the table does not exist an error message is displayed. If current read/write capacity is equals to requested read/write capacity or the requested read/write capacity is 0 or less than 0 no table updation is performed.

Arguments

table_name

The table name of the dynamoDB to be updated.

read_capacity

The read capacity the table should be updated with.

write_capacity

The write capacity the table should be updated with.



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
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 37

def update_table_capacity(table_name, read_capacity, write_capacity)
  table_details = get_table_details(table_name)
  raise "Update cannot be performed. Table #{table_name} does not exists." if table_details.nil?

  wait_until_table_available(table_name) if table_details.table_status != 'ACTIVE'

  if read_capacity <= 0 || write_capacity <= 0
    puts "Table: #{table_name} not updated. Read/Write capacity should be greater than or equal to 1."
  elsif read_capacity == table_details.provisioned_throughput.read_capacity_units ||
        write_capacity == table_details.provisioned_throughput.write_capacity_units
    puts "Table: #{table_name} not updated. Current and requested reads/writes are same."
    puts 'Current ReadCapacityUnits provisioned for the table: ' \
            "#{table_details.provisioned_throughput.read_capacity_units}."
    puts "Requested ReadCapacityUnits: #{read_capacity}."
    puts 'Current WriteCapacityUnits provisioned for the table: ' \
      "#{table_details.provisioned_throughput.write_capacity_units}."
    puts "Requested WriteCapacityUnits: #{write_capacity}."
  else
    response = @client.update_table(
      table_name: table_name,
      provisioned_throughput: { read_capacity_units: read_capacity, write_capacity_units: write_capacity }
    )

    if response.table_description.table_status == 'UPDATING'
      puts "Updated new read/write capacity for table #{table_name}.
      Read capacity updated to: #{read_capacity}.
      Write capacity updated to: #{write_capacity}."
    else
      raise "Read and writes capacities was not updated for table: #{table_name}."
    end
  end
end