diff --git a/Part2-API-Schemas/openapi.yaml b/Part2-API-Schemas/openapi.yaml index 9b9efa7d..a495a662 100644 --- a/Part2-API-Schemas/openapi.yaml +++ b/Part2-API-Schemas/openapi.yaml @@ -625,10 +625,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)))$ + 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" @@ -792,7 +796,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: @@ -1054,7 +1073,7 @@ components: type: object properties: $field: - $ref: '#/components/schemas/modelStringPattern' + $ref: '#/components/schemas/FieldIdentifier' $strVal: $ref: '#/components/schemas/standardString' $strCast: @@ -1178,7 +1197,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 1498412d..37e5604c 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/changelog.adoc @@ -16,7 +16,7 @@ Major Changes: * 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) Minor Changes: @@ -27,7 +27,6 @@ Minor Changes: * Removed the `GetAllAssetAdministrationShellDescriptorsByAssetType` operation from the OpenAPI files for the Asset Administration Shell Registry Service Specification, as it was not intended to be included in the first place and is not implemented by any known implementation. (https://github.com/admin-shell-io/aas-specs-api/issues/515[#515]) * Editorial: Remove links to SwaggerHub from the HTTP API section, as the links are maintained in the service specifications and profiles sections. (https://github.com/admin-shell-io/aas-specs-api/issues/475[#475]) - === Operation Changes w.r.t. V3.1.2 to V3.2 [%autowidth,width="100%",cols="40%,15%,45%",options="header",] 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 ad894b63..c54e23f4 100644 --- a/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc +++ b/documentation/IDTA-01002-3/modules/ROOT/pages/query-language.adoc @@ -507,6 +507,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 @@ -530,14 +637,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 @@ -564,7 +672,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 8ea759ce..91124a2c 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)))?|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)))$" + "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 dcb67770..00d3d5ec 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 a5f131d6..0223bc53 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": [