module Shrine::Plugins::Lambda::AttacherMethods
Public Instance Methods
Triggers AWS Lambda
processing defined by the user in the uploader's `Shrine#lambda_process`, first checking if the specified Lambda
function is available (raising an error if not).
Generates a random key, stores the key into the cached file metadata, and passes the key to the Lambda
function for signing the request.
Stores the DB record class and name, attacher data atribute and uploader class names, into the context attribute of the Lambda
function invokation payload. Also stores the cached file hash object and the generated path into the payload.
After the AWS Lambda
function invocation, a `Shrine::Error` will be raised if the response is containing errors. No more response analysis is performed, because Lambda
is invoked asynchronously (note the `invocation_type`: 'Event' in the `invoke` call). The results will be sent by Lambda
by HTTP requests to the specified `callbackUrl`.
# File lib/shrine/plugins/shrine-lambda.rb, line 140 def lambda_process(data) cached_file = uploaded_file(data['attachment']) assembly = lambda_default_values assembly.merge!(store.lambda_process_versions(cached_file, context)) function = assembly.delete(:function) raise Error, 'No Lambda function specified!' unless function raise Error, "Function #{function} not available on Lambda!" unless function_available?(function) prepare_assembly(assembly, cached_file, context) assembly[:context] = data.except('attachment', 'action', 'phase') response = lambda_client.invoke(function_name: function, invocation_type: 'Event', payload: assembly.to_json) raise Error, "#{response.function_error}: #{response.payload.read}" if response.function_error swap(cached_file) || _set(cached_file) end
Receives the `result` hash after Lambda
request was authorized. The result could contain an array of processed file versions data hashes, or a single file data hash, if there were no versions and the original attached file was just moved to the target storage bucket.
Deletes the signing key, if it is present in the original file's metadata, converts the result to a JSON string, and writes this string into the `data_attribute` of the Shrine
attacher's record.
Chooses the `save_method` either for the ActiveRecord or for Sequel, and saves the record. @param [Hash] result
# File lib/shrine/plugins/shrine-lambda.rb, line 167 def lambda_save(result) versions = result['versions'] attr_content = if versions tmp_hash = versions.inject(:merge!) tmp_hash.dig('original', 'metadata')&.delete('key') tmp_hash.to_json else result['metadata']&.delete('key') result.to_json end record.__send__(:"#{data_attribute}=", attr_content) save_method = if record.is_a?(ActiveRecord::Base) :save elsif record.is_a?(::Sequel::Model) :save_changes end record.__send__(save_method, validate: false) end
Private Instance Methods
@param [Array] buckets that will be sent to Lambda
function for use
# File lib/shrine/plugins/shrine-lambda.rb, line 197 def buckets_to_use(buckets) buckets.map do |b| { b.to_s => { name: Shrine.storages[b].bucket.name, prefix: Shrine.storages[b].prefix } } end.inject(:merge!) end
Checks if the specified Lambda
function is available. @param [Symbol] function name
# File lib/shrine/plugins/shrine-lambda.rb, line 210 def function_available?(function) Shrine.opts[:lambda_function_list].map(&:function_name).include?(function.to_s) end
# File lib/shrine/plugins/shrine-lambda.rb, line 224 def get_upload_options(cached_file, context, storage) options = store.opts[:upload_options][storage[0].to_sym] options = options.call(cached_file, context) if options.respond_to?(:call) options end
A cached instance of an AWS Lambda
client.
# File lib/shrine/plugins/shrine-lambda.rb, line 204 def lambda_client @lambda_client ||= Shrine.lambda_client end
# File lib/shrine/plugins/shrine-lambda.rb, line 189 def lambda_default_values { callbackURL: Shrine.opts[:callback_url], copy_original: true, storages: buckets_to_use(%i[cache store]), target_storage: :store } end
# File lib/shrine/plugins/shrine-lambda.rb, line 214 def prepare_assembly(assembly, cached_file, context) assembly[:path] = store.generate_location(cached_file, context) assembly[:storages].each do |s| upload_options = get_upload_options(cached_file, context, s) s[1][:upload_options] = upload_options if upload_options end cached_file.metadata['key'] = SecureRandom.base64(12) assembly[:attachment] = cached_file end