Skip to content

Commit

Permalink
Adjust READMEs
Browse files Browse the repository at this point in the history
  • Loading branch information
zrgt committed Nov 28, 2024
1 parent dbfe3c1 commit 4164ff1
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 859 deletions.
235 changes: 1 addition & 234 deletions schemas/json/README.md
Original file line number Diff line number Diff line change
@@ -1,236 +1,3 @@
# JSON

[JavaScript Object Notation (JSON)] is a popular serialization format. Beside XML and
RDF, it is an "official" serialization format for models of Asset Administration
Shells (AAS). Since JSON is a very versatile format, there are many ways how we could
map an AAS model to it. In this document, we explore our particular design of the
serialization schema based on [JSON schema 2019-09], and explain in detail the rules how
we mapped the [AAS meta-model] to it.

[JavaScript Object Notation (JSON)]: https://www.json.org

[JSON schema 2019-09]: https://json-schema.org/specification-links.html#2019-09-formerly-known-as-draft-8

[AAS meta-model]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf

## Top-Level Structure

The root of our serialization is a JSON object representing the instance
of [Environment]. This environment contains three aggregations, corresponding to
all [Identifiable] classes:

* [AssetAdministrationShell]'s,
* [Submodel]'s, and
* [ConceptDescription]'s.

[Environment]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=80

[Identifiable]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=52

[AssetAdministrationShell]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=58

[Submodel]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=62

[ConceptDescription]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=79

The JSON properties of the environment correspond to these three aggregations.

To simplify exploration of the JSON data, identifiable instances are only available at
the level of the environment, and nowhere else.

## Mapping Rules

### Classes to JSON definitions

For each class of the [AAS meta-model], we provide [a definition] in the JSON schema.
The instances of the classes, abstract and concrete alike, are modeled as [JSON objects]
.

[a definition]: https://json-schema.org/understanding-json-schema/structuring.html#defs

[JSON objects]: https://json-schema.org/understanding-json-schema/reference/object.html

### UML properties to JSON properties

The class properties of the meta-model (attributes and aggregations) correspond directly
to [JSON properties].

[JSON properties]: https://json-schema.org/understanding-json-schema/reference/object.html#properties

Optional attributes, *i.e.*, the attributes with the cardinality ``0..1``, are modeled
as [non-required properties].

[non-required properties]: https://json-schema.org/understanding-json-schema/reference/object.html#required-properties

Aggregations, *i.e.*, the properties with the cardinality ``0..*``, ``1..*`` *etc.*, are
modeled as [JSON arrays].

[JSON arrays]: https://json-schema.org/understanding-json-schema/reference/array.html

We explicitly forbid empty JSON arrays to avoid confusion about properties which have
cardinality ``0..*``. Namely, an empty array is semantically equal to an omitted
attribute (according to the meta-model). Thus, the JSON property representing an
aggregation attribute must be omitted if the aggregation is empty.

In UML, it is the convention to name associations and aggregations in singular form. The
cardinality is to be taken into account to decide on whether there are none, a single or
several elements in the corresponding association or aggregation. In JSON it is best
practice to use plural form for array in class properties. The singular name is used for
its descriminator (see section on decriminators). Typically the plural name is derived
by just adding an "s" to the name. For example, ``submodelElements`` instead
of ``submodelElement`` in case of [Submodel] class.

If plural form made no sense for a property, we kept it as-is (*e.g.*, `isCaseOf`). The
full list of exceptions is available [as code in aas-core-meta].

[as code in aas-core-meta]: https://github.com/aas-core-works/aas-core-meta/blob/02712deeff530a75fda99aee25961aa4ea38a420/tests/test_v3.py#L1069

### Primitive attribute values

The UML specification uses XSD types. For the [mapping of XSD to JSON types] please
refer to [Part 2 of the series of the Asset Adminsistration Shell].

There are the following exceptions:

[Property]/``value`` and [Range]/``min`` and [Range]/``max`` are mapped to a JSON
string. The type it needs to be converted to by the data consumer is declared
in [Property]/``valueType`` or [Range]/``valueType``, resp.

Primitive type [BlobType] (group of ``byte``s) is mapped to a JSON string with base64
encoding.

Note: in valueOnly Format of [Part 2 of the series of the Asset Adminsistration Shell]
value has the JSON type as declared in [Property]/``valueType`` taking
the [mapping of XSD to JSON types] into account.

[Part 2 of the series of the Asset Adminsistration Shell]: https://industrialdigitaltwin.org/en/wp-content/uploads/sites/2/2023/04/IDTA-01002-3-0_SpecificationAssetAdministrationShell_Part2_API.pdf

[mapping of XSD to JSON types]: https://industrialdigitaltwin.org/en/wp-content/uploads/sites/2/2023/04/IDTA-01002-3-0_SpecificationAssetAdministrationShell_Part2_API.pdf#page=96

[JSON strings]: https://json-schema.org/understanding-json-schema/reference/string.html

[Property]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=74

[Range]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=75

[BlobType]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=96

[JSON number]: https://www.rfc-editor.org/rfc/rfc4627#section-2.4

[JSON boolean]: https://json-schema.org/understanding-json-schema/reference/boolean.html

[XSD types]: https://www.w3.org/TR/xmlschema-2

[5.7.12 Primitive and Simple Data Types]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=96

#### Hint: Round-Trip Conversions

Round-trip conversions XML to JSON to XML or RDF to JSON to RDF may not result in the
original file.

The result of a model saved as XML is different to the model saved as JSON. For example,
if the user typed in `1` for a boolean UML attribute (e.g. for ``SubmodelElementList``
/``orderRelevant``)
in the editor, saved the model as JSON and opened it again, she would suddenly
see `true` instead of `1`
(since the JSON library would silently convert `1` to a [JSON boolean] `true`).

### Inheritance

The inheritance relationships between the classes are modeled using [allOf composition].
While JSON schema knows no inheritance, we enforce through ``allOf`` that all the
properties of the parent are defined in the descendants.

[allOf composition]: https://json-schema.org/understanding-json-schema/reference/combining.html#allof

### Discriminator

Many attributes in the meta-model refer to an abstract class. When we de-serialize such
attributes, we need to know the concrete class at runtime, since otherwise the
de-serialization algorithm would not know how to interpret the properties of the object.

For example, consider the attribute [Submodel] which contains instances
of [SubmodelElement]. When the de-serializer encounters the
property ``submodelElements`` as an array and starts de-serializing its items, how can
it know which constructor to call to parse the item? This necessary nugget of
information is commonly called "discriminator" (*e.g.*,
see [OpenAPI 3 specification on polymorphism]).

[SubmodelElement]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=63

[OpenAPI 3 specification on polymorphism]: https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/

We define the discriminator for our serialization as an additional property, `modelType`
, which do not correspond to any attribute in the meta-model. Every class which has one
or more descendants will have the discriminator `modelType` in its definition.

When a deserializer needs to de-serialize an instance of an abstract class, it can do so
by dispatching the de-serialization to the appropriate de-serialization method based
on `modelType`.

### Enumerations

The enumerations of the meta-model are directly mapped
to [enumerated values in JSON schema]. Each enumeration is defined separately, and we do
not in-line enumerations for readability.

[enumerated values in JSON schema]: https://json-schema.org/understanding-json-schema/reference/generic.html#enumerated-values

Enumerations which are not directly used in the schema are omitted. For example, subsets
of [KeyTypes] are omitted since only [KeyTypes] is used to define value of an attribute.

[KeyTypes]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=85

### Embedded Data Specifications

The meta-model defines data specifications in abstract (see
Section [6 Predefined Data Specification Templates]). However, the meta-model omits data
specifications in an [Environment], and data specifications are intentionally
non-identifiable.

[6 Predefined Data Specification Templates]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=106

For practical applications, we need to access them *somehow*. Therefore, the meta-model
mandates to embed them in serializations (see
Section [7.2.5 Embedded Data Specifications]).

[7.2.5 Embedded Data Specifications]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=114

We consequently embed the data specifications by adding `embeddedDataSpecifications`
property to the definition corresponding to [HasDataSpecification], and deliberately
omit the attribute [HasDataSpecification]/``dataSpecification`` in the schema.

[HasDataSpecification]: https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01001-3-0_SpecificationAssetAdministrationShell_Part1_Metamodel.pdf#page=48

## Examples

Examples of the JSON serializations can be found in [schemas/json/examples/](examples)
folder.

## Background

### From Manual Transcription ...

The serialization to and from JSON changed over the course of different versions of the
meta-model. Originally, the schema had been manually designed, where a group of authors
combed "the book" and manually transcribed it to JSON schema. This was obviously
error-prone as it often caused mismatches between other serializations (*e.g.*, XML and
RDF), contained inconsistencies *etc.*

### ... to Automatic Generation

We eventually moved over to generate the serialization schemas based on a
single-point-of-truth. The current source is [aas-core-meta], a domain-specific Python
representation of the meta-model. The schemas are generated using [aas-core-codegen], a
translating tool which transpiles aas-core-meta into different schemas and other targets
such as SDKs.

[aas-core-meta]: https://github.com/aas-core-works/aas-core-meta

[aas-core-codegen]: https://github.com/aas-core-works/aas-core-codegen

While this approach reduced the rate of errors significantly, it also imposed certain
limits on our schema design. For example, the classes and enumerations are now
programmatically mapped to JSON definitions, allowing for no exceptions. Where we could
in-line some of them for better readability, we are now forced to stick with the
programmatic definitions.
Refer to the [json.adoc](../documentation/IDTA-01001/modules/ROOT/pages/mappings/formats/json.adoc) for detailed information.
103 changes: 1 addition & 102 deletions schemas/rdf/README.md
Original file line number Diff line number Diff line change
@@ -1,104 +1,3 @@
# Resource Description Framework

The Resource Description Framework ([RDF](https://www.w3.org/TR/rdf11-primer/))
is recommended standard of the W3C to unambiguously model and present semantic data. RDF
documents are structured in the form of triples, consisting of subjects, relations and
objects. The resulting model is often interpreted as a graph, with the subject and
object elements as the nodes and the relations as the graph edges.

RDF is closely related to Web standards, illustrated by the fact that all elements are
encoded using (HTTP-)URIs. As a common practice, the provision of additional information
at the referenced location of an RDF entity directly allows the interlinking of entities
based on the Web. This process, the following of links in order to discover related
information, is called dereferencing a resource and is supported by any browser or web
client. As the AAS namespace (`https://admin-shell.io/aas/<version>/<revision>/`) is not
yet equipped with an hosting server, the dereferencing of the AAS entities is not
possible yet. Nevertheless, the current state already allows the connection of
distributed data sources through the Web, a mechanism known
as [Linked Data](https://www.w3.org/standards/semanticweb/data). Connecting the
capabilities of Linked Data with the expressiveness of the Asset Shell is one motivation
for the RDF serialization.

In addition, RDF is the basis of a wide range of logical inference and reasoning
techniques. Vocabularies like RDF Schema ([RDFS](https://www.w3.org/TR/rdf-schema/)) and
the Web Ontology Language ([OWL](https://www.w3.org/TR/owl2-overview/)) combine the
graph-based syntax of RDF with formal definitions and axioms. This allows automated
reasoners to understand the relation between entities to some extent and draw
conclusions.

Combining both worlds, the RDF mapping of the Asset Administration Shell can provide the
basis for complex queries and requests. SPARQL, the standard query language for the
Semantic Web, can combine reasoning features with the integration of external data
sources. In order to benefit of these abilities, the AAS requires a clear scheme of its
RDF representation. In the following, the necessary transformation rules are presented,
followed by an illustration of relevant parts of the scheme and an example. The
complete [data model](rdf-ontology.ttl) together with the [schema](shacl-schema.ttl) are
listed in this repository.

## RDF Mapping Rules

The concepts of the RDF and the derived RDF serialization of the AAS are explained by
the mapping rules. These rules are implemented by
the [generators](https://github.com/aas-core-works/aas-core-codegen) used to create the
ontology and shacl files based on the independent
project [aas-core-works](https://github.com/aas-core-works/). The main design rules the
following:

- The default serialization format is Turtle - also for the ontology and the shapes.
However, several equivalent serializations exist for RDF. Among them, the Turtle
syntax is regarded as the most appropriate compromise between readability and
tool-support. Other formats (RDF/XML, JSON-LD, N3, etc.) can be used without any loss
of information.
- [Shape Graphs](./shacl-schema.ttl) represent the validation schema. The data model
itself is an [RDF ontology](./rdf-ontology.ttl). As RDF itself is following the
open-world-assumption, [SHACL](https://www.w3.org/TR/shacl/) constraints are necessary
in order to enable schema validation. Similarly to XSD for XML, the SHACL format can
be used to describe constraints (called shapes) of RDF graphs.
- Every entity is encoded as either an IRI or a Literal. RDF uses IRIs for both entities
and relations. If no IRI is predefined, a globally unique IRI is generated. Primitive
values are encoded as Typed Literals.
- Entities are enhanced with well-known RDF attributes. Interoperability of concepts and
attributes is the main advantage of the RDF mapping. Therefore, applying common
attributes (`rdf:type` (similar to `modelType` discriminator in JSON), `rdfs:label`,
and `rdfs:comment`) enables the usage of standard tools and interfaces.
- Repeating elements are described once and then linked using their IRI identifier. If a
distinct element appears more than one time in the original model but in a different
context, for instance in more than one submodel, the RDF entity represents the
combination of all attributes.
- Multilanguage Strings are split into distinct language strings (`rdf:langString`).
Objects are expected to contain a singular information entity, and the currently
available tools would not recognize the AAS LangString pattern.
- Multiple object values are represented by repeating the property, one for each value
object.
- Abstract AAS classes are modeled in the ontology, nevertheless, using them leads to
validation errors in the shapes. RDF does not contain a concept for abstract classes,
therefore custom checks using SPARQL queries are supplied.

## Example Overview

RDF is often regarded as a graph model, as it provides the flexibility to interlink
entities at any stage. In the following,
the [complete example](./examples/Complete_Example.ttl) is originally provided in Turtle
but accompanied with visualizations of the represented graph (see Fig. 1): Attributes
referencing non-literal values are shown as directed links while Literal values are
drawn together with the corresponding entity itself. In order to increase readability,
the namespace declaring sections are omitted. The complete example with all namespaces
can be found in the [example folder](examples). One can see the additionally inserted
triples for `rdf:type`, `rdfs:label`, and `rdfs:comment` as determined by Rule 4. The
first attribute states the instance’ class. The second provides its commonly used name,
for instance based on the idShort attribute. `rdfs:comment` supplies a short description
about the regarded entity, based on the description value. The generally available
tools, for instance the open source tool [Protégé](https://protege.stanford.edu), render
these attributes and display the correct class hierarchy, render the elements with their
labels or supply short explanations based on the comments.

![Simplified graph of the core classes in the example](../rdf/media/aas-rdf-graph.png)

___Figure 1: Simplified graph of the core classes in the example___

A comprehensive set of generated examples is also provided in the
subfolder [examples/generated](./examples/generated), always containing a complete and a
minimal version of each class. The files have been created using
the [aas-core3.0-testgen](https://github.com/aas-core-works/aas-core3.0-testgen)
project to simplify the maintenance process and to stick directly to the efforts made
at [aas-core-meta](https://github.com/aas-core-works/aas-core-meta).
Refer to the [rdf.adoc](../documentation/IDTA-01001/modules/ROOT/pages/mappings/formats/rdf.adoc) for detailed information.
Loading

0 comments on commit 4164ff1

Please sign in to comment.