Skip to content

Add eventing with CloudEvents-based events, Event Interface, and Event profiles - #690

Open
aaronzi wants to merge 2 commits into
admin-shell-io:IDTA-01002-3-3_workingfrom
aaronzi:aaronzi/add-eventing-chapter
Open

aaronzi wants to merge 2 commits into
admin-shell-io:IDTA-01002-3-3_workingfrom
aaronzi:aaronzi/add-eventing-chapter

Conversation

@aaronzi

@aaronzi aaronzi commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Resolves #557. Related to #41, #297, and #600.

Rendered draft (PDF):
AAS-Part2-Eventing-Draft.pdf

Summary

This PR adds eventing to Part 2: services provide CloudEvents for every modification of their content, which clients retrieve with the new operation GetAllEvents (GET /events) or receive via message brokers. The design follows the existing structure and conventions of the specification: the chapter defines the semantics, while the operation, the payload classes, the profiles, and the OpenAPI documents are placed where all other operations and classes are defined.

Content of the chapter "Eventing"

  • Event: CloudEvents core context attributes only, no extension attributes; source is the base URL of the service, subject identifies the modified object independently of the API: the plain identifier for AAS, Submodel, and Concept Description events, the globalAssetId for asset events, and the text serialization of the ModelReference from Part 1 for SubmodelElement events (e.g. (Submodel)urn:example:sm:1, (SubmodelElementCollection)Measurements, (Property)temperature).
  • Event types: io.admin-shell.<object>.<modification>.v1 for aas, submodel, submodelelement, conceptdescription, and asset with created, updated, deleted.
  • Event data: composed of existing AAS representations and selected with the SerializationModifier Content (Normal, Value, Reference); dataschema identifies class and Content. Submodel and SubmodelElement events carry the globalAssetIds of the referencing AAS; references carry referredSemanticId.
  • Modifications and events: precise rules for when events result, including the derivation of SubmodelElement events by comparing states (no cascades to parents, list index rule, idShort changes) and asset events for changes of the set of linked AAS.
  • Event profiles: rules for domain-specific event types of Submodel templates (e.g. Product Change Notifications).
  • Retrieval of events: GetAllEvents with filters (type, aasIdentifier, submodelIdentifier, cdIdentifier, idShortPath, globalAssetId, semanticId, submodelSemanticId, since, lastEventId; parameters with several values are repeated), standard pagination from the oldest to the most recent event, and continuation with lastEventId; transmission via message brokers (MQTT, Kafka, AMQP) using the CloudEvents protocol bindings with identical events.
  • Relation to other concepts: recent changes, versions at a point in time, EventElement/EventPayload (not used).
  • Informative: a clearly marked proposal for filtering with the AAS Query Language, with FieldIdentifiers following the event structure ($event#type, $event#data.globalAssetIds[], …) and queries sent with QueryEvents (POST /query/events); it is not part of the specification.

Further changes

  • API Interfaces: new Event Interface with the operation GetAllEvents.
  • Data Types for Payload: Event, EventData, and the event data classes; interface short name EVENT; Event profile identifiers for the ServiceDescription.
  • Service Specifications and Profiles: Event profiles AssetAdministrationShellRepositoryServiceSpecification/SSP-007, SubmodelRepositoryServiceSpecification/SSP-008, ConceptDescriptionRepositoryServiceSpecification/SSP-004, DiscoveryServiceSpecification/SSP-003, and the Event API in the overview.
  • HTTP/REST API: mapping of GetAllEvents (/events, /events/$value, /events/$reference).
  • OpenAPI: the four profile documents (V3.3_SSP-*.yaml), schemas and query parameters in Part2-API-Schemas/openapi.yaml, and the operations in Entire-API-Collection/V3.2.yaml.
  • Annexes: Operation to RIGHT mapping for GetAllEvents, GetAllEvents-ValueOnly, GetAllEvents-Reference; new informative annex "Eventing Examples" with examples for all event types and Contents.
  • Operation naming grammar: model element name Event.
  • Applicability of SerializationModifiers, terms, bibliography (CloudEvents, JSON event format, protocol bindings, RFC 9562), navigation, and change notes.

Points for review

  • GetAllEvents-ValueOnly and GetAllEvents-Reference are mapped to the RIGHT READ, because the event data also contains globalAssetIds and asset links.
  • List query parameters use explode: true like the existing OpenAPI parameters; the Design Decisions text mentions comma-separated lists.
  • The new profile documents use the file prefix V3.3_ and profile identifiers …/3/3/…, while the combined OpenAPI document is still Entire-API-Collection/V3.2.yaml.
  • Not covered on purpose: acknowledgements of receipt, events for registries and SpecificAssetIds, and normative broker topic structures.

Validation

  • tools/validate_spec_artifacts.py, tools/validate_multipart_uploads.py, and the query unit tests pass.
  • All event examples validate against the new OpenAPI schemas, including the schema of the respective Content.

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QDJVMC found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@aaronzi
aaronzi force-pushed the aaronzi/add-eventing-chapter branch from 0c9c3c7 to e075cd4 Compare October 7, 2026 09:06
| GenerateSerializationByIds | GET | /serialization | READ | "/serialization"
| GetAllEvents | GET | /events | READ | "/events"
| GetAllEvents-ValueOnly | GET | /events/$value | READ | "/events/$value"
| GetAllEvents-Reference | GET | /events/$reference | READ | "/events/$reference"

@gataka gataka Oct 15, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why are this endpoints needed? There is no benefit to have only $reference structure in the events. If you need one you can design own types that represent them but generally you only want 1 event to store for one action. Not 3. If you have thousands of events, this is not acceptable and makes nothing better, than polling the REST resources directly. The only thing to manipulate the result is to have more or less details. of an event. but this can be solved by having different kinds of types and filtering by type.

@aaronzi aaronzi Oct 15, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is only one event. This is just the representation (same way as in the standard service endpoints). The benefit here is flexibility. The consumer can decide which representation is needed for the use case.

@tfunken tfunken Oct 16, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also have a problem with all this serialization formats. I understand the approach of keeping it consistent with the existing spec, but it’s already extremely time-consuming today for companies that don’t have an AAS server -but instead use AAS only as a facade layer - to maintain all those serialization formats. That’s why companies usually just don’t implement them and only offer the standard serialization. This makes it virtually impossible to have clear contracts between clients and servers regarding what can and cannot be delivered, and it greatly increases the complexity of the spec, which is already quite complex. That’s why nobody uses profiles either.

This is probably a fundamental debate: whether, in cases of doubt, decisions made in the past, which lead to major challenges during production implementation in the field, must absolutely be carried over to new features.

But from a productive solution perspective it would be a lot better to have defined payloads that solve actual use cases than having just a list of serilizations that you need to figure out by yourself not knowing the side effects (e.g. request with payload for very large submodels).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a fundamental debate, and I feel you on that point. But two points basically dictate that this is probably the only viable solution right now:

  1. We need different representations for the use cases we wrote down
  2. Introducing a new approach to achieve the same solution would make the problem even bigger

Maybe AAS v4.0 could resolve such problems. Additionally, I don't see any harm if companies decide not to implement all endpoints of a profile as long as there is a way to tell the client what is supported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, I don't see any harm if companies decide not to implement all endpoints of a profile as long as there is a way to tell the client what is supported.

And that is the point: there is no way. Which means everything is discussed between people instead of clear contracting between systems. And the more options you introduce, the more cases you have to deal with on client side. We (as a company) have a large network of partners with whom we want to exchange data and this is currently already becoming a nightmare to handle for the existing standard.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that but that can't be solved in the eventing feature alone. Adding deviations from the already existing approach here would just make it worse

@gataka gataka Oct 19, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it not an option, to skip the representation until someone really needs it? In the spec it also comes later and there is a way to skip it.

Events != Submodel and the events are not meta model based. So the representations won't work, because they are solving the complexity of the meta model (this is why everyone uses $value in demonstrators). It only works on the meta model endpoints. If you think further: if you have custom events, than the representation options based on meta model structures makes no sense any more.

There is no law that treat us to put bad concepts from the AAS spec to the eventing. So if someone outside of the "event"-Team wants to have this representations they are free to argument to add it. Currently it makes a good concept worse.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the motivation, since we offer this option for many other resources as well. The behavior, however, would be different. As I understand it, this would only affect the content of data in the CloudEvent payload, right? The other attributes of the payload would remain unchanged.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TF Meeting 2026/10/21

  • Preference to have $reference as mandatory for all servers
  • Other serialization formats should be defined $value, $normal but remain optional for a server to implement
  • Custom payload formats should be allowed
  • Some form of description/capabilities operation is needed for the client to discover what the server offers/supports

|GetAllEvents |GET |/events a|
path-suffix= $value/$reference or no suffix for normal

?type=, ?id=, ?idShortPath=, ?globalAssetId=, ?semanticId=, ?submodelSemanticId=, ?since=, ?lastEventId=

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you have Query parameters that are not in the response of the API? This breaks every API convention. There should only be query parameters of the headers of Cloud events. (Subject etc). What is "id"? No one will understand this. What if you want more than one type? Or more than one semanticId?

There was a reason to use a "SQL"-Like Query-Language that gives all this capabilities.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Why you have Query parameters that are not in the response of the API? This breaks every API convention.

Not uncommon and already exists in multiple places here in the API spec (e.g. in getAllSubmodels)

Also mostly incorrect anyway:

  • type and since filter directly on the CloudEvent attributes type and time.
  • lastEventId works like cursor: it’s a position, not a filter, and refers to id.
  • globalAssetId and submodelSemanticId filter on fields that are in the data (globalAssetIds, submodel.referredSemanticId).
  1. Only filter on CloudEvents attributes

This contradicts our requirements and use cases that we discussed during the workshop and agreed on. Filtering by semanticId and asset was an explicit requirement, including in the EPLAN use cases.

  1. What is "id"? No one will understand this.

id and idShortPath follow the way objects are addressed everywhere else in the API ({aasIdentifier}, {submodelIdentifier}, {idShortPath}) and the existing convention to filter on model attributes (?semanticId=, ?idShort=, ?assetIds=). A client that wants to observe a Submodel or SubmodelElement already has its identifier and idShortPath, so it does not need to construct encoded paths for filtering.

Fair point regarding the name, though: in a CloudEvent, id is the event id. I will rename it to aasIdentifier, submodelIdentifier, and cdIdentifier, so that submodelIdentifier together with idShortPath reads exactly like /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}.

  1. What if you want more than one type? Or more than one semanticId?

Already supported: these parameters have the cardinality 0..* and are repeatable in the OpenAPI (?type=a&type=b). I will make this more explicit in the HTTP mapping.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I miss some parameters based on our discussion in the workshop, namely dataSchema, limit, and cursor.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TF Meeting 2026/10/21

  • Options

    • Option 1
      • Only GET with complex parameters base64Url-encoded in query string
      • Not a good idea because we already deprecated similar calls in the past, e.g., GET /lookup/shells
    • Option 2
      • Only POST
    • Option 3
      • GET with only primitive parameters + POST with all parameters
    • Note: Additional query can be implemented to offer more complex filter functionality
  • Things to consider

    • need to define semantics regarding AND / OR across different parameters (probably AND) and across multiple appearances of the same parameter (probably OR, may be parameter-specific)

I miss some parameters based on our discussion in the workshop, namely dataSchema, limit, and cursor.

dataSchema is addressed via other parameters, e.g., idShortPath. limit and cursor are define but in different file (using something similar to inheritance).

e|specversion a|CloudEvents version; value `1.0` |string |1
e|id a|Identifier of the event, unique within the scope of `source`, e.g. a UUID xref:bibliography.adoc#bib19[[19\]] |string |1
e|source a|Base URL of the service, see xref:eventing.adoc#eventing-source-subject[Source and Subject] |string (URI-reference) |1
e|subject a|Path of the modified object relative to `source`, see xref:eventing.adoc#eventing-source-subject[Source and Subject] |string |1

@gataka gataka Oct 15, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the examples: it is not useful to add here the path of the API with an base64-encoded ID. So no one will be able to route the event to the correct place, that is interested to update of some assets, AAS or submodels. You mixing here constraints that comes from the REST-API design and constraints that some has, who want to have events. I would agree if you put this path to the source field.

The subject needs to have only the ID of the resource that has changed. AASId, AssetId and SubmodelId (also for submodel elements event or define a pattern like "submodelid#path-to-element" ),. All systems before and after the AAS world has only the ID in clear not the base64-encoding. And what when the encoding changes? Then every event is broken. The same when the API has changed. Best example: the lookup endpoint changed in the last months. This is the reason why there are noch API specification details in source and subject. And you do not need it, because the AAS API itself tells the client if you have an submodel Id you have to follow the patterns of the Submodel-Repository-API to get the resources. There is no need to repeat the API again. also the prefix for submode/shells etc. is not needed, because the event-type tells the consumer which part of the API to use.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Coupling the subject to the REST API layout and especially its encoding contradicts the goal that events are independent of the protocol, and the event type already tells the consumer which kind of resource is affected. I will change the subject to the plain identifier: the AAS id, Submodel id, Concept Description id, or globalAssetId.

Two remarks:

  • Moving the path to source would only move the same coupling there and would create a separate source per Submodel. source should stay the base URL of the service.
  • A pattern like submodelId#path does not work, because AAS identifiers may contain # (e.g. IRDIs like 0173-1#01-AHE582#003). For SubmodelElement events, I suggest using the text serialization of the ModelReference as defined in Part 1, e.g. (Submodel)urn:example:sm:1, (SubmodelElementCollection)Measurements, (Property)temperature. It contains the plain identifier, is defined by the metamodel instead of the API, and still allows selecting all events of a Submodel by prefix.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding source being the URL of the service I want to add that a server is not required to have an HTTP/REST endpoint but could also just have an OPC UA endpoint. Therefore, it would be best to use the Endpoint class instead. However, I assume that would conflict with the CloudEvent spec, wouldn't it?

This would allow filters that the input parameters cannot express, e.g. a negation:

[source,json]
----

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How should this be passed to a query parameter in a URL?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not meant to be passed as a query parameter. Like the existing query operations (e.g. QuerySubmodels with POST /query/submodels), the query would be sent as JSON in the request body of a dedicated operation, e.g. QueryEvents with POST /query/events. The sentence describing this got lost in a revision of the chapter; I will add it again.

@gataka gataka Oct 19, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use POST /query/events, then this endpoint has also to fulfil the since, lastEvent and pagination capabilities as the normal /event endpoint do. You cannot tell someone to use GET /events for events without Query-Requirements and POST /query/events when you have complex query requirements. That will not work. Sorry but RSQL fits better. Is it not better to create a query-parameter-scoped version of that query language, that is similar to RSQL to support complex query parameter queries? This will help in multiple places. (e.g. GetAllShells). It is not so hard. We can use the same field-specification and apply just new operators for query-parameter-usage.

Again: There is no law that treat us to put bad concepts from the AAS spec to the eventing.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wouldn't having both GET and POST not work? We have this approach in multiple places in the API already and it works fine.

In totally understand your reasoning for a purely URL-based query language. While design of the AAS query language we also discussed this option but it has been rejected by the majority. We now have the following options

  1. Create a new URL-based query language just for eventing
  2. Define a URL-based query language that is consistent across all API parts
  3. Use the approach/style of the current API also for eventing (as suggested by Aaron)

Option 1 is not viable in my opinion because it not only introduces a second, completely different query language which further complicates the API but also it is unclear whether this will get replaced in v4.0 when trying to unify query languages again.

Option 2 would address this problem by making sure we introduce something that can be used throughout the whole API in an upcoming v4.0 but has the downside that we would need quite some time to properly design this which would delay the introduction of events.

Therefore, Option 3 seems the most sensible solution to me to both get eventing published in a timely manner and not introduce additional complexity by adding a new query language. When working an v4.0 we can then talk about updating/changing the query language to be URL-based across all aspects of the API.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation, @mjacoby. That was exactly the thought process I had when writing my proposal. I never claimed that the specification I proposed would be the best approach if starting from scratch. In fact, I would probably have done many things differently. However, the proposal I made involves the least friction and can be implemented and specified in a timely manner.

We can't forget that some have already implemented things like the query language because that's what was agreed upon. For those companies, introducing alternatives that conflict with the agreed specifications could be very costly. If I understand correctly, this even involves your use case's implementation partners, @gataka.

The normative filters are the input parameters of xref:specification/interfaces.adoc#GetAllEvents[GetAllEvents].
====

The xref:query-language.adoc[AAS Query Language] could be extended by a root element `$event` for FieldIdentifiers, e.g. `$event#type`, `$event#subject`, `$event#time`, `$event#globalAssetIds[]`, `$event#semanticId`, and `$event#submodelSemanticId`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be necessary to filter based on data fields related to event types. like event#globalAssetId (not in ever event type) or the submodelSemanticId are type specific filters. So if you combine them with the wrong event-type you would never get an answer. So if the field is part of the data it should be marked as it like $event#data.globalAssetIds or $event#data.semanticId. A the filter fields should match 1:1 to the fields in the event and data object. Otherwise the complete filter is useless.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed for the Query Language proposal. This is also how FieldIdentifiers work for the other root elements, e.g. $aas#assetInformation.globalAssetId. I will change the proposal to $event#<attribute> for the CloudEvents attributes ($event#type, $event#subject, $event#time) and $event#data.<path> for the event data (e.g. $event#data.globalAssetIds[], $event#data.submodel.semanticId), referring to the event data with Content Normal.

Combining a data field with a different event type is not an issue: according to the evaluation semantics of the Query Language, a FieldIdentifier that does not exist for a candidate excludes it without an error, so such filters are typically combined with $event#type.

For the query parameters of GetAllEvents, I would keep the current approach, which follows the existing GetAll… operations (e.g. ?semanticId= in GetAllSubmodels, which also covers supplementalSemanticId).

…t profiles

Add the chapter "Eventing" defining CloudEvents-based events for
modifications of Asset Administration Shells, Submodels, SubmodelElements,
Concept Descriptions, and asset links: event structure, source and subject,
event types, event data with the Contents Normal, Value, and Reference,
data schemas, the modifications that result in events including the
derivation of SubmodelElement and asset events, event profiles, retrieval
with GetAllEvents and transmission via message brokers, the relation to
other concepts, and an informative proposal for filtering with the AAS
Query Language.

Add the Event Interface with the operation GetAllEvents, the Event and
event data classes, the interface short name EVENT, the Event profiles
AssetAdministrationShellRepositoryServiceSpecification/SSP-007,
SubmodelRepositoryServiceSpecification/SSP-008,
ConceptDescriptionRepositoryServiceSpecification/SSP-004, and
DiscoveryServiceSpecification/SSP-003 with their OpenAPI documents, the
schemas and query parameters in the Part 2 schemas, the operations in the
combined OpenAPI document and the Operation to RIGHT mapping, the HTTP/REST
mapping, the applicability of SerializationModifiers, the annex "Eventing
Examples", terms, bibliography, navigation, and change notes.
@aaronzi
aaronzi force-pushed the aaronzi/add-eventing-chapter branch from e075cd4 to bb2cdf8 Compare October 15, 2026 10:08
Use the plain identifier as subject of AAS, Submodel, Concept Description,
and asset events and the text serialization of the ModelReference for
SubmodelElement events, so that the subject no longer depends on the
paths and encoding of the HTTP/REST API.

Replace the input parameter id of GetAllEvents with aasIdentifier,
submodelIdentifier, and cdIdentifier, and state explicitly that
parameters with several values are repeated.

Let the FieldIdentifiers of the Query Language proposal follow the event
structure ($event#<attribute> and $event#data.<path>) and describe the
transmission of queries with QueryEvents (POST /query/events).

Add Event to the model element names of the operation naming grammar and
remove the no longer referenced RFC 8785.
hide methods
left to right direction

class Event {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to use camel case for property names as in the rest of the specification, i.e.,

  • specversion --> specVersion
  • datacontenttype -> DataContentType
  • dataschema --> dataSchema

activate Client
Client -> EventService : GetAllEvents(submodelSemanticId, lastEventId)
activate EventService
Client <-- EventService : submodelelement.updated ("Measurements.temperature"),\nsubmodel.updated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand the diagram correctly that you expect to trigger both a SubmodelElement updated and Submodel updated event? If yes, I think this contradicts what we discussed at the workshop that only a single event should be triggered by one action.

alt dataschema with Content Normal
Client -> Client : use SubmodelElement from event data
else dataschema with Content Reference
Client -> SMService : GetSubmodelVersionByIdAndDate(submodelId, time)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to allow the client to request just this exact event with normal/valueOnly serialization (e.g. by eventId) as an alterntive?

[#eventing-general]
== General

Eventing enables clients to react to modifications of Asset Administration Shells, Submodels, SubmodelElements, Concept Descriptions, and asset links.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about descriptors?

* *Synchronization:* systems such as engineering tools, product configurators, PLM, and ERP systems, as well as replicas, caches, and search indexes, keep their data consistent with a service.
* *Asset links:* a client detects that an Asset Administration Shell for an asset has become available or has been replaced.

In these use cases, one provider informs one or many receivers, within seconds or within the interval in which receivers retrieve events.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are talking about both pub/sub and pull-based "distribution" of events, I would rephrase this in passive voice, e.g., "the provider offers ways to receive events..." because in the HTTP case, the provider does not actively inform anyone but just provides the data for the client/consumer to fetch.


In these use cases, one provider informs one or many receivers, within seconds or within the interval in which receivers retrieve events.

Events are represented according to CloudEvents xref:bibliography.adoc#bib16[[16\]] in the JSON event format xref:bibliography.adoc#bib17[[17\]].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if using CloudEvents should be made on technology-agnostic level as some technologies could in the future could not be compatible with CloudEvents. Maybe change this to something along the lines of "CloudEvents should be used for any supported protocols".


The following rules apply:

. All events resulting from the same modification shall have the same `time`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly should this time represent? I think we agreed on something like "time the changes have been presisted/stored"

The following rules apply:

. All events resulting from the same modification shall have the same `time`.
. An event with a given `source` and `id` shall always have the same context attributes, except `dataschema`, and the same data for the same Content.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are "context attributes"?

[#eventing-source-subject]
=== Source and Subject

The `source` of an event is the base URL of the HTTP/REST API of the service.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not every AAS server implementation is required to have a REST API

|Events of |subject
e|AssetAdministrationShell |Identifier of the Asset Administration Shell
e|Submodel |Identifier of the Submodel
e|SubmodelElement |ModelReference to the SubmodelElement in the link:https://industrialdigitaltwin.io/aas-specifications/IDTA-01001/v3.2/mappings/mappings.html#reference-serialization[text serialization of References] without _ReferenceType_ and _referredSemanticId_

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReferenceType is mandatory according to metamodel, so I would rather enforce it to be ModelReference and enfore referredSemanticId to be empty via constraint

== Event

[#eventing-event-structure]
=== Event Structure

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to CloudEvents spec, the subject attribute is an optional attribute. Just trying to understand, are we deviating because AAS Events requires this as a mandatory attribute?

. Every modification shall result in the events defined in this clause, regardless of whether it is caused by an API operation, an import of an AASX package or environment, or the service itself.
Unsuccessful operations and operations without any change of the content result in no events.
. A modification of an Asset Administration Shell, Submodel, or Concept Description results in exactly one event for this Identifiable, of type `created`, `updated`, or `deleted`.
. A modification of SubmodelElements additionally results in SubmodelElement events according to <<eventing-sme-events>>.

@mdanish98 mdanish98 Oct 22, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additionally here means that if any modification is done to SME, then an SME event + a Submodel event will be triggered, correct?

For example:
When SME is removed:

submodelelement.deleted + submodel.updated

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants