%%% @author Heinz Nikolaus Gies %%% @copyright (C) 2012, Heinz Nikolaus Gies %%% @doc %%% %%% @end %%% Created : 23 Aug 2012 by Heinz Nikolaus Gies -module(ft_hypervisor). -behaviour(fifo_dt). -include("ft_hypervisor.hrl"). -include("ft_helper.hrl"). -export([ is_a/1, load/2, new/1, getter/2, to_json/1, merge/2 ]). -export([ last_seen/3, alias/3, etherstubs/3, host/3, resources/1, set_resource/3, set_resource/4, services/1, set_service/3, set_service/4, characteristics/1, set_characteristic/3, set_characteristic/4, metadata/1, set_metadata/3, set_metadata/4, pools/1, set_pool/3, set_pool/4, networks/3, path/3, port/3, endpoint/1, sysinfo/3, uuid/3, version/3, virtualisation/3, architecture/3 ]). -ignore_xref([ merge/2, alias/3, etherstubs/3, host/3, set_pool/4, set_characteristic/4, set_metadata/4, networks/3, path/3, port/3, set_resource/4, set_service/4, sysinfo/3, uuid/3, version/3, virtualisation/3 ]). -export([ alias/1, last_seen/1, etherstubs/1, host/1, networks/1, path/1, port/1, sysinfo/1, uuid/1, version/1, virtualisation/1, architecture/1 ]). -ignore_xref([ characteristics/1, alias/1, etherstubs/1, host/1, metadata/1, networks/1, path/1, pools/1, port/1, resources/1, services/1, sysinfo/1, uuid/1, version/1, virtualisation/1 ]). -ignore_xref([to_json/1, load/2, set/4, getter/2, uuid/1]). -type architecture() :: arm64 | x86. -type hypervisor() :: #{ type => ?TYPE, version => non_neg_integer(), architecture => riak_dt_lwwreg:lwwreg(), last_seen => riak_dt_lwwreg:lwwreg(), characteristics => riak_dt_map:riak_dt_map(), etherstubs => riak_dt_lwwreg:lwwreg(), host => riak_dt_lwwreg:lwwreg(), metadata => riak_dt_map:riak_dt_map(), alias => riak_dt_lwwreg:lwwreg(), networks => riak_dt_lwwreg:lwwreg(), path => riak_dt_lwwreg:lwwreg(), pools => riak_dt_map:riak_dt_map(), port => riak_dt_lwwreg:lwwreg(), resources => riak_dt_map:riak_dt_map(), services => riak_dt_map:riak_dt_map(), sysinfo => riak_dt_lwwreg:lwwreg(), uuid => riak_dt_lwwreg:lwwreg(), chunter_version => riak_dt_lwwreg:lwwreg(), virtualisation => riak_dt_lwwreg:lwwreg() }. -export_type([hypervisor/0, architecture/0]). -spec is_a(any()) -> true | false. ?IS_A. -spec new(fifo_dt:tid()) -> hypervisor(). new(_) -> {ok, Empty} = ?NEW_LWW([], 1), {ok, Zero} = ?NEW_LWW(0, 1), {ok, Arch} = ?NEW_LWW(undefined, 1), #{ type => ?TYPE, version => ?VERSION, architecture => Arch, last_seen => Zero, characteristics => riak_dt_map:new(), etherstubs => Empty, host => riak_dt_lwwreg:new(), metadata => riak_dt_map:new(), alias => riak_dt_lwwreg:new(), networks => Empty, path => Empty, pools => riak_dt_map:new(), port => riak_dt_lwwreg:new(), resources => riak_dt_map:new(), services => riak_dt_map:new(), sysinfo => Empty, uuid => riak_dt_lwwreg:new(), chunter_version => riak_dt_lwwreg:new(), virtualisation => Empty }. load(_, #{type := ?TYPE, version := ?VERSION} = H) -> H; load({T, _ID} = TID, #{type := ?TYPE, version := 0} = H) -> {ok, Arch} = ?NEW_LWW(x86, T), H1 = H#{architecture => Arch, version => 1}, load(TID, H1); load(TID, #hypervisor_0{ characteristics = Characteristics, etherstubs = Etherstubs, host = Host, metadata = Metadata, alias = Alias, networks = Networks, path = Path, pools = Pools, port = Port, resources = Rsources, services = Services, sysinfo = Sysinfo, uuid = UUID, version = Version, virtualisation = Virt }) -> {ok, Zero} = ?NEW_LWW(0, 1), H1 = #{ type => ?TYPE, version => 0, last_seen => Zero, characteristics => Characteristics, etherstubs => Etherstubs, host => Host, metadata => Metadata, alias => Alias, networks => Networks, path => Path, pools => Pools, port => Port, resources => Rsources, services => Services, sysinfo => Sysinfo, uuid => UUID, chunter_version => Version, virtualisation => Virt }, load(TID, H1); load(TID, #hypervisor_0_1_0{ characteristics = Characteristics, etherstubs = Etherstubs, host = Host, metadata = Metadata, alias = Alias, networks = Networks, path = Path, pools = Pools, port = Port, resources = Rsources, services = Services, sysinfo = Sysinfo, uuid = UUID, version = Version, virtualisation = Virt }) -> H1 = #hypervisor_0{ characteristics = fifo_dt:update_map(Characteristics), etherstubs = Etherstubs, host = Host, metadata = fifo_dt:update_map(Metadata), alias = Alias, networks = Networks, path = Path, pools = fifo_dt:update_map(Pools), port = Port, resources = fifo_dt:update_map(Rsources), services = fifo_dt:update_map(Services), sysinfo = Sysinfo, uuid = UUID, version = Version, virtualisation = Virt }, load(TID, H1). to_json(H) -> Arch = case architecture(H) of undefined -> null; O -> atom_to_binary(O, utf8) end, #{ <<"alias">> => alias(H), <<"architecture">> => Arch, <<"characteristics">> => characteristics(H), <<"etherstubs">> => etherstubs(H), <<"host">> => host(H), <<"last_seen">> => last_seen(H), <<"metadata">> => metadata(H), <<"networks">> => networks(H), <<"path">> => path_to_json(path(H)), <<"pools">> => pools(H), <<"port">> => port(H), <<"resources">> => resources(H), <<"services">> => services(H), <<"sysinfo">> => sysinfo(H), <<"uuid">> => uuid(H), <<"version">> => version(H), <<"virtualisation">> => virtualisation(H) }. path_to_json(P) -> [#{<<"cost">> => C, <<"name">> => N} || {N, C} <- P]. merge(H=#{ type := ?TYPE, architecture := Arch1, last_seen := LastSeen1, characteristics := Characteristics1, alias := Alias1, etherstubs := Etherstubs1, host := Host1, metadata := Metadata1, networks := Networks1, path := Path1, pools := Pools1, port := Port1, resources := Resources1, services := Services1, sysinfo := Sysinfo1, uuid := UUID1, chunter_version := Version1, virtualisation := Virtualisation1 }, #{ type := ?TYPE, last_seen := LastSeen2, architecture := Arch2, characteristics := Characteristics2, alias := Alias2, etherstubs := Etherstubs2, host := Host2, metadata := Metadata2, networks := Networks2, path := Path2, pools := Pools2, port := Port2, resources := Resources2, services := Services2, sysinfo := Sysinfo2, uuid := UUID2, chunter_version := Version2, virtualisation := Virtualisation2 }) -> H#{ architecture => riak_dt_lwwreg:merge(Arch1, Arch2), characteristics => fifo_map:merge(Characteristics1, Characteristics2), alias => riak_dt_lwwreg:merge(Alias1, Alias2), last_seen => riak_dt_lwwreg:merge(LastSeen1, LastSeen2), etherstubs => riak_dt_lwwreg:merge(Etherstubs1, Etherstubs2), host => riak_dt_lwwreg:merge(Host1, Host2), metadata => fifo_map:merge(Metadata1, Metadata2), networks => riak_dt_lwwreg:merge(Networks1, Networks2), path => riak_dt_lwwreg:merge(Path1, Path2), pools => fifo_map:merge(Pools1, Pools2), port => riak_dt_lwwreg:merge(Port1, Port2), resources => fifo_map:merge(Resources1, Resources2), services => fifo_map:merge(Services1, Services2), sysinfo => riak_dt_lwwreg:merge(Sysinfo1, Sysinfo2), uuid => riak_dt_lwwreg:merge(UUID1, UUID2), chunter_version => riak_dt_lwwreg:merge(Version1, Version2), virtualisation => riak_dt_lwwreg:merge(Virtualisation1, Virtualisation2) }. -spec uuid(hypervisor()) -> binary(). ?REG_GET(uuid). -spec uuid(fifo_dt:tid(), binary(), hypervisor()) -> hypervisor(). ?REG_SET_BIN(uuid). -spec alias(hypervisor()) -> binary(). ?REG_GET(alias). -spec alias(fifo_dt:tid(), binary(), hypervisor()) -> hypervisor(). ?REG_SET_BIN(alias). -spec version(hypervisor()) -> binary(). version(#{type := ?TYPE, chunter_version := V}) -> riak_dt_lwwreg:value(V). -spec version(fifo_dt:tid(), binary(), hypervisor()) -> hypervisor(). version({T, _ID}, V, O = #{type := ?TYPE, chunter_version := Reg0}) when is_binary(V) -> ?REG_SET_BODY(chunter_version). -spec last_seen(hypervisor()) -> pos_integer(). ?REG_GET(last_seen). -spec last_seen(fifo_dt:tid(), pos_integer(), hypervisor()) -> hypervisor(). ?REG_SET_PI(last_seen). -spec host(hypervisor()) -> binary(). ?REG_GET(host). -spec host(fifo_dt:tid(), binary(), hypervisor()) -> hypervisor(). ?REG_SET_BIN(host). -spec port(hypervisor()) -> pos_integer(). ?REG_GET(port). -spec port(fifo_dt:tid(), pos_integer(), hypervisor()) -> hypervisor(). ?REG_SET_PI(port). -spec virtualisation(hypervisor()) -> [binary()]. ?REG_GET(virtualisation). -spec virtualisation(fifo_dt:tid(), [binary()], hypervisor()) -> hypervisor(). ?REG_SET(virtualisation). -spec etherstubs(hypervisor()) -> [binary()]. ?REG_GET(etherstubs). -spec etherstubs(fifo_dt:tid(), [binary()], hypervisor()) -> hypervisor(). ?REG_SET(etherstubs). -spec networks(hypervisor()) -> [binary()]. ?REG_GET(networks). -spec networks(fifo_dt:tid(), [{non_neg_integer(), binary()}], hypervisor()) -> hypervisor(). ?REG_SET(networks). -spec architecture(hypervisor()) -> undefined | architecture(). ?REG_GET(architecture). -spec architecture(fifo_dt:tid(), architecture(), hypervisor()) -> hypervisor(). architecture({T, _ID}, V, O = #{type := ?TYPE, architecture := Reg0}) when V =:= x86; V =:= arm64 -> {ok, Reg1} = riak_dt_lwwreg:update({assign, V, T}, none, Reg0), O#{architecture => Reg1}. -spec path(hypervisor()) -> [{binary(), non_neg_integer()}]. %% We need to ensure we get an list path(#{type := ?TYPE, path := V}) -> case riak_dt_lwwreg:value(V) of <<>> -> []; R -> R end. -spec path(fifo_dt:tid(), [{binary(), non_neg_integer()}], hypervisor()) -> hypervisor(). ?REG_SET(path). -spec sysinfo(hypervisor()) -> term(). ?REG_GET(sysinfo). -spec sysinfo(fifo_dt:tid(), term(), hypervisor()) -> hypervisor(). ?REG_SET(sysinfo). -spec endpoint(hypervisor()) -> {string(), pos_integer()}. endpoint(H) -> {binary_to_list(host(H)), port(H)}. ?MAP_GET(pools). ?MAP_SET_3(set_pool). ?MAP_SET_4(set_pool, pools). ?MAP_GET(characteristics). ?MAP_SET_3(set_characteristic). ?MAP_SET_4(set_characteristic, characteristics). ?MAP_GET(resources). ?MAP_SET_3(set_resource). ?MAP_SET_4(set_resource, resources). ?MAP_GET(services). ?MAP_SET_3(set_service). ?MAP_SET_4(set_service, services). ?META. ?SET_META_3. ?SET_META_4. ?G(<<"path">>, path); ?G(<<"uuid">>, uuid); ?G(<<"virtualisation">>, virtualisation); ?G(<<"etherstubs">>, etherstubs); ?G(<<"alias">>, alias); ?G(<<"resources">>, resources); getter(O, <<"architecture">>) -> atom_to_binary(architecture(O), utf8); getter(O, <<"resources.", K/binary>>) -> V = ft_obj:val(O), Rs = resources(V), jsxd:get(K, <<>>, Rs); getter(O, [<<"resources">> | K]) -> V = ft_obj:val(O), Rs = resources(V), jsxd:get(K, <<>>, Rs); ?G_JSX.