69 lines
2.0 KiB
Ruby
69 lines
2.0 KiB
Ruby
module Resources
|
|
# Takes a bunch of unsafe, string-y data that came in over AMQP and parses it
|
|
# into fully formed
|
|
class PreProcessor < Mutations::Command
|
|
def self.from_amqp(delivery_info, body)
|
|
# Parse the AMQP rotuing key into an Array of strings.
|
|
# A properly formatted routing_key will look like this after processing:
|
|
#
|
|
# ["bot", "device_3", "resources_v0", "destroy", "Sequence", "2", "xyz"]
|
|
segments = delivery_info.routing_key.split(".")
|
|
_, device_name, _, action, resource, uuid, resource_id = segments
|
|
run!(device_name: device_name,
|
|
action: action,
|
|
resource: resource,
|
|
resource_id: resource_id,
|
|
uuid: uuid,
|
|
body: body.empty? ? "{}" : body)
|
|
end
|
|
|
|
required do
|
|
string :action, in: ACTIONS # "destroy"
|
|
string :device_name, matches: DEVICE_REGEX # "device_3"
|
|
string :resource, in: RESOURCES.keys # "Sequence"
|
|
end
|
|
|
|
optional do
|
|
integer :resource_id, default: 0 # 2
|
|
string :body # "{\"json\":true}"
|
|
string :uuid, default: "NONE" # "0dce-1d-41-1d-e95c3b"
|
|
end
|
|
|
|
def validate
|
|
maybe_set_device
|
|
maybe_set_body
|
|
end
|
|
|
|
def execute
|
|
{
|
|
action: action,
|
|
device: @device,
|
|
body: @body,
|
|
resource_id: resource_id,
|
|
resource: RESOURCES.fetch(resource),
|
|
uuid: uuid,
|
|
}
|
|
end
|
|
|
|
private
|
|
|
|
def fail_body
|
|
add_error :body, :body, "body must be a JSON object"
|
|
end
|
|
|
|
def maybe_set_body
|
|
hash = JSON.parse(body)
|
|
fail_body unless hash.is_a?(Hash)
|
|
@body = hash
|
|
rescue JSON::ParserError
|
|
fail_body
|
|
end
|
|
|
|
def maybe_set_device
|
|
id = device_name.gsub("device_", "").to_i
|
|
@device = Device.find_by(id: id)
|
|
add_error :device, :device, "Can't find device ##{id}" unless @device
|
|
end
|
|
end # PreProcessor
|
|
end # Resources
|