Skip to content
This repository has been archived by the owner on Jun 11, 2023. It is now read-only.

Commit

Permalink
WIP - Add Henforcers for MotherboardUpdateRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomassaro committed Dec 12, 2017
1 parent 43e5c58 commit aed06db
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 1 deletion.
35 changes: 35 additions & 0 deletions lib/entity/henforcer/entity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ defmodule Helix.Entity.Henforcer.Entity do

import Helix.Henforcer

alias Helix.Server.Model.Component
alias Helix.Server.Model.Server
alias Helix.Server.Henforcer.Component, as: ComponentHenforcer
alias Helix.Server.Henforcer.Server, as: ServerHenforcer
alias Helix.Server.Query.Component, as: ComponentQuery
alias Helix.Entity.Model.Entity
alias Helix.Entity.Query.Entity, as: EntityQuery

Expand Down Expand Up @@ -63,4 +66,36 @@ defmodule Helix.Entity.Henforcer.Entity do
end
|> wrap_relay(%{entity: entity, server: server})
end

def owns_component?(entity_id = %Entity.ID{}, component, owned) do
henforce entity_exists?(entity_id) do
owns_component?(relay.entity, component, owned)
end
end

def owns_component?(entity, component_id = %Component.ID{}, owned) do
henforce(ComponentHenforcer.component_exists?(component_id)) do
owns_component?(entity, relay.component, owned)
end
end

def owns_component?(entity = %Entity{}, component = %Component{}, nil) do
owned_components =
entity
|> EntityQuery.get_components()
|> Enum.map(&(ComponentQuery.fetch(&1.component_id)))

owns_component?(entity, component, owned_components)
end

def owns_component?(entity = %Entity{}, component = %Component{}, owned) do
if component in owned do
reply_ok()
else
reply_error({:component, :not_belongs})
end
|> wrap_relay(
%{entity: entity, component: component, owned_components: owned}
)
end
end
125 changes: 125 additions & 0 deletions lib/server/henforcer/component.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
defmodule Helix.Server.Henforcer.Component do

import Helix.Henforcer

alias Helix.Entity.Henforcer.Entity, as: EntityHenforcer
alias Helix.Server.Model.Component
alias Helix.Server.Model.Motherboard
alias Helix.Server.Query.Component, as: ComponentQuery

def component_exists?(component_id = %Component.ID{}) do
with component = %Component{} <- ComponentQuery.fetch(component_id) do
reply_ok(%{component: component})
else
_ ->
reply_error({:component, :not_found})
end
end

def is_motherboard?(component = %Component{type: :mobo}),
do: reply_ok(%{component: component})
def is_motherboard?(%Component{}),
do: reply_error({:component, :not_motherboard})
def is_motherboard?(component_id = %Component.ID{}) do
henforce(component_exists?(component_id)) do
is_motherboard?(relay.component)
end
end

def can_link?(
mobo = %Component{type: :mobo},
component = %Component{},
slot_id)
do
with :ok <- Motherboard.check_compatibility(mobo, component, slot_id, []) do
reply_ok()
else
{:error, reason} ->
reply_error({:motherboard, reason})
end
end

def has_initial_components?(components) do
if Motherboard.has_required_initial_components?(components) do
reply_ok()
else
reply_error({:motherboard, :missing_initial_components})
end
end

def can_update_mobo?(entity_id, mobo_id, components, network_connections) do
reduce_components = fn mobo ->
init = {{true, %{}}, nil}

components
|> Enum.reduce_while(init, fn {slot_id, comp_id}, {{true, acc}, cache} ->
with \
{true, r1} <- component_exists?(comp_id),
component = r1.component,

{true, r2} <-
EntityHenforcer.owns_component?(entity_id, component, cache),

{true, _} <- can_link?(mobo, component, slot_id)
do
acc_components = Map.get(acc, :components, [])

new_acc =
acc
|> put_in([:components], acc_components ++ [{component, slot_id}])
|> put_in([:entity], r2.entity)
|> put_in([:owned_components], r2.owned_components)

{:cont, {{true, new_acc}, r2.owned_components}}
else
error ->
{:halt, {error, cache}}
end

end)
|> elem(0)
end

reduce_network_connections = fn components ->
init = {{true, %{}}, nil}

network_connections
|> Enum.reduce_while(init, fn {nic_id, nip}, {{true, acc}, cache} ->

# PAREI AQUI \/. COMECAR COM `OWNS_NC?`. Similar a `owns_component?`
{true, r1} <- NetworkHenforcer.nip_exists?(nip)
{true, r2} <- NetworkHenforcer.owns_nc?(entity, nc)

{:cont, {{true, acc}, cache}}
end)
|> elem(0)
end

with \
{true, r0} <- component_exists?(mobo_id),
mobo = r0.component,

# Make sure user is plugging components into a motherboard
{true, _} <- is_motherboard?(mobo),

# Iterate over components/slots and make the required henforcements
{true, r1} <- reduce_components.(mobo),
components = r1.components,
entity = r1.entity,
owned = r1.owned_components,

# Ensure mobo belongs to entity
{true, _} <- EntityHenforcer.owns_component?(entity, mobo, owned),

# Ensure all required initial components are there
{true, _} <- has_initial_components?(components),

{true, r2} <- reduce_network_connections.(components)
do
reply_ok(relay(r1))
else
error ->
error
end
end
end
1 change: 1 addition & 0 deletions lib/server/henforcer/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ defmodule Helix.Server.Henforcer.Server do
@doc """
Ensures the requested server exists on the database.
"""
# TODO: REVIEW: Why does it accept `Server.t` as input?
def server_exists?(server = %Server{}),
do: server_exists?(server.server_id)
def server_exists?(server_id = %Server.ID{}) do
Expand Down
2 changes: 1 addition & 1 deletion lib/server/model/motherboard.ex
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ defmodule Helix.Server.Model.Motherboard do
| {:error, :wrong_slot_type}
| {:error, :slot_in_use}
| {:error, :bad_slot}
defp check_compatibility(
def check_compatibility(
mobo = %Component{},
component = %Component{},
slot_id,
Expand Down
30 changes: 30 additions & 0 deletions test/entity/henforcer/entity_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Helix.Entity.Henforcer.EntityTest do
alias Helix.Entity.Model.Entity
alias Helix.Entity.Henforcer.Entity, as: EntityHenforcer

alias Helix.Test.Server.Component.Setup, as: ComponentSetup
alias Helix.Test.Server.Setup, as: ServerSetup
alias Helix.Test.Entity.Setup, as: EntitySetup

Expand Down Expand Up @@ -50,4 +51,33 @@ defmodule Helix.Entity.Henforcer.EntityTest do
assert reason == {:server, :not_belongs}
end
end

describe "owns_component?/3" do
test "accepts when entity owns the component" do
{server, %{entity: entity}} = ServerSetup.server()

assert {true, relay} =
EntityHenforcer.owns_component?(
entity.entity_id, server.motherboard_id, nil
)

assert relay.component.component_id == server.motherboard_id
assert relay.entity == entity
assert length(relay.owned_components) >= 4

assert_relay relay, [:component, :entity, :owned_components]
end

test "rejects when entity does not own the component" do
{entity, _} = EntitySetup.entity()
{component, _} = ComponentSetup.component()

assert {false, reason, relay} =
EntityHenforcer.owns_component?(entity, component, nil)

assert reason == {:component, :not_belongs}

assert_relay relay, [:component, :entity, :owned_components]
end
end
end
Loading

0 comments on commit aed06db

Please sign in to comment.