From 8298236908ef8ed7ae237acaf4ec6a6ec6681d61 Mon Sep 17 00:00:00 2001 From: Andrew Mayorov Date: Fri, 3 Feb 2023 12:38:02 +0300 Subject: [PATCH] refactor(ft): bring back userdata to filemeta schema --- apps/emqx_ft/src/emqx_ft.erl | 3 +- apps/emqx_ft/src/emqx_ft_schema.erl | 40 +++++++++++++++++++++++++ apps/emqx_ft/src/emqx_ft_storage_fs.erl | 34 +++------------------ 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/apps/emqx_ft/src/emqx_ft.erl b/apps/emqx_ft/src/emqx_ft.erl index be2f80831..ce3a7a97d 100644 --- a/apps/emqx_ft/src/emqx_ft.erl +++ b/apps/emqx_ft/src/emqx_ft.erl @@ -66,7 +66,8 @@ %% TTL of individual segments %% Somewhat confusing that we won't know it on the nodes where the filemeta %% is missing. - segments_ttl => _Seconds :: pos_integer() + segments_ttl => _Seconds :: pos_integer(), + user_data => emqx_ft_schema:json_value() }. -type segment() :: {offset(), _Content :: binary()}. diff --git a/apps/emqx_ft/src/emqx_ft_schema.erl b/apps/emqx_ft/src/emqx_ft_schema.erl index f40d2f40e..70acb8322 100644 --- a/apps/emqx_ft/src/emqx_ft_schema.erl +++ b/apps/emqx_ft/src/emqx_ft_schema.erl @@ -23,6 +23,20 @@ -export([namespace/0, roots/0, fields/1, tags/0]). +-export([schema/1]). + +-type json_value() :: + null + | boolean() + | binary() + | number() + | [json_value()] + | #{binary() => json_value()}. + +-reflect_type([json_value/0]). + +%% + namespace() -> file_transfer. tags() -> @@ -47,3 +61,29 @@ fields(local_storage) -> desc => ?DESC("local") }} ]. + +schema(filemeta) -> + #{ + roots => [ + {name, hoconsc:mk(string(), #{required => true})}, + {size, hoconsc:mk(non_neg_integer())}, + {expire_at, hoconsc:mk(non_neg_integer())}, + {checksum, hoconsc:mk({atom(), binary()}, #{converter => converter(checksum)})}, + {segments_ttl, hoconsc:mk(pos_integer())}, + {user_data, hoconsc:mk(json_value())} + ] + }. + +converter(checksum) -> + fun + (undefined, #{}) -> + undefined; + ({sha256, Bin}, #{make_serializable := true}) -> + _ = is_binary(Bin) orelse throw({expected_type, string}), + _ = byte_size(Bin) =:= 32 orelse throw({expected_length, 32}), + binary:encode_hex(Bin); + (Hex, #{}) -> + _ = is_binary(Hex) orelse throw({expected_type, string}), + _ = byte_size(Hex) =:= 64 orelse throw({expected_length, 64}), + {sha256, binary:decode_hex(Hex)} + end. diff --git a/apps/emqx_ft/src/emqx_ft_storage_fs.erl b/apps/emqx_ft/src/emqx_ft_storage_fs.erl index a530c9cf8..e2bda8fcb 100644 --- a/apps/emqx_ft/src/emqx_ft_storage_fs.erl +++ b/apps/emqx_ft/src/emqx_ft_storage_fs.erl @@ -16,9 +16,6 @@ -module(emqx_ft_storage_fs). --include_lib("typerefl/include/types.hrl"). --include_lib("hocon/include/hoconsc.hrl"). - -behaviour(emqx_ft_storage). -export([store_filemeta/3]). @@ -224,17 +221,6 @@ verify_checksum(undefined, _) -> -define(PRELUDE(Vsn, Meta), [<<"filemeta">>, Vsn, Meta]). -schema() -> - #{ - roots => [ - {name, hoconsc:mk(string(), #{required => true})}, - {size, hoconsc:mk(non_neg_integer())}, - {expire_at, hoconsc:mk(non_neg_integer())}, - {checksum, hoconsc:mk({atom(), binary()}, #{converter => converter(checksum)})}, - {segments_ttl, hoconsc:mk(pos_integer())} - ] - }. - % encode_filemeta(Meta) -> % emqx_json:encode( % ?PRELUDE( @@ -261,26 +247,14 @@ schema() -> encode_filemeta(Meta) -> % TODO: Looks like this should be hocon's responsibility. - Term = hocon_tconf:make_serializable(schema(), emqx_map_lib:binary_key_map(Meta), #{}), + Schema = emqx_ft_schema:schema(filemeta), + Term = hocon_tconf:make_serializable(Schema, emqx_map_lib:binary_key_map(Meta), #{}), emqx_json:encode(?PRELUDE(_Vsn = 1, Term)). decode_filemeta(Binary) -> + Schema = emqx_ft_schema:schema(filemeta), ?PRELUDE(_Vsn = 1, Term) = emqx_json:decode(Binary, [return_maps]), - hocon_tconf:check_plain(schema(), Term, #{atom_key => true, required => false}). - -converter(checksum) -> - fun - (undefined, #{}) -> - undefined; - ({sha256, Bin}, #{make_serializable := true}) -> - _ = is_binary(Bin) orelse throw({expected_type, string}), - _ = byte_size(Bin) =:= 32 orelse throw({expected_length, 32}), - binary:encode_hex(Bin); - (Hex, #{}) -> - _ = is_binary(Hex) orelse throw({expected_type, string}), - _ = byte_size(Hex) =:= 64 orelse throw({expected_length, 64}), - {sha256, binary:decode_hex(Hex)} - end. + hocon_tconf:check_plain(Schema, Term, #{atom_key => true, required => false}). % map_into(Fun, Into, Ks, Map) -> % map_foldr(map_into_fn(Fun, Into), Into, Ks, Map).