java.lang.Object
com.tccc.kos.ext.dispense.pipeline.beverage.graph.GraphNode
All Implemented Interfaces:
Comparable<GraphNode>
Direct Known Subclasses:
AndNode, DeadNode, OrNode, PumpNode

public abstract class GraphNode extends Object implements Comparable<GraphNode>
A key component of a PourEngine is a BevGraph. This is a structure that ultimately defines beverages, brand and groups using a dependency graph that describes the relationship between pumps, ingredients and beverages. This is used to monitor real time changes in state and recompute the availability of beverages, brands and groups. For example, if an ingredient becomes sold out while pouring, the sold out trouble on the container will cause the graph to be updated and any beverage that depends on the sold out ingredient will become unavailable (assuming there is not a second source of the same ingredient).

They key component of the dependency graph is a GraphNode. A node can have child nodes and parent nodes and a collection of nodes forms a dependency graph linking pumps at the bottom of the graph to beverages at the top of the graph. Each node in the graph can examine the state of its children, state of the node itself, or objects linked to the node to determine the availability state of the node. This ripples up the graph until it reaches beverages, brands, groups and any changes will be sent via the broker. This allows ui code to fetch availability of beverages, brands, groups and then monitor changes to keep the ui in sync in real time.

A base GraphNode ignores any child nodes and only computes availability information using the override values. Subclasses implement different types of logic and allow users to construct a dependency graph that represents their business logic.

Every node has a type and the type can be used for debugging the graph as well as performing searches within the graph. For example, consider a dependency graph with three layers: pumps, ingredients and beverages. The bottom layer includes all the pumps, the second layer defines a node for each ingredient and adds pumps that have that ingredient assigned as a child of the ingredient node. Finally the third layer consists of beverages and each node includes children that for the ingredients required to pour the beverage (water and BiB ingredient for example). If a pump reports a sold out, that pump will be blocked from beverage pouring which will make the ingredient unavailable which will make any beverage requiring that ingredient unavailable.

Consider pouring a beverage. There is a need to know which ingredients to pour for a given beverage, and ultimately which pumps to turn on. As this information is encoded in the graph, searches can be used to extract this information without having to maintain separate data structures. By naming nodes with custom types it makes the search process easier to perform.

Since:
1.0
Version:
2023-02-07
  • Constructor Details

    • GraphNode

      public GraphNode(String type, String id)
      Create a new graph node with the specified id and type. The id of a node must be unique within the graph. The id is typically related to an object such as a pump, ingredient, beverage, brand and so on. In these cases the identifier of the associated object is typically used as the node id. For example, every pump has a unique path so the path can be used as the node id. In cases where id's between different types of objects may overlap (ingredients and beverages for example), it is common to add a prefix to the id to make it unique, such as "ing:" as a prefix for ingredient id's.

      If the id will be externally visible, such as part of a beverage, brand or group node, it is common to make sure that these id's align with any meta data the external system has. For example, ui code may have a list of beverage / brand icons associated with beverage / brand id's. In this case the beverage / brand nodes should try to use the same id's to make it easier to match up the data.

      The type is only exposed when viewing graph internals during debugging and can also facilitate search rules when processing the graph. All standard nodes have a unique type but the type can be set as needed after node creation.

      Parameters:
      type - symbolic type of the node, useful for searching and debugging
      id - unique id of the node in the graph
  • Method Details

    • getId

      public String getId()
      The unique id of this node.
    • setAltId

      public GraphNode setAltId(String altId)
      Set the alt id of this node. This can be used if natural id's of various nodes (ingredients, beverages, brands, etc...) would collide. Synthetic id's can be used as the node id's and the actual id's can be stored in the altId to allow correlation with other data. This will be exposed in availability data from endpoints.
      Parameters:
      altId - the alternate id for the node
    • getAltId

      public String getAltId()
      Return the alternate id for the node. The alternate id can be used to store correlation id's to link nodes to other data in the event that node id's can't be used due to potentially id collisions.
    • getType

      public String getType()
      The type of the node. This can be used during graph searches to find child nodes of a given type.
    • setType

      public GraphNode setType(String type)
      Set the node type.
    • getVersion

      public int getVersion()
      The version of the graph when this value last changed.
    • getData

      public Object getData()
      Get user data for this node. This is data that can be attached to this node and fetched later for internal use. This will not be exposed via endpoints.
    • setData

      public GraphNode setData(Object data)
      Set user data for this node. This is data that can be attached to this node and fetched later for internal use. This will not be exposed via endpoints.
    • getClientData

      public com.tccc.kos.commons.util.json.JsonViewWrapper getClientData()
      Get the client data for this node. This will be exposed as part of the availability data if this node is a beverage / brand / group.
    • setClientData

      public GraphNode setClientData(com.tccc.kos.commons.util.json.JsonViewWrapper clientData)
      Set the client data for this node. This will be exposed as part of the availability data if this node is a beverage / brand / group.
    • isAvailable

      public boolean isAvailable()
      Cached availability value based on override value or availability of child nodes using the node operation type. If no children, availability will be false.
    • isVisible

      public boolean isVisible()
      Cached visibility value based on override value or visibility of child nodes using the node operation type. If no children, availability will be false.
    • getNote

      public String getNote()
      Return the note associated with the node. This is primarily used for debugging.
    • setNote

      public GraphNode setNote(String note)
      Set the note associated with the node. This is primarily used for debugging.
    • addOverride

      public void addOverride(NodeOverride override)
      Add an external override for the node. This allows external logic to override the natural visibility / availability results for this node. This will update the graph once added.

      Multiple overrides can be added. Overrides should return null if there is no explicit visibility or availability. This delegates to other overrides and default logic. A forced not visible or not available will override a forced visible or available.

    • removeOverride

      public void removeOverride(NodeOverride override)
      Remove an override from the node.
    • removeOverride

      public void removeOverride(NodeOverride override, boolean update)
      Remove an override from the node with optional graph update.
    • getOverrides

      public List<NodeOverride> getOverrides()
      Return the external overrides for the node.
    • getChildren

      public List<GraphNode> getChildren()
      Return the child nodes.
    • getChildrenIds

      public Collection<String> getChildrenIds()
      Return the id's of the children.
    • getParentIds

      public Collection<String> getParentIds()
      Return the id's of the parents.
    • computeVisible

      public boolean computeVisible()
      Compute visible state of the node. This will only be called if the visibility is not overridden. Override to create nodes that use custom logic for visibility.
    • computeAvailable

      public boolean computeAvailable()
      Compute available state of the node. This will only be called if the availability is not overridden and the node is visible. Override to create nodes that use custom logic for visibility.
    • compareTo

      public int compareTo(GraphNode o)
      Specified by:
      compareTo in interface Comparable<GraphNode>
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object