Graph Service API
This section covers the Graph Service API, which was heavily inspired by the GraphML model and the original Topology API.
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.
Generic Graph Model
The generic graph model is very similar to GraphML's model and consists of the basic elements:
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. The
container idmust 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
namespacemust 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
idmust not be unique in the system, but within the graph.
Each vertex and edge has the same
namespaceas 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
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 same
namespaceas the edge itself. This is the "owning" side, thus the edge will be a member of that graph.
A graph may define a property
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.|
features/graph/provider/bsm for a domain model using the basic domain graph classes (
features/graph/provider/graphml for a domain model using the Generic Graph Model classes.
To get a new graph or graph container to the system either a
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.
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>
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.
SearchProvider are used that allow to first make suggestions based on an input.
NodeSearchProvider might return a list of suggestions representing nodes in the system.
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.
Each graph or graph container can be persisted to the database using the
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.
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.
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
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.