Skip to main content

Extensions

Andromeda has a few capabilities NGSI-LD v1.9.1 doesn't define. Each one is an extension. You switch it on in the [extensions] section of the configuration, and all of them except cursor pagination are off by default. With an extension off, Andromeda answers exactly like a conformant broker that never had it.

Turning one on​

Every extension has a mode setting under its own table. Set it to "enabled" to switch it on.

[extensions.accept_language]
mode = "enabled"

Every setting also works as an environment variable, named ANDROMEDA__EXTENSIONS__ followed by the setting name in upper case, with a double underscore for the dot, such as ANDROMEDA__EXTENSIONS__ACCEPT_LANGUAGE__MODE=enabled.

All extensions are in the same binary. Configuration chooses which are on, and no special build is needed. Andromeda advertises the enabled ones. GET /ngsi-ld/v1/info/sourceIdentity lists their tokens under contextSourceExtras.extensions and leaves the key out when none is on. Anything you set in [federation.identity.extras] stays next to it.

Querying and paging​

  • Cursor pagination pages collections with an opaque cursor instead of an offset, once a client starts its walk with an empty cursor=. Setting cursor_pagination.mode, advertised as cursorPagination, and cursor_pagination.fresh_requests for whether a fresh request pages by offset (default) or by cursor. It is the only extension that is on by default.
  • Target languages in q filters LanguageProperties by full language tags and ranges, such as q=marque[en-GB]=="Vauxhall Viva". Setting q_target_languages.mode, and q_target_languages.level for language-tags (default) or language-ranges, advertised as languageTags and languageRangeFiltering.
  • Near distance band adds minDistance and maxDistance together in one near query, so you can find entities between two distances. Setting near_distance_band.mode, advertised as nearDistanceBand.
  • Accept-Language picks the language of LanguageProperties with the HTTP Accept-Language header instead of the lang parameter. Setting accept_language.mode, advertised as acceptLanguage.

Temporal​

  • Temporal aggregation grouping groups a temporal aggregation by calendar month, hour of the day, unit, or the value another attribute had at the time. Setting temporal_aggregation_grouping.mode, advertised as temporalAggregationGrouping.
  • Temporal linked retrieval accepts join on temporal queries to bring back the history of linked entities over the same time window. Setting temporal_linked_retrieval.mode, advertised as temporalLinkedRetrieval.
  • Temporal delete-by-query deletes a slice of temporal history across many entities in one request, picked by query, attributes and time window. Setting temporal_delete_by_query.mode, advertised as temporalDeleteByQuery.

Data and tenants​

  • Purge dataset scope purges single datasetId instances of an attribute across many entities, instead of the whole attribute. Setting purge_dataset_scope.mode, advertised as purgeDatasetScope.
  • Tenant management lists tenants, shows one, and takes one out of service and back again over the API. Setting tenant_management.mode, advertised as tenantManagement.

Each extension page starts with the same "At a glance" list, giving the setting, the environment variable, the advertised token, what happens with context sources, and what you get with the extension off.

How extensions behave​

Nothing changes unless you ask for it. An extension adds a parameter, a header reading, an operation or a wider range of values, and a client has to use it on purpose. A request that doesn't use it is answered as the specification defines.

Off means gone. With an extension off, its parameters are refused like any parameter the specification doesn't define, and its routes don't exist, so a method it would add answers 405 and a path it would add answers 404. Nothing is advertised, so a conformant client sees a conformant broker.

Context sources need care. Most extensions are applied by Andromeda after it merges the answers and are never forwarded, or are forwarded only to sources that advertise the same extension. A few are forwarded regardless. Each page says which.

Two exceptions​

Cursor pagination is on by default. Opaque page pointers are something the specification allows outright, so serving them is still conformant. A request still pages by offset until it sends an empty cursor=, so a client that never asks for a cursor gets the offset paging the specification defines. It is an extension only because the cursor parameter is Andromeda's own name, which you may want to turn off.

q_target_languages at language-ranges changes a filter the specification already defines. Its language-tags level only accepts target languages the grammar would refuse. Its language-ranges level also changes what an existing q selects, since [en] then matches en-GB too. It is negotiated with every context source a query reaches. Its page has the details. If an extension changes the answer to a request the specification already defines, or what something you stored means, its page says so near the top, before you turn it on.

Conformance mode​

extensions.mode = "conformance" turns every extension off, whatever the individual settings say, and logs a warning for each one it overrode. That includes cursor pagination, so collections are then paged by offset only and a cursor gets 400 InvalidRequest. Use it to run the ETSI conformance suite against the same binary you deploy.

If ETSI standardises something similar​

ETSI may later standardise functionality that covers what an extension does, quite possibly in a different shape. Andromeda keeps its extensions out of the ETSI vocabulary so the two can't be confused. Their tokens live under the plain extensions key of contextSourceExtras, never under ngsi-ld:. When that happens, this is the policy.

  • Andromeda adds the standard behaviour in a minor release, and the extension keeps working beside it, unchanged. Nobody has to migrate on the day the standard appears.
  • Whether both can be on at once depends on whether they conflict. If they don't, they run together. If they do, the extension's page says which one wins when both are on, and with the extension off you always get the standard behaviour.
  • If the standard covers only part of what the extension does, and the two fit together, the extension stays and its page says what remains beyond the standard. If the standard covers all of it, the extension is deprecated. If the standard differs too much from the extension's design to build on, the extension is deprecated in its current form, and a new extension may replace it. The new one completes the standard in the way most compatible with it, and keeps a different token so the two can't be mistaken for each other.
  • A deprecation is announced in the changelog and on the extension's page, with the standard way to do the same thing, and the broker logs a loud warning at startup while a deprecated extension is on. The extension keeps working for at least one more release after the announcement.
  • Removal happens only in a major release, because it changes behaviour, and the changelog says so. The advertised token is removed with the extension, and is never reused for something else.