Graph Service API
This section covers the Graph Service API, which was heavily inspired by the GraphML model and the original Topology API.
Terminology
A graph consists of any number of points with any number of connections in between. Usually these points are called nodes, but as nodes have a specific meaning in Horizon, in the context of the graph service they are called vertices. The connection between two vertices is usually called link; however, it also has a specific meaning in Horizon, thus it is called edge. A graph container contains any number of graphs. In general, an element can be either a graph, vertex, or edge.
Graph Model
Generic Graph Model
The generic graph model is very similar to GraphML's model and consists of the basic elements:
-
GenericGraphContainer
-
GenericGraph
-
GenericVertex
-
GenericEdge
In addition to their designated functionality described in Terminology each of these elements also has properties assigned to it. Some properties are mandatory and determined by the element’s type. Others are optional and totally up to the entity providing a graph to the system.
The following rules apply to the generic graph model:
-
Each graph container must be uniquely identified. This identifier is called a
container id
. Thecontainer id
must be unique over all containers and graph namespaces. -
Each graph must be uniquely identified over all graphs (meaning the namespace must be unique throughout the system). This identifier is called a
namespace
. Eachnamespace
must be unique over all container IDs and graph namespaces. -
Each vertex and edge must be uniquely identified by an identifier. This identifier is called an
id
. Theid
must not be unique in the system, but within the graph. -
Each vertex and edge has the same
namespace
as the graph it is part of. This lets you to uniquely identify vertices and edges throughout the system. -
Each graph, vertex, or edge has additional properties to define its nature in more detail. e.g., a vertex may contain a
label
,node
, orlocation
property. -
Each edge contains the source and target ID of the vertex it connects; therefore, it is ALWAYS directed.
-
Each edge may reference vertices from a different graph (
namespace
). However, at least one side must share the samenamespace
as the edge itself. This is the "owning" side, thus the edge will be a member of that graph.
A graph may define a property id besides the property namespace .
This is mostly only relevant when importing graphs via GraphML, as each graph element must have an id attribute set.
When importing such GraphML each imported graph will have a namespace and id property set.
In general, we recommended that the value of the attribute id SHOULD be identical to the namespace property even if it MUST NOT.
|
Refer to module features/graph/api
in package org.opennms.netmgt.graph.api.generic
for implementation details.
Domain Graph Model
A domain graph model is a model that implements a use case in its domain using the generic graph model. To achieve this, use the generic graph model and set the corresponding properties. For more complex use cases in a more Java-friendly way, basic domain objects are available to act as a "view" on the generic graph model to provide a more convenient implementation. These domain objects do not hold information on their own but provide only access to information that can be deducted from the underlying generic model and its properties.
For the domain graph model the same rules apply as for the Generic Graph Model. |
See features/graph/provider/bsm
for a domain model using the basic domain graph classes (AbstractDomainGraph
, AbstractDomainVertex
, etc.).
See features/graph/provider/graphml
for a domain model using the Generic Graph Model classes.
Providers
To get a new graph or graph container to the system either a GraphContainerProvider
or GraphProvider
must be implemented and exposed via the OSGi-registry.
The latter is a convenient way to expose a container that consists of only one graph.
Cache
All calls to GraphContainerProvider.loadGraphContainer()
are cached until Horizon restarts.
This means it is up to the implementor to invalidate the cache.
To achieve this, manually invoke the org.opennms.netmgt.graph.api.service.GraphContainerCache.invalidate(String containerId)
method, as the GraphContainerCache
is exposed as an OSGi-service.
Alternatively, you can use a service property to invalidate a cache entry after it was first populated to the cache:
<service interface="org.opennms.netmgt.graph.api.service.GraphProvider" ref="applicationGraphProvider">
<service-properties>
<entry key="cacheInvalidateInterval" value="300" /> <!-- seconds -->
</service-properties>
</service>
Search
The goal behind searching is usually to bring one or more vertices into the users’s focus. Usually the user searches for something like a node label or category name. Mostly, those things do not directly relate to any element in the graph.
Therefore, a search always consists of the following process:
-
Search for a concrete item in the system (e.g., node, vertex, category).
-
Resolve all vertices that match the concrete item.
Internally, SearchProvider
are used that allow to first make suggestions based on an input.
A NodeSearchProvider
might return a list of suggestions representing nodes in the system.
The NodeSearchProvider
knows how to "resolve" that selection to a unique set of vertices after the user selected one.
Searching is ALWAYS performed in the context of a given namespace. Searching over multiple namespaces is not supported or encouraged. |
Focus/Semantic Zoom Level/View
The focus itself is a list of vertices within the graph.
The semantic zoom level (or szl
) indicates the number of hops (= distance) a vertex may be away from any vertex within the focus to be shown.
If the semantic zoom level is 0
only if the vertices in focus are shown.
The applied semantic zoom level and focus are called a view of the graph.
If the focus contains elements that are not part of the graph, they are not shown.
The Graph Service API lets you create a view on any given graph considering a custom or default focus as well as the semantic zoom level. If no focus is provided when requesting the view, the default focus is applied.
Listening for Changes
It is possible to listen for graph or graph container changes. Various listeners can be exposed as an OSGi service.
The calculation of changes must be triggered manually.
To do so, use the org.opennms.netmgt.graph.api.updates.GraphNotificationService
service, which is exposed as an OSGi service
Refer to package org.opennms.netmgt.graph.api.updates
in module features/graph/api
for available options.
Persistence
Each graph or graph container can be persisted to the database using the org.opennms.netmgt.graph.api.persistence.GraphRepository
.
Enrichment
Enrichment is the process to enrich the view of the graph with additional information, usually used when the enriched data is expensive to load/calculate, e.g., load node data or calculate the status.
Due to performance considerations, enrichment only works on the view of a graph and cannot be performed on the full graph.
Built-in Enrichment
Node Enrichment
By default, all vertices can be enriched with node information if node enrichment is enabled.
To enable the enrichment of node information, the property enrichment.resolveNodes
must be set to true
on the graph.
Afterwards, each vertex which has either a nodeID (integer)
or foreignSource (string)
and foreignID (string)
property assigned will be enriched if a node with that information is found in the system.
A shorter version in form of nodeCriteria=<foreignSource>:<foreignID>
is also available.
ReST API
The Graph Service API provides a REST API which is documented in detail here.
The Graph Service API ReST endpoints serialize the requested graph container, graph, or view in JSON.
As the container and each element within that container may contain custom properties, the type of the property is not static.
This means each GraphContainerProvider
(or GraphProvider
) can set properties on any element using a type that is only known by the domain the graph container is created in.
However, when serializing this object as JSON it is not clear to the REST endpoint how to do that.
To allow these values to be set as properties anyway, expose a custom org.opennms.netmgt.graph.rest.api.PropertyConverter
as an OSGi service.