-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add type information for inbound messages on the DeviceChannel #1444
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,135 @@ | ||||||||||||||||||||||||||||||||||||
defmodule NervesHubWeb.DeviceChannel.Messages do | ||||||||||||||||||||||||||||||||||||
@moduledoc false | ||||||||||||||||||||||||||||||||||||
alias NervesHub.Devices.Device | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
require Logger | ||||||||||||||||||||||||||||||||||||
@type alarm_id() :: String.t() | ||||||||||||||||||||||||||||||||||||
@type alarm_description() :: String.t() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type health_check_report() :: %{ | ||||||||||||||||||||||||||||||||||||
timestamp: DateTime.t(), | ||||||||||||||||||||||||||||||||||||
metadata: %{String.t() => String.t()}, | ||||||||||||||||||||||||||||||||||||
alarms: %{alarm_id() => alarm_description()}, | ||||||||||||||||||||||||||||||||||||
metrics: %{String.t() => number()}, | ||||||||||||||||||||||||||||||||||||
checks: %{String.t() => %{pass: boolean(), note: String.t()}} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type scripts_run() :: %{ | ||||||||||||||||||||||||||||||||||||
ref: String.t(), | ||||||||||||||||||||||||||||||||||||
output: String.t(), | ||||||||||||||||||||||||||||||||||||
return: String.t() | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type fwup_progress() :: %{ | ||||||||||||||||||||||||||||||||||||
percent: integer() | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type location() :: term() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type connection_types() :: %{types: list(atom())} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type status_update() :: map() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@type check_update_available() :: map() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
# We parse out messages explicitly to let the compiler help with types and | ||||||||||||||||||||||||||||||||||||
# to keep track of what we have coming in and out of the system | ||||||||||||||||||||||||||||||||||||
# They are not structs to reduce the proliferation of modules for what is mostly | ||||||||||||||||||||||||||||||||||||
# an inbetween layer | ||||||||||||||||||||||||||||||||||||
# If the role of these definitions grows to much it may make sense to turn them into | ||||||||||||||||||||||||||||||||||||
# structs. | ||||||||||||||||||||||||||||||||||||
@spec parse(event :: String.t(), params :: map()) :: | ||||||||||||||||||||||||||||||||||||
{:fwup_progress, fwup_progress()} | ||||||||||||||||||||||||||||||||||||
| {:location_update, location()} | ||||||||||||||||||||||||||||||||||||
| {:connection_types, connection_types()} | ||||||||||||||||||||||||||||||||||||
| {:status_update, status_update()} | ||||||||||||||||||||||||||||||||||||
| {:check_update_available, check_update_available()} | ||||||||||||||||||||||||||||||||||||
| {:health_check_report, health_check_report()} | ||||||||||||||||||||||||||||||||||||
| {:scripts_run, scripts_run()} | ||||||||||||||||||||||||||||||||||||
| {:rebooting, map()} | ||||||||||||||||||||||||||||||||||||
| {:unknown, map()} | ||||||||||||||||||||||||||||||||||||
def parse(event, params) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("fwup_progress", %{"value" => percent}) do | ||||||||||||||||||||||||||||||||||||
{:fwup_progress, %{percent: percent}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("location:update", location) do | ||||||||||||||||||||||||||||||||||||
{:location_update, location} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
@valid_types Device.connection_types() | ||||||||||||||||||||||||||||||||||||
def parse("connection_types", %{"values" => types}) do | ||||||||||||||||||||||||||||||||||||
types = | ||||||||||||||||||||||||||||||||||||
types | ||||||||||||||||||||||||||||||||||||
|> Enum.map(fn type -> | ||||||||||||||||||||||||||||||||||||
try do | ||||||||||||||||||||||||||||||||||||
String.to_existing_atom(type) | ||||||||||||||||||||||||||||||||||||
rescue | ||||||||||||||||||||||||||||||||||||
_ -> nil | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
end) | ||||||||||||||||||||||||||||||||||||
|> Enum.filter(fn type -> | ||||||||||||||||||||||||||||||||||||
if type in @valid_types do | ||||||||||||||||||||||||||||||||||||
true | ||||||||||||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||||||||||||
Logger.warning("Received invalid type for connection_types: #{inspect(type)}") | ||||||||||||||||||||||||||||||||||||
false | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
end) | ||||||||||||||||||||||||||||||||||||
Comment on lines
+64
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We can use the Ecto.Enum mappings to get the valid types out of this. I'm unsure we need to warn on invalid being included? (this would mostly be hidden to the users anyway) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just figured we'd do something when we see weird things :) Would Ecto.Enum be smoother somehow or are you thinking full-on embedded schema? |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
{:connection_types, %{types: types}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("status_update", %{"status" => _status}) do | ||||||||||||||||||||||||||||||||||||
{:status_update, %{}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("check_update_available", _params) do | ||||||||||||||||||||||||||||||||||||
{:check_update_available, %{}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("health_check_report", %{ | ||||||||||||||||||||||||||||||||||||
"value" => %{ | ||||||||||||||||||||||||||||||||||||
"timestamp" => iso_ts, | ||||||||||||||||||||||||||||||||||||
"metadata" => metadata, | ||||||||||||||||||||||||||||||||||||
"alarms" => alarms, | ||||||||||||||||||||||||||||||||||||
"metrics" => metrics, | ||||||||||||||||||||||||||||||||||||
"checks" => checks | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
}) do | ||||||||||||||||||||||||||||||||||||
{:ok, ts, _} = DateTime.from_iso8601(iso_ts) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
status = %{ | ||||||||||||||||||||||||||||||||||||
timestamp: ts, | ||||||||||||||||||||||||||||||||||||
metadata: metadata, | ||||||||||||||||||||||||||||||||||||
alarms: alarms, | ||||||||||||||||||||||||||||||||||||
metrics: metrics, | ||||||||||||||||||||||||||||||||||||
checks: to_checks(checks) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
{:health_check_report, status} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("scripts/run", %{"ref" => ref, "output" => output, "return" => return}) do | ||||||||||||||||||||||||||||||||||||
{:scripts_run, %{ref: ref, output: output, return: return}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse("rebooting", _) do | ||||||||||||||||||||||||||||||||||||
{:rebooting, %{}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
def parse(event, params) do | ||||||||||||||||||||||||||||||||||||
Logger.warning( | ||||||||||||||||||||||||||||||||||||
"Unmatched incoming event in device channel messages '#{event}' with #{inspect(params)}" | ||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
{:unknown, params} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
defp to_checks(checks) do | ||||||||||||||||||||||||||||||||||||
for {key, %{"pass" => pass, "note" => note}} <- checks, into: %{} do | ||||||||||||||||||||||||||||||||||||
{key, %{pass: pass, note: note}} | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming this is a dialyzer fix? We should prob include this in a different PR so its away from these changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, dialyzer