From e5372532d8adc99e6db4aa7cba75a219a0f4f19f Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 19 Aug 2025 17:51:45 +0200 Subject: [PATCH 1/2] refactor: format fix: removed deprecated unless statetement --- lib/mix/tasks/arke.seed_project.ex | 377 ++++++++++++++++++----------- 1 file changed, 233 insertions(+), 144 deletions(-) diff --git a/lib/mix/tasks/arke.seed_project.ex b/lib/mix/tasks/arke.seed_project.ex index ca41516..ef01d64 100644 --- a/lib/mix/tasks/arke.seed_project.ex +++ b/lib/mix/tasks/arke.seed_project.ex @@ -34,28 +34,31 @@ defmodule Mix.Tasks.Arke.SeedProject do all: :boolean, format: :string, persistence: :string, + update: :boolean ] @aliases [ p: :project, A: :all, f: :format, ps: :persistence, + u: :update ] @impl true def run(args) do - case OptionParser.parse!(args, strict: @switches, aliases: @aliases) do - {[], _opts}-> + {[], _opts} -> Mix.Tasks.Help.run(["arke.seed_project"]) - {opts, []} -> - persistence = parse_persistence!(opts[:persistence] || "arke_postgres") - app_to_start(persistence) ++ [:arke] + {opts, []} -> + persistence = parse_persistence!(opts[:persistence] || "arke_postgres") + + (app_to_start(persistence) ++ [:arke]) |> Enum.each(&Application.ensure_all_started/1) repo_module = Application.get_env(:arke, :persistence)[String.to_atom(persistence)][:repo] Mix.shell().info("--- Starting repo --- ") + case start_repo(repo_module) do {:ok, pid} -> opts |> parse_file() @@ -66,21 +69,26 @@ defmodule Mix.Tasks.Arke.SeedProject do opts |> parse_file() :ok end - end - end - defp app_to_start("arke_postgres"), do: [:ecto_sql, :postgrex] - defp parse_persistence!(ps) when ps in @persistence_repo, do: ps - defp parse_persistence!(ps), do: Mix.raise("Invalid persistence: `#{ps}`\nSupported persistence are: #{Enum.join(@persistence_repo, " | ")}") + defp parse_persistence!(ps) when ps in @persistence_repo, do: ps - defp check_file(_arke_id,project, []), do: nil - defp check_file(arke_id,project, data) do + defp parse_persistence!(ps), + do: + Mix.raise( + "Invalid persistence: `#{ps}`\nSupported persistence are: #{Enum.join(@persistence_repo, " | ")}" + ) + + defp check_file(_arke_id, project, []), do: nil + + defp check_file(arke_id, project, data) do + if Mix.env() != :test do + {:ok, datetime} = + Arke.Utils.DatetimeHandler.now(:datetime) + |> Arke.Utils.DatetimeHandler.format("{ISO:Basic:Z}") - unless Mix.env() == :test do - {:ok, datetime} = Arke.Utils.DatetimeHandler.now(:datetime) |> Arke.Utils.DatetimeHandler.format("{ISO:Basic:Z}") dir_path = "log/arke_seed_project/#{project}" path = "#{dir_path}/#{datetime}_#{to_string(arke_id)}.log" Mix.shell().info("--- Writing errors to #{path} --- ") @@ -88,7 +96,6 @@ defmodule Mix.Tasks.Arke.SeedProject do File.mkdir_p!(dir_path) write_log_to_file(path, data) end - end defp write_log_to_file(path, data) do @@ -98,184 +105,232 @@ defmodule Mix.Tasks.Arke.SeedProject do File.close(file) end - defp start_repo(nil), do: Mix.raise("Invalid repo module in arke configuration. Please provide a valid module accordingly to the persistence supported") + defp start_repo(nil), + do: + Mix.raise( + "Invalid repo module in arke configuration. Please provide a valid module accordingly to the persistence supported" + ) + # this is for arke_postgres defp start_repo(repo_module) do repo_module.start_link() end - defp parse_file(opts) do + defp parse_file(opts) do Mix.shell().info("--- Parsing registry files --- ") format = opts[:format] || "json" check_format!(format) all = opts[:all] || false + update = opts[:update] || false # get core file to decode (arke) and append all other arke_deps registry files - core_registry = arke_registry("arke", format,"all") - core_data = parse(core_registry,format) + core_registry = arke_registry("arke", format, "all") + core_data = parse(core_registry, format) - arke_deps_registry = get_arke_deps_registry(format,"all") - arke_deps_data = parse(arke_deps_registry,format) + arke_deps_registry = get_arke_deps_registry(format, "all") + arke_deps_data = parse(arke_deps_registry, format) Mix.shell().info("--- Get core data ---") - core_parameter = Map.get(core_data,:parameter, []) ++ Map.get(arke_deps_data, :parameter, []) - core_arke = Map.get(core_data,:arke, []) ++ Map.get(arke_deps_data, :arke, []) - core_group = Map.get(core_data,:group, []) ++ Map.get(arke_deps_data, :group, []) - core_link = Map.get(core_data,:link, []) ++ Map.get(arke_deps_data, :link, []) - + core_parameter = Map.get(core_data, :parameter, []) ++ Map.get(arke_deps_data, :parameter, []) + core_arke = Map.get(core_data, :arke, []) ++ Map.get(arke_deps_data, :arke, []) + core_group = Map.get(core_data, :group, []) ++ Map.get(arke_deps_data, :group, []) + core_link = Map.get(core_data, :link, []) ++ Map.get(arke_deps_data, :link, []) # start core manager before create everything Mix.shell().info("--- Starting core managers --- ") - error_parameter_manager = Arke.handle_manager(core_parameter,:arke_system,:parameter) - error_arke_manager = Arke.handle_manager(core_arke,:arke_system,:arke) - error_group_manager = Arke.handle_manager(core_group,:arke_system,:group) + error_parameter_manager = Arke.handle_manager(core_parameter, :arke_system, :parameter) + error_arke_manager = Arke.handle_manager(core_arke, :arke_system, :arke) + error_group_manager = Arke.handle_manager(core_group, :arke_system, :group) - check_file("parameter_manager","arke_system",error_parameter_manager) - check_file("arke_manager","arke_system",error_arke_manager) - check_file("group_manager","arke_system",error_group_manager) + check_file("parameter_manager", "arke_system", error_parameter_manager) + check_file("arke_manager", "arke_system", error_arke_manager) + check_file("group_manager", "arke_system", error_group_manager) input_project = String.to_atom(opts[:project]) || :arke_system project_list = get_project(input_project, all) Enum.each(project_list, fn project -> - if to_string(project) == "arke_system" do - write_data(project,core_data,core_parameter,core_arke,core_group,core_link) - else - file_list = Path.wildcard("./lib/registry/*.#{format}") - shared_arke_list = arke_registry("arke", format,"shared") - shared_arke_deps_list = get_arke_deps_registry(format,"shared") - - raw_data = parse(shared_arke_list++shared_arke_deps_list++file_list,format) - parameter_list = Map.get(raw_data, :parameter, []) - arke_list = Map.get(raw_data, :arke, []) - group_list = Map.get(raw_data, :group, []) - link_list = Map.get(raw_data, :link, []) - write_data(project,core_data,parameter_list,arke_list,group_list,link_list) - end + if to_string(project) == "arke_system" do + write_data(project, core_data, core_parameter, core_arke, core_group, core_link) + else + file_list = Path.wildcard("./lib/registry/*.#{format}") + shared_arke_list = arke_registry("arke", format, "shared") + shared_arke_deps_list = get_arke_deps_registry(format, "shared") + + raw_data = parse(shared_arke_list ++ shared_arke_deps_list ++ file_list, format) + parameter_list = Map.get(raw_data, :parameter, []) + arke_list = Map.get(raw_data, :arke, []) + group_list = Map.get(raw_data, :group, []) + link_list = Map.get(raw_data, :link, []) + write_data(project, core_data, parameter_list, arke_list, group_list, link_list) + end end) - end - defp write_data(input_project,core_data,parameter_list,arke_list,group_list,link_list) do - project_key= to_string(input_project) + defp write_data(input_project, core_data, parameter_list, arke_list, group_list, link_list) do + project_key = to_string(input_project) # if the project is arke_system the managers have already been started so skip - unless project_key =="arke_system" do - Mix.shell().info("--- Parsing registry files --- ") - error_parameter_manager = Arke.handle_manager(Map.get(core_data,:parameter, []),input_project,:parameter) - error_arke_manager = Arke.handle_manager(Map.get(core_data,:arke, []),input_project,:arke) - error_group_manager = Arke.handle_manager(Map.get(core_data,:group, []),input_project,:group) - check_file("parameter_manager",project_key,error_parameter_manager) - check_file("arke_manager",project_key,error_arke_manager) - check_file("group_manager",project_key,error_group_manager) - end - error_parameter = handle_parameter(parameter_list, input_project,[]) - error_arke = handle_arke(arke_list, input_project,[]) - error_group = handle_group(group_list, input_project,[]) - error_link = handle_link(link_list, input_project,[]) - check_file("parameter",project_key,error_parameter) - check_file("arke",project_key,error_arke) - check_file("group",project_key,error_group) - check_file("link",project_key,error_link) - end + if project_key != "arke_system" do + Mix.shell().info("--- Parsing registry files --- ") + + error_parameter_manager = + Arke.handle_manager(Map.get(core_data, :parameter, []), input_project, :parameter) - defp arke_registry(package_name,format,type) do + error_arke_manager = + Arke.handle_manager(Map.get(core_data, :arke, []), input_project, :arke) + + error_group_manager = + Arke.handle_manager(Map.get(core_data, :group, []), input_project, :group) + + check_file("parameter_manager", project_key, error_parameter_manager) + check_file("arke_manager", project_key, error_arke_manager) + check_file("group_manager", project_key, error_group_manager) + end + + error_parameter = handle_parameter(parameter_list, input_project, []) + error_arke = handle_arke(arke_list, input_project, []) + error_group = handle_group(group_list, input_project, []) + error_link = handle_link(link_list, input_project, []) + check_file("parameter", project_key, error_parameter) + check_file("arke", project_key, error_arke) + check_file("group", project_key, error_group) + check_file("link", project_key, error_link) + end + + defp arke_registry(package_name, format, type) do # Get arke's dependecies based on the env path. env_var = System.get_env() - folder_path = get_folder(type,format) - case Enum.find(env_var,fn {k,_v}-> String.contains?(String.downcase(k), "ex_dep_#{package_name}_path") end) do - {_package_name, ""} -> Path.wildcard("./**/arke*/**/registry/#{folder_path}") - {_package_name, local_path} -> + folder_path = get_folder(type, format) + + case Enum.find(env_var, fn {k, _v} -> + String.contains?(String.downcase(k), "ex_dep_#{package_name}_path") + end) do + {_package_name, ""} -> + Path.wildcard("./**/arke*/**/registry/#{folder_path}") + + {_package_name, local_path} -> Path.wildcard("#{local_path}/lib/registry/#{folder_path}") - nil -> Path.wildcard("./**/arke*/**/registry/#{folder_path}") - end + nil -> + Path.wildcard("./**/arke*/**/registry/#{folder_path}") + end end - defp get_folder("shared",format),do: "shared/*.#{format}" - defp get_folder("system",format),do: "system/*.#{format}" - defp get_folder("all",format),do: "**/*.#{format}" + + defp get_folder("shared", format), do: "shared/*.#{format}" + defp get_folder("system", format), do: "system/*.#{format}" + defp get_folder("all", format), do: "**/*.#{format}" defp get_project(_input_project, true) do QueryManager.filter_by(arke_id: :arke_project, project: :arke_system) - |> Enum.map( fn unit -> to_string(unit.id) end) + |> Enum.map(fn unit -> to_string(unit.id) end) end defp get_project(input_project, _all), do: [input_project] - defp check_format!(format) when format in @supported_format, do: format - defp check_format!(format), do: Mix.raise("Invalid format: `#{format}`\nSupported format are: #{Enum.join(@supported_format, " | ")}") + + defp check_format!(format), + do: + Mix.raise( + "Invalid format: `#{format}`\nSupported format are: #{Enum.join(@supported_format, " | ")}" + ) # get all the registry file for all the arke_deps except arke itself which is used alone - defp get_arke_deps_registry(format,type) do - Enum.reduce(Mix.Project.config() |> Keyword.get(:deps, []),[], fn tuple,acc -> + defp get_arke_deps_registry(format, type) do + Enum.reduce(Mix.Project.config() |> Keyword.get(:deps, []), [], fn tuple, acc -> name = List.first(Tuple.to_list(tuple)) - if name != :arke and String.contains?(to_string(name),"arke") do - arke_registry(to_string(name),format,type) ++ acc - else acc + + if name != :arke and String.contains?(to_string(name), "arke") do + arke_registry(to_string(name), format, type) ++ acc + else + acc end end) end + defp parse(file_list, format, file_data \\ %{}) - defp parse(file_list,format,file_data \\ %{}) - defp parse([filename | t],"json"=format, data) do + defp parse([filename | t], "json" = format, data) do try do - body = File.read!(filename) - json = Jason.decode!(body, keys: :atoms) + body = File.read!(filename) + json = Jason.decode!(body, keys: :atoms) + new_data = Enum.reduce(@decode_keys, %{}, fn key, acc -> Map.put(acc, key, Map.get(data, key, []) ++ Map.get(json, key, [])) end) - parse(t, format,new_data) + + parse(t, format, new_data) rescue - err in Jason.DecodeError -> + err in Jason.DecodeError -> + %{data: data, token: token, position: position} = err - %{data: data, token: token, position: position} = err - Mix.raise("Json error in: #{filename}.\n Position: #{position}\n token: #{token}\n data: #{data}") - err in File.Error -> - %{reason: reason}= err - Mix.raise("Error open file: #{filename}. \n Reason: #{reason}") + Mix.raise( + "Json error in: #{filename}.\n Position: #{position}\n token: #{token}\n data: #{data}" + ) + + err in File.Error -> + %{reason: reason} = err + Mix.raise("Error open file: #{filename}. \n Reason: #{reason}") end end # tutti i file parsati quindi proseguire - defp parse([],format, data), do: data - + defp parse([], format, data), do: data - defp handle_parameter([%{id: id, label: nil} = current | t], project, error), - do: handle_parameter([Map.put(current, :label, String.capitalize(id)) | t], project, error) + defp handle_parameter([%{id: id, label: nil} = current | t], project, error), + do: handle_parameter([Map.put(current, :label, String.capitalize(id)) | t], project, error) defp handle_parameter( - [%{id: id, type: type} = current | t], + [%{id: id, type: type} = current | t], project, error ) do Mix.shell().info("--- Creating parameter #{id} --- ") + with nil <- QueryManager.get_by(id: id, project: project, arke_id: type), %Unit{} = model <- ArkeManager.get(String.to_atom(type), project), {:ok, _unit} <- QueryManager.create(project, model, current) do - handle_parameter(t, project, error) else - nil -> handle_parameter(t, project, parse_error(create_error(:parameter, "manager does not exists for: `#{id}`") , error)) - %Unit{} -> handle_parameter(t, project, parse_error(create_error(:parameter, "Record already exists in db for: `#{id}`") , error)) - {:error, err} -> - handle_parameter(t, project, parse_error(err, error,id)) - _err -> - handle_parameter(t, project, parse_error(create_error(:parameter, "Something went wrong for: `#{id}`") ,error)) - end + nil -> + handle_parameter( + t, + project, + parse_error(create_error(:parameter, "manager does not exists for: `#{id}`"), error) + ) + %Unit{} -> + handle_parameter( + t, + project, + parse_error(create_error(:parameter, "Record already exists in db for: `#{id}`"), error) + ) + {:error, err} -> + handle_parameter(t, project, parse_error(err, error, id)) + + _err -> + handle_parameter( + t, + project, + parse_error(create_error(:parameter, "Something went wrong for: `#{id}`"), error) + ) + end end defp handle_parameter([_current | t], project, error) do - handle_parameter(t, project, parse_error(create_error(:parameter, "Missing parameter `id` or `type`") , error)) + handle_parameter( + t, + project, + parse_error(create_error(:parameter, "Missing parameter `id` or `type`"), error) + ) end defp handle_parameter([], _project, error), do: error defp handle_arke([%{id: id, label: nil} = current | t], project, error), - do: handle_arke([Map.put(current, "label", String.capitalize(id)) | t], project, error) + do: handle_arke([Map.put(current, "label", String.capitalize(id)) | t], project, error) defp handle_arke( [%{id: id} = current | t], @@ -283,26 +338,35 @@ defmodule Mix.Tasks.Arke.SeedProject do error ) do Mix.shell().info("--- Creating arke #{id} --- ") - {parameter,new_data} = Map.pop(current, :parameters, []) + {parameter, new_data} = Map.pop(current, :parameters, []) - #aggiungere try do block + # aggiungere try do block with nil <- QueryManager.get_by(id: id, project: project, arke_id: "arke"), %Unit{} = model <- ArkeManager.get(:arke, project), {:ok, unit} <- QueryManager.create(project, model, new_data), link_parameter_error <- link_parameter(parameter, unit, project) do if length(link_parameter_error) == 0 do - handle_arke(t, project, error) - else - handle_arke(t, project, [%{"#{id}_parameter_association": link_parameter_error}|error]) + handle_arke(t, project, error) + else + handle_arke(t, project, [%{"#{id}_parameter_association": link_parameter_error} | error]) end - else nil -> - handle_arke(t, project, parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error)) - %Unit{}=_unit -> - handle_arke(t, project, parse_error(create_error(:arke, "Record already exists in db for: `#{id}`") , error)) + handle_arke( + t, + project, + parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error) + ) + + %Unit{} = _unit -> + handle_arke( + t, + project, + parse_error(create_error(:arke, "Record already exists in db for: `#{id}`"), error) + ) + {:error, err} -> - handle_arke(t, project, [err | error]) + handle_arke(t, project, [err | error]) end end @@ -310,9 +374,11 @@ defmodule Mix.Tasks.Arke.SeedProject do defp handle_group( [%{id: id} = current | t], - project,error + project, + error ) do Mix.shell().info("--- Creating group #{id} --- ") + with nil <- QueryManager.get_by(id: id, project: project, arke_id: :group), %Unit{} = model <- ArkeManager.get(:group, project), {:ok, unit} <- QueryManager.create(project, model, current), @@ -320,32 +386,45 @@ defmodule Mix.Tasks.Arke.SeedProject do handle_group(t, project, error ++ error_group) else nil -> - handle_group(t, project, parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error)) - %Unit{}=_unit -> - handle_group(t, project, parse_error(create_error(:arke, "Record already exists in db for: `#{id}`"),error)) + handle_group( + t, + project, + parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error) + ) + + %Unit{} = _unit -> + handle_group( + t, + project, + parse_error(create_error(:arke, "Record already exists in db for: `#{id}`"), error) + ) + {:error, err} -> - handle_group(t, project, [err | error]) + handle_group(t, project, [err | error]) end end defp handle_group([], _project, error), do: error - defp handle_link(_data,_project, _error \\ []) + defp handle_link(_data, _project, _error \\ []) + defp handle_link( [%{type: type, parent: parent, child: child} = current | t], project, error ) do Mix.shell().info("--- Creating link from #{parent} to #{child} --- ") + case LinkManager.add_node( - project, - parent, - child, - type, - Map.get(current, :metadata, %{}) - ) do - - {:ok, _unit} -> handle_link(t, project, error) - {:error, link_error} -> + project, + parent, + child, + type, + Map.get(current, :metadata, %{}) + ) do + {:ok, _unit} -> + handle_link(t, project, error) + + {:error, link_error} -> handle_link( t, project, @@ -354,13 +433,19 @@ defmodule Mix.Tasks.Arke.SeedProject do end end - defp handle_link([current | t], project, error),do: - handle_link(t, project, parse_error(create_error(:link, "invalid parameters for #{current}}"),error)) + defp handle_link([current | t], project, error), + do: + handle_link( + t, + project, + parse_error(create_error(:link, "invalid parameters for #{current}}"), error) + ) defp handle_link([], _project, error), do: error defp link_parameter(p_list, arke, project) do Mix.shell().info("--- Adding parameters to arke #{arke.id} --- ") + param_link = Enum.reduce(p_list, [], fn parameter, acc -> [ @@ -380,6 +465,7 @@ defmodule Mix.Tasks.Arke.SeedProject do defp add_arke_to_group(group, project) do Mix.shell().info("--- Adding arkes to group #{group.id} --- ") arke_list = Map.get(group, :arke_list, []) + group_link = Enum.reduce(arke_list, [], fn arke, acc -> [ @@ -396,13 +482,16 @@ defmodule Mix.Tasks.Arke.SeedProject do handle_link(group_link, project, []) end - - defp create_error(context,msg) do - {:error,msg} = Error.create(context,msg) + defp create_error(context, msg) do + {:error, msg} = Error.create(context, msg) msg end - defp parse_error(error_message, error_accumulator) when is_list(error_message), do: error_message ++error_accumulator + defp parse_error(error_message, error_accumulator) when is_list(error_message), + do: error_message ++ error_accumulator + defp parse_error(error_message, error_accumulator), do: [error_message | error_accumulator] - defp parse_error(error_message, error_accumulator,id), do: [%{create: id, error: error_message} | error_accumulator] -end \ No newline at end of file + + defp parse_error(error_message, error_accumulator, id), + do: [%{create: id, error: error_message} | error_accumulator] +end From 7e2d6e796da25be5aaa35f9a0a6ee45d838a33bc Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 20 Aug 2025 15:48:49 +0200 Subject: [PATCH 2/2] chore: update flag to add parameters to arke --- lib/arke/boundary/group_manager.ex | 19 +++--- lib/arke/boundary/unit_manager.ex | 47 ++++++++----- lib/mix/tasks/arke.seed_project.ex | 106 ++++++++++++++++++----------- 3 files changed, 108 insertions(+), 64 deletions(-) diff --git a/lib/arke/boundary/group_manager.ex b/lib/arke/boundary/group_manager.ex index 14dc073..6868a4b 100644 --- a/lib/arke/boundary/group_manager.ex +++ b/lib/arke/boundary/group_manager.ex @@ -20,7 +20,7 @@ defmodule Arke.Boundary.GroupManager do manager_id(:group) defp check_module(%{__module__: nil} = unit), - do: Unit.update(unit, __module__: Arke.System.BaseGroup) + do: Unit.update(unit, __module__: Arke.System.BaseGroup) defp check_module(unit), do: unit @@ -59,11 +59,11 @@ defmodule Arke.Boundary.GroupManager do unit -> with %Unit{} = arke <- - Enum.find(get_arke_list(unit), {:error, "arke id not found"}, fn f -> - f.id == arke_id - end), - do: arke, - else: ({:error, msg} -> nil) + Enum.find(get_arke_list(unit), {:error, "arke id not found"}, fn f -> + f.id == arke_id + end), + do: arke, + else: ({:error, msg} -> nil) end end @@ -77,15 +77,17 @@ defmodule Arke.Boundary.GroupManager do Enum.reduce(group_keys, [], fn {g, _}, groups -> group = get(g, project) + if arke_id in Enum.map(group.data.arke_list, fn a -> a.id end) do - [group | groups] + [group | groups] else - groups + groups end end) end def get_parameters(group_id, project), do: get(group_id, project) |> get_parameters + def get_parameters(%{id: id, metadata: %{project: project}} = group) do parameters = get_arke_list(group) @@ -93,7 +95,6 @@ defmodule Arke.Boundary.GroupManager do |> init_parameters_by_ids(project) end - defp get_group_parameters(arke_list, _project) do Enum.reduce(arke_list, [], fn arke, group_parameters -> check_group_parameters(group_parameters, Arke.Boundary.ArkeManager.get_parameters(arke)) diff --git a/lib/arke/boundary/unit_manager.ex b/lib/arke/boundary/unit_manager.ex index 1fe19c4..f8a9b24 100644 --- a/lib/arke/boundary/unit_manager.ex +++ b/lib/arke/boundary/unit_manager.ex @@ -101,7 +101,7 @@ defmodule Arke.Boundary.UnitManager do {manager, opts} = Keyword.pop(opts, :manager, __MODULE__) {unit, project} = before_create(unit, project) current_node_create = GenServer.call(manager, {:create, unit, project}) - call_nodes_manager(manager,:create,[unit,project]) + call_nodes_manager(manager, :create, [unit, project]) current_node_create end @@ -113,7 +113,7 @@ defmodule Arke.Boundary.UnitManager do def update(unit_id, project, new_unit) do unit = get(unit_id, project) current_node_update = GenServer.call(__MODULE__, {:update, new_unit, project}) - call_nodes_manager(__MODULE__,:update,[new_unit,project]) + call_nodes_manager(__MODULE__, :update, [new_unit, project]) current_node_update end @@ -126,9 +126,8 @@ defmodule Arke.Boundary.UnitManager do defp exec_call_func(unit, func, opts) when is_nil(unit), do: get(:arke, :arke_system) |> exec_call_func(func, opts) - defp exec_call_func(%{__module__: module} = unit, func, opts) when is_nil(module), do: - {:error, "No Module"} - + defp exec_call_func(%{__module__: module} = unit, func, opts) when is_nil(module), + do: {:error, "No Module"} defp exec_call_func( %{id: id, metadata: %{project: project}, __module__: module} = unit, @@ -171,10 +170,15 @@ defmodule Arke.Boundary.UnitManager do manager = __MODULE__ case get(unit_id, project) do - nil -> {:error, "#{unit_id} doesn't exist in project: #{project}"} + nil -> + {:error, "#{unit_id} doesn't exist in project: #{project}"} + unit -> - current_node_update = GenServer.call(manager, {:add_link, unit, parameter_id, child_id, metadata}) - call_nodes_manager(manager,:add_link,[unit, parameter_id, child_id, metadata]) + current_node_update = + GenServer.call(manager, {:add_link, unit, parameter_id, child_id, metadata}) + + call_nodes_manager(manager, :add_link, [unit, parameter_id, child_id, metadata]) + current_node_update end end @@ -188,10 +192,14 @@ defmodule Arke.Boundary.UnitManager do manager = __MODULE__ case get(unit_id, project) do - nil -> {:error, "#{unit_id} doesn't exist in project: #{project}"} + nil -> + {:error, "#{unit_id} doesn't exist in project: #{project}"} + unit -> - current_node_update = GenServer.call(manager, {:remove_link, unit, parameter_id, child_id}) - call_nodes_manager(manager,:remove_link,[unit, parameter_id, child_id]) + current_node_update = + GenServer.call(manager, {:remove_link, unit, parameter_id, child_id}) + + call_nodes_manager(manager, :remove_link, [unit, parameter_id, child_id]) current_node_update end end @@ -222,6 +230,8 @@ defmodule Arke.Boundary.UnitManager do _from, state ) do + + opts = %{} |> Map.put(parameter_id, [ @@ -238,16 +248,19 @@ defmodule Arke.Boundary.UnitManager do do: %{id: child_id, metadata: metadata} # Update all nodes manager - defp call_nodes_manager(manager,func_name,opts) do - tuple_data = Enum.reduce(opts,{func_name},fn opt,acc -> Tuple.append(acc,opt) end) - {right_nodes, bad_nodes} = :rpc.multicall(Node.list(),GenServer,:call,[manager, tuple_data]) - if length(bad_nodes)>0 do + defp call_nodes_manager(manager, func_name, opts) do + tuple_data = Enum.reduce(opts, {func_name}, fn opt, acc -> Tuple.append(acc, opt) end) + + {right_nodes, bad_nodes} = + :rpc.multicall(Node.list(), GenServer, :call, [manager, tuple_data]) + + if length(bad_nodes) > 0 do Enum.each(bad_nodes, fn unit -> Logger.warning("Something went wrong during multi node update for unit: `#{unit.id}`") end) - end - {right_nodes,bad_nodes} + + {right_nodes, bad_nodes} end # Remove link diff --git a/lib/mix/tasks/arke.seed_project.ex b/lib/mix/tasks/arke.seed_project.ex index ef01d64..3ecb5d5 100644 --- a/lib/mix/tasks/arke.seed_project.ex +++ b/lib/mix/tasks/arke.seed_project.ex @@ -112,16 +112,14 @@ defmodule Mix.Tasks.Arke.SeedProject do ) # this is for arke_postgres - defp start_repo(repo_module) do - repo_module.start_link() - end + defp start_repo(repo_module), do: repo_module.start_link() defp parse_file(opts) do Mix.shell().info("--- Parsing registry files --- ") format = opts[:format] || "json" check_format!(format) all = opts[:all] || false - update = opts[:update] || false + ArkePostgres.init() # get core file to decode (arke) and append all other arke_deps registry files core_registry = arke_registry("arke", format, "all") @@ -151,7 +149,7 @@ defmodule Mix.Tasks.Arke.SeedProject do Enum.each(project_list, fn project -> if to_string(project) == "arke_system" do - write_data(project, core_data, core_parameter, core_arke, core_group, core_link) + write_data(project, core_data, core_parameter, core_arke, core_group, core_link, opts) else file_list = Path.wildcard("./lib/registry/*.#{format}") shared_arke_list = arke_registry("arke", format, "shared") @@ -162,13 +160,23 @@ defmodule Mix.Tasks.Arke.SeedProject do arke_list = Map.get(raw_data, :arke, []) group_list = Map.get(raw_data, :group, []) link_list = Map.get(raw_data, :link, []) - write_data(project, core_data, parameter_list, arke_list, group_list, link_list) + write_data(project, core_data, parameter_list, arke_list, group_list, link_list, opts) end end) end - defp write_data(input_project, core_data, parameter_list, arke_list, group_list, link_list) do + defp write_data( + input_project, + core_data, + parameter_list, + arke_list, + group_list, + link_list, + opts \\ [] + ) do project_key = to_string(input_project) + update = if project_key == "arke_system", do: false, else: opts[:update] || false + # if the project is arke_system the managers have already been started so skip if project_key != "arke_system" do Mix.shell().info("--- Parsing registry files --- ") @@ -187,10 +195,10 @@ defmodule Mix.Tasks.Arke.SeedProject do check_file("group_manager", project_key, error_group_manager) end - error_parameter = handle_parameter(parameter_list, input_project, []) - error_arke = handle_arke(arke_list, input_project, []) - error_group = handle_group(group_list, input_project, []) - error_link = handle_link(link_list, input_project, []) + error_parameter = handle_parameter(parameter_list, input_project, [update: update], []) + error_arke = handle_arke(arke_list, input_project, [update: update], []) + error_group = handle_group(group_list, input_project, [update: update], []) + error_link = handle_link(link_list, input_project, [update: update], []) check_file("parameter", project_key, error_parameter) check_file("arke", project_key, error_arke) check_file("group", project_key, error_group) @@ -278,12 +286,19 @@ defmodule Mix.Tasks.Arke.SeedProject do # tutti i file parsati quindi proseguire defp parse([], format, data), do: data - defp handle_parameter([%{id: id, label: nil} = current | t], project, error), - do: handle_parameter([Map.put(current, :label, String.capitalize(id)) | t], project, error) + defp handle_parameter([%{id: id, label: nil} = current | t], project, opts, error), + do: + handle_parameter( + [Map.put(current, :label, String.capitalize(id)) | t], + project, + opts, + error + ) defp handle_parameter( [%{id: id, type: type} = current | t], project, + opts, error ) do Mix.shell().info("--- Creating parameter #{id} --- ") @@ -291,12 +306,13 @@ defmodule Mix.Tasks.Arke.SeedProject do with nil <- QueryManager.get_by(id: id, project: project, arke_id: type), %Unit{} = model <- ArkeManager.get(String.to_atom(type), project), {:ok, _unit} <- QueryManager.create(project, model, current) do - handle_parameter(t, project, error) + handle_parameter(t, project, opts, error) else nil -> handle_parameter( t, project, + opts, parse_error(create_error(:parameter, "manager does not exists for: `#{id}`"), error) ) @@ -304,91 +320,100 @@ defmodule Mix.Tasks.Arke.SeedProject do handle_parameter( t, project, + opts, parse_error(create_error(:parameter, "Record already exists in db for: `#{id}`"), error) ) {:error, err} -> - handle_parameter(t, project, parse_error(err, error, id)) + handle_parameter(t, project, opts, parse_error(err, error, id)) _err -> handle_parameter( t, project, + opts, parse_error(create_error(:parameter, "Something went wrong for: `#{id}`"), error) ) end end - defp handle_parameter([_current | t], project, error) do + defp handle_parameter([_current | t], project, opts, error) do handle_parameter( t, project, + opts, parse_error(create_error(:parameter, "Missing parameter `id` or `type`"), error) ) end - defp handle_parameter([], _project, error), do: error + defp handle_parameter([], _project, _opts, error), do: error - defp handle_arke([%{id: id, label: nil} = current | t], project, error), + defp handle_arke(list, project, opts \\ [], error \\ []) + + defp handle_arke([%{id: id, label: nil} = current | t], project, opts, error), do: handle_arke([Map.put(current, "label", String.capitalize(id)) | t], project, error) defp handle_arke( [%{id: id} = current | t], project, + opts, error ) do Mix.shell().info("--- Creating arke #{id} --- ") {parameter, new_data} = Map.pop(current, :parameters, []) + update = opts[:update] || false - # aggiungere try do block with nil <- QueryManager.get_by(id: id, project: project, arke_id: "arke"), %Unit{} = model <- ArkeManager.get(:arke, project), {:ok, unit} <- QueryManager.create(project, model, new_data), - link_parameter_error <- link_parameter(parameter, unit, project) do - if length(link_parameter_error) == 0 do - handle_arke(t, project, error) - else - handle_arke(t, project, [%{"#{id}_parameter_association": link_parameter_error} | error]) - end + error <- link_parameter(parameter, unit, project, error) do + handle_arke(t, project, opts, error) else nil -> handle_arke( t, project, + opts, parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error) ) + %Unit{} = unit when update -> + error = link_parameter(parameter, unit, project, error) + handle_arke(t, project, opts, error) + %Unit{} = _unit -> handle_arke( t, project, + opts, parse_error(create_error(:arke, "Record already exists in db for: `#{id}`"), error) ) {:error, err} -> - handle_arke(t, project, [err | error]) + handle_arke(t, project, opts, [err | error]) end end - defp handle_arke([], _project, error), do: error + defp handle_arke([], _project, _opts, error), do: error defp handle_group( [%{id: id} = current | t], project, + opts, error ) do Mix.shell().info("--- Creating group #{id} --- ") with nil <- QueryManager.get_by(id: id, project: project, arke_id: :group), %Unit{} = model <- ArkeManager.get(:group, project), - {:ok, unit} <- QueryManager.create(project, model, current), - error_group <- add_arke_to_group(unit, project) do - handle_group(t, project, error ++ error_group) + {:ok, unit} <- QueryManager.create(project, model, current) do + handle_group(t, project, opts, error) else nil -> handle_group( t, project, + opts, parse_error(create_error(:arke, "manager does not exists for: `#{id}`"), error) ) @@ -396,20 +421,22 @@ defmodule Mix.Tasks.Arke.SeedProject do handle_group( t, project, + opts, parse_error(create_error(:arke, "Record already exists in db for: `#{id}`"), error) ) {:error, err} -> - handle_group(t, project, [err | error]) + handle_group(t, project, opts, [err | error]) end end - defp handle_group([], _project, error), do: error - defp handle_link(_data, _project, _error \\ []) + defp handle_group([], _project, _opts, error), do: error + defp handle_link(_data, _project, _opts, _error \\ []) defp handle_link( [%{type: type, parent: parent, child: child} = current | t], project, + opts, error ) do Mix.shell().info("--- Creating link from #{parent} to #{child} --- ") @@ -422,18 +449,19 @@ defmodule Mix.Tasks.Arke.SeedProject do Map.get(current, :metadata, %{}) ) do {:ok, _unit} -> - handle_link(t, project, error) + handle_link(t, project, opts, error) {:error, link_error} -> handle_link( t, project, + opts, [link_error | error] ) end end - defp handle_link([current | t], project, error), + defp handle_link([current | t], project, opts, error), do: handle_link( t, @@ -441,9 +469,9 @@ defmodule Mix.Tasks.Arke.SeedProject do parse_error(create_error(:link, "invalid parameters for #{current}}"), error) ) - defp handle_link([], _project, error), do: error + defp handle_link([], _project, _opts, error), do: error - defp link_parameter(p_list, arke, project) do + defp link_parameter(p_list, arke, project, error) do Mix.shell().info("--- Adding parameters to arke #{arke.id} --- ") param_link = @@ -459,7 +487,9 @@ defmodule Mix.Tasks.Arke.SeedProject do ] end) - handle_link(param_link, project, []) + new_error = handle_link(param_link, project, [], []) + + [%{"#{arke.id}_parameter_association": new_error} | error] end defp add_arke_to_group(group, project) do