This documentation and the Cisco Observability Platform functionalities it describes are subject to change. Data saved on the platform may disappear and APIs may change without notice.
Behind the Scenes
The configuration-driven UI is designed to allow the creation of reusable composite UI elements (widgets) without writing JavaScript. The core innovation that makes this possible is that these soft-coded widgets can bind to a topology context (a pointer to a set of entities of a specific type) provided by the enclosing parent component, and request the data they need to render themselves. In other words, the parent component does not need to get involved in the query building and data binding for child components. The child components are handled by the framework based on information declared in the configuration.
The following diagram illustrates the entire process: The soft-coded description of a UI is shown as a tree of templates, or template elements on the left side.
Only when an entity centric page (ECP) is to be rendered, the full hierarchy of the corresponding templates (which is implied by template references) is embodied (1), by means of instantiators (one for each template element). For each kind of atomic building block there is a dedicated instantiator (in other words, a piece of code that creates instances of this building block). The root instantiator receives a query node that represents the scope of the ECP.
In the first phase, the instantiators evaluate their corresponding template elements and "order" the required data through the query nodes (2). Whenever the path to a child element specifies a traversal to a related entity (or metric, event, log...), a child query node is created, which serves as the topology context for the corresponding child elements, and so on.
Once the first phase is complete and all instantiators have submitted their orders, the data is fetched from the Unified Query Engine (UQE). The query node tree is translated into one or multiple (optimized) UQE queries (3), which are sent to the backend by the UQE Connector (4, 5). The received data is then converted from UQE's response format into a traversible tree structure of data nodes (6).
These data nodes are recursively passed down the instantiator hierarchy (7). Each instantiator can now create the UI elements described by its template (8). In contrast to conventional React programming, the React base components know nothing whatsoever about how their children are created. The instantiators create these elements recursively from the bottom up and each instantiator passes the created React components to its parent instantiator, which injects them as children into the React element it creates itself.
The practical implication of all this is that template elements do not need to know what particular data their nested child elements consume, and the child elements can be arbitrarily exchanged as long as they are compatible with the topology context of the parent. The parent element simply passes down the topology context and the child element specifies what data it needs. In cases where the child is meant to render a different topology context (such as when a template element binding to a set of services contains a child element to render the related service instances), the child element is wrapped into a building block that changes the topology context.