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
cursorinstead of an offset, once a client starts its walk with an emptycursor=. Settingcursor_pagination.mode, advertised ascursorPagination, andcursor_pagination.fresh_requestsfor whether a fresh request pages by offset (default) or bycursor. It is the only extension that is on by default. - Target languages in
qfilters LanguageProperties by full language tags and ranges, such asq=marque[en-GB]=="Vauxhall Viva". Settingq_target_languages.mode, andq_target_languages.levelforlanguage-tags(default) orlanguage-ranges, advertised aslanguageTagsandlanguageRangeFiltering. - Near distance band adds
minDistanceandmaxDistancetogether in onenearquery, so you can find entities between two distances. Settingnear_distance_band.mode, advertised asnearDistanceBand. - Accept-Language picks the language of LanguageProperties with the HTTP
Accept-Languageheader instead of thelangparameter. Settingaccept_language.mode, advertised asacceptLanguage.
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 astemporalAggregationGrouping. - Temporal linked retrieval accepts
joinon temporal queries to bring back the history of linked entities over the same time window. Settingtemporal_linked_retrieval.mode, advertised astemporalLinkedRetrieval. - 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 astemporalDeleteByQuery.
Data and tenants
- Purge dataset scope purges single
datasetIdinstances of an attribute across many entities, instead of the whole attribute. Settingpurge_dataset_scope.mode, advertised aspurgeDatasetScope. - Tenant management lists tenants, shows one, and takes one out of service and back again over the API. Setting
tenant_management.mode, advertised astenantManagement.
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.