Repository navigation
server: Discovery PostAllAssetLinksById does not replace links #669
Description
PostAllAssetLinksById is specified as "Creates or replaces all
asset links associated to the Asset Administration Shell":
The server merges the posted links into the existing ones instead:
basyx-python-sdk/server/app/interfaces/discovery.py
Lines 222 to 231 in 2773ac0
| def post_all_asset_links_by_id( | |
| self, request: Request, url_args: dict, response_t: Type[APIResponse], **_kwargs | |
| ) -> Response: | |
| aas_identifier = str(url_args["aas_id"]) | |
| specific_asset_ids = HTTPApiDecoder.request_body_list(request, model.SpecificAssetId, False) | |
| self.persistent_store.add_specific_asset_ids_to_aas(aas_identifier, specific_asset_ids) | |
| for asset_id in specific_asset_ids: | |
| self.persistent_store._add_aas_id_to_specific_asset_id(asset_id, aas_identifier) | |
| updated = {aas_identifier: self.persistent_store.get_all_specific_asset_ids_by_aas_id(aas_identifier)} | |
| return response_t(updated) |
Steps to reproduce:
POST /lookup/shells/{aasId}with[{"name": "serial", "value": "123"}]POST /lookup/shells/{aasId}with[{"name": "batch", "value": "xyz"}]GET /lookup/shells/{aasId}
Expected behavior: Only batch=xyz is linked to the AAS.
Actual behavior: Both links are returned, and a lookup by
serial=123 still finds the AAS. The test test_post_is_additive
asserts this behavior:
basyx-python-sdk/server/test/interfaces/test_discovery.py
Lines 258 to 267 in 2773ac0
| def test_post_is_additive(self) -> None: | |
| self.register(self.AAS_ID, [("serial", "123")]) | |
| response = self.format_client.post( | |
| f"/lookup/shells/{base64url_encode(self.AAS_ID)}", obj=[{"name": "batch", "value": "xyz"}] | |
| ) | |
| self.assert_ok(response) | |
| stored = {(a["name"], a["value"]) for a in self.format_client.parse_object(response)[self.AAS_ID]} | |
| self.assertEqual({("serial", "123"), ("batch", "xyz")}, stored) |
Environment: develop @ 2773ac0.
Possible fix: In post_all_asset_links_by_id, drop the AAS from
the reverse index for its old links, then store the new ones. Adapt
test_post_is_additive. #625 / #641 fix the status codes of the same
endpoint, but not this.
Activity
zrgt commentedon Oct 22, 2026
While fixing this: the reverse index (
asset_id_to_aas_ids) ismaintained in the handlers, not in
DiscoveryStore.post_all_asset_links_by_idcalls the private_add_aas_id_to_specific_asset_id(), anddelete_all_asset_links_by_idloops over the store's dict andleaves empty sets behind:
basyx-python-sdk/server/app/interfaces/discovery.py
Lines 222 to 240 in 2773ac0
Moving both updates into
add_specific_asset_ids_to_aas()anddelete_specific_asset_ids_by_aas_id()keeps the two maps in sync inone place, which is also where #663 would persist the store.
zrgt commentedon Oct 22, 2026
Small addition:
search_aas_ids_by_asset_link()scans the wholereverse index on every lookup, because it is keyed by
SpecificAssetId(which also comparesexternalSubjectIdandsemantic ids) while a lookup only has
nameandvalue:basyx-python-sdk/server/app/interfaces/discovery.py
Lines 59 to 64 in 2773ac0
If the index moves into
DiscoveryStoreanyway, keying it by(name, value)makes the lookup a dict access.