diff --git a/Part2-API-Schemas/openapi.yaml b/Part2-API-Schemas/openapi.yaml index 927c7472..8c6a3c4c 100644 --- a/Part2-API-Schemas/openapi.yaml +++ b/Part2-API-Schemas/openapi.yaml @@ -709,10 +709,14 @@ components: type: string pattern: "^-?(([1-9][0-9][0-9][0-9]+)|(0[0-9][0-9][0-9]))-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))T(((([01][0-9])|(2[0-3])):[0-5][0-9]:([0-5][0-9])(\\.[0-9]+)?)|24:00:00(\\.0+)?)(Z|\\+00:00|-00:00)$" type: object - modelStringPattern: + FieldIdentifier: type: string pattern: >- - ^(?:\$aas#(?:idShort|id|assetInformation\.assetKind|assetInformation\.assetType|assetInformation\.globalAssetId|assetInformation\.specificAssetIds\[[0-9]*\]\.(?:name|value|externalSubjectId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?)|submodels\[[0-9]*\]\.(?:type|keys\[[0-9]*\]\.(?:type|value)))|\$sm#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id)|\$sme(?:\.[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9_](?:\[[0-9]*\])*(?:\.[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9_](?:\[[0-9]*\])*)*)?#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|value|valueType|language)|\$cd#(?:idShort|id)|\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\[[0-9]*\]\.(?:name|value|externalSubjectId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?)|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)|submodelDescriptors\[[0-9]*\]\.(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)))|\$smdesc#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)))$ + ^(?:\$aas#(?:idShort|id|assetInformation\.assetKind|assetInformation\.assetType|assetInformation\.globalAssetId|assetInformation\.specificAssetIds\[[0-9]*\]\.(?:name|value|externalSubjectId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?)|submodels\[[0-9]*\]\.(?:type|keys\[[0-9]*\]\.(?:type|value)))|\$sm#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id)|\$sme(?:\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\[[0-9]*\])*(?:\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\[[0-9]*\])*)*)?#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|value|valueType|language)|\$cd#(?:idShort|id)|\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\[[0-9]*\]\.(?:name|value|externalSubjectId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?)|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)|submodelDescriptors\[[0-9]*\]\.(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)))|\$smdesc#(?:semanticId(?:\.(?:type|keys\[[0-9]*\]\.(?:type|value)))?|idShort|id|endpoints\[[0-9]*\]\.(?:interface|protocolinformation\.href)))$ + FragmentFieldIdentifier: + type: string + pattern: >- + ^(?:\$aas#(?:idShort|assetInformation\.assetType|assetInformation\.globalAssetId|assetInformation\.specificAssetIds\[[0-9]*\](?:\.externalSubjectId(?:\.keys\[[0-9]*\])?)?|submodels\[[0-9]*\](?:\.keys\[[0-9]*\])?)|\$sm#(?:semanticId(?:\.keys\[[0-9]*\])?|idShort|id)|\$sme(?:\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\[[0-9]*\])*(?:\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\[[0-9]*\])*)*)?(?:#(?:semanticId(?:\.keys\[[0-9]*\])?|idShort|value|valueType|language))?|\$cd#idShort|\$aasdesc#(?:idShort|description|displayName|extension|administration|assetKind|assetType|globalAssetId|specificAssetIds\[[0-9]*\](?:\.externalSubjectId(?:\.keys\[[0-9]*\])?)?|endpoints\[[0-9]*\]|submodelDescriptors\[[0-9]*\](?:\.(?:semanticId(?:\.keys\[[0-9]*\])?|idShort|endpoints\[[0-9]*\]))?)|\$smdesc#(?:semanticId(?:\.keys\[[0-9]*\])?|idShort|endpoints\[[0-9]*\]))$ MultiLanguagePropertyMetadata: allOf: - $ref: "#/components/schemas/SubmodelElementAttributes" @@ -876,7 +880,22 @@ components: pattern: ^id$ $condition: $ref: '#/components/schemas/logicalExpression' + $filters: + type: array + items: + $ref: '#/components/schemas/QueryFilter' + required: + - $condition + additionalProperties: false + QueryFilter: + type: object + properties: + $fragment: + $ref: '#/components/schemas/FragmentFieldIdentifier' + $condition: + $ref: '#/components/schemas/logicalExpression' required: + - $fragment - $condition additionalProperties: false QueryResultAssetAdministrationShell: @@ -1149,7 +1168,7 @@ components: type: object properties: $field: - $ref: '#/components/schemas/modelStringPattern' + $ref: '#/components/schemas/FieldIdentifier' $strVal: $ref: '#/components/schemas/standardString' $strCast: @@ -1292,7 +1311,7 @@ components: type: object properties: $field: - $ref: '#/components/schemas/modelStringPattern' + $ref: '#/components/schemas/FieldIdentifier' $strVal: $ref: '#/components/schemas/standardString' $numVal: diff --git a/documentation/IDTA-01002-3/modules/ROOT/images/plantuml/query-language-overview.puml b/documentation/IDTA-01002-3/modules/ROOT/images/plantuml/query-language-overview.puml index 7980a755..ce8118ba 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/images/plantuml/query-language-overview.puml +++ b/documentation/IDTA-01002-3/modules/ROOT/images/plantuml/query-language-overview.puml @@ -86,7 +86,7 @@ enum SelectField { } enum FieldIdentifier { - $strModel + $field } enum Value { diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc b/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc index d1cb9e1c..1b5b672c 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc @@ -19,6 +19,7 @@ Major Changes: * Added a new profile for the AAS Repository Service Specification, the "Identifiable Profile", which only includes operations that require an identifier as input parameter. (https://github.com/admin-shell-io/aas-specs-api/issues/496[#496]) * New API operations and profiles for signing, including Asset Administration Shell Repository Service Specification - Signature Profile SSP-004, Submodel Repository Service Specification - Signature Profile SSP-003, and Concept Description Repository Service Specification - Signature Profile SSP-004 (https://github.com/admin-shell-io/aas-specs-api/issues/518[#518]) * Add the asynchronous AASX File Server Service Specification (https://github.com/admin-shell-io/aas-specs-api/issues/347[#347]) +* Added: Query Filter and FragmentFieldIdentifiers (https://github.com/admin-shell-io/aas-specs-api/issues/517) * Add new section in the annex on the usage of the AAS Services for implementing a digital product passport (DPP) based on EN 18222 and the relevant API operations for DPP interactions. This section also includes an overview of how to expose the DPP interactions through a REST API that follows the specifications of the AAS Services. diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/http-rest-api/test/query/test1.json b/documentation/IDTA-01002-3/modules/ROOT/pages/http-rest-api/test/query/test1.json index 96798d18..81840f11 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/http-rest-api/test/query/test1.json +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/http-rest-api/test/query/test1.json @@ -1,21 +1,21 @@ { "$schema": "../../query-json-schema.json", "select": "id", - "filter": { - "$and":[ - { + "$filters": [ + { + "$fragment": "$sme#value", + "$condition": { "$eq": [ { - "strModel": "$sm.semanticId.keys.value" + "$field": "$sm#semanticId.keys[].value" }, { - "strVal": "https://example.org/value" + "$strVal": "https://example.org/value" } ] - }, - {} - ] - }, + } + } + ], "option": { "sort": { "id": "asc" diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc b/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc index 43149df5..0140fe39 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc @@ -545,6 +545,113 @@ a| | Both $match conditions are fulfilled, even though for different SpecificAssetIds. Therefore the OR clause also evaluates to `true` for both items. |=== +== Query Filter + +The Query Language supports a `$filters` option that allows clients to reduce the amount of returned data. This can significantly improve response times, as the backend may scan and process fewer data elements. Furthermore, filtering is an important mechanism in the security domain, as it helps restrict access to sensitive information by preventing unnecessary exposure of internal data structures. + +`$filters` expressions can be applied to specific metamodel elements of the AAS (e.g., `Submodel`, `Submodel Elements` contained within an `Submodel`, etc.). However, not all elements can be filtered arbitrarily. If a particular metamodel element is mandatory according to the AAS specification, filtering it out would result in invalid or incomplete data structures. Therefore, such filtering operations are prohibited to ensure consistency and correctness of the returned data. +Since a valid Reference requires at least one key, filters that eliminate all keys remain valid but result in the removal of the entire Reference rather than just its keys. + +If no `$filters` is specified for a particular metamodel element, that element remains unfiltered. Thus, applying additional filters can only reduce the amount of data returned; it can never increase the amount of data or introduce information that is not already present in the underlying AAS. If multiple filters are specified and apply to overlapping data, they are combined using logical AND semantics. + +Filter example with boolean condition +[.table-with-appendix-table] +[width=100%, cols="40%,40%,20%"] +|=== +h| Grammar h| JSON Schema h| Comment +a| +[source] +---- +$sm#semanticId $eq + "https://admin-shell.io/idta/nameplate/3/0/Nameplate" +$filters + $fragment $sme.AddressInformation.Zipcode + $condition false +---- +a| +[source,json] +---- +{ + "$condition": { + "$eq": [ + { + "$field": "$sm#semanticId" + }, + { + "$strVal": "https://admin-shell.io/idta/nameplate/3/0/Nameplate" + } + ] + }, + "$filters": [ + { + "$fragment": "$sme.AddressInformation.Zipcode", + "$condition": { + "$boolean": false + } + } + ] +} + +---- +a| Selects Nameplate submodels and filters out `AddressInformation.Zipcode` data. +a| +[source] +---- +$sm#semanticId $eq + "https://admin-shell.io/idta/nameplate/3/0/Nameplate" +$filters + $fragment $sme#value + $condition $sm#semanticId.keys[].value $eq "HIDE_VALUE" + $fragment $sm#semanticId.keys[] + $condition $sm#semanticId.keys[].value $eq "HIDE_VALUE" +---- +a| +[source,json] +---- +{ + "$condition": { + "$eq": [ + { + "$field": "$sm#semanticId" + }, + { + "$strVal": "https://admin-shell.io/idta/nameplate/3/0/Nameplate" + } + ] + }, + "$filters": [ + { + "$fragment": "$sme#value", + "$condition": { + "$eq": [ + { + "$field": "$sm#semanticId.keys[].value" + }, + { + "$strVal": "HIDE_VALUE" + } + ] + } + }, + { + "$fragment": "$sm#semanticId.keys[]", + "$condition": { + "$eq": [ + { + "$field": "$sm#semanticId.keys[].value" + }, + { + "$strVal": "HIDE_VALUE" + } + ] + } + } + ] +} + +---- +a| Selects Nameplate submodels and filters out values from all nested submodel elements when the key "HIDE_VALUE" is present in the submodel’s semanticId. Additionally, any "HIDE_VALUE" keys in the submodel’s semanticId are removed from the result. +|=== == Sorting and Pagination @@ -593,14 +700,15 @@ The table follows the structure of the JSON schema top to bottom. [width=100%, cols="25%,25%,50%"] |=== h| JSON Schema h| Grammar h| Comment -| modelStringPattern | | AAS model elements are strings which start with a $ +| FieldIdentifier | | AAS model elements are strings which start with a $ +| FragmentFieldIdentifier | | AAS model fragments for query/security filtering | standardString | | All other value strings | hexLiteralPattern | | | dateTimeLiteralPattern | | | timeLiteralPattern | | | Value | | Comparisons eq, ne, gt, ge, lt, le; explicit properties for automatic code generation: strModel etc. | stringValue | | String operations contains, starts-with, ends-with, regex; explicit properties for automatic code generation: strModel etc. -| $field | - | string following the modelStringPattern +| $field | - | string following the FieldIdentifier pattern | $strVal | - | string following the standardString | $attribute | - | explained in Security Access Rules; not used for query language | $numVal | | Number constant @@ -627,7 +735,9 @@ h| JSON Schema h| Grammar h| Comment | rightsEnum | - | explained in Security Access Rules; not used for query language | AccessPermissionRule | - | explained in Security Access Rules; not used for query language | AllAccessPermissionRules | - | explained in Security Access Rules; not used for query language +| QueryFilter | | A single filter block with $fragment and $condition | $condition | | Root object for the query condition expression +| $filters | * | Optional list of filter blocks evaluated together | $select | | Optional expresion to control the returned fields. Only 'id' is possible. |=== diff --git a/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc b/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc index 4b4bcd86..5b6df557 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/schema.adoc @@ -1,4 +1,4 @@ -.... +.... { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Common JSON Schema for AAS Queries and Access Rules", @@ -8,9 +8,13 @@ "type": "string", "pattern": "^(?!\\$).*" }, - "modelStringPattern": { + "FieldIdentifier": { + "type": "string", + "pattern": "^(?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|submodels\\[[0-9]*\\]\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))|\\$sm#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*)*)?#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|value|valueType|language)|\\$cd#(?:idShort|id)|\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)|submodelDescriptors\\[[0-9]*\\]\\.(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))|\\$smdesc#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))$" + }, + "FragmentFieldIdentifier": { "type": "string", - "pattern": "^(?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|submodels\\[[0-9]*\\]\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))|\\$sm#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[[0-9]*\\])?(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*)*)?#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[[0-9]*\\])?(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|value|valueType|language)|\\$cd#(?:idShort|id)|\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)|submodelDescriptors\\[[0-9]*\\]\\.(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[[0-9]*\\])?(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))|\\$smdesc#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|supplementalSemanticIds(?:\\[[0-9]*\\])?(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))$" + "pattern": "^(?:\\$aas#(?:idShort|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[[0-9]*\\](?:\\.externalSubjectId(?:\\.keys\\[[0-9]*\\])?)?|submodels\\[[0-9]*\\](?:\\.keys\\[[0-9]*\\])?)|\\$sm#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*)*)?(?:#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|value|valueType|language))?|\\$cd#idShort|\\$aasdesc#(?:idShort|description|displayName|extension|administration|assetKind|assetType|globalAssetId|specificAssetIds\\[[0-9]*\\](?:\\.externalSubjectId(?:\\.keys\\[[0-9]*\\])?)?|endpoints\\[[0-9]*\\]|submodelDescriptors\\[[0-9]*\\](?:\\.(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|endpoints\\[[0-9]*\\]))?)|\\$smdesc#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|endpoints\\[[0-9]*\\]))$" }, "hexLiteralPattern": { "type": "string", @@ -28,7 +32,7 @@ "type": "object", "properties": { "$field": { - "$ref": "#/definitions/modelStringPattern" + "$ref": "#/definitions/FieldIdentifier" }, "$strVal": { "$ref": "#/definitions/standardString" @@ -180,7 +184,7 @@ "type": "object", "properties": { "$field": { - "$ref": "#/definitions/modelStringPattern" + "$ref": "#/definitions/FieldIdentifier" }, "$strVal": { "$ref": "#/definitions/standardString" @@ -653,6 +657,12 @@ "FILTER": { "$ref": "#/definitions/SecurityQueryFilter", "additionalProperties": false + }, + "FILTERLIST": { + "type": "array", + "items": { + "$ref": "#/definitions/SecurityQueryFilter" + } } }, "allOf": [ @@ -705,7 +715,7 @@ "type": "object", "properties": { "FRAGMENT": { - "type": "string" + "$ref": "#/definitions/FragmentFieldIdentifier" }, "CONDITION": { "$ref": "#/definitions/logicalExpression" @@ -730,10 +740,23 @@ } ], "additionalProperties": false - } - }, - "type": "object", - "properties": { + }, + "QueryFilter": { + "type": "object", + "properties": { + "$fragment": { + "$ref": "#/definitions/FragmentFieldIdentifier" + }, + "$condition": { + "$ref": "#/definitions/logicalExpression" + } + }, + "required": [ + "$fragment", + "$condition" + ], + "additionalProperties": false + }, "Query": { "type": "object", "properties": { @@ -743,6 +766,12 @@ }, "$condition": { "$ref": "#/definitions/logicalExpression" + }, + "$filters": { + "type": "array", + "items": { + "$ref": "#/definitions/QueryFilter" + } } }, "required": [ diff --git a/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf b/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf index ec3a9b5d..0f11cb34 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf +++ b/documentation/IDTA-01002-3/modules/ROOT/partials/bnf/grammar.bnf @@ -1,7 +1,10 @@ ::= | - ::= ? + ::= ? ( "$filters" * )? ::= "$select" "id" + ::= + ( "$fragment" ) + ( "$condition" ) ::= | | | | | | | @@ -91,21 +94,22 @@ ( "DEFACLS" )* ( "DEFOBJECTS" )* ( "DEFFORMULAS" )* - ( )* - + ( )* + ::= - "ACCESSRULE:" + "ACCESSRULE:" ( | ) "OBJECTS:" ( )* ( )* - ( ( "FORMULA:" ) | ( ) ) - ( "FILTER:" )? - - ::= - + ( ( "FORMULA:" ) | ( ) ) + ( "FILTER:" )? + ( "FILTERLIST:" ( )* )? + + ::= + ( "FRAGMENT:" ) ( ( "CONDITION:" ) | ( ) ) - + ::= "ATTRIBUTES:" ( )* @@ -124,7 +128,7 @@ ::= | | - + ::= "CLAIM" "(" ")" @@ -132,12 +136,17 @@ "GLOBAL" "(" ( "LOCALNOW" | "UTCNOW" | "CLIENTNOW" | "ANONYMOUS" ) ")" ::= - "REFERENCE" "(" ")" - + "REFERENCE(" ( + ("$aas" "#" ) | + ("$sm" "#" ) | + ("$cd" "#" ) | + ("$sme" "." "#" ) + ) ")" + ::= ( )* ( )* - + ::= "USEATTRIBUTES" @@ -147,17 +156,20 @@ ::= "ROUTE" + ::= "(" ")" + ::= | "(\"*\")" + ::= - "IDENTIFIABLE" + "IDENTIFIABLE" ("$aas" | "$sm" | "$cd") ::= - "REFERABLE" - - ::= + "REFERABLE" "$sme" "." + + ::= "FRAGMENT" ::= - "DESCRIPTOR" + "DESCRIPTOR" ("$aasdesc" | "$smdesc") ::= ( )* @@ -182,11 +194,10 @@ ::= ::= ::= + - + ::= [0-9] ::= "\"" ( [A-Z] | [a-z] | [0-9] | "/" | "*" | "[" | "]" | "(" | ")" | " " | "_" | "@" | "#" | "\\" | "+" | "-" | "." | "," | ":" | "$" | "^" )+ "\"" ::= - ::= ::= ::= ::= @@ -197,18 +208,44 @@ ::= "true" | "false" ::= | | | | | - ::= "$aas#" ( "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels" ( "[" ( [0-9]* ) "]" ) "." ) - ::= "$sm#" ( | "idShort" | "id" ) - ::= "$sme" ( "." )? "#" ( | "idShort" | "value" | "valueType" | "language" ) - ::= "$cd#" ( "idShort" | "id" ) - ::= "$aasdesc#" ( "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | | "endpoints" ( "[" ( [0-9]* ) "]" ) "." | "submodelDescriptors" ( "[" ( [0-9]* ) "]" ) "." ) + + ::= "$aas#" + ::= "$sm#" + ::= "$sme" ( "." )? "#" + ::= "$cd#" + ::= "$aasdesc#" ::= "$smdesc#" + + ::= "idShort" | "id" | "assetInformation.assetKind" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels" ( "[" ( [0-9]* ) "]" ) "." + ::= | "idShort" | "id" + ::= | "idShort" | "value" | "valueType" | "language" + ::= "idShort" | "id" + ::= "idShort" | "id" | "assetKind" | "assetType" | "globalAssetId" | | "endpoints" ( "[" ( [0-9]* ) "]" ) "." | "submodelDescriptors" ( "[" ( [0-9]* ) "]" ) "." ::= ( | "idShort" | "id" | "endpoints" ( "[" ( [0-9]* ) "]" ) "." ) - ::= "interface" | "protocolinformation.href" - + ::= "interface" | "protocolinformation.href" + ::= ( "type" | "keys" ( "[" ( [0-9]* ) "]" ) ( ".type" | ".value" ) ) ::= ( "semanticId" | "semanticId." ) ::= ( "specificAssetIds" ( "[" ( [0-9]* ) "]" ) ( ".name" | ".value" | ".externalSubjectId" | ".externalSubjectId." ) ) + + + ::= | | | | | + + ::= "$aas#" ( "idShort" | "assetInformation.assetType" | "assetInformation.globalAssetId" | "assetInformation." | "submodels" ( "[" ( [0-9]* ) "]" ) ("." )? ) + ::= "$sm#" ( | "idShort" | "id" ) + ::= "$sme" ( "." )? ( "#" ( | "idShort" | "value" | "valueType" | "language" ))? + ::= "$cd#" ( "idShort" ) + ::= "$aasdesc#" ( "idShort" | "description" | "displayName" | "extension" | "administration" | "assetKind" | "assetType" | "globalAssetId" | | | "submodelDescriptors[" ( [0-9]* ) "]" ("." )? ) + ::= "$smdesc#" + + ::= "specificAssetIds" ( "[" ( [0-9]* ) "]" ) (".externalSubjectId" | ".externalSubjectId." )? + ::= ( | "idShort" | ) + ::= "endpoints" ( "[" ( [0-9]* ) "]" ) + + ::= "semanticId" | "semanticId." + ::= "keys[" ( [0-9]* ) "]" + + ::= ( ("[" ( [0-9]* ) "]" )* ( "." )* ) ::= ( ( [a-z] | [A-Z] ) ( [a-z] | [A-Z] | [0-9] | "_" | "-" )* ( [a-z] | [A-Z] | [0-9] | "_" ) ) diff --git a/documentation/IDTA-01002-3/modules/ROOT/partials/diagrams/query-language-overview.puml b/documentation/IDTA-01002-3/modules/ROOT/partials/diagrams/query-language-overview.puml index 22fc8029..128128bd 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/partials/diagrams/query-language-overview.puml +++ b/documentation/IDTA-01002-3/modules/ROOT/partials/diagrams/query-language-overview.puml @@ -89,7 +89,7 @@ enum SelectField { } enum FieldIdentifier { - $strModel + $field } enum Value { diff --git a/documentation/IDTA-01002-3/modules/ROOT/partials/query-json-schema.json b/documentation/IDTA-01002-3/modules/ROOT/partials/query-json-schema.json index 78ab1b23..6de4936e 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/partials/query-json-schema.json +++ b/documentation/IDTA-01002-3/modules/ROOT/partials/query-json-schema.json @@ -8,10 +8,14 @@ "type": "string", "pattern": "^(?!\\$).*" }, - "modelStringPattern": { + "FieldIdentifier": { "type": "string", "pattern": "^(?:\\$aas#(?:idShort|id|assetInformation\\.assetKind|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|submodels\\[[0-9]*\\]\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))|\\$sm#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id)|\\$sme(?:\\.[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9_](?:\\[[0-9]*\\])*(?:\\.[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9_](?:\\[[0-9]*\\])*)*)?#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|value|valueType|language)|\\$cd#(?:idShort|id)|\\$aasdesc#(?:idShort|id|assetKind|assetType|globalAssetId|specificAssetIds\\[[0-9]*\\]\\.(?:name|value|externalSubjectId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?)|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)|submodelDescriptors\\[[0-9]*\\]\\.(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))|\\$smdesc#(?:semanticId(?:\\.(?:type|keys\\[[0-9]*\\]\\.(?:type|value)))?|idShort|id|endpoints\\[[0-9]*\\]\\.(?:interface|protocolinformation\\.href)))$" }, + "FragmentFieldIdentifier": { + "type": "string", + "pattern": "^(?:\\$aas#(?:idShort|assetInformation\\.assetType|assetInformation\\.globalAssetId|assetInformation\\.specificAssetIds\\[[0-9]*\\](?:\\.externalSubjectId(?:\\.keys\\[[0-9]*\\])?)?|submodels\\[[0-9]*\\](?:\\.keys\\[[0-9]*\\])?)|\\$sm#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|id)|\\$sme(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*(?:\\.[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\[[0-9]*\\])*)*)?(?:#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|value|valueType|language))?|\\$cd#idShort|\\$aasdesc#(?:idShort|description|displayName|extension|administration|assetKind|assetType|globalAssetId|specificAssetIds\\[[0-9]*\\](?:\\.externalSubjectId(?:\\.keys\\[[0-9]*\\])?)?|endpoints\\[[0-9]*\\]|submodelDescriptors\\[[0-9]*\\](?:\\.(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|endpoints\\[[0-9]*\\]))?)|\\$smdesc#(?:semanticId(?:\\.keys\\[[0-9]*\\])?|idShort|endpoints\\[[0-9]*\\]))$" + }, "hexLiteralPattern": { "type": "string", "pattern": "^16#[0-9A-F]+$" @@ -28,7 +32,7 @@ "type": "object", "properties": { "$field": { - "$ref": "#/definitions/modelStringPattern" + "$ref": "#/definitions/FieldIdentifier" }, "$strVal": { "$ref": "#/definitions/standardString" @@ -172,7 +176,7 @@ "type": "object", "properties": { "$field": { - "$ref": "#/definitions/modelStringPattern" + "$ref": "#/definitions/FieldIdentifier" }, "$strVal": { "$ref": "#/definitions/standardString" @@ -637,6 +641,12 @@ "FILTER": { "$ref": "#/definitions/SecurityQueryFilter", "additionalProperties": false + }, + "FILTERLIST": { + "type": "array", + "items": { + "$ref": "#/definitions/SecurityQueryFilter" + } } }, "allOf": [ @@ -689,7 +699,7 @@ "type": "object", "properties": { "FRAGMENT": { - "type": "string" + "$ref": "#/definitions/FragmentFieldIdentifier" }, "CONDITION": { "$ref": "#/definitions/logicalExpression" @@ -715,6 +725,22 @@ ], "additionalProperties": false }, + "QueryFilter": { + "type": "object", + "properties": { + "$fragment": { + "$ref": "#/definitions/FragmentFieldIdentifier" + }, + "$condition": { + "$ref": "#/definitions/logicalExpression" + } + }, + "required": [ + "$fragment", + "$condition" + ], + "additionalProperties": false + }, "Query": { "type": "object", "properties": { @@ -724,6 +750,12 @@ }, "$condition": { "$ref": "#/definitions/logicalExpression" + }, + "$filters": { + "type": "array", + "items": { + "$ref": "#/definitions/QueryFilter" + } } }, "required": [