Class: LambdaWrap::DynamoTable

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

Overview

The DynamoTable class simplifies Creation, Updating, and Destroying Dynamo DB Tables.

Since:

  • 1.0

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ DynamoTable

Sets up the DynamoTable for the Dynamo DB Manager. Preloading the configuration in the constructor.

Parameters:

  • options (Hash)

    The configuration for the DynamoDB Table.

Options Hash (options):

  • :table_name (String)

    The name of the DynamoDB Table. A “Base Name” can be used here where the environment name can be appended upon deployment.

  • :attribute_definitions (Array<Hash>) — default: [{ attribute_name: 'Id', attribute_type: 'S' }]

    An array of attributes that describe the key schema for the table and indexes. The Hash must have symbols: :attribute_name & :attribute_type. Please see AWS Documentation for the Data Model.

  • :key_schema (Array<Hash>) — default: [{ attribute_name: 'Id', key_type: 'HASH' }]

    Specifies the attributes that make up the primary key for a table or an index. The attributes in key_schema must also be defined in the AttributeDefinitions array. Please see AWS Documentation for the Data Model.

    Each element in the array must be composed of:

    • :attribute_name - The name of this key attribute.

    • :key_type - The role that the key attribute will assume:

      • HASH - partition key

      • RANGE - sort key

    The partition key of an item is also known as its hash attribute. The term “hash attribute” derives from DynamoDB’s usage of an internal hash function to evenly distribute data items across partitions, based on their partition key values.

    The sort key of an item is also known as its range attribute. The term “range attribute” derives from the way DynamoDB stores items with the same partition key physically close together, in sorted order by the sort key value.

    For a simple primary key (partition key), you must provide exactly one element with a KeyType of HASH.

    For a composite primary key (partition key and sort key), you must provide exactly two elements, in this order: The first element must have a KeyType of HASH, and the second element must have a KeyType of RANGE.

    For more information, see Specifying the Primary Key in the Amazon DynamoDB Developer Guide.

  • :read_capacity_units (Integer) — default: 1

    The maximum number of strongly consistent reads consumed per second before DynamoDB returns a ThrottlingException. Must be at least 1. For current minimum and maximum provisioned throughput values, see Limits in the Amazon DynamoDB Developer Guide.

  • :write_capacity_units (Integer) — default: 1

    The maximum number of writes consumed per second before DynamoDB returns a ThrottlingException. Must be at least 1. For current minimum and maximum provisioned throughput values, see Limits in the Amazon DynamoDB Developer Guide.

  • :local_secondary_indexes (Array<Hash>) — default: []

    One or more local secondary indexes (the maximum is five) to be created on the table. Each index is scoped to a given partition key value. There is a 10 GB size limit per partition key value; otherwise, the size of a local secondary index is unconstrained.

    Each element in the array must be a Hash with these symbols:

    • :index_name - The name of the local secondary index. Must be unique only for this table.

    • :key_schema - Specifies the key schema for the local secondary index. The key schema must begin with the same partition key as the table.

    • :projection - Specifies attributes that are copied (projected) from the table into the index. These are in addition to the primary key attributes and index key attributes, which are automatically projected. Each attribute specification is composed of:

      • :projection_type - One of the following:

        • KEYS_ONLY - Only the index and primary keys are projected into the index.

        • INCLUDE - Only the specified table attributes are projected into the index. The list of projected attributes are in non_key_attributes.

        • ALL - All of the table attributes are projected into the index.

      • :non_key_attributes - A list of one or more non-key attribute names that are projected into the secondary index. The total count of attributes provided in NonKeyAttributes, summed across all of the secondary indexes, must not exceed 20. If you project the same attribute into two different indexes, this counts as two distinct attributes when determining the total.

  • :global_secondary_indexes (Array<Hash>) — default: []

    One or more global secondary indexes (the maximum is five) to be created on the table. Each global secondary index (Hash) in the array includes the following:

    • :index_name - The name of the global secondary index. Must be unique only for this table.

    • :key_schema - Specifies the key schema for the global secondary index.

    • :projection - Specifies attributes that are copied (projected) from the table into the index. These are in addition to the primary key attributes and index key attributes, which are automatically projected. Each attribute specification is composed of:

      • :projection_type - One of the following:

        • KEYS_ONLY - Only the index and primary keys are projected into the index.

        • INCLUDE - Only the specified table attributes are projected into the index. The list of projected attributes are in NonKeyAttributes.

        • ALL - All of the table attributes are projected into the index.

      • non_key_attributes - A list of one or more non-key attribute names that are projected into the secondary index. The total count of attributes provided in NonKeyAttributes, summed across all of the secondary indexes, must not exceed 20. If you project the same attribute into two different indexes, this counts as two distinct attributes when determining the total.

    • :provisioned_throughput - The provisioned throughput settings for the global secondary index, consisting of read and write capacity units.

  • :append_environment_on_deploy (Boolean) — default: false

    Option to append the name of the environment to the table name upon deployment and teardown. DynamoDB Tables cannot shard data in a similar manner as how Lambda aliases and API Gateway Environments work. This option is supposed to help the user with naming tables instead of managing the environment names on their own.

Raises:

  • (ArgumentError)

Since:

  • 1.0



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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 99

def initialize(options)
  default_options = { append_environment_on_deploy: false, read_capacity_units: 1, write_capacity_units: 1,
                      local_secondary_indexes: nil, global_secondary_indexes: nil,
                      attribute_definitions: [{ attribute_name: 'Id', attribute_type: 'S' }],
                      key_schema: [{ attribute_name: 'Id', key_type: 'HASH' }] }

  options_with_defaults = options.reverse_merge(default_options)

  @table_name = options_with_defaults[:table_name]
  raise ArgumentError, ':table_name is required.' unless @table_name

  @attribute_definitions = options_with_defaults[:attribute_definitions]
  @key_schema = options_with_defaults[:key_schema]

  # Verify that all of key_schema is defined in attribute_definitions
  defined_in_attribute_definitions_guard(@key_schema)

  @read_capacity_units = options_with_defaults[:read_capacity_units]
  @write_capacity_units = options_with_defaults[:write_capacity_units]
  provisioned_throughput_guard(read_capacity_units: @read_capacity_units,
                               write_capacity_units: @write_capacity_units)

  unless @read_capacity_units >= 1 && @write_capacity_units >= 1 && (@read_capacity_units.is_a? Integer) &&
         (@write_capacity_units.is_a? Integer)
    raise ArgumentExecption, 'Read and Write Capacity must be positive integers.'
  end

  @local_secondary_indexes = options_with_defaults[:local_secondary_indexes]

  if @local_secondary_indexes && @local_secondary_indexes.length > 5
    raise ArgumentError, 'Can only have 5 LocalSecondaryIndexes per table!'
  end
  if @local_secondary_indexes && !@local_secondary_indexes.empty?
    @local_secondary_indexes.each { |lsindex| defined_in_attribute_definitions_guard(lsindex[:key_schema]) }
  end

  @global_secondary_indexes = options_with_defaults[:global_secondary_indexes]

  if @global_secondary_indexes && @global_secondary_indexes.length > 5
    raise ArgumentError, 'Can only have 5 GlobalSecondaryIndexes per table1'
  end
  if @global_secondary_indexes && !@global_secondary_indexes.empty?
    @global_secondary_indexes.each do |gsindex|
      defined_in_attribute_definitions_guard(gsindex[:key_schema])
      provisioned_throughput_guard(gsindex[:provisioned_throughput])
    end
  end

  @append_environment_on_deploy = options_with_defaults[:append_environment_on_deploy]
end

Instance Method Details

#delete(client, region = 'AWS_REGION') ⇒ Object

Deletes all DynamoDB tables that are prefixed with the @table_name specified in the constructor. This is an attempt to tear down all DynamoTables that were deployed with the environment name appended.

Parameters:

  • client (Aws::DynamoDB::Client)

    Client to use with SDK. Should be passed in by the API class.

  • region (String) (defaults to: 'AWS_REGION')

    AWS Region string. Should be passed in by the API class.

Since:

  • 1.0



197
198
199
200
201
202
203
204
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 197

def delete(client, region = 'AWS_REGION')
  super
  puts "Deleting all tables with prefix: #{@table_name}."
  table_names = retrieve_prefixed_tables(@table_name)
  table_names.each { |table_name| delete_table(table_name) }
  puts "Deleted #{table_names.length} tables."
  table_names.length
end

#deploy(environment_options, client, region = 'AWS_REGION') ⇒ Object

Deploys the DynamoDB Table to the target environment. If the @append_environment_on_deploy option is set, the table_name will be appended with a hyphen and the environment name. This will attempt to Create or Update with the parameters specified from the constructor. This may take a LONG time for it will wait for any new indexes to be available.

Parameters:

  • environment_options (LambdaWrap::Environment)

    Target environment to deploy.

  • client (Aws::DynamoDB::Client)

    Client to use with SDK. Should be passed in by the API class.

  • region (String) (defaults to: 'AWS_REGION')

    AWS Region string. Should be passed in by the API class.

Since:

  • 1.0



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 158

def deploy(environment_options, client, region = 'AWS_REGION')
  super

  puts "Deploying Table: #{@table_name} to Environment: #{environment_options.name}"

  full_table_name = @table_name + (@append_environment_on_deploy ? "-#{environment_options.name}" : '')

  table_details = retrieve_table_details(full_table_name)

  if table_details.nil?
    create_table(full_table_name)
  else
    wait_until_table_is_available(full_table_name) if table_details[:table_status] != 'ACTIVE'
    update_table(full_table_name, table_details)
  end

  puts "Dynamo Table #{full_table_name} is now available."
  full_table_name
end

#teardown(environment_options, client, region = 'AWS_REGION') ⇒ Object

Deletes the DynamoDB table specified by the table_name and the Environment name (if append_environment_on_deploy) was specified. Otherwise just deletes the table.

Parameters:

  • environment_options (LambdaWrap::Environment)

    Target environment to teardown

  • client (Aws::DynamoDB::Client)

    Client to use with SDK. Should be passed in by the API class.

  • region (String) (defaults to: 'AWS_REGION')

    AWS Region string. Should be passed in by the API class.

Since:

  • 1.0



184
185
186
187
188
189
190
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 184

def teardown(environment_options, client, region = 'AWS_REGION')
  super
  puts "Tearingdown Table: #{@table_name} from Environment: #{environment_options.name}"
  full_table_name = @table_name + (@append_environment_on_deploy ? "-#{environment_options.name}" : '')
  delete_table(full_table_name)
  full_table_name
end

#to_sObject

Since:

  • 1.0



206
207
208
209
# File 'lib/lambda_wrap/dynamo_db_manager.rb', line 206

def to_s
  return @table_name if @table_name && @table_name.is_a?(String)
  super
end