Skip to main content

From source to response

This page follows one value, the status of the device fw-01, from NetBox to an API response.

1. Fetch​

The refresh loop of the contribution calls the connector's fetch_all for each object type. The NetBox connector pages through GET /api/dcim/devices/ 100 objects at a time; the Infrahub connector sends a GraphQL query whose selection is built from the contribution's paths. Each object comes back as a SourceObject: its native id, its source reference (the NetBox URL or the Infrahub node id), its object type and its JSON body. The connector applies no mapping, so one connection serves every contribution that uses it.

The objects are held in memory until every page has been fetched. An error on any page ends the refresh with nothing written.

2. Build a record​

For each object, fic-core builds a record for the contribution (crates/core/src/observation.rs):

  • The HFID: the value at the hfid path, cleaned (crates/core/src/hfid.rs).
  • One observation per mapped field: the value at the field's path, normalized and type checked (crates/core/src/normalize.rs). A missing path or null gives no observation. Otherwise the observation keeps the normalized value, the outcome, the original value, the path and the time.
  • One location observation: the names at each mapped level, translated and matched against the hierarchy (crates/core/src/location.rs).

3. Publish​

The inventory's writer takes its lock and compares the refresh with the stored records of the contribution (crates/sync/src/writer.rs). It keeps webhook observations newer than the refresh, removes records the refresh no longer contains, recomputes which records are excluded for a missing or duplicate HFID, and lists every HFID whose records changed. For each of those HFIDs it loads the eligible records of every contribution and resolves the entity (crates/core/src/resolve.rs). Records, entities and the contribution's state go to Memgraph in one transaction.

The write path describes publication and webhooks in detail.

4. Resolve​

Resolution walks each field's priority list and takes the first contribution whose observation is a value or an unknown; it skips contributions with no observation. The entity stores each resolved value as its own property, f_status = "active", next to the full resolution as JSON. The location is resolved the same way, then refined by a lower-priority location that lies strictly below it.

5. Query​

The API parses the query string against the inventory's definition (crates/server/src/api/query.rs), then asks the store for entities. The Memgraph backend filters, sorts and counts on the f_<field> and loc_<level> properties, so a filter applies to the value the response shows (crates/stores/memgraph/src/query.rs).

6. Respond​

The API adds what depends on the time of the request or on other contributions:

  • Completeness, from the contributions' states and the count of excluded records.
  • Contribution health, from the contributions' states.
  • Freshness of each entity, from the confirmation time of each resolved value and the inventory's budgets.
  • With detail=full, the records of each entity, read by HFID.

A query reads only the cache. The one exception is the first query of a branch view, which fetches the branch from the sources before it answers (Branch views).